|
Вопрос # 2 530/ вопрос открыт / |
|
Здравствуйте, эксперты!
У меня возникла проблема с заполнением компонента TreeView данными из БД. Т.е. при нажатии на кнопку дерево должно заполняться данными из БД. В базе 3 таблицы: дисциплины, темы, подтемы; связь между ними осуществляется по принципу: дисциплины--} темы--} подтемы (один ко многим). Заполнение TreeView должно происходить по этим же принципам. База Данных Access. Использую ADO.
Приложение: Переключить в обычный режим-
- 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;
- DM1.DataModule2.ADOQuery2.Open;
-
- TreeView1.Items.BeginUpdate;
- TreeView1.Items.Clear;
-
- While not DM1.DataModule2.ADOQuery1.Eof do
- begin
-
- ID:=DM1.DataModule2.ADOQuery1DSDesigner2.Index;
-
- While not DM1.DataModule2.ADOQuery2.Eof do
- begin
- ID1:=DM1.DataModule2.ADOQuery2DSDesigner.Index;
- if ID=ID1 then
-
-
- DM1.DataModule2.ADOQuery2.Next;
- end;
-
- DM1.DataModule2.ADOQuery1.Next;
- end;
-
- TreeView1.Items.EndUpdate;
- end;
-
 |
Вопрос задал: Плакош Алексей (статус: Посетитель)
Вопрос отправлен: 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]:
Огромное спасибо за помощь, ошибку нашёл.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|