Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 11.12.2013, 22:07
Daryll Daryll вне форума
Прохожий
 
Регистрация: 26.11.2013
Сообщения: 4
Версия Delphi: Delphi xe3
Репутация: 10
По умолчанию Сортировка StringGrid

Почему то сортирует столбец с числами вот так:
Получается:
100
110
150
20
250

А нужно:
20
100
110
150
250

Помогите разобраться.

Вот код сортировки:
Код:
procedure SortStringGrid(var GenStrGrid: TStringGrid; ThatCol: Integer);
const
TheSeparator = '@';
var
CountItem, I, J, K, ThePosition: integer;
MyList: TStringList;
MyString, TempString: string;
begin
CountItem := GenStrGrid.RowCount;
MyList        := TStringList.Create;
MyList.Sorted := False;
try
begin
for I := 1 to (CountItem - 1) do
MyList.Add(GenStrGrid.Rows[i].Strings[ThatCol] + TheSeparator +
GenStrGrid.Rows[i].Text);
Mylist.Sort;
for K := 1 to Mylist.Count do
begin
MyString := MyList.Strings[(K - 1)];
ThePosition := Pos(TheSeparator, MyString);
TempString  := '';
TempString := Copy(MyString, (ThePosition + 1), Length(MyString));
MyList.Strings[(K - 1)] := '';
MyList.Strings[(K - 1)] := TempString;
end;
for J := 1 to (CountItem - 1) do
GenStrGrid.Rows[J].Text := MyList.Strings[(J - 1)];
end;
finally
MyList.Free;
end;
end;
Ответить с цитированием
  #2  
Старый 11.12.2013, 22:30
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Daryll
Почему то сортирует столбец с числами вот так:
Получается:
100
110
150
20
250

А нужно:
20
100
110
150
250

Помогите разобраться.
Потому что это не числа, а строки. Эти классы так и называются TStringGrid и TStringList, а не TNumberGrid и TNumberList. А с точки зрения строк он сортирует правильно. Т.е. Численно 20<150, но для строк '20'>'150', так как сравнение строк идёт посимвольно, а не по численному значению.

У класса TStringList есть метод CustomSort в котором можно указать своё правило сортировки - в данном случае просто преобразуем строки в число и сравниваем.

Пример:
Код:
function NumberSort(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := StrToInt(List[Index1]) - StrToInt(List[Index2]); 
end;  

procedure TForm1.Button1Click(Sender: TObject);
var
  MyList: TStringList;
begin
  MyList:=TStringList.Create;
  try
    MyList.Add('150');
    MyList.Add('100');
    MyList.Add('20');
    MyList.Add('250');
    MyList.Add('110');

    MyList.CustomSort(NumberSort);
    
    ShowMessage(MyList.Text);
  finally
    MyList.Free;
  end;
end;

Последний раз редактировалось poli-smen, 11.12.2013 в 22:38.
Ответить с цитированием
  #3  
Старый 11.12.2013, 22:44
Daryll Daryll вне форума
Прохожий
 
Регистрация: 26.11.2013
Сообщения: 4
Версия Delphi: Delphi xe3
Репутация: 10
По умолчанию

Дело в том что у меня в StringGrid могут заносится ещё числа, так как
в таблице есть столбцы ещё: Название, Раздел, Цена.
А эти числа я написал для примера.
Ответить с цитированием
  #4  
Старый 11.12.2013, 23:39
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Daryll
Дело в том что у меня в StringGrid могут заносится ещё числа, так как
в таблице есть столбцы ещё: Название, Раздел, Цена.
А эти числа я написал для примера.
Т.е. тебе нужна число-текстовая сортировка. Для этого в Windows есть специальная API-функция StrCmpLogicalW. Просто изменяешь правило сортировки примерно так:
Код:
function StrCmpLogicalW(psz1, psz2: PWideChar): Integer; stdcall; external 'shlwapi.dll';

function NumberSort(List: TStringList; Index1, Index2: Integer): Integer;
var
  ws1, ws2: WideString;
begin
  ws1 := List[Index1];
  ws2 := List[Index2];
  Result := StrCmpLogicalW(Pointer(ws1), Pointer(ws2));
end;  

Или вот ещё Rouse в своём блоге публикует свою аналогичную функцию чисто на Delphi: "Сортировка списка по аналогу "Проводника Windows""
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:36.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025