Sorting StringGrid by two (or more) columns lazarus / 61-Beginners ---------------------------------------------------------------------- TomTom · 2022-10-03 07:04 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ----------- ---------------------------------+-------------------------------- B:\OLDCRC konwersja\53\636\0\1\8\2_org.jpg  | 2012.11.16 22:11:08.527420630B:\OLDCRC konwersja\53\636\0\1\8\3_org.jpg  | 2012.11.16 22:11:08.527420630B:\OLDCRC konwersja\53\636\0\1\8\6_org.jpg  | 2012.11.16 22:11:08.527420630B:\OLDCRC konwersja\53\636\0\1\8\5_org.jpg  | 2012.11.16 22:11:08.527420630B:\OLDCRC konwersja\53\636\0\1\8\4_org.jpg  | 2012.11.16 22:11:08.527420630B:\OLDCRC konwersja\53\636\0\1\8\10_org.jpg | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\11_org.jpg | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\7_org.jpg  | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\8_org.jpg  | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\9_org.jpg  | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\12_org.jpg | 2012.11.16 22:11:09.527420235B:\OLDCRC konwersja\53\636\0\1\8\17_org.jpg | 2012.11.16 22:11:10.527419840B:\OLDCRC konwersja\53\636\0\1\8\16_org.jpg | 2012.11.16 22:11:10.527419840B:\OLDCRC konwersja\53\636\0\1\8\15_org.jpg | 2012.11.16 22:11:10.527419840B:\OLDCRC konwersja\53\636\0\1\8\13_org.jpg | 2012.11.16 22:11:10.527419840----- ---------------------------------------+------------------------------ -- ---------------------------------------------------------------------- Josh · 2022-10-03 07:17 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. ---------------------------------------------------------------------- TomTom · 2022-10-03 07:45 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... It should be... How to sort stringGrid without changing order of sorting, or how to sort it, always in ascending order . ---------------------------------------------------------------------- wp · 2022-10-03 08:46 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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,  BRow: Integer; var Result: integer);begin  if StringGrid1.SortColumn = 1 then  begin    Result := CompareStr(StringGrid1.Cells[ACol, ARow], StringGrid1.Cells[BCol, BRow]);    if Result = 0 then      Result := CompareStr(StringGrid1.Cells[0, ARow], StringGrid1.Cells[0, BRow]);  if StringGrid1.SortOrder = soDescending then      Result := -Result;  end;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][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.StringGrid1CompareCells(Sender: TObject; ACol, ARow, BCol,  BRow: Integer; var Result: integer);var  sa, sb: String;  na, nb: Integer;begin  if StringGrid1.SortColumn = 1 then  begin    Result := CompareStr(StringGrid1.Cells[ACol, ARow], StringGrid1.Cells[BCol, BRow]);    if Result = 0 then    begin      sa := ExtractFileName(StringGrid1.Cells[0, ARow]);      sb := ExtractFileName(StringGrid1.Cells[0, BRow]);      SetLength(sa, pos('_', sa)-1);      SetLength(sb, pos('_', sb)-1);      na := StrToInt(sa);      nb := StrToInt(sb);      Result := na-nb;    end;  if StringGrid1.SortOrder = soDescending then      Result := -Result;  end;end; See attachment. (Sort by clicking in the column header) ---------------------------------------------------------------------- paweld · 2022-10-03 09:03 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button1Click(Sender: TObject);const  firstcol = 2;  secondcol = 1;var  i, idxfrom, idxto: Integer;  s: String;begin  StringGrid1.BeginUpdate;  StringGrid1.SortOrder := soAscending;  //firscol ASC  StringGrid1.SortColRow(True, firstcol);  s := '';  idxfrom := 0;  idxto := 0;  StringGrid1.SortOrder := soDescending; //secondcol DESC  for i := 1 to StringGrid1.RowCount - 1 do  begin    if s <> StringGrid1.Cells[firstcol, i] then    begin      idxto := i - 1;      if idxfrom < idxto then        StringGrid1.SortColRow(True, secondcol, idxfrom, idxto);      s := StringGrid1.Cells[firstcol, i];      idxfrom := i;    end;  end;  idxto := i;  if idxfrom < idxto then    StringGrid1.SortColRow(True, secondcol, idxfrom, idxto);  StringGrid1.EndUpdate();end;