1

So the string grid I have in the program I mentioned here: (Delphi - Changing active page's tab color and having it reset after clicking on another tab) sorts perfectly from smallest to largest but the grid glitches/goes haywire in a way. The sorted rows get thrown to the end of the grid (sometimes even without row numbers or the rows keep their numbers). So my problem is how can I sort my string grid without completely ruining the grid in the process?

Code I'm using:

//code that sorts the grid
procedure TfrmPuntehou.SortSTLGrid(var grid:TStringGrid; columntotal:integer);
const
separator = ',';
var
iCount,i,j,k,iPos:integer;
TheList:TStringList;
sString,sTempString:string;
begin
  //procedure to sort from small to large values

  //get row amount
  iCount:=grid.RowCount;

  //create list
  TheList:=TStringList.Create;
  TheList.Sorted:=False;

  //start of try..finally block
    try
    begin

      //fill the list
      for i := 1 to (iCount - 1) do
      begin
      TheList.Add(grid.Rows[i].Strings[columntotal]+separator+grid.Rows[i].Text);
      end;

      //sort the list
      TheList.Sort;

      for k := 1 to TheList.Count do
      begin
      //take the line of the list and put it in a string var
      sString:= TheList.Strings[(k-1)];
      //get separator pos in that string
      iPos:=AnsiPos(separator,sString);
      sTempString:='';
      //remove separator and the column text at the front of the string
      sTempString:=Copy(sString,(iPos+2),Length(sString));
      TheList.Strings[(k-1)]:= '';
      TheList.Strings[(k-1)]:= sTempString;
      end;

      //fill the grid
      for j:= 1 to (iCount - 1) do
      begin
      grid.Rows[j].Text := TheList.Strings[(J-1)] ;
      end;

    end;
    finally
    TheList.Free;
    end;
  //end of try..finally block

end;

//code that I use to customize the grid on startup

procedure TfrmPuntehou.TitlesAndNumbering(grid: TStringGrid);
var
  i:integer;
begin
  //procedure that customizes the grid entered as a parameter
  with grid do
  begin
    //names the columns
    Cells[0,0]:='Row Number';
    Cells[1,0]:='Car Number';
    Cells[2,0]:='Name';
    Cells[3,0]:='Licence';
    Cells[4,0]:='Heat 1';
    Cells[5,0]:='Heat 2';
    Cells[6,0]:='Subtotal 1';
    Cells[7,0]:='Heat 3';
    Cells[8,0]:='Subtotal 2';
    Cells[9,0]:='Final';
    Cells[10,0]:='Final Total';

        //for loop to number the rows
        for i := 1 to rowMax do
        begin
            Cells[0,i]:=IntToStr(i);
        end;
        //end of for

    //other extra settings
    RowCount:=rowMax;
    ColCount:=colMax;
    DefaultColWidth:=100;
    FixedCols:=0;
    FixedRows:=1;
  end;
end;

Screenshots to illustrate the problem:

Before sorting:
enter image description here

After sorting:
enter image description here

enter image description here

Thanks in advance for the help!
Kind Regards
PrimeBeat

PrimeBeat
  • 444
  • 5
  • 15
  • 1
    If I understand correctly, you have many empty rows except the row number on the left column because you set RowCount equal to RowMax. Once sorted, the empty cells goes to the top of the list. Why are you maintaining such empty rows at the bottom of the unsorted grid (coming to the top after sorting)? If you want to keep those rows, you have to change the compare function used for sorting so that empty string is greater than all others so that they stay at the bottom. – fpiette Jan 17 '21 at 09:53
  • Well, I thought that if I set the row amount to 40 at startup, it would make inserting info into the rows a bit easier by having all the rows generated ahead of time. Is it possible to just insert data into the rows of the grid without having to set a certain row amount or max amount of rows type thing? Cause I reckon it would make sorting,etc a lot easier. – PrimeBeat Jan 17 '21 at 10:14
  • 1
    @PrimeBeat yes it’s possible to change the rowcount at any point. Just add some buttons which allow the user to ‘add’ or ‘delete’ a row. Off course you’ll need to add code to actually make that work – R. Hoek Jan 17 '21 at 10:37
  • 1
    On the other hand, you could also skip adding ‘empty’ rows to your sorting stringlist and then, when reading the data back just stop at the point where grid rowcount exceeds the stringlist count and then only write empty strings to the grid instead of the data from the sortlist. – R. Hoek Jan 17 '21 at 10:40

1 Answers1

1

To summarize an answer from comments:

Your problem comes from the fact that you add a lot of empty rows because you set RowCount equal to RowMax. Once sorted, the empty cells goes to the top of the list.

There are two solutions:

  1. You stop adding empty lines and sorting will be as expected
  2. Manage to sort with a comparer that makes empty string BIGGER as all other string instead of the default which is smaller. See the documentation for CustomSort

Note that you can change the row count at anytime. Just assign the RowCount property. For example, when you add a row, do:

   Grid.RowCount := Grid.RowCount + 1;

And when you remove the last line, do:

   Grid.RowCount := Grid.RowCount - 1;
fpiette
  • 11,983
  • 1
  • 24
  • 46
  • I edited the row amount in the TitlesAndNumbering procedure to be equal to 2 and I set iCount from the sort procedure to RowCount - 1. Now it works perfectly, thanks for all your help! – PrimeBeat Jan 17 '21 at 13:35