delphidelphi-11-alexandriatstringlist

Tstringlist fails to iterate


I am trying to import a CSV file via a TStringlist.

procedure TOrder_import.Button1Click(Sender: TObject);
var
F: textfile;
ST : Tstringlist;
datas : string;
i : integer;    
 begin
 try
  ProgressBar1.Position := 0;
  ST:= Tstringlist.Create;
  order_entry.OpenDialog1.Execute;
  AssignFile(F, order_entry.OpenDialog1.FileName);
  Reset(F);
  read(F, Datas);
  st.CommaText := (datas);
  ExtractStrings([',' ],[], Pchar(datas), ST);
  begin
    for i :=  st.Count -1 downto 0 do
    begin
     Memo1.Lines.Add(ST[4]);
     Memo1.Lines.Add(ST[12]);
     Memo1.Lines.Add(ST[22]);
     Memo1.Lines.Add(ST[46]);
     Memo1.Lines.Add(ST[57]);
     Memo1.Lines.Add(ST[60]);
     Memo1.Lines.Add(ST[62]);
     Memo1.Lines.Add(ST[72]);
     Memo1.Lines.Add(ST[88]);
     ProgressBar1.StepIt;
     // readln;
    end;
  end;

  finally
  ST.Free;
  ShowMessage('Sucess!!')
 end;

end;

This code compiles and runs without errors, however it fails to iterate to the next string in the TStringlist.

I tried putting a readln at the end of the loop but then the program crashed with

i/o error 6

Why is the TStringlist not iterating through it's strings?


Solution

  • Why is the TStringlist not iterating through it's strings?

    Because you didn't write your code to do that. You are extracting specific (and apparently random) strings from the TStringList, completely ignoring the loop index variable.

    The memo is supposed to have the columns mentioned displayed in order- the Memo is basically a test to make sure we're reading it right (which we obviously aren't)

    If you are trying to display the column names from the 1st line, then try something more like this:

    procedure TOrder_import.Button1Click(Sender: TObject);
    var
      F : TextFile;
      // Reader : TStreamReader;
      ST : TStringlist;
      dataS : string;
      i : integer;    
    begin
      ProgressBar1.Position := 0;
    
      if not order_entry.OpenDialog1.Execute then
        Exit;
    
      AssignFile(F, order_entry.OpenDialog1.FileName);
      try
        Reset(F);
        Readln(F, dataS);
      finally
        CloseFile(F);
      end;
    
      { alternatively:
      Reader := TStreamReader.Create(order_entry.OpenDialog1.FileName);
      try
        dataS := Reader.ReadLine;
      finally
        Reader.Free;
      end; }
    
      ST := TStringList.Create;
      try
        ST.CommaText := dataS;
        { or, NOT both:
        ExtractStrings([','], [], PChar(dataS), ST); }
    
        ProgressBar1.Max := ST.Count;
        ProgressBar1.Step := 1;
    
        for i := 0 to ST.Count-1 do
        begin
          Memo1.Lines.Add(ST[i]);
          ProgressBar1.StepIt;
        end;
      finally
        ST.Free;
      end;
    
      ShowMessage('Sucess!!')
    end;
    

    On the other hand, if you are trying to display the actual data values for specific columns in the file, then try this instead:

    procedure TOrder_import.Button1Click(Sender: TObject);
    var
      FileST, LineST : TStringlist;
      i : integer;    
    begin
      ProgressBar1.Position := 0;
    
      if not order_entry.OpenDialog1.Execute then
        Exit;
    
      FileST := TStringList.Create;
      try
        FileST.LoadFromFile(order_entry.OpenDialog1.FileName);
    
        ProgressBar1.Max := FileST.Count;
        ProgressBar1.Step := 1;
    
        LineST := TStringList.Create;
        try
          for i := 0 to FileST.Count-1 do
          begin
            LineST.CommaText := FileST[i];
            { or:
            LineST.Clear;
            ExtractStrings([','], [], PChar(FileST[i]), LineST); }
    
            if LineST.Count > 88 then
            begin
              Memo1.Lines.Add(LineST[4]);
              Memo1.Lines.Add(LineST[12]);
              Memo1.Lines.Add(LineST[22]);
              Memo1.Lines.Add(LineST[46]);
              Memo1.Lines.Add(LineST[57]);
              Memo1.Lines.Add(LineST[60]);
              Memo1.Lines.Add(LineST[62]);
              Memo1.Lines.Add(LineST[72]);
              Memo1.Lines.Add(LineST[88]);
            end else
            begin
              //...
            end;
            ProgressBar1.StepIt;
          end;
        finally
          LineST.Free;
        end; 
      finally
        FileST.Free;
      end;
    
      ShowMessage('Sucess!!')
    end;