Recent

Author Topic: StringGrid and LoadFromCSVFile  (Read 5810 times)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
StringGrid and LoadFromCSVFile
« on: April 05, 2018, 11:28:23 am »
Hi! I have a StringGrid and want to fill it from a csv file.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.     StringGrid1.LoadFromCSVFile('list.csv');
  4. end;
I have a fixed row for title (see picture).
My problem is that when loading from the csv, the title row will be overwritten with the first line of the csv.
How can I "protect" the title row?

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: StringGrid and LoadFromCSVFile
« Reply #1 on: April 05, 2018, 11:43:28 am »
LoadFromCSV has a lot of optional parameters:
Code: Pascal  [Select][+][-]
  1.     procedure LoadFromCSVFile(AFilename: string; ADelimiter: Char=',';
  2.       UseTitles: boolean=true; FromLine: Integer=0; SkipEmptyLines: Boolean=true);
Maybe setting "UseTitle := false" helps

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #2 on: April 05, 2018, 11:52:49 am »
LoadFromCSV has a lot of optional parameters:
Code: Pascal  [Select][+][-]
  1.     procedure LoadFromCSVFile(AFilename: string; ADelimiter: Char=',';
  2.       UseTitles: boolean=true; FromLine: Integer=0; SkipEmptyLines: Boolean=true);
Maybe setting "UseTitle := false" helps

Works, thank you! (But, it is strange. Default is TRUE. Logically it should have to be TRUE for displaying the title, not FALSE.)

An other question: can I insert a column (which shows the line numbers) during loading before the first csv column (First)?

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: StringGrid and LoadFromCSVFile
« Reply #3 on: April 05, 2018, 12:06:45 pm »
I think, "UseTitle" means "Write the first data line as a title line in row 0"

Quote
can I insert a column (which shows the line numbers) during loading before the first csv column (First)
I don't think that this is possible during loading because the csv reader begins at the very first column. Of course, after loading you can add a column:
Code: Pascal  [Select][+][-]
  1.     procedure InsertColRow(IsColumn: boolean; index: integer);
Afterwards, the easiest way to generate numbers is by turning the Option goFixedRowNumbering on (AFTER loading). If the number column is too wide you can adapt its width by chaingig ColWidths[0].

In total:
Code: Pascal  [Select][+][-]
  1.   StringGrid.LoadFromCSVFile(filename, ',', false, 0, true);
  2.   StringGrid.InsertColRow(true, 0);
  3.   StringGrid.Options := StringGrid.Options + [goFixedrowNumbering];
  4.   StringGrid.ColWidths[0] := StringGrid.Canvas.TextWidth(IntToStr(StringGrid.RowCount) + 8;


justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #4 on: April 05, 2018, 12:36:44 pm »
"I think, "UseTitle" means "Write the first data line as a title line in row 0"
Yes, you are right!

The solution is not perfect, I got this, see picture grid.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var numOfLines: integer;
  3. begin    
  4.     StringGrid1.LoadFromCSVFile('list.csv',',',false);
  5.     StringGrid1.InsertColRow(true,0);
  6.     StringGrid1.Options := StringGrid1.Options + [goFixedrowNumbering];
  7.     StringGrid1.ColWidths[0] := 100;
  8.     numOfLines:=StringGrid1.RowCount-1;
  9.     Button1.Caption:='Load list ('+IntToStr(numOfLines)+' records)';
  10. end;
 
If I add this:
Code: Pascal  [Select][+][-]
  1. StringGrid1.FixedCols:=1;
then I got grid1 picture.
« Last Edit: April 05, 2018, 12:42:18 pm by justnewbie »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: StringGrid and LoadFromCSVFile
« Reply #5 on: April 05, 2018, 12:55:28 pm »
The solution is not perfect, I got this, see picture grid.
I did not test my solution. Please post your data file (or a similar one following the same specification), then I can have a closer look. Zip it because the forum software does not accept all file types. Use "Attachments and other options" to upload the file here.

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #6 on: April 05, 2018, 01:00:13 pm »
OK, attached. So, I need the filled grid from csv and a very first column that contains the line numbers.
Doesn't matter if the line numbers column is fixed or not. Fixed is a bit better.

Also, how can I achieve that button caption do show the "Loading ..." text during the load process (the real list contains more than 100.000 lines)?
I tried the
Code: Pascal  [Select][+][-]
  1. Button1.Caption:='Loading ...';
  2. Button1.Update;
and
Code: Pascal  [Select][+][-]
  1. Button1.Caption:='Loading ...';
  2. Button1.Repaint;
but none of them was good.
« Last Edit: April 05, 2018, 01:42:24 pm by justnewbie »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: StringGrid and LoadFromCSVFile
« Reply #7 on: April 05, 2018, 02:20:39 pm »
See attachment

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #8 on: April 05, 2018, 02:41:49 pm »
See attachment
Fantastic solution, thank you very much!  :)
(Just one note: Button1.Refresh; did not work, but Application.ProcessMessages; worked perfectly.)

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #9 on: April 05, 2018, 07:12:37 pm »
+Questions:
1./ How can I get BOLD font for the title row?
2./ Is it possible to automatically resize the StringGrid's width? If yes, how?
« Last Edit: April 05, 2018, 07:18:58 pm by justnewbie »

wp

  • Hero Member
  • *****
  • Posts: 11916
Re: StringGrid and LoadFromCSVFile
« Reply #10 on: April 05, 2018, 07:23:10 pm »
The event OnPrepareCanvas is generated immediately before a cell is drawn. The canvas is already set up for painting, but you have a last chance to intercept. Just set the StringGrid.Canvas.Font.Style to [fsBold] if the row parameter is zero:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
  2.   aState: TGridDrawState);
  3. begin
  4.   if aRow = 0 then
  5.     StringGrid1.Canvas.Font.Style := [fsBold];
  6. end;

Maybe you did not notice: I applied the same technique in my example above in order to right-justify the number column.

If you want to learn more about the Lazarus grids have a look at http://wiki.lazarus.freepascal.org/Grids_Reference_Page

justnewbie

  • Sr. Member
  • ****
  • Posts: 292
Re: StringGrid and LoadFromCSVFile
« Reply #11 on: April 05, 2018, 08:08:47 pm »
@wp: your help is really great, thank you!

 

TinyPortal © 2005-2018