Import CSV Dateien + Befüllung von geb. Verkaufslieferungen

6. März 2020 20:30

Hallo zusammen,

ich habe ein paar Fragen bezüglich einer Übungsaufgabe die ich bekommen habe, da ich erst dieses Jahr meine Ausbildung als AE begonnen habe, habe ich noch nicht so viel Erfahrung in der Programmierung bzw. der Anwendung von NAV und hoffe das ihr mir weiterhelfen könnt.

Folgende Situation ist gegeben:
Der Kunde bekommt jede Nacht auf den Verzeichnissen "C:\temp\tracking\<Zusteller>\CSV-Datei" eine Datei von den Zustellern DHL und UPS abgelegt. Diese CSV Dateien beinhalten Informationen über die Lieferscheinnr., die Paketverfolgunsnr. und den Zustellzeitpunkt. Der Kunde wünscht sich nun den automatischen import dieser Dateien in das ERP per Job (für Aufgabenwarteschlange). Über die Lieferscheinnr. sollen entsprechend die Paketverfolgungsnr. und das Zustelldatum in der Geb. Verkaufslieferung gefüllt werden. Bestehende Daten sollen überschrieben werden. Zukünftig kommen noch mehr Zusteller hinzu.

Layout CSV-Dateien:

DHL:
Lieferscheinnr.;Paketverfolgunsnr.;Zustelldatum
LS00001|DHL00001|11.02.2020

UPS:
Positionsnr.|Lieferscheinnr.|Int. Referenznr.|Paketverfolgunsnr.|Zustellung
001|LS00002|UPS00001|2020-02-11 15:30

Nach der Verarbeitung der Dateien sollen diese in ein Unterverzeichnis "Archiv" verschoben werden.
Wenn es bei der Verarbeitung einer Datei zu einem Fehler kommt, muss die Datei in das Unterverzeichnis "Error" verschoben werden.
Für diese Datei darf keine Verarbeitung in der Datenbank erfolgen, d.h. wenn nach 5 Zeilen ein Fehler auftritt, dürfen die Daten aus den ersten 4 Zeilen nicht in der Datenbank stehen!
Bei einem Fehler soll kein Abbruch des Imports eines anderen Zustellers passieren.

Optionale Erweiterung: Protokollierung in eigener Tabelle mit Dateiname, Datum, Uhrzeit, eingelesenen Zeilen und ggf. zuletzt aufgetretenem Fehler.


Bisher habe ich folgende Anpassungen vorgenommen:
Table 110 - Sales Shipment Header: Feld "Delivered on" (Date) hinzugefügt.
Page 130 - Posted Sales Shipment: Feld "Delivered on" eingefügt.
Table 311 - Sales & Receivables Setup: Feld "Export to Path" Text[30] hinzugefügt.
OnAfterValidate Event auf "Export to Path" mit folgendem Code:
Code:
IF STRLEN("Export to Path") > 0 THEN BEGIN
            IF COPYSTR("Export to Path", STRLEN("Export to Path")) <> '\' THEN BEGIN
                "Export to Path" += '\';
            END;
         END;

Table 311 Sales & Receivables Setup: Feld "Archive Folder" Text[30] hinzugefügt.
OnAfterValidate Event auf "Archive Folder" mit gleichem Code wie im "Export to Path" Event.
Table 311 Sales & Receivables Setup: Feld "Error Folder" Text[30] hinzugefügt.
OnAfterValidate Event auf "Error Folder" mit gleichem Code wie im "Export to Path" Event.
Page 459 - Sales & Receivables Setup: Feld "Export to Path", "Archive Folder", "Error Folder" eingefügt.
XMLPort 50004 - Shipment Head. File Import erstellt.
Layout:
ShipmentFileImport | Element | Text | <ShipmentFileImport>
SalesShipmtHeadRec | Elemnt | Table | <Sales Shipment Header>(Sales Shipment Header)
SalesShipmtHeadNo | Element | Field | Sales Shipment Header::No
PackageTrackingNo | Element | Field | Sales Shipment Header::Packaging Tracking No
DeliveredOn | Element | Field | Sales Shipment Header::Delivered on
SalesShipmtHeadRec geänderte Properties: AutoUpdate: "Yes"
DeliveredOn geänderte Properties: Widht: 10
XMLPort geänderte Properties: -Direction: Import
-Format: Variable Text
-FieldSeperator: |
-UseRequestPage: No
Codeunit - 50009 "Job Queue Shipmt. File Import" erstellt.
Folgender Code wurde im OnRun-Trigger der CU hinterlegt:
Code:
SalesReceivablesSetupLoc.GET;
          FileLoc.SETRANGE(Path,SalesReciablesSetupLoc."Export to Path");
          FileLoc.SETRANGE("Is a file", TRUE)
          IF FileLoc.FINDSET THEN BEGIN
            REPEAT
               ImportCSVFileLoc.OPEN(SalesReceivablesSetupLoc."Export to Path" + FileLoc.Name);
               ImportCSVFileLoc.CREATEINSTREAM(CSVInStreamLoc)
               IF XMLPort.IMPORT(XMLPORT::"Shipment Head. File Import", CSVInStreamLoc) THEN BEGIN
                   ImportCSVFileLoc.CLOSE;
                   FILE.COPY(SalesReceivablesSetupLoc."Export to Path" + FileLoc.Name,
                                    SalesReceivablesSetupLoc."Archive Folder" + FileLoc.Name);
                   FILE.ERASE(SalesReceivablesSetupLoc."Export to Path" + FileLoc.Name);
                   END ELSE BEGIN
                        ImportCSVFileLoc.CLOSE;
                         FILE.COPY(SalesReceivablesSetupLoc."Export to Path" + FileLoc.Name,
                                          SalesReceivablesSetupLoc."Archive Folder" + FileLoc.Name);
                         FILE.ERASE(SalesReceivablesSetupLoc."Export to Path" + FileLoc.Name);
                   END;
             UNTIL FileLoc.NEXT = 0
          END;

Das klappt bisher auch ganz gut so, jedoch musste ich dafür das Layout der CSV Datei auf folgendes ändern:
DHL-Datei:
LS00001|DHL00001|11.02.2020
UPS-Datei:
LS00002|UPS00001|11.02.2020

Meine Frage wäre hier wie bekomme ich das bei der UPS/DHL Datei so hin, dass ich die Überschriften mit in die Datei nehmen kann also "Lieferscheinnr." "Positionsnr." etc. und ich die Dateien
dann trotzdem noch importieren kann, falls das überhaupt so möglich ist?
Außerdem sollte ich für DHL und UPS jeweils eine eigene Codeunit/Report zum importieren nutzen? Oder kann ich das auch in einer CU/Report erledigen?
Brauche ich dann zusätzlich noch einen 2. XMLPort mit angepassten Feldern im Bezug auf UPS wegen der Positionsnr.?

Die zweite Frage wäre wie kann ich das
Wenn es bei der Verarbeitung einer Datei zu einem Fehler kommt, muss die Datei in das Unterverzeichnis "Error" verschoben werden.
Für diese Datei darf keine Verarbeitung in der Datenbank erfolgen, d.h. wenn nach 5 Zeilen ein Fehler auftritt, dürfen die Daten aus den ersten 4 Zeilen nicht in der Datenbank stehen!

umsetzen? Das einzige was ich dazu gefunden habe ist, dass man mit COMMITS bzw. in der Codeunit das Property Subtype auf Test stellen kann, wann dann jedoch ein Rollback passiert habe ich nicht ganz verstanden bzw wie ich dieses Rollback an die Bedingung Import ist fehlgeschlagen knüpfen kann. Außerdem habe ich noch etwas zu einem Rollback mit einem ASSERTERROR Statement gelesen, jedoch auch nicht richtig verstanden ob das in meinem Fall hilfreich ist bzw. wie ich es in meinem Fall nutzen könnte.

Ich hoffe ihr könnt mir weiterhelfen und ich entschuldige mich schon mal dafür, dass es so ein riesiger Post geworden ist.

MFG Horizon

Re: Import CSV Dateien + Befüllung von geb. Verkaufslieferun

6. März 2020 21:08

Hallo,

als erstes möchte ich dir empfehlen, dich mir der Codeunit 419 "Filemanagement" auseinander zu setzen. Dort werden Funktionen für das Dateihandling sowohl auf dem Server als auch auf dem Client zur Verfügung gestellt.

Ich persönlich halte nicht viel von XML-Ports zum Import von CSV-Dateien. Ich verwende dazu meist Reports oder direkt eine Codeunit.
Darin lese ich die Datei Zeilenweise ein, und verwende eine selbst gebaute Funktion Split, die funktioniert wie die entsprechende .Net- Funktion.

Ich hoffe dir damit ein paar Tipps gegeben zu haben, um deine Probleme zu lösen.

Ich werde dir keine Lösung präsentieren. Du willst ja etwas lernen, und das tut man nur wenn man etwas selbst tut. :lol:
Aber vielleicht, wenn du gar nicht mehr weiter weißt, wenn man hier etwas sucht. 8-)

Gruß Fiddi

Re: Import CSV Dateien + Befüllung von geb. Verkaufslieferun

7. März 2020 13:03

Vielen Dank ich werde mir auf jeden Fall mal die Codeunit anschauen. Wie die .NET Funktion Split aufgebaut ist und was sie macht werde ich mir wohl auch noch anschauen.
Ich melde mich dann noch mal falls, Unklarheiten bestehen.

MFG Horizon