Hello World - I am going insane here people, and I am hoping that some of you would be able to help me out here. After implementing a NAS Server, we found out the hard way, that the NAS do NOT support Dataports. I am getting a TAB delimeted file, but I can’t seperate the fields: Here is what I have tried: Variables: ICSManifestFile - File FileContent - Text 1024 Tabulator - Char TabTxt - Text 30 TabPos - Integer ICSManifestFile.Textmode(True); ICSManifestFile.OPEN('C:\TEMP\ICSMANIFEST.TXT'); // <- Just Testing I would NEVER dream of hardcoding ICSManifestFile.READ(FileContent);
That gives me a Textvariable with the first line of the file. - All with me so far? Tabulator := 9; // I'm in the US - I have seen it as 11 also (tried both) TabTxt := FORMAT(Tabulator); TabPos := STRPOS(FileContent,TabTxt);
I would expect this would result in ‘TabPos’ being populated with 9 in my case, but it’s 0 I then tried annother approach: Variables: ICSManifestFile - File FileContent - Text 1024 Tabulator - Char TabTxt - Text 30 TabPos - Integer ICSManifestFile.Textmode(False); <- This is the Change ICSManifestFile.OPEN('C:\TEMP\ICSMANIFEST.TXT'); // <- Just Testing I would NEVER dream of hardcoding ICSManifestFile.READ(FileContent);
An Booom - I get an error, due to the fact the variable isn’t Long enough to contain the full value of the file. The help said that it would only read to the lenght of the variable - Well it sure as hell dodn’t work for a text variable. [V] After that, I tried importing the file into a Binary variable, and that goes fine - But how the do I get that value into something I can read - I cannot do an evaluate… Any help would be greatly appreciated!
Try creating an InStream for your file and reading the file using InStream.Read.
Henrik, I’ve had this problem as well. If you create a loop and show the ‘FileContent’ one character at a time type-casted to an integer, you will notice that Navision has converted the tabs to spaces (and a random amount between 1 and 8)! I solved by reading the file one character at a time (binary). A real pain, unless you have control over the format of the ICSmanifest file, in which case you could convert the file to fixed length or convert tabs to ~'s before you import. Or … perhaps an easier idea … run a dos command line program as part of your code to convert the icsmanifest file tabs to another character before you import! -john
Try This:- strCRLF := ’ '; strCRLF[1] := 13; // ASCII Value strCRLF[2] := 10; // ASCII Value strTAB := ’ '; strTAB[1] := 9; // ASCII Value File2.TEXTMODE(FALSE); // REQUIRED FOR SUCCESS //Start Writing Fields WriteFields(‘Field1’); WriteFields(‘Field2’); . . . WriteFields2(‘final Field’); File2.WRITE(strCRLF[1]); File2.WRITE(strCRLF[2]); //Functions WriteFields(FieldValue : Text[30]) FOR ChrPos := 1 TO STRLEN(FieldValue) DO File2.WRITE(FieldValue[ChrPos]); File2.WRITE(strTAB[1]); WriteFields2(FieldValue : Text[30]) FOR ChrPos := 1 TO STRLEN(FieldValue) DO File2.WRITE(FieldValue[ChrPos]); Variables are as under: strCRLF Text 2 strTAB Text 1 File2 File
Naveen - You do not need to have textmode to False when WRITING a file… Create a CHAR variable and a Text Variable Variables MyFile File Tabulator Char Tab Text 1 ==================== Tabulator := 9; Tab := format(Tabulator); MyFile.TEXTMODE(True); MyFile.CREATE('C:\temp\See_It_Works.txt'); MyFile.Write(STRSUBSTNO('%2%1%3%1%4',Tab,Field1,Field2,Field3)); MyFile.Close;
But more importently, I was asking how to IMPORT the file. I did figure it out, and I will post the code here once completed [-;]
OK - I promissed to get beck to y’all - **Variables** Name DataType Subtype Length ICSManifestFile File Package Record Package PostedPackage Record Posted Package FileContent Binary 100 Reference Text 50 AccountNo Text 30 Charges Text 30 ManifestReference Text 30 PINNumber Text 30 Voided Text 10 ChargesDec Decimal SkipProcessing Boolean FieldNo Integer BytesRead Integer FilePos Integer FileNameGUID GUID NewFileName Text 250 FileExtention Text 30 i Integer **Code** NewFileName := FileName; i := STRLEN(NewFileName); REPEAT i := i - 1; IF FileExtention = '' THEN BEGIN IF COPYSTR(NewFileName,i,1) = '.' THEN FileExtention := COPYSTR(NewFileName,i); END; UNTIL (i = 0) OR (COPYSTR(NewFileName,i,1) = '\'); NewFileName := COPYSTR(NewFileName,1,i); FileNameGUID := CREATEGUID; NewFileName := NewFileName + FORMAT(FileNameGUID) + FileExtention; IF EXISTS(FileName) THEN RENAME(FileName,NewFileName) ELSE EXIT; ICSManifestFile.TEXTMODE(FALSE); ICSManifestFile.OPEN(NewFileName); FieldNo := 1; REPEAT BytesRead := ICSManifestFile.READ(FileContent); FilePos := 0; REPEAT FilePos += 1; CASE FileContent[FilePos] OF 9 : FieldNo += 1; // TAB 13 : BEGIN // CR ProcesRecord; FieldNo := 1; FilePos += 1; // CR is two END; ELSE BEGIN CASE FieldNo OF 1 : Reference := Reference + FORMAT(FileContent[FilePos]); 2 : AccountNo := AccountNo + FORMAT(FileContent[FilePos]); 3 : Charges := Charges + FORMAT(FileContent[FilePos]); 4 : ManifestReference := ManifestReference + FORMAT(FileContent[FilePos]); 5 : PINNumber := PINNumber + FORMAT(FileContent[FilePos]); 6 : Voided := Voided + FORMAT(FileContent[FilePos]); END; END; END; UNTIL FilePos = BytesRead; UNTIL ICSManifestFile.POS = ICSManifestFile.LEN; IF FieldNo > 1 THEN ProcesRecord; ICSManifestFile.CLOSE; **ProcesRecord()** CASE TRUE OF PostedPackage.GET(Reference) : BEGIN IF UPPERCASE(Voided) <> UPPERCASE('YES') THEN PostedPackage."External Tracking No." := PINNumber ELSE PostedPackage."External Tracking No." := 'Voided'; EVALUATE(PostedPackage."Shipping Charge",Charges); PostedPackage.MODIFY; END; Package.GET(Reference) : BEGIN IF UPPERCASE(Voided) <> UPPERCASE('YES') THEN Package."External Tracking No." := PINNumber ELSE Package."External Tracking No." := 'Voided'; EVALUATE(PostedPackage."Shipping Charge",Charges); Package.MODIFY; END; END; Reference := ''; AccountNo := ''; Charges := ''; ManifestReference := ''; PINNumber := ''; Voided := ''; FieldNo := 1;
Thank you for sharing this info (and completing the topic), nice to have
quote:
Originally posted by ajhvdb
Thank you for sharing this info (and completing the topic), nice to have
My Pleasure - Hopefully I will be a trendsetter … [:)]
Ive never tried this, but can’t a NAS run a codeunit which in turn runs the dataport?
Nope - And you can’t even use a function that resides on a form!
Tx, It works. I was looking for this.
I ran across this old post and it has been very useful in a project I’ve been working on.
I’ve ran into an issue though that I’m struggling to come up with a solution for and I’ve looked at it so long now I think it’s something simple I’m just overlooking.
My problem is that the tab delimited files I’m working with have a field of text for the particular record that can well over 250 characters. That’s all fine, I’m doing some BigText things and using Waldo NavPad to throw the description in sort of a line table broken up in strings of 250. So in the end I get a header record and then multiple line records.
My issue occurs when the record exceeds 2000 characters. Since that FileContent variable is binary, once I exceed the 2000 max length I get an array is outside the permitted range error.
I know I’m just overthinking this because I can’t seem to find a solution. Any suggestions on how to restructure this code to work in this scenario?
REPEAT
BytesRead := ICSManifestFile.READ(FileContent);
FilePos := 0;
REPEAT
FilePos += 1;
CASE FileContent[FilePos] OF
9 : FieldNo += 1; // TAB
13 : BEGIN // CR
ProcesRecord;
FieldNo := 1;
FilePos += 1; // CR is two
END;
ELSE BEGIN