Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка ListView, delphi7 
V
    Опции темы
kovalenko123
Дата 12.12.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



Всем привет я понимаю что тема уже стара как мир но обнаружился какой то странный косяк в сортирвке listview

при закидывании записей в listview (через DragADrop) записи естественно не упорядочиваются при нажитии на header в LV  записи сортируються  (не без помощи функций конечно) но получаеться совсем не то что нужно (а нужно сортировка по возврастанию) 
вот пример 
user posted image
Это уже после сортировки а по идеи должна быть от 2 до 17
подскажите пожалуйста что можно сделать 



PM MAIL ICQ   Вверх
THandle
Дата 12.12.2009, 11:52 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 65
Всего: 372



kovalenko123, у тебя происходит сортировка строк по убыванию.

Символ '9' больше чем символа '1'.

Тебе видимо придется писать функцию сортировки, которая из каждой строки вынимает это число, и сортировать по числовому представлению, а не строчному.

PM   Вверх
kovalenko123
Дата 12.12.2009, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



THandle
Цитата

у тебя происходит сортировка строк по убыванию

так тогда бы начиналось бы все с 17 (17 , 16 , 15 и т д ) а тут с 9-2 потом начинаеться 17  smile 
 
Цитата

из каждой строки вынимает это число

Откровенно говоря не совсем понял это высказывание 





PM MAIL ICQ   Вверх
THandle
Дата 12.12.2009, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Хранитель Клуба
Group Icon
Награды: 1



Профиль
Группа: Админ
Сообщений: 3639
Регистрация: 31.7.2007
Где: Moscow, Dubai

Репутация: 65
Всего: 372



Цитата(kovalenko123 @  12.12.2009,  14:32 Найти цитируемый пост)
так тогда бы начиналось бы все с 17 (17 , 16 , 15 и т д ) а тут с 9-2 потом начинаеться 17  smile 


Нет. Так бы было если бы сортировал числа, а не строки. Тут же сортировка идет по коду символа. То есть Ord('9') > Ord('1').

Чтобы получить нужный тебе результат, тебе в коде функции сортировки надо сравнивать не строчки LV, а вынутые из этих строк числа(1...17).

Напиши для этого "вынимания" функцию типа:

Код

function Compare(const AStr: String): Integer;
begin
  { А тут вынимаем из строчки AStr это число и присваиваем его Result. Можно сделать с помощью Pos, Copy, StrToInt }
end;


В параметр AStr передавай каждую строчку из столбца "Название". В результате должно возвращаться число из скобочек. Вот эти числа и нужно сравнивать в сортировке, когда переставляешь элементы.

Попробуй сам это сделать. Если не получится - дай свою функцию сортировки, попробуем её изменить вместе. smile
PM   Вверх
kovalenko123
Дата 12.12.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



Дело в том что если я сделаю как вы предложили
Цитата

надо сравнивать не строчки LV, а вынутые из этих строк числа(1...17)

то в случае другого примере она может не сработать Иногда моя работает правильно. я тут одну ссылочку отыскал может она пригодиться Тынц
там общие принцпиы сортировки может и для моего тяжелого случая подойдет
PM MAIL ICQ   Вверх
amsoft
Дата 12.12.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 17.10.2009
Где: KZ, Astana

Репутация: 3
Всего: 4



kovalenko123

для затравки:

в строках ищи положение символов '[' и ']' с помощью функции Pos и исходя из их значений выдергивай строку между ними через Copy,
преобразовывай в число и сравнивай  smile 
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин
PM   Вверх
kovalenko123
Дата 12.12.2009, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



amsoft 
а если их не будет этих символов?  smile 
PM MAIL ICQ   Вверх
amsoft
Дата 12.12.2009, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 17.10.2009
Где: KZ, Astana

Репутация: 3
Всего: 4



kovalenko123
как я вижу по примеру они есть  smile 
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин
PM   Вверх
kovalenko123
Дата 12.12.2009, 16:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



amsoft 
Это был просто пример я щас могу таких пример с десяток наскринить 
щас попробую реализовать то что предложил THandle

Код

function CustomNameSortProc(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall;
begin
Result := CompareText(Item1.Caption,Item2.Caption);
end;

procedure Tmain.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
try
if column =ListView1.columns[0] then
 ListView1.CustomSort(@CustomNameSortProc, 0);
 except
 end;
end;


Вот функция для сортировки

Это сообщение отредактировал(а) kovalenko123 - 12.12.2009, 16:34
PM MAIL ICQ   Вверх
amsoft
Дата 12.12.2009, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 17.10.2009
Где: KZ, Astana

Репутация: 3
Всего: 4



тогда сравнивай по каждому символу, если символ - цифра, то сравнивай число, если нет - сравнивай код символа
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин
PM   Вверх
kovalenko123
Дата 12.12.2009, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



amsoft
А можно какой нить кодовый пример на эту тему? 
PM MAIL ICQ   Вверх
amsoft
Дата 12.12.2009, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 17.10.2009
Где: KZ, Astana

Репутация: 3
Всего: 4



1. (на всякий случай) код символа определяется по функции Ord()

2. Вопрос: у тебя наименования имеют один формат:

abcd1234
abcd1234
...

или же в некоторых случаях кол-во букв перед цифрами разное:

abcd1234
abc1234
a1234
...

?
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин
PM   Вверх
kovalenko123
Дата 13.12.2009, 07:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



amsoft
К сожалению определенного правила формата нету так что может быть и как в 1 случае так и во втором но точно могу сказать что одна цифра будет например

abcd1.pdf
abcd2.pdf
abcd3.pdf

либо все доки будут начинаться с цифры например

1abcd.pdf
2abcd.pdf
3abcd.pdf
PM MAIL ICQ   Вверх
amsoft
Дата 13.12.2009, 07:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 201
Регистрация: 17.10.2009
Где: KZ, Astana

Репутация: 3
Всего: 4



Код

procedure TForm1.ListView1Compare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
var
S1,S2,S1Int,S2Int: string;
begin
S1 := Item1.Caption;
S2 := Item2.Caption;
Compare := 0;
while Compare = 0 do
      begin
      if ((S1 = '') and (S2 = '')) then Exit;
      if S1 = ''
      then begin
           Compare := -1;
           Exit;
           end;
      if S2 = ''
      then begin
           Compare := 1;
           Exit;
           end;
      if ((Ord(S1[1]) in [48..57]) and (Ord(S2[1]) in [48..57]))
      then begin
           S1Int := '';
           while (Ord(S1[1]) in [48..57]) do
                 begin
                 S1Int := S1Int + S1[1];
                 S1 := Copy(S1,2,Length(S1));
                 if S1 = '' then Break;
                 end;
           S2Int := '';
           while (Ord(S2[1]) in [48..57]) do
                 begin
                 S2Int := S2Int + S2[1];
                 S2 := Copy(S2,2,Length(S2));
                 if S2 = '' then Break;
                 end;
           Compare := StrToInt(S1Int) - StrToInt(S2Int);
           end
      else begin
           Compare := Ord(S1[1]) - Ord(S2[1]);
           S1 := Copy(S1,2,Length(S1));
           S2 := Copy(S2,2,Length(S2));
           end;
      end;
end;


ЗЫ Здесь я сравниваю только Caption, если надо по другим столбцам, то можешь подкорректировать в самом начале.
ЗЗЫ Сортировка идет по возрастанию
--------------------
"Кто бы ты ни был - не думай о себе слишком"Дельфин
PM   Вверх
kovalenko123
Дата 13.12.2009, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 229
Регистрация: 12.5.2008

Репутация: 1
Всего: 1



amsoft и THandle Спасибо Вам с задачей справился следующим образом

Код

function SortCaptionAsString(Item1, Item2: TListItem; ParamSort: integer): integer; stdcall;
begin
   Result := 0;
   if AnsiUpperCase( Item1.Caption ) > AnsiUpperCase( Item2.Caption ) then
      Result := ParamSort
   else
   if AnsiUpperCase( Item1.Caption ) < AnsiUpperCase( Item2.Caption ) then
      Result := -ParamSort;
end;

procedure Tmain.ListView1ColumnClick(Sender: TObject; Column: TListColumn);
begin
    Sort := -Sort;
if Column = ListView1.Columns[0] then
  ListView1.CustomSort( @SortCaptionAsString, Sort);
end;


результат в принципе устраевает тока вот с 10 все равно проблемы а со всем остальным нормально но ниче DAD подвинет куда надо будет эту 10  smile 

Успехов ВАМ!
PM MAIL ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1461 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.