powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / нестандартная сортировка в TreeView
25 сообщений из 57, страница 2 из 3
нестандартная сортировка в TreeView
    #39599190
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arioch,

надеюсь разобраться))
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599197
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterinaШтифт 2х14
Штифт 2х16
Штифт 2х4
Штифт 2х5

Хмммм....

Это всё-таки правильный конечный результат или нет?????


В ровно таком виде вам даже писать ничего не надо, только попросить дерево отсортироваться - и оно само отсортируется построчно.

Потому что текст "16" меньше, чем текст "2" - первая буквоцифра меньше, остальное не волнует
А вот число 16 больше, чем число 2, если его выделить из текста

и какая вам сортировка на самом деле нужна я уже не понимаю
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599200
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arioch,

второпях писала, поэтому и последовательность не учла.. прошу прощения за ошибки. сортироваться должно каждое последовательное число.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599206
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterina,

тогда прямая вам дорого в Гугл

https://www.google.ru/search?q=delphi alphanumeric comparison

например первые два результата

https://www.experts-exchange.com/questions/23086281/Natural-Order-String-Sort-Compare-in-Delphi.html
http://forum.lazarus.freepascal.org/index.php?topic=24450.0

только имейте в виду, что это просто обсуждения вопроса между делом, и насколько тамошними заримсовками можно пользоваться - они для этого в общем случае и не предназначены: http://www.gunsmoker.ru/2010/05/90.html
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599214
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterina,
Можешь для интереса глянуть . Я там своё решение кидал для похожей задачи, только надо на уточняющие вопросы по ТЗ ответить
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599220
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Огромное Вам спасибо за помощь! буду со всем разбираться... возможно, появятся вопросы!
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599282
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterina,

перед построением дерева отсортируй данные, заранее. А потом загружай.

Очень простой алгоритм: загрузи текст в TStringList, потом вызови CustomSort c указанием функции хитрой сортировки.

В этой самой функции разбирай текст на куски, ищи среди них числа. Если оба куска - числа - то сравнивай их как числа. Иначе - как строки.

Всё. :)

Пример: на форме есть TMemo, в ней твой неотсортированный текст. Задача - отсортировать его.

Пример
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
var
  fSL: TStringList;
begin
  fSL := TStringList.Create;
  try
    fSL.Text:= Memo1.Lines.Text; // Копируем текст из TMemo
    fSL.CustomSort(MyCompare); // Хитро сортируем его
    Memo1.Lines.Text := fSL.Text; // Обратно закидываем в TMemo.
  finally
    fSL.Text
  end;
end;



Что за функция MyCompare?
Вот она:
Код: pascal
1.
function MyCompare(List: TStringList; Index1, Index2: Integer): Integer;


На вход подается список строк (TStringList) и индексы (Index1, Index2) строк, которые надо сравнить.

Пример реализации:
MyCompare
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
function MyCompare(List: TStringList; Index1, Index2: Integer): Integer;
var
  fItem1: string; // Очередные элементы для сравнения
  fItem2: string;

  fpStr1: pChar; // Указатели на очередной элемент исходной строки
  fpStr2: pChar;

  fVal1: Extended; // Значения элементов в виде чисел
  fVal2: Extended;

  fCode1: Integer; // Коды завершения для val()
  fCode2: Integer;


begin
  Result := AnsiCompareStr(List[Index1], List[Index2]); // Сперва сравниваем "в лоб"
  if Result = 0 then Exit; // Строки совпали

  // Теперь сравниваем поэлементно
  fpStr1 := pChar(List[Index1]);
  fpStr2 := pChar(List[Index2]);

  repeat
    fItem1 := NextItem(fpStr1); // Берем очередные куски
    fItem2 := NextItem(fpStr2);

    Result := AnsiCompareStr(fItem1, fItem2); // Снова сперва сравниваем "в лоб"
    if Result = 0 then Continue; // Одинаковые - сравниваем следующие

    Val(fItem1, fVal1, fCode1); // Это числа?
    Val(fItem2, fVal2, fCode2);
    if (fCode1 <> 1) and (fCode2 <> 1) then begin // Это числа
      if fVal1 = fVal2 then Continue; // Одинаковые - сравниваем дальше
                                      // PS: тут можно помудрить и
                                      // учесть fCode1 и fCode2, но не
                                      // в этой задаче
      if fVal1 < fVal2 then
        Result := -1
      else
        Result := 1;
      Exit
    end;

  until (fItem1 = '') or (fItem2 = '');

end;



Осталась совсем мелочь: разбор исходных строк. Не будем мудрить:

NextItem
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
function NextItem(var aSrcStr: PChar): string;
var
  fIsInNumber: Boolean;
  fpStart: PChar;
const
  cDigits = ['0'..'9', '-', '+', '.'];
  cDelimiters = [' ', #9];
begin
  Result := '';
  while (aSrcStr^ <> #0) and (aSrcStr^ in cDelimiters) do // Пропускаем разделители
    Inc(aSrcStr);

  if aSrcStr = nil then Exit;

  fpStart := aSrcStr;
  fIsInNumber := fpStart^ in cDigits;

  if fIsInNumber then
    while (aSrcStr^ <> #0) and not (aSrcStr^ in cDelimiters) and (aSrcStr^ in cDigits) do
      Inc(aSrcStr)
  else
    while (aSrcStr^ <> #0) and not (aSrcStr^ in cDelimiters) and not (aSrcStr^ in cDigits) do
      Inc(aSrcStr);

  SetString(Result, fpStart, aSrcStr - fpStart);
end;

...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599290
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДОчень простой алгоритм: загрузи текст в TStringList

Это медленно, TList<string> лучше

Но.... это в предположении что у нее есть строки и только строки, нет никаких реальных данных за этими строками (объекта, записи, артикула на складе или в ценнике - ничего нет, только строки)

А оно должно быть

и сортировтаь надо будет реальные объекты, а не только строки из объектов выдранные
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599296
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

а вдруг файл текстовый больше семи гигабайт будет, или эмбаркадеро эмбарго для России на стринглист введет.

Тут тоже без специально нанятого программиста никак, да-да.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599325
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД,

я именно поэтому избегал называть конкретные классы, а когда называл - называл сразу несколько кандидатов

потому что одно дело - общая методика, а другая - якобы готовый к использованию код

В принципе, там вполне может быть TStringList - для того, чтобы в .Objects[i] хранить скастованный указатель на record с реальными данными, например. В 1990-х это была стандартная практика.

В общем, детали реализации могут быть весьма развесистыми, так что пусть ТС научится общему подходу, а потом применяет его к своим частностям.

тем более тьфу-тьфу кажется человек готов учиться сам, а не требовать готового кода
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599333
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччДразбор исходных строк. Не будем мудрить:

кстати, хороший пример для филиппики Раймонда Чена про программы с форумов

потому что твой парсер при случае "123.24.543" назовёт одним числом. И "212-85-06" тоже за число посчитает. И ".0123" тоже, хотя это уже серая зона.
Такие дела....
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599339
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch...твой парсер при случае "123.24.543" назовёт одним числом. И "212-85-06" тоже за число посчитает. И ".0123" тоже, хотя это уже серая зона.
Такие дела....
Ну так исправь, коль неймётся. И кэшед буфферз подключи для полного счастья.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599342
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД,

"говнокода" (с) на форумах и так полно, зачем его количество увеличивать?

я даже в функцию с E-E не вчитывался внимательно, хотя она как минимум про ситуацию "две точки" в курсе

написать этот парсер я за полчаса могу, повторяю ,конечные автоматы штука простая, но ооооочень нудная.

я человеку объяснял где искать удочки
ты вместо удочек дал ему рыбу
второй свежести, как внезапно (с) оказалось
но виноват оказываюсь я

пичалька
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599348
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Arioch,

ты проблемы на пустом месте выдумываешь.

Ну ладно, используй константу в cDigits вот такую:
Код: pascal
1.
  cDigits = ['0'..'9'];


...ах, снова беда, с отрицательными числами будет не та сортировка? А они есть, в номенклатуре, отрицательные?
Это одноразовая задача, од-но-ра-зо-ва-я.

С чего ты вдруг решил, что ТС глубинное погружение более важно, чем решение частного случая?
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39599396
Фотография JayDi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сделать компаратор (comparer), где для каждой пары:
- парсить первые два числа по возможности (достаточно по цифрам);
- если оба числа -- сравнивается одно, потом второе (CompareValue);
- если у кого-то одно числа -- сравнивается одно;
- если нет числе -- ничего (результат считать одинаковым);
- если результат одинаков, то сравнивается уже обычный текст (CompareText)
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606037
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
еще раз добрый день! Пыталась я разобраться с функцией AnsiCompareStr, но так думаю, что это не то, что нужно. дело в том, что я, наверно, неправильно все-таки описала ТЗ. Я привела единичный случай данных одного узла. на самом деле в разных узлах дерева хранятся типы данных с разными значениями. и сравнить их нужно не по наименованию или госту, а именно, по обозначению, например, в записи Болт 5х25 ГОСТ 11111-2018 сортировать буду только по значению 5х25 и т.д. как-то можно отсортировать данные в каждом узле отдельно?
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606041
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
это данные из другого узла
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606045
TsYekaterina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
есть данные и такого плана
5584АП5Т
5584ИЕ10Т
5559ИН1Т
5584ЛИ1Т
5584ЛЛ1Т
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606078
чччД
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterina,

что за косноязычность. Разберись и четко сформулируй задачу, а не картинки вываливай, всякий раз неправильные.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606083
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо, используя мозг, придумать алгоритм удовлетворяющий вашим критериям. После того как сможете его описать, закодировать не составит труда (в крайнем случае здесь помогут). А телепаты, знающие что там у вас может встретиться, готовятся к празднику
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606104
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterinaкак-то можно отсортировать данные в каждом узле отдельно?

Ещё раз прочитай 21176860 и покажи как ты это пыталась реализовать и что получиось.

white_niggerНадо, используя мозг, придумать алгоритм удовлетворяющий вашим критериям

А именно:
Как рубить названия на отдельные части?
Какие типы частей могут быть и как это определять?
Как сравнивать части того или иного типа.

А самое правильное (если возможно) было бы не строками заниматься, а тащить через программу "паспорт изделия" - типа record или class, в котором все параметры будут отдельно и явно прописаны как разные переменные.

У тебя сейчас где-то есть нормальное представление о предметах.
Скажем, винт характеризуется
0) тем, что он винт, а не болт
1) длиной
2) диаметром (строго говоря, двумя диаметрами)
3) типом головки (потайная, полукруглая, ...)
4) типом отвертки (плоский шлиц, крест, 6-гранник, ....)
5) диаметром головки
6) возможно, высотой(длиной) головки
7) направлением резьбы
8) шагом резьбы ( или наклоном )
9) саморез или нужно предварительно сверлить
10) для какого материала - в дерево вкручиивать, в пластик, в металл....
....и вероятно есть ещё разные признаки.

Насчёт двух диаметров - если когда-то чертила или видела чертежи, то отдельно считается и чертится по гребням резьбы и по "канавкам" между гребнями. Но там редко бывают необычные соотношения, так что редко нужно хранить оба значения. А вот выбрать какое одно из двух будет использовать программа и не путать в дальнейшем - надо.

Понятно, что для каждого артикула вести полный паспорт - накладно.
И не во всех случаях нужно.
Но это уже вам решать, что нужно, а что нет.

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

В идеале у тебя к каждой "строке" должен быть "привязан" паспорт. И тогда функция сравнения была бы тривиальна, ты бы сначала проверяла типы изделий (например, любой винт всегда больше любого болта), а потом убедившись, что типы паспортов совпадают, просто бы шла по отдельным "графам" паспортов от более важного к менее важному и сравнивала.

У тебя же получилось, что некоторая информация из паспортов была отброшена, некоторая же была свалена в одну строку, полу-формализованную, полу-стандартную.
И тебе сейчас нужно рзобрать (parse) строку и попытаться из неё извлечь это информацию обратно.
Задача нечёткая и неприятная.

Да, если тебе нужна только сортировка (а не нужен поиск/фильтр, нет (и никогда не будет) задачи покупателю/продавцу "показать винты и болты длиной от 3 до 5 см") то полный парсинг не нужен, достаточно упрощённого. Но во-первых и это медленнее, чем прямое сравнения регулярных паспортов.

A во-вторых "задача нечёткая": вот у тебя винт в середине "....gx6.ВТ1-0...." а над ним и под ним "....gx6.36.01...."
Вот приедут эти строки в твой компаратор.
Поползёт он по ним.
".....gx", а дальше цифра - это кусок-строка, сравниваем через AnsiTextCompare, получаем 0, надо сравнивтаь дальше

Ползёт дальше "....6." - это число шесть и... точка это уже новая строка или всё ещё число?
Ну ладно, допустим (оооочень плохое слово), что точка - всегда разделят блоки, а дробная часть всегда отбивается запятыми и никогда точками (а если мы не угадали, что тогда?), но пока - д-о-п-у-с-т-и-м.

...."6" в обеих строках. Кусок-число. Превращаем его из строки в число (операция сама по себе долгая и чреватая ошибками) и сравниваем две переменных integer или single. Sign( int1-int2 ) = 0, опять равенство, опять надо дальше сравнивать.

Ползём по двум строка синхронно дальше.

строка 2: "." и за ним цифра 3. Значит кусок-строка была один символ "." , а дальше будет кусок-число
строка 1: ".ВТ" и за ним цифра 1. Значит кусок строка будет ".ВТ" и эти два куска сравниваем в AnsiTextCompare - тут строки разные, результат будет не ноль, и сравнение заканчиваем.

А вот ЕСЛИ БЫ сравнение не закончилось, то дальше бы сравнивали числа "36" (ил "36.016") и "1" (из "1-0").
Т.е. вероятно (слово настолько же отвратительное, как "допустим") пошла рассинхронизация, начали вероятно сравнивать разные по смыслу блоки.

Вот такие дела....
Перед тобой три дороги, и выбрать из них можешь только ты, оценивая состояние вашей программы, состояние бизнес-процессов и компетентности/аккуратности пользователей программы, и свои умения.

1) добиться, чтобы до самого списка доходили не просто полу-бессистемные строки, а полноценные РЕГУЛЯРНЫЕ паспорта изделий. Сортировку/поиск/фильтрацию делать по ним. Это наиболее "правильный" и быстрый способ, но не всегда возможный.
2) сделать полноценный парсинг строк, восстановление типа паспорт и заполнение всех полей, которые удастся заполнить (и отметку какие поля заполнены, какие нет), потом сортировку по временному паспорту. Это наиболее медленный способ. Но ты хотя бы сама будешь понимать что и с чем ты сравниваешь.
3) сделать халявный полу-парсинг, понадеявшись что большая часть строк заполнена более-менее стандартно, а на редкие исключения наплевать, виноват кто-то другой будет. Это то, о чём тебе с самого начала говорили.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606111
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterinaШтифт 2.2х16.Хим.Окс.прм
Штифт 2.2х20
Штифт 2.3х16.019

Ага, хренушки там. Вот здесь явно точка отделяет не разные смысловые блоки, а целую и дробную часть одного и того же числа.

А на картинке твоей - "Винт В.М2,5-gx6....." - тут дробная часть отбивается запятыми. А точки отбивают только смысловые блоки.

А если дальше рыться, наверное найдётся и место, гед через запятую перечислены разные аттрибуты, разные по смыслу куски.

И вот для каждой строки твоей программе придется угадывать, что означает каждая точка ,и что означает каждая запятая.

И либо делать полноценный парсинг, восстановление паспорта по строке. В программу закладывая какие смысловые блоки могут встречаться в разных типах названий, и как эти смысловые блоки отбиваются друг от друга.
Либо не терять данные изначально, вести по программе именно паспорт изделия, а не его бесформенное название-строку. Строка уже будет необязательным дополнением к паспорту, а не наоборот.

Либо выпендриться и сделать ууумную функцию, которая сможет в каждой строке угадать где какие блоки.
А и всё равно однажды встретится хитровыподвернутая строка, которую даже такая функция не разгадает....

Ведь не даром во всех магазинах/складах есть артикул (он же SKU - Storage Kept Unit number), уникальный идентификатор, по которому можно выдернуть "карточку товара", где в явном и раздельном виде будут (должны быть) описаны его свойства.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606114
Arioch
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чччД,

человек НЕ программист, не математик.

знаешь как бывает, "ты ж программист - вон секретарша телефон сломала, почини"
а тут обратная ситуация, похоже.

"ты похожа на программиста - иди затыкай дырку"
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606207
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TsYekaterina,

авторданных с разными значениями. и сравнить их нужно не по наименованию или госту, а именно, по обозначению, например, в записи Болт 5х25 ГОСТ 11111-2018 сортировать буду только по значению 5х25 и т.д. как-то можно отсортировать данные в каждом узле отдельно?

Значит в компараторе нужно сравнивать не всю строку целиком, а конкретное значение. Нужно из строки это значение выделить и передавать компоратору.
...
Рейтинг: 0 / 0
нестандартная сортировка в TreeView
    #39606227
Василий №2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В данном случае будет уместней такой алгоритм:
1. При добавлении узла в дерево разбиваем строку детали на составные части по максимуму. В алгоритм уж не буду влезать, неохота. Но разбиваем на составные части.
2. Копируем эти составные части в запись aka структуру, выделенную в памяти (New / AllocMem)
3. Добавляем узел, указатель на заполненную структуру как его поле Data
4. Реализуем OnCompare, где в зависимости от текущего режима сортировки элементарно сравниваются поля структур двух узлов.
...
Рейтинг: 0 / 0
25 сообщений из 57, страница 2 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / нестандартная сортировка в TreeView
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]