Форум программистов
 
О проблемах, например, с регистрацией пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль.

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail


Ответ
 
Опции темы
Старый 06.10.2019, 21:53   #1
Kara1989
Пользователь
 
Регистрация: 04.05.2009
Сообщений: 49
По умолчанию treeview дельфи

Добрый вечер, уважаемые программисты!
Нужна помощь в решении данного вопроса по построению дерева treeview из одной таблицы.

Скрин приложил, слева результат, что именно хочется, справа данные одной таблицы для дальнейшего построения.
Действующий код по построению написал, используя циклы из 3 таблиц, но для этого уходит много времени. Думаю понятно разложил

Безымянный.png

Заранее спасибо за помощь!
Kara1989 вне форума Ответить с цитированием
Старый 07.10.2019, 09:44   #2
evg_m
Старожил
 
Регистрация: 20.04.2008
Сообщений: 5,060
По умолчанию

нужно то что ?
построить ТРЕХ уровневое дерево
1. gruppa (или roles?!)
2. roles (gruppa)
3. конечный пользователь(специалист) ФИО

Цитата:
используя циклы из 3 таблиц
циклы по доступу к БД (для КАЖДОГО узла свой отдельный запрос)?
циклы по просмотру единого (з-x частного) НД (3 НД -по одному на каждый уровень) ?

I.
могут помочь скобки "отключения" реакции обновления
1. DataSet.DisableControls; //особенно если у нас есть "бесконечное" блуждание по НД в поисках записей подходящих именно данному узлу.
2. TreeView.Items.BeginUpdate;
до начала циклов построения(всех), вместе с соответствующими "закрывающими" скобками после циклов построения

II.
З полных набора (таблицы) для построения ВСЕГО дерева
1. строим первый уровень и ЗАПОМИНАЕМ где у нас что.
- берем таблицу первого уровня и добавляем узлы отмечая(запоминая) где что.
"индексный" массив узлов первого уровня
2. строим второй уровень
берем таблицу второго уровня и добавляем узлы в соответствии с нашими отметками(см.1)
"индексный" массив второго уровня
3.строим третий уровень. на основе наших "индексных" массивов.


III.
берем полную таблицу (вся информация для построения узла любого уровня в одной)
строи ДВА пустых индексных массива (первый, второй уровень)
берем запись.
ищем узел первого уровня
НЕТ добавляем и заносим в массив
ДА значит будем добавлять сюда
ищем узел второго уровня
НЕТ добавляем В найденный(или В только что созданный), включаем.
ДА ...
узел третьего уровня просто добавляем В найденный узел.

в конце-то концов индексный массив может быть и двумерным
[ первый уровень, второй уровень ]

IV.
берем УПОРЯДОЧЕННЫЙ по gruppa, roles НД третьего уровня.
1.проверяем (находим и/или если надо добавляем) узлы второго и первого уровня.
2.добавляем ВСЕХ специалистов данного узла они будут в НД рядом(идти последовательно) по условию упорядоченности
3.если можем переходим к п.1.
программа — запись алгоритма на языке понятном транслятору

Последний раз редактировалось evg_m; 07.10.2019 в 09:53.
evg_m на форуме Ответить с цитированием
Старый 07.10.2019, 18:33   #3
Kara1989
Пользователь
 
Регистрация: 04.05.2009
Сообщений: 49
По умолчанию Вот собственно рабочий код

Код:
procedure TForm1.RefreshPilot;
var
  i, g, k, l, m: integer;
  CurrNode, CurrNode1, CurrNode2: TTreeNode;
begin
  TreeViewPilot.Items.Clear;
  TreeViewPilot.SortType:=stNone;

  QueryTree1.Close;
  QueryTree1.SQL.Clear;
  QueryTree1.SQL.Add('select * from roles order by id');
  QueryTree1.Open;
  QueryTree1.First;

  QueryTree3.Close;
  QueryTree3.SQL.Clear;
  QueryTree3.SQL.Add('select * from division order by name');
  QueryTree3.Open;
  QueryTree3.First;

  for i:=1 to QueryTree1.RecordCount do begin
    CurrNode:=TreeViewPilot.Items.Add(nil, QueryTree1.FieldByName('name').AsString);
    k:=CurrNode.AbsoluteIndex;
    CurrNode.ImageIndex:=9;
    CurrNode.SelectedIndex:=9;

    QueryTree3.First;

    for l:=1 to QueryTree3.RecordCount do begin
      QueryTree2.Close;
      QueryTree2.SQL.Clear;
      QueryTree2.SQL.Add('select id, roles, gruppa, full_name, full_name1, alias, iin, birthday, area, active from pilot where (((roles like :A) AND (gruppa like :B))) order by full_name');
      QueryTree2.Params.ParamByName('A').Value:=QueryTree1.FieldByName('id').AsString;
      QueryTree2.Params.ParamByName('B').Value:=QueryTree3.FieldByName('id').AsString;
      QueryTree2.Open;
      QueryTree2.Filtered:=false;

      if QueryTree2.RecordCount <> 0 then begin
        CurrNode1:=TreeViewPilot.Items.AddChild(TreeViewPilot.Items[k], QueryTree3.FieldByName('name').AsString);
        m:=CurrNode1.AbsoluteIndex;
        CurrNode1.ImageIndex:=10;
        CurrNode1.SelectedIndex:=10;

        QueryTree2.First;

        for g:=1 to QueryTree2.RecordCount do begin
          CurrNode2:=TreeViewPilot.Items.AddChild(TreeViewPilot.Items[m], QueryTree2.FieldByName('full_name').AsString);
          CurrNode2.StateIndex:=QueryTree2.FieldByName('id').AsInteger;
          CurrNode2.ImageIndex:=11;
          CurrNode2.SelectedIndex:=11;
          QueryTree2.Next;
        end;
      end;

      QueryTree3.Next;
    end;

    QueryTree1.Next;
  end;

  TreeViewPilot.SortType:=stText;
  TreeViewPilot.FullExpand;
  TreeViewPilot.Items[0].Selected:=true;
  TreeViewPilot.SetFocus;
end;
Kara1989 вне форума Ответить с цитированием
Старый 07.10.2019, 23:05   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,061
По умолчанию

Код:
select r.*,p.*,d.* 
  from roles r
    left join pilot p on p.roles=r.id
    left join division d on d.id=p.gruppa
  order by r.id,d.name,p.full_name
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 09.10.2019, 18:30   #5
Kara1989
Пользователь
 
Регистрация: 04.05.2009
Сообщений: 49
По умолчанию

данный запрос думаю никак не поможет для дальнейшего построения дерева
Kara1989 вне форума Ответить с цитированием
Старый 09.10.2019, 18:51   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,061
По умолчанию

Почему? При изменении r.id добавляй узел 1-го уровня, при изменении d.name - 2-уровня и для каждой записи - соответственно узел 3-го уровня. то же самое что в твоем коде, только одним запросом и без запроса в цикле. Думаю быстрей будет существенно

add

Там есть нюанс - записей из pilot и division может и не быть для некоторых из roles. Тогда проверять на null соответствующие поля и не строить узлы 2-го и 3-го уровня
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 09.10.2019 в 19:50.
Аватар вне форума Ответить с цитированием
Старый 09.10.2019, 20:58   #7
Kara1989
Пользователь
 
Регистрация: 04.05.2009
Сообщений: 49
По умолчанию

Поторопился с ответом. Как раз помог ваш запрос для дальнейшего построения дерева без цикла. Спасибо за помощь! Тема закрыта
Kara1989 вне форума Ответить с цитированием
Ответ

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
TreeView Mr.Steroid Общие вопросы Delphi 10 30.10.2013 20:29
ASP.NET C# компонент TreeView. Перетащить какой - либо пункт меню из TreeView в TextBox Claster ASP.NET 0 02.01.2013 17:59
TreeView Gudzik11 Общие вопросы Delphi 2 28.05.2012 13:07
таблицы подстановок в дельфи(базы данных в дельфи) ManiagoZ БД в Delphi 0 15.05.2011 14:07
TreeView W0LF Общие вопросы Delphi 3 10.04.2010 16:10


Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru
Пеллетный котёл Emtas
котлы EMTAS
Здесь нужно купить рекламу за 7 тыс руб в месяц! )
пишите сюда - alarforum@yandex.ru
ИКС 840