Import Fixed Lenght File

BeliasBelias Member Posts: 2,998
hi everyone, i have to import a textfile with fields with fixed lenght.
I can't use dataports for a couple of reasons, so i have started to work with the well known loop
WHILE lFLFile.POS < lINTFileLen DO BEGIN
  lFLFile.READ(lTXTLine);
  FunctionToModifyTheTable(lTXTLine);
END;
lFLFile.CLOSE;

FunctionToModifyTheTable(ptxtline):
...
EVALUATE("Posting Date",COPYSTR(pTXTLine,50,8));
...

as you can see, i've had to hardcode the startpos and len of the piece of string...which means that if the file changes it's an hard work to do :(
Do someone have already avoided this issue? if so, Can you share the code with us, please?
P.S.: i thought to use integers and calculate dynamically the startpos based on the width...but i risk to clutter the code with a lot of variables or declare a not self documenting array...
Thanks in advance
-Mirko-
"Never memorize what you can easily find in a book".....Or Mibuso
My Blog

Comments

  • koubekkoubek Member Posts: 84
    Why You can`t use dataport... I believe You can do it better with dataport than without it. But still if You use dataport with Fixed Format You must set as a Start Position as a Length too (ok, it`s much more transparent to do it in dataport than in code).
    Maybe only the way is to use separators in text files, but I think You would do it if it is possible...
  • BeliasBelias Member Posts: 2,998
    I'm saying i CAN'T do it with dataport. Lines have different field lenghts and meanings based on the first char of the line...
    my colleague suggest me to split the lines like this
    IF condition then begin
      intpos := 1;
      intlen := 20;
      field1 := copystr(intpos,intlen);
    
      intpos += intlen;
      intlen := 5;
      field2 := copystr(intpos,intlen);
    end else begin
      intpos := 1;
      intlen := 8;
      field8 := copystr(intpos,intlen);
    
      intpos += intlen;
      intlen := 21;
      field9 := copystr(intpos,intlen);
    end;
    

    and then assign the variables to the fields (i can't do it in one go because i read and set the values not in the order they're written in the file.

    It's not so bad...
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • koubekkoubek Member Posts: 84
    OK, You are right in this case... The solution drafted by your collegue is fine. But as You told you can not read the file by one pass only, because you haven`t lines ordered for your processing algorithm. Dataport can solve this situation maybe too :shock: If you set more dataitems, every single DI for specific line type, You can skip unsuitable lines for each DI and at the end, You can set pointer (SEEK) to read from the begining of file again...
  • BeliasBelias Member Posts: 2,998
    The table is the same, but the behaviour is different depending on the first field...here's the final code, i'm satisfied
    FNTFillVariables(pTXTLine : Text[1024])
    //this function fill variables in the same order they are written in the text file. In this way i simply hardcode the lenght
    //of the field and leave the system calculate the starting position. TXTDummy is a filler.
    IF pTXTLine[1] = 'H' THEN BEGIN
      TXTLineType := FNTPosAndLen(pTXTLine,1);
      TXTDummy := FNTPosAndLen(pTXTLine,26);
      TXTDocType := FNTPosAndLen(pTXTLine,2);
      …
    END;
    
    IF pTXTLine[1] = 'M' THEN BEGIN
      //TODO
    END;
    
    FNTPosAndLen(pTXTLine : Text[1024];pINTLen : Integer) TXTCutText : Text[1024]
    TXTCutText := COPYSTR(pTXTLine,INTPos,pINTLen);
    INTPos += pINTLen;
    
    The different behaviour is conditioned to
    IF pTXTLine[1] = 'H' THEN BEGIN
    and
    IF pTXTLine[1] = 'M' THEN BEGIN
    lines
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
Sign In or Register to comment.