[Gelöst] Alle Dateien eines Ordners abarbeiten

14. Dezember 2007 16:31

Mit NAV + File kenn ich mich ja überhaupt nicht aus ...

Ich habe einen Ordner, in denen einige txt-Dateien abgelegt werden.
Für jede dieser Dateien soll ein Dataport laufen (das nur als Hintergrund).

Was ich nicht habe, ist ein fester Dateiname, nur den Ordner.
Wie kann ich nun in einer Schleife alle enthaltenen Dateien abarbeiten?

Hier in Pseudocode
Code:
Gehe in Ordner.
AktDatei := Erste Datei.
REPEAT
  Lese Pfad + Name und führe damit was aus
  Gehe zu  nächster Datei
UNTIL letzte Datei gelesen
Zuletzt geändert von Natalie am 18. Dezember 2007 12:36, insgesamt 2-mal geändert.

14. Dezember 2007 16:34

Liegt der Ordner immer im gleichen Pfad? Weil das haben wir bei uns auch. Also txt-Dateien liegen in einem Ordner (immer gleicher Pfad) und werden mit Hilfe eines Dataports in Navision eingespielt. Wobei der Name der txt-Datei immer variiert.

14. Dezember 2007 16:35

Exakt so meine ich es :-)

14. Dezember 2007 16:39

Also bei uns ist das so aufgebaut:

In der Tabelle 311 Sales & Receivables Setup ist der Pfad für den Ordner hinterlegt.
Dann haben wir eine CodeUnit welche den Pfadnamen ausliesst, die Dateinamen aus dem Ordner nimmt und dies dann komplett einem Dataport übergibt, welcher dann den Import durchführt.

Ich werd mal den Code kürzen und dann hier reineditieren. Dauert n paar minütchen.

Nachtrag:

Code:
//OnRun
StartImport(TRUE);

//StartImport(Var : Boolean)
SaleSetup.GET;
SaleSetup.TESTFIELD("Dateiverzeichnis Import");

SaleSetup."Dateiverzeichnis Import" :=
  DELCHR(SaleSetup."Dateiverzeichnis Import",'>','\')  + '\';


File.RESET;
File.SETRANGE(Path,SaleSetup."Dateiverzeichnis Import");
File.SETRANGE("Is a file",TRUE);
File.SETFILTER(Name,'*.txt');
REPEAT
ImportiereDatei(File.Name)
UNTIL File.NEXT = 0;

//ImportiereDatei(Dateiname : Text[250]) : Boolean

IF NOT EXISTS(SaleSetup."Dateiverzeichnis Import" + Dateiname) THEN BEGIN
  EXIT(FALSE);
END;

CLEAR(Dataportimport);
Dataportimport.DateinameSetzen(SaleSetup."Dateiverzeichnis Import" + Dateiname);
Dataportimport.RUNMODAL;
EXIT(TRUE);

File ist eine Record Variable vom Subtyp File.

Ich hoffe das ist einigermaßen verständlich.. und auch richtig. Bei uns ist da noch n bischen mehr drumm herum.. deswegen hoff ich, ich hab nix vergessen oder so :/ Hoffe du kannst damit was anfangen.

15. Dezember 2007 13:44

um bei dem nächsten Durchlauf die neuen Files zu sehen ist aber noch was nötig, sonst hat die Tabelle File immer noch den alten Inhalt, auch wenn die tatsächlichen Dateien nicht mehr existieren. Das Verzeichnis wird nämlich nur neu gescannt, wenn zwischendurch ein anderer Pfad gewählt wurde.
Am einfachsten geht das, wenn du nach dem File.RESET noch folgende beiden Zeilen einfügst:
Code:
File.SETRANGE(Path,'');
IF File.ISEMPTY THEN;

16. Dezember 2007 21:27

Super ihr zwei, danke, :-)
werd das gleich Montag mal ausprobieren ...

17. Dezember 2007 10:52

Hm, fehlt hier
Code:
File.RESET;
File.SETRANGE(Path,SaleSetup."Dateiverzeichnis Import");
File.SETRANGE("Is a file",TRUE);
File.SETFILTER(Name,'*.txt');
REPEAT
  ImportiereDatei(File.Name)
UNTIL File.NEXT = 0;

vor dem REPEAT nicht ein FIND ...?

17. Dezember 2007 11:22

Oh ja sorry. Hatte ich übersehen. Bei uns steht da auch ein Findfirst :oops:

17. Dezember 2007 11:59

Heike Bennerscheid hat geschrieben:Bei uns steht da auch ein Findfirst :oops:


Performanter wäre hier aber ein FIND('-').

Gruß, Marc

17. Dezember 2007 12:13

Soooo das klappt, nun schon die nächste Aufgabe:
Folgendes möchte ich realisieren (bzw. habe ich auch)

(Pseudocode)
Code:
Für alle Dateien
  RufeDataportAuf;
  IF Dataport erfolgreich
    Verschiebe Datei In Order 1
  ELSE
    Verschiebe Datei in Ordner 2


Problem war: Wie teilt mir der Dataport mit, dass er zwischendurch keinen Fehler gefunden hat?
Zuerst hatte ich eine Funktion, die mir den Inhalt einer globalen Variablen zurück geliefert hat.
Rief ich diese Funktion nach Dataport.RUN auf, gab sie immer ein FALSE zurück (nicht erfolgreich). Grund laut Onlinehilfe:
Dataport.RUN

Data type: dataport

... The system automatically clears the variable after it executes this function.


Oje.
Ich habs so gelöst, indem ich im Dataport die Datei je nach Erfolg in Order 1 oder 2 KOPIERE.
Meine aufrufende Codeunit (siehe Pseudocode oben) löscht die Datei nur noch.

Klappt alles wunderbar, aber - hätte ich das nicht einfacher lösen können? Das Verschieben der Codeunits gehört meiner Meinung nach in die Codeunit, nicht in den Dataport (der jetzt kopiert).

17. Dezember 2007 12:21

@Marc

Bei uns steht auch ein Find('-') ... war nur vorhin etwas in Eile als ich das getippt habe. Entschuldigung. Das nächste mal achte ich genauer darauf :oops:

@Natalie

Verstehe ich das richtig? Der Dataport läuft auf einen Fehler und soll dann die Datei in Ordner2 verschieben. Jedoch kopiert es dies zur Zeit nur und die CodeUnit löscht diese Datei dann aus dem Ursprungsordner?

17. Dezember 2007 12:25

Heike Bennerscheid hat geschrieben:@Natalie

Verstehe ich das richtig? Der Dataport läuft auf einen Fehler und soll dann die Datei in Ordner2 verschieben. Jedoch kopiert es dies zur Zeit nur und die CodeUnit löscht diese Datei dann aus dem Ursprungsordner?


So ist es.
Eigentlich wollte ich, dass der Dataport die Datei einfach nur verschiebt, doch das geht nicht, weil der Dataport bis zum Ausführungsende die Datei noch im Zugriff hat und diese sich dadurch nicht verschieben lässt.

17. Dezember 2007 12:30

Heike Bennerscheid hat geschrieben:Bei uns steht auch ein Find('-') ... war nur vorhin etwas in Eile als ich das getippt habe. Entschuldigung. Das nächste mal achte ich genauer darauf :oops:

Hier muss sich doch keiner entschuldigen! :-)

Gruß, Marc

17. Dezember 2007 17:40

Marc Teuber hat geschrieben:
Heike Bennerscheid hat geschrieben:Bei uns steht da auch ein Findfirst :oops:


Performanter wäre hier aber ein FIND('-').
Gruß, Marc


Da man hier aber mit hoher Wahrscheinlichkeit davon ausgehen kann, dass deutlich weniger als 500 Dateien in dem Verzeichnis stehen, ist FINDSET(FALSE,FALSE) die beste Lösung

17. Dezember 2007 19:48

Michael Schumacher hat geschrieben:Da man hier aber mit hoher Wahrscheinlichkeit davon ausgehen kann, dass deutlich weniger als 500 Dateien in dem Verzeichnis stehen, ist FINDSET(FALSE,FALSE) die beste Lösung


*kopfschüttel*
Nee, wir sind in NAV 3.70 ;-)
(oder zumindest ich im Augenblick)

17. Dezember 2007 20:28

Michael Schumacher hat geschrieben:Da man hier aber mit hoher Wahrscheinlichkeit davon ausgehen kann, dass deutlich weniger als 500 Dateien in dem Verzeichnis stehen, ist FINDSET(FALSE,FALSE) die beste Lösung

Vorausgesetzt, dass in den Datenbank-Einstellungen die Datensatzmenge auch entsprechend hoch eingestellt ist. ;-) Aber natürlich geben dir Recht, dass FINDSET(FALSE,FALSE) besser ist.

Gruß, Marc

18. Dezember 2007 12:31

*heul*
Das Ganze soll sich innerhalb des NAS abspielen, und der mag doch keine Dataports :-(
Dabei hatte alles bisher so toll geklappt ...