Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/35: Рейтинг темы: голосов - 35, средняя оценка - 4.69
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
1

Нестандартная сортировка в TreeView

20.02.2018, 10:43. Показов 7151. Ответов 23
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
добрый день! снова меня сортировка в узлах treeview озадачила. не могу, не знаю, как отсортировать данные в узлах treeview.
сортировать нужно в порядке возрастания не цифр, а чисел...
Миниатюры
Нестандартная сортировка в TreeView   Нестандартная сортировка в TreeView  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.02.2018, 10:43
Ответы с готовыми решениями:

нестандартная сортировка
Здравствуйте! Требуется отсортировать массив по убыванию и возрастанию с помощью одноленточной...

Нестандартная сортировка
Прошу помочь в решении задачи: Есть MySQL таблица: CREATE TABLE `bugreport` ( `id`...

Нестандартная сортировка
Добрый день! Посоветуйте, пожалуйста, как сделать нестандартную сортировку по полю. В таблице...

Нестандартная сортировка
Есть некоторая таблица "Табл" В ней есть поле1 Можно ли как-то выбирать данные в нужном мне...

23
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 11:14 2
А откуда туда берутся данные? Просто если это какая-то запись, где эти данные содержатся в виде полей, с которыми можно удобно поработать, то это одна ситуация. Если вдруг эти данные находятся прямо в TTreeView и туда попадают, например, через запрос к базе, то все сложнее. В любом случае, задача, имхо, нетривиальна. Просто так поставить галочку и получить результат не получится, потому что то, что вы сейчас видите является последствием того, что сортировка осуществляется путем сравнения строк (если точнее, то символов строки), а не чисел.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 11:23  [ТС] 3
Nanotentacle,
Цитата Сообщение от Nanotentacle Посмотреть сообщение
Если вдруг эти данные находятся прямо в TTreeView и туда попадают, например, через запрос к базе
именно так и происходит.

Добавлено через 5 минут
я так понимаю, что нужно использовать функцию AnsiCompareStr?
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 11:38 4
Цитата Сообщение от tsareva Посмотреть сообщение
я так понимаю, что нужно использовать функцию AnsiCompareStr?
Нет, это не приведет совершенно ни к чему. Потому как для системы переменная типа integer = 10 и строковая переменная '10' - это вообще разные вещи. Сравнение строк для сортировки происходит посимвольно. Поэтому как строку ни сравнивай, толку не будет.

Чтобы справиться с проблемой с наименьшими проблемами мне было бы интересно узнать, если ли какая-то переменная в базе данных, которая бы отделяла болты от резисторов? Если есть, то можно попробовать написать свой собственный сортировщик для всего этого дела. Если нету - то тут опять, все сложно, но решаемо.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 11:47  [ТС] 5
в базе нет такой переменной

Добавлено через 3 минуты
единственное, что для каждой записи в бд поле с записью, например, С5-35В-50-36 Ом± 5 %, уникально.
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 11:57 6
Тогда пришлите две вещи: структуру таблицы, где хранятся данные по товарам (это же товары?) и пришлите код процедуры, где происходит загрузка данных из БД в TreeView.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 12:02  [ТС] 7
Delphi
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
procedure CreateStandNodes(Parent:TTreeNode);
var
  okp_id, Text:string;
  MyRecPtr:array of PDataStand;
  i:integer;
  node:TTreeNode;
  Node1, Node2: TTreeNode; Data: Integer;
begin
  //Ищем изделия, которые входят в этот класс
  okp_id:=IntToStr(PDataStand(Parent.Data)^.ID);
  StdMainForm.ADOQuery.SQL.Clear;
  StdMainForm.ADOQuery.SQL.Add('Select Stand.Stand_ID,Stand.Mark,Stand.Type,Gost.Name, Stand.Prd, Stand.Symbol, Stand.Name as ProductName from Stand, Gost');
  StdMainForm.ADOQuery.SQL.Add('where Stand.OKP_ID='+QuotedStr(okp_id));
  StdMainForm.ADOQuery.SQL.Add('and Gost.Gost_ID=Stand.Gost_ID');
  try StdMainForm.ADOQuery.Open;
  except
    on E:Exception do begin
      ShowMessage(E.Message);
      Exit;
    end;
  end;
  //Выводим в дереве изделия, относящиеся к указанному классу
  if StdMainForm.DataSource.DataSet.RecordCount=0 then begin
    //Изделий в классе нет
  //  Parent.Delete;
  //  DeleteEmptyParents(Parent);
    Parent.HasChildren:=False;
    Exit;
  end;
  with StdMainForm.DataSource.DataSet do begin
    SetLength(MyRecPtr, RecordCount);
    StdMainForm.TreeStandart.Items.BeginUpdate;
    for i:=0 to RecordCount-1 do begin
      new(MyRecPtr[i]);
      //формирование записи в дереве (последовательность атрибутов в записи)
      if FieldByName('Type').AsInteger=0 then
        MyRecPtr[i]^.ObjectType:=soERE
      else
        MyRecPtr[i]^.ObjectType:=soStand;
        if FieldByName('Prd').AsInteger=0 then begin
          if FieldByName('Symbol').AsInteger=0 then
          Text:=FieldByName('ProductName').AsString+' '+FieldByName('Name').AsString+' '+FieldByName('Mark').AsString else
          if FieldByName('Symbol').AsInteger=1 then
          Text:=FieldByName('ProductName').AsString+' '+FieldByName('Name').AsString+' '+'-'+' '+FieldByName('Mark').AsString else
          if FieldByName('Symbol').AsInteger=2 then
          Text:=FieldByName('ProductName').AsString+' '+FieldByName('Name').AsString+''+'-'+''+FieldByName('Mark').AsString;
         end else
        Text:=FieldByName('ProductName').AsString+' '+FieldByName('Mark').AsString+' '+FieldByName('Name').AsString ;
      MyRecPtr[i]^.ID:=FieldByName('stand_id').AsInteger;
      MyRecPtr[i]^.OKP_ID:=PDataStand(Parent.Data)^.ID;
      node:=StdMainForm.TreeStandart.Items.AddChildObject(Parent, text, MyRecPtr[i]);
      case MyRecPtr[i]^.ObjectType of
        soERE:begin
            node.ImageIndex:=IconStandERE;
            node.SelectedIndex:=IconStandERE;
          end;
        soStand:begin
            node.ImageIndex:=IconStandSTD;
            node.SelectedIndex:=IconStandSTD;
          end;
      end;
      Next;
    end;
    StdMainForm.TreeStandart.Items.EndUpdate;
  end;
end;
Миниатюры
Нестандартная сортировка в TreeView  
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 15:43 8
Судя по тому, что я вижу, происходит следующее: имя в TreeView состоит из трех частей - "Продукт", "Название", "Марка". Продукт и название, имхо, нас не сильно беспокоит. Там навряд ли будут какие-то уникальные данные, по которым мы сможем сортировать (я, конечно, могу ошибаться, так как информация все же усеченная).

Предлагаю разбить приведенную процедуру на следующие процедуры:
- импорт данных из базы в массив данных, элементами которого будут записи, содержащие продукт, название, марку, данные из столбца Prd, Symbol и Type;
- сортировка массива (тут несколько вариантов сортировки). Данные, содержащиеся в марке, достаточно типизированы, имхо, и вытащить оттуда Омы или диаметр болта вполне возможно.
- публикация отсортированного списка в TTreeView с отключенной сортировкой.


В целом, я готов помочь в этом деле. Вопрос в том, что вам тоже придется над этим поработать, так как у меня нет, например, базы, и я не могу сориентироваться над всеми возможными вариантами "вычленения" чисел для сортировки.
0
174 / 160 / 71
Регистрация: 22.02.2013
Сообщений: 1,769
Записей в блоге: 2
20.02.2018, 15:48 9
tsareva,
я бы посоветовал делить каждую строку на сущности - признаком деления выступает символ "-" (тире) и пробел
и далее сравнивать эти сущности.
Плюс надо учесть тип для каждый этой сущности, т.к. сортировка строки и числа происходит по разным правилам
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 15:55  [ТС] 10
Цитата Сообщение от Nanotentacle Посмотреть сообщение
я готов помочь в этом деле
была бы очень благодарна.
Цитата Сообщение от Nanotentacle Посмотреть сообщение
вам тоже придется над этим поработать
меня это совершенно не расстраивает, хочу во всем разобраться

Добавлено через 5 минут
Цитата Сообщение от Nanotentacle Посмотреть сообщение
Продукт и название, имхо, нас не сильно беспокоит. Там навряд ли будут какие-то уникальные данные, по которым мы сможем сортировать
так и есть, уникальные данные относятся только к полю mark
0
5784 / 4526 / 1431
Регистрация: 14.04.2014
Сообщений: 20,157
Записей в блоге: 20
20.02.2018, 16:03 11
добавлю пять копеек
может быть, есть смысл делать это прямо в БД, а не каждый раз заново разбирать в памяти?

далее, у всех элементов набор свойств сильно отличается
поэтому хорошая мысль хранить их не в таблице как тут, а в нескольких таблицах по методике EAV
1
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 16:13  [ТС] 12
боюсь, что в бд не получится, потому что набор свойств, как Вы заметили,
Цитата Сообщение от krapotkin Посмотреть сообщение
сильно отличается
. и каждый кусочек данных из бд попадает в свой узел в treeview. в данном случае, думаю, стоит сортировать именно каждый этот узел (кусочек бд) дерева при его заполнении.

Добавлено через 2 минуты
думаю, что не стоит разбивать таблицу на несколько. это усложнит алгоритм сортировки.
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 16:21 13
ну давайте приступим. Для начала проведите анализ.

Разбивать строку на параметры можно по символу тире. Значимое для сортировки значение находится после второго знака тире, например.
Также, судя по тому, что я вижу в коде, параметр в столбце Symbol может иметь четыре значения - 0, 1, 2 и "остальное".

Задача для вас: надо убедиться, что все строки, у которых одинаковый Symbol, имеют значимое для сортировки значение после одного и того же знака тире (в смысле его порядкового номера). Объяснить вышло запутанно, надеюсь, понять меня получится. Жду результатов.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 16:29  [ТС] 14
еще, как мне кажется, поля Prd и Symbol можно не использовать при сортировке, потому что первое отвечает за последовательность атрибутов в записи (Наименование ГОСТ обозначение ИЛИ Наименование Обозначение ГОСТ), а второй отвечает за установку символа "тире" между ГОСТ и обозначением. Думаю, что в данном случае нужно обратить внимание только на поле mark, потому что именно по нему будет сортироваться запись.

Добавлено через 1 минуту
поле mark - это и есть обозначение
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
20.02.2018, 17:06 15
Это понятно. Но посмотрим теперь на скрины из первого поста. В случае резисторов те самые омы находятся после второго знака тире. Смотрим на следующий скрин - там диаметр болта находится после первого знака тире. Надо как-то определять положение нужных значений относительно знака тире. Я подозреваю, что поле Symbol вполне может помочь, но так как у меня нет БД, могу только предполагать.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
20.02.2018, 18:37  [ТС] 16
Цитата Сообщение от Nanotentacle Посмотреть сообщение
поле Symbol вполне может помочь
нет, я могу Вам точно сказать, что в данном случае поле Symbol не участвует в формировании записи поля mark вообще. это разделитель между словами, но не между значениями mark. поле mark - это цельная запись, больше с никакими другими полями оно не связано.
0
5395 / 4323 / 1060
Регистрация: 29.08.2013
Сообщений: 27,129
Записей в блоге: 3
20.02.2018, 21:30 17
вам тут объясняли
на sql.ru объясняли, а вы опять со своей сортировкой

сортировать нужно не в дереве, а раньше, запросом в БД или после запроса в памяти

для сортировки запросом нужно разделить вашу строку на подстроки что бы получилось
SQL
1
SELECT stroka, s, t, r, o, k, a
далее ты делаешь
SQL
1
2
SELECT stroka, s, t, r, o, k, a
ORDER BY t, r
и выводишь уже отсортированную строку в TreeView

для сортировки в памяти
нужно создать класс или record с нужными полями как в запроса
Delphi
1
2
3
4
5
6
7
8
9
TmyName = class
  stroka
  s
  t
  r
  o
  k
  a
end;
Создаешь массив, загоняешь все свои записи в массив, сортируешь по нужным полям и выводишь
0
884 / 404 / 174
Регистрация: 20.10.2016
Сообщений: 1,828
21.02.2018, 07:59 18
Цитата Сообщение от tsareva Посмотреть сообщение
нет, я могу Вам точно сказать, что в данном случае поле Symbol не участвует в формировании записи поля mark вообще. это разделитель между словами, но не между значениями mark. поле mark - это цельная запись, больше с никакими другими полями оно не связано.
А я разве говорил, что Symbol участвует в формировании записи? Symbol нам может подсказать, с какой записью мы имеем дело. Ту же функцию может выполнить поле Name. Нам от чего-то же надо оттолкнуться, чтобы нормально сортировать? И я уже писал выше, что отталкиваться просто от строки не получится (вернее, получится, но это будет тот еще костыль. Мы и так костыли всякие придумываем, но это будет вообще костыльный костыль). Поэтому задача стоит не в том, чтобы найти какие параметры не участвуют в формировании, а исходя из какого столбца в вашей БД будет просматриваться закономерность, исходя из которой будем парсить марку.
0
0 / 0 / 0
Регистрация: 22.12.2017
Сообщений: 218
21.02.2018, 08:17  [ТС] 19
понятно.
Цитата Сообщение от Nanotentacle Посмотреть сообщение
Задача для вас: надо убедиться, что все строки, у которых одинаковый Symbol, имеют значимое для сортировки значение после одного и того же знака тире (в смысле его порядкового номера)
то есть мне сейчас надо разобраться с этим полем.

Добавлено через 6 минут
Цитата Сообщение от qwertehok Посмотреть сообщение
для сортировки запросом нужно разделить вашу строку на подстроки
дело в том, что в бд записи имеют различные свойства по своему содержанию. есть МДМ160-1Е60ВП, и С2-33-0,25-150 Ом ± 10 %-Г- В, и 1206-X7R-100В-0,47 мкФ± 10 %. Поэтому сортировать по какому-то параметру невозможно.
0
5784 / 4526 / 1431
Регистрация: 14.04.2014
Сообщений: 20,157
Записей в блоге: 20
21.02.2018, 08:47 20
Цитата Сообщение от tsareva Посмотреть сообщение
не стоит разбивать таблицу на несколько
вот у вас уже болты, резисторы. а если добавятся емкости, светодиоды, кабель и пр?
вы будете на каждый товар держать отдельную таблицу??
а движение товара как делать? ID из каждой таблицы брать???

еще раз предлагаю ознакомиться с моделью EAV. Сущность. Атрибут. Значение атрибута.
тогда будет справочник сущностей, справочник свойств, таблица значений

Болт | Размер | 10
Резистор | Сопротивление | 1000
0
21.02.2018, 08:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.02.2018, 08:47
Помогаю со студенческими работами здесь

Нестандартная сортировка
Добрый день! Подскажите, пожалуйста, как сделать подобного рода сортировку, есть файл с данным...

Нестандартная сортировка массива
Всем доброго времени суток. Возник такой вопрос, как будет правильнее организовать сортировку...

Нестандартная сортировка ArrayList
Допустим, у меня есть список файлов: ArrayList <File> list = new ArrayList<>(); Файлы в лист...

Нестандартная сортировка строк
Выбираю из таблицы номера домов(они типа varchar, т.к дома имеют и цифры и буквы и слэш) когда...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru