Delphi - проблема со строковой сеткой после сортировки

Итак, строковая сетка, которую я имею в программе, которую я упомянул здесь: (Delphi - Изменение цвета вкладки активной страницы и его сброс после нажатия на другую вкладку) отлично сортирует от наименьшего к наибольшему, но сетка в некотором роде дает сбои / выходит из строя. Отсортированные строки выбрасываются в конец сетки (иногда даже без номеров строк или строки сохраняют свои номера). Итак, моя проблема заключается в том, как я могу отсортировать свою сетку строк, не разрушая сетку полностью в процессе?

Код, который я использую:

//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;

Скриншоты, иллюстрирующие проблему:

Перед сортировкой:
введите здесь описание изображения

После сортировки:
введите здесь описание изображения

введите здесь описание изображения

Заранее спасибо за помощь!
С уважением
PrimeBeat


person PrimeBeat    schedule 17.01.2021    source источник
comment
Если я правильно понимаю, у вас много пустых строк, кроме номера строки в левом столбце, потому что вы установили RowCount равным RowMax. После сортировки пустые ячейки помещаются в начало списка. Почему вы поддерживаете такие пустые строки в нижней части несортированной сетки (выходя наверх после сортировки)? Если вы хотите сохранить эти строки, вам нужно изменить функцию сравнения, используемую для сортировки, чтобы пустая строка была больше, чем все остальные, чтобы они оставались внизу.   -  person fpiette    schedule 17.01.2021
comment
Ну, я подумал, что если я установлю количество строк равным 40 при запуске, вставка информации в строки будет немного проще, поскольку все строки будут сгенерированы заранее. Можно ли просто вставлять данные в строки сетки без необходимости устанавливать определенное количество строк или максимальное количество строк? Потому что я считаю, что это сделает сортировку и т. д. намного проще.   -  person PrimeBeat    schedule 17.01.2021
comment
@PrimeBeat да, количество строк можно изменить в любой момент. Просто добавьте несколько кнопок, которые позволяют пользователю «добавить» или «удалить» строку. Конечно, вам нужно будет добавить код, чтобы это действительно заработало ????   -  person R. Hoek    schedule 17.01.2021
comment
С другой стороны, вы также можете пропустить добавление «пустых» строк в свой список строк сортировки, а затем при обратном чтении данных просто остановиться в точке, где количество строк сетки превышает количество строк списка, а затем записывать только пустые строки в сетку вместо данные из списка сортировки.   -  person R. Hoek    schedule 17.01.2021


Ответы (1)


Подводя итог ответа из комментариев:

Ваша проблема связана с тем, что вы добавляете много пустых строк, потому что устанавливаете RowCount равным RowMax. После сортировки пустые ячейки помещаются в начало списка.

Есть два решения:

  1. Вы перестанете добавлять пустые строки и сортировка будет такой, как ожидалось
  2. Управляйте сортировкой с помощью comparer, которая делает пустую строку БОЛЬШЕ, чем все остальные строки, а не по умолчанию, которая меньше. См. документацию по CustomSort.

Обратите внимание, что вы можете изменить количество строк в любое время. Просто назначьте свойство RowCount. Например, когда вы добавляете строку, выполните:

   Grid.RowCount := Grid.RowCount + 1;

И когда вы удалите последнюю строку, сделайте:

   Grid.RowCount := Grid.RowCount - 1;
person fpiette    schedule 17.01.2021
comment
Я отредактировал количество строк в процедуре TitlesAndNumbering, чтобы оно было равно 2, и я установил iCount из процедуры сортировки на RowCount - 1. Теперь все работает отлично, спасибо за вашу помощь! - person PrimeBeat; 17.01.2021