Cортировка строк в TStringGrid (готовый пример)

На нем тоже кодим под винду =)
Аватара пользователя
Scamper
Постоялец
Сообщения: 67
Зарегистрирован: 17 дек 2014, 18:09
Откуда: Екатеринбург
Контактная информация:

Cортировка строк в TStringGrid (готовый пример)

Сообщение Scamper » 21 дек 2014, 12:41

Автор:Diffit

Delphi / Pascal » Cортировка строк в TStringGrid (готовый пример)


Cортировка строк в TStringGrid

Наваял готовую функцию для сортировки по алфавиту строк в компоненте StringGrid.
Гуголь даёт общие ответы, но готового примера не нашёл. Встроенного метода тоже нет. Поэтому и выкладываю свою процедуру :)

Сортировка организавана методом пузырька. Сравнение строковое (благо делфи с лёгкостью сравнивает строки).
Хотя там три вложенных цикла, работает довольно шустро (к тому же в процессе создания темы я допилил отсечение)))

В общем вот:
Code

Код: Выделить всё

procedure TDialog.sortStringGrid(mGrid: TStringGrid; col:integer);
var
  a: string;
  i,j,k, Rows, Colls: integer;
  fin: boolean;
begin
  //mGrid.Cells[0,0]:='123';
  Rows := mGrid.RowCount;
  Colls := mGrid.ColCount;

  //Sorting
  for j:=1 to Rows-1 do begin
   fin := true;

   for i:=1 to Rows-2 do begin
    if UpperCase(mGrid.Cells[col,i])>UpperCase(mGrid.Cells[col,i+1]) then begin
     //Swap
     for k:=0 to Colls-1 do begin
      a := mGrid.Cells[k,i];
      mGrid.Cells[k,i] := mGrid.Cells[k,i+1];
      mGrid.Cells[k,i+1] := a;
     end;

     fin := false;
    end;
   end;

   if fin=true then break;
  end;
end;


Применение: sortStringGrid(имя_контролла, колонка)
Имя контролла - это само имя элемента
Колонка - номер колонки (начиная с 0), по которой нужно отсортировать .
    
         

Хотел сразу написать с подробными разъяснениями, но отвлекли :)

Щас постараюсь расписать досконально, как что устроено, чтобы каждый мог сходу допилить под свои нужды. Заодно будет полезно тем, кто только начал изучать программирование ;)

Понеслась.

Code

procedure TDialog.sortStringGrid(mGrid: TStringGrid; col:integer);       
        var       
        //Переменные
         a: string; //Буффер, в который будем помещать одну из обрабатываемых строк
         i,j,k, Rows, Colls: integer; //счётчики, кол-во строк и колонок
         fin: boolean; //Флаг отсечения (Чтобы не проходить все циклы до конца)       
        begin       
         // Этого тут вообще не должно быть, просто проверял, можно ли обратиться напрямую к элементу управления. Проверил. Можно =)
         //mGrid.Cells[0,0]:='123';       

         //Получаем кол-ва строк и столбцов. Необязательно, но так красивше
         Rows := mGrid.RowCount;       
         Colls := mGrid.ColCount;       

         //Поехали сортировать
         //Для тех кто не вкурсе, стоит погуглить про метод пузырька
         //Этот цикл описывает проходы пузырька по списку. Его-то мы и прервём, когда всё устаканится =)       
         //если вы таки почитали про пузырёк, то знаете, что проходов нужно на один меньше,
         //чем строк в списке
         for j:=1 to Rows-1 do begin       
          //Ставим флаг отсечения. Если список еще недосортирован, мы его снимем, иначе перестанем впустую есть процессорноое время
          fin := true;       

          //Цикл одного прохода пузырька
          //начинаем с 1 потомучно в 0 у нас заголовки столбцов (если у вас не так - переделайте)
          //вычитаем 2 потому что:
          //1) из-за присутствия нулевого элемента колво элементов на один больше, чем номер последнего элемента
          //2) последний элемент нам не нужен, потому что после него ничего нет, а сам он обрабатывается на предыдущей строке
          for i:=1 to Rows-2 do begin       
           //Теперь берём из указанного для сортировки столбца две ячейки
           //Из текущей строки и из следующей за ней
           //Приводим обе строки в верхний регистр, ибо у строчных и заглавных букв разные коды, а нас интересуют только сами буквы
           //Сравниваем строки и если вторая строка должна быть выше первой, меняем их местами
           if UpperCase(mGrid.Cells[col,i])>UpperCase(mGrid.Cells[col,i+1]) then begin       

            //Меняем. Каждую ячейку по отдельности, поэтому ещё один цикл
            //Можно менять и целые строки, но так надёжнее и безглючнее
            for k:=0 to Colls-1 do begin       
             //Меняем местами
             //Первую строку в буффер
             a := mGrid.Cells[k,i];       
             //вторую строку на место первой
             mGrid.Cells[k,i] := mGrid.Cells[k,i+1];       
             //а во вторую то, что было в буффере
             mGrid.Cells[k,i+1] := a;       
             //и так с каждым столбцом
            end;       

            fin := false; //раз мы что-то нашли, сбрасываем флаг отсечения
           end;       

          //Двигаем пузырёк к следующей строке
          end;       

          //Если за полный проход пузырька по списку, мы ничего не нашли (флаг не сброшен)
          //То список уже отсортирован. Поэтому просто прерываем цикл
          if fin=true then break;       
         end;       
        //конец =)
        end;



Ещё я добавил
Code
application.ProcessMessages;
после
Code
if fin=true then break;


Это то же самое, что и DoEvents в ВБ.
Просто избавляет от подвисания при сортировке больших списков. и смотрится прикольно :)

Вернуться в «Pascal & Delphi»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость

cron