Recent

Author Topic: Sorting StringGrid by two (or more) columns  (Read 758 times)

TomTom

  • Full Member
  • ***
  • Posts: 170
Sorting StringGrid by two (or more) columns
« on: October 03, 2022, 09:04:20 am »
I have something like this in StringGrid. I need to sort it firstly by second column and then by first column.
Sorting by one column is easy but I can't figure out how to sort a grid by more than one.
Code: Pascal  [Select][+][-]
  1. --------------------------------------------+--------------------------------
  2. B:\OLDCRC konwersja\53\636\0\1\8\2_org.jpg  | 2012.11.16 22:11:08.527420630
  3. B:\OLDCRC konwersja\53\636\0\1\8\3_org.jpg  | 2012.11.16 22:11:08.527420630
  4. B:\OLDCRC konwersja\53\636\0\1\8\6_org.jpg  | 2012.11.16 22:11:08.527420630
  5. B:\OLDCRC konwersja\53\636\0\1\8\5_org.jpg  | 2012.11.16 22:11:08.527420630
  6. B:\OLDCRC konwersja\53\636\0\1\8\4_org.jpg  | 2012.11.16 22:11:08.527420630
  7. B:\OLDCRC konwersja\53\636\0\1\8\10_org.jpg | 2012.11.16 22:11:09.527420235
  8. B:\OLDCRC konwersja\53\636\0\1\8\11_org.jpg | 2012.11.16 22:11:09.527420235
  9. B:\OLDCRC konwersja\53\636\0\1\8\7_org.jpg  | 2012.11.16 22:11:09.527420235
  10. B:\OLDCRC konwersja\53\636\0\1\8\8_org.jpg  | 2012.11.16 22:11:09.527420235
  11. B:\OLDCRC konwersja\53\636\0\1\8\9_org.jpg  | 2012.11.16 22:11:09.527420235
  12. B:\OLDCRC konwersja\53\636\0\1\8\12_org.jpg | 2012.11.16 22:11:09.527420235
  13. B:\OLDCRC konwersja\53\636\0\1\8\17_org.jpg | 2012.11.16 22:11:10.527419840
  14. B:\OLDCRC konwersja\53\636\0\1\8\16_org.jpg | 2012.11.16 22:11:10.527419840
  15. B:\OLDCRC konwersja\53\636\0\1\8\15_org.jpg | 2012.11.16 22:11:10.527419840
  16. B:\OLDCRC konwersja\53\636\0\1\8\13_org.jpg | 2012.11.16 22:11:10.527419840
  17. --------------------------------------------+--------------------------------
  18.  

Josh

  • Hero Member
  • *****
  • Posts: 1271
Re: Sorting StringGrid by two (or more) columns
« Reply #1 on: October 03, 2022, 09:17:50 am »
hi i dont use stringgrid much, but a couple of ideas
1 sort data by 2nd column then from that result sort by 1st column
2 join column 1 data and column 2 data together and sort that.

ps with filenames from a drive they will all be unique in windows,so sorting by name should be all that is required.

The best way to get accurate information on the forum is to post something wrong and wait for corrections.

TomTom

  • Full Member
  • ***
  • Posts: 170
Re: Sorting StringGrid by two (or more) columns
« Reply #2 on: October 03, 2022, 09:45:22 am »
Well, this is part of my program for restoring proper file order. Those files have wrong names (messed by someone else who used third party software for renaming). I'm asking how to sort stringgrid by two columns because in my program when user is changing the date of file (well just a text) then program sorts whole StringGrid to show the changes, and that is ok. But, there is small problem. Every time sorting order is different... For example, I have something like that:

B:\OLDCRC konwersja\53\636\0\1\8\2_org.jpg   2012.11.16 22:11:08.527420630
B:\OLDCRC konwersja\53\636\0\1\8\3_org.jpg   2012.11.16 22:11:08.527420630
B:\OLDCRC konwersja\53\636\0\1\8\6_org.jpg   2012.11.16 22:11:08.527420630
B:\OLDCRC konwersja\53\636\0\1\8\5_org.jpg   2012.11.16 22:11:08.527420630
B:\OLDCRC konwersja\53\636\0\1\8\4_org.jpg   2012.11.16 22:11:08.527420630

I change the date of file 6_org.jpg from 2012.11.16 22:11:08.527420630 to 2012.11.16 22:11:08.527420635 and then StringGrid is being sorted by date Column. As expected file is positioned at last row. But... the roder of other files is also changed. For example 2_org.jpg and 3_org.jpg switch their places. Even when I ... Never mind...
 While writing this I realized that I need to change my question... :D

It should be... How to sort stringGrid without changing order of sorting, or how to sort it, always in ascending order :P.





wp

  • Hero Member
  • *****
  • Posts: 11853
Re: Sorting StringGrid by two (or more) columns
« Reply #3 on: October 03, 2022, 10:46:47 am »
Use a special handler for the OnCompareCells event. It is called when sorting is requested. Assuming that the filenames are in column 0 and the date/times in column 1, this works for me:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
  2.   BRow: Integer; var Result: integer);
  3. begin
  4.   if StringGrid1.SortColumn = 1 then
  5.   begin
  6.     Result := CompareStr(StringGrid1.Cells[ACol, ARow], StringGrid1.Cells[BCol, BRow]);
  7.     if Result = 0 then
  8.       Result := CompareStr(StringGrid1.Cells[0, ARow], StringGrid1.Cells[0, BRow]);
  9.     if StringGrid1.SortOrder = soDescending then
  10.       Result := -Result;
  11.   end;
  12. end;
Please note that "10_org.jpg" is "smaller" than "7_org.jpg" because "1" is smaller than "7" and "0" is smaller than "_"! However, you probably want to sort by the filenames numerically. Therefore, you must extract the numbers from the filenames (e.g. 7 from "B:\OLDCRC konwersja\53\636\0\1\8\7_org.jpg", and compare them as numbers rather than strings.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,
  2.   BRow: Integer; var Result: integer);
  3. var
  4.   sa, sb: String;
  5.   na, nb: Integer;
  6. begin
  7.   if StringGrid1.SortColumn = 1 then
  8.   begin
  9.     Result := CompareStr(StringGrid1.Cells[ACol, ARow], StringGrid1.Cells[BCol, BRow]);
  10.     if Result = 0 then
  11.     begin
  12.       sa := ExtractFileName(StringGrid1.Cells[0, ARow]);
  13.       sb := ExtractFileName(StringGrid1.Cells[0, BRow]);
  14.       SetLength(sa, pos('_', sa)-1);
  15.       SetLength(sb, pos('_', sb)-1);
  16.       na := StrToInt(sa);
  17.       nb := StrToInt(sb);
  18.       Result := na-nb;
  19.     end;
  20.     if StringGrid1.SortOrder = soDescending then
  21.       Result := -Result;
  22.   end;
  23. end;

See attachment. (Sort by clicking in the column header)

paweld

  • Hero Member
  • *****
  • Posts: 970
Re: Sorting StringGrid by two (or more) columns
« Reply #4 on: October 03, 2022, 11:03:39 am »
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   firstcol = 2;
  4.   secondcol = 1;
  5. var
  6.   i, idxfrom, idxto: Integer;
  7.   s: String;
  8. begin
  9.   StringGrid1.BeginUpdate;
  10.   StringGrid1.SortOrder := soAscending;  //firscol ASC
  11.   StringGrid1.SortColRow(True, firstcol);
  12.   s := '';
  13.   idxfrom := 0;
  14.   idxto := 0;
  15.   StringGrid1.SortOrder := soDescending; //secondcol DESC
  16.   for i := 1 to StringGrid1.RowCount - 1 do
  17.   begin
  18.     if s <> StringGrid1.Cells[firstcol, i] then
  19.     begin
  20.       idxto := i - 1;
  21.       if idxfrom < idxto then
  22.         StringGrid1.SortColRow(True, secondcol, idxfrom, idxto);
  23.       s := StringGrid1.Cells[firstcol, i];
  24.       idxfrom := i;
  25.     end;
  26.   end;
  27.   idxto := i;
  28.   if idxfrom < idxto then
  29.     StringGrid1.SortColRow(True, secondcol, idxfrom, idxto);
  30.   StringGrid1.EndUpdate();
  31. end;          
Best regards / Pozdrawiam
paweld

 

TinyPortal © 2005-2018