Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 2 530

/ вопрос открыт /

Здравствуйте, эксперты!
У меня возникла проблема с заполнением компонента TreeView данными из БД. Т.е. при нажатии на кнопку дерево должно заполняться данными из БД. В базе 3 таблицы: дисциплины, темы, подтемы; связь между ними осуществляется по принципу: дисциплины--} темы--} подтемы (один ко многим). Заполнение TreeView должно происходить по этим же принципам. База Данных Access. Использую ADO.

Приложение:
  1.  
  2. procedure TForm1.Button1Click(Sender: TObject);
  3.  
  4. Var n:TTreeNode;
  5. c:TTreeNode;
  6. ID:Integer;
  7. ID1:Integer;
  8.  
  9. Begin
  10.  
  11. DM1.DataModule2.ADOQuery1.Active:=false;
  12. DM1.DataModule2.ADOQuery1.Open;
  13. DM1.DataModule2.ADOQuery2.Active:=false;
  14. DM1.DataModule2.ADOQuery2.Open;
  15.  
  16. TreeView1.Items.BeginUpdate;
  17. TreeView1.Items.Clear;
  18.  
  19. While not DM1.DataModule2.ADOQuery1.Eof do
  20. begin
  21.  
  22. ID:=DM1.DataModule2.ADOQuery1DSDesigner2.Index;
  23.  
  24. While not DM1.DataModule2.ADOQuery2.Eof do
  25. begin
  26. ID1:=DM1.DataModule2.ADOQuery2DSDesigner.Index;
  27. if ID=ID1 then
  28.  
  29.  
  30. DM1.DataModule2.ADOQuery2.Next;
  31. end;
  32.  
  33. DM1.DataModule2.ADOQuery1.Next;
  34. end;
  35.  
  36. TreeView1.Items.EndUpdate;
  37. end;
  38.  


Плакош Алексей Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Плакош Алексей (статус: Посетитель)
Вопрос отправлен: 16 марта 2009, 09:13
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Плакош Алексей!
В принципе код очень похож на правдоподобный, кроме одного - он статический.
Суть в том, что во внутреннем цикле нужно каждый раз менять запрос к базе. К сожалению, Вы не привели ни структуры базы, ни каких то намеков, поэтому код будет схематический. Надеюсь, что SQL Вы знаете.

procedure TForm1.Button1Click(Sender: TObject);
 
Var n:TTreeNode;
    c:TTreeNode;
    ID:Integer;
    ID1:Integer;
Begin
 
DM1.DataModule2.ADOQuery1.Active:=false;
DM1.DataModule2.ADOQuery1.Open;
DM1.DataModule2.ADOQuery2.Active:=false;
 
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
 
While not DM1.DataModule2.ADOQuery1.Eof do
  begin
 n:=TreeView1.Items.Add (nil, DM1.DataModule2.ADOQuery1.FieldByName('Наименование').AsString);
ID:=DM1.DataModule2.ADOQuery1DSDesigner2.Index;
 
DM1.DataModule2.ADOQuery2.SQL.text := 'SELECT * FROM Mytable WHERE disciplin_id = '+inttostr(ID);
DM1.DataModule2.ADOQuery2.Open;
While not DM1.DataModule2.ADOQuery2.Eof do
  begin
   ID1:=DM1.DataModule2.ADOQuery2DSDesigner.Index;
    if ID=ID1 then
     c:=TreeView1.Items.AddChild(n, DM1.DataModule2.ADOQuery2.FieldByName('Наименование2').AsString);
 
    DM1.DataModule2.ADOQuery2.Next;
  end;
  DM1.DataModule2.ADOQuery2.Active:=false;
  DM1.DataModule2.ADOQuery1.Next;
end;
 
TreeView1.Items.EndUpdate;
end;
если надо делать тройную вложенность - появиться просто ещё один вложенный цикл.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 16 марта 2009, 09:56
Оценка за ответ: 5


Мини-форум вопроса

Всего сообщений: 8; последнее сообщение — 16 марта 2009, 17:21; участников в обсуждении: 4.
Плакош Алексей

Плакош Алексей (статус: Посетитель), 16 марта 2009, 10:13 [#1]:

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

Таблица 1 (Дисциплины):
КодДисциплины
Наименование
Информация

Таблица 2 (Темы):
КодДисциплиныД
КодТемы
Наименование2
Информация2

Таблица 3 (Подтемы);
КодТемыД
КодПодтемы
Наименование3
Информация3

Запрос1 (ADOQuery1):
SELECT Наименование, КодДисциплины
FROM Дисциплины

Запрос2(ADOQuery2):
SELECT Наименование2, КодДисциплиныД
FROM Темы

Связь между таблицами:
1 и 2
По полям КодДисциплины и КодДисциплиныД

2 и 3
По полям КодТемы и КодТемыД

Тип связей один-ко-многим.
Тов. Женька

Тов. Женька (статус: 3-ий класс), 16 марта 2009, 10:22 [#2]:

Я обычно в таких случаях делаю следующее:
1. Создаю таблицу со следующей структурой:
ID PARENT NAME HasChild
1 0 1 Корневой уровень True
2 0 2 Корневой уровень True
3 1 1 Подуровень False
4 1 2 Подуровень False
5 2 3 Подуровень True
6 5 4 Подуровень False
2. Беру компонент TdxDBTreeView и настраиваю его соответственно.

А все потому, что стандартный TreeView очень медленный. Во-вторых, очень удобно "перемещать" уровни и подуровни. Вы попробуйте в стандартном TreeView поставить для записи с ID=1 поле Parent = 4.
Конечно, это несложно побороть и самостоятельно, но TdxDBTreeView справится не хуже.
Плакош Алексей

Плакош Алексей (статус: Посетитель), 16 марта 2009, 10:25 [#3]:

К сожалению необходим именно TreeView...
Поправка, добавление необходимых тем происходит, но темы добавляться во все начальные узлы, и только те которые относятся к первой дисциплине. Остальные не добавляться.
Вадим К

Вадим К (статус: Академик), 16 марта 2009, 11:19 [#4]:

При правильном подходе TreeView очень таки быстрый. Медленный он только если обращаться по индексу.
то Плакош Алексей
А условие where у Вас есть? или Вы надеетесь, что таблицы связаны и этого достаточно?
Присмотрелся детальнее, строка ID:=DM1.DataModule2.ADOQuery1DSDesigner2.Index; возвращает не знаю что, надо тут подставлять ид, где то так
ID := DM1.DataModule2.ADOQuery1.FieldByName('Коддисциплині').AsInteger
Галочка "подтверждения прочтения" - вселенское зло.
Косолапов Дмитрий Юрьевич

Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 16 марта 2009, 11:56 [#5]:

В принципе для оптимизации обращений к БД (избавиться от запросов в цикле) я бы сделал один общий запрос из внутренних соединений нужных таблиц и отсортировал бы запрос нужным образом и в одном цицле по запросу анализировал бы изменения значений полей. На основании этого добавлял бы Node нужного уровня.
Вадим К

Вадим К (статус: Академик), 16 марта 2009, 12:01 [#6]:

Нужна ли эта оптимизация, если там десяток записей. Для начала надо написать, что бы работало. И работало адекватно. А потом уже смотреть, что тормозить, если вообще тормозит.
Галочка "подтверждения прочтения" - вселенское зло.
Тов. Женька

Тов. Женька (статус: 3-ий класс), 16 марта 2009, 13:17 [#7]:

В Интернете есть статья "DBTreeView своими руками". Очень может помочь, я думаю.
Плакош Алексей

Плакош Алексей (статус: Посетитель), 16 марта 2009, 17:21 [#8]:

Огромное спасибо за помощь, ошибку нашёл.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:43
Выполнено за 0.03 сек.