Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

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

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

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.10.2007, 23:36   #1
Aska
 
Аватар для Aska
 
Регистрация: 21.10.2007
Сообщений: 3
Сообщение Как отобразить категории, имеющие вложенность произвольной глубины?!

У меня в БД таблицы продуктов, категорий. Каждый товар принадлежит к одной категории. Категории имеют вложенность произвольной глубины.
Категории надо отобразить как дерево папок. Можно ли что-то подобное сделать в гриде, я не знаю, поэтому решила использовать тривью, но т.к. никогда не пользовалась им раньше, то тут у меня ничего путного не выходит. Может подскажете, пожтолкнету меня в нужную сторону ?!!
Использую firebird, к компоненты table не использую, пользую IBDataSet и т.п. В таблице категорий храню идентификатор, ссылку на родителя и наименование категории, а в таблице товаров идентификатор, ссылку на категорию, ну и наименования, цена там и т.п.
Заранее спасибо!
Aska вне форума Ответить с цитированием
Старый 23.10.2007, 02:25   #2
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Результирующий набор из таблицы категорий должен быть отсортирован по двум полям - идентификатор, ссылка на родителя. Или создайте такой составной индекс.
После этого процесс построения дерева происходит за один проход.
Если вкратце:
- заносим первого родителя (у него парент ноль, ведь он в корне)
- смотрим, кто папа у следующего. Если первый родитель (его код надо запомнить в переменной), то добавляем папе детеныша
- аналогично проверяем следующую запись, а вдруг там окажется детка детеныша?
Ну, и так далее...
mihali4 вне форума Ответить с цитированием
Старый 23.10.2007, 09:37   #3
Aska
 
Аватар для Aska
 
Регистрация: 21.10.2007
Сообщений: 3
По умолчанию

if DataSet_Category.FieldByName('CT_PA RENT').AsInteger = 0 then
TreeView.Items.Add(nil, DataSet_Category.FieldByName('CT_NA ME').AsString) - здесь я создала узел в корне, а вот как мне теперь ему его id присвоить? Не совсем поняла, как хранить в переменной ( Тут трабл с индексами, первая запись в таблице, она будет с parent=0 и будет корневой и в тривью индекс тож будет 1 , а вот вторая запись тоже может быть корневой, а третья дите первого, но в тривью дите будет иметь индекс 2, а у втораой корневой индекс 3.
Чего-то туплю (((

Последний раз редактировалось Aska; 23.10.2007 в 10:26.
Aska вне форума Ответить с цитированием
Старый 23.10.2007, 14:36   #4
mihali4
*
Старожил
 
Регистрация: 22.11.2006
Сообщений: 9,201
По умолчанию

Ну вот пример из моей программульки:

Код:
//построение дерева из трех таблиц
//для вас важен принцип
procedure Tfmain.GetTree;
var nnod,nnor: TTreeNode;
    MyRecPtr: PMyRec;
    rnum,wnum: integer;
begin
TreeView.Items.BeginUpdate;
PLoad.Caption:='Подождите. Загрузка базы';
PLoad.Visible:=True;
Gauge.Visible:=PLoad.Visible;
Application.ProcessMessages;
rnum:=TQuest.RecordCount;
wnum:=0;
Gauge.Progress:=wnum;
Gauge.MaxValue:=rnum;
TreeView.SortType:=stNone;
TreeView.Items.Clear;
TTema.First;
if TTema.RecordCount>0 then
begin
while not TTema.Eof do
begin
New(MyRecPtr);
MyRecPtr^.FName:=TTemaId.Value;
MyRecPtr^.LName:='Tema';
MyRecPtr^.KName:=True;
nnod:=TreeView.Items.AddObject(nil, TTemaTema.Text, MyRecPtr);
TRazdel.Filter:='IdTema='+IntToStr(TTemaId.Value);
if TRazdel.RecordCount>0 then
begin
TRazdel.First;
while not TRazdel.Eof do
begin
New(MyRecPtr);
MyRecPtr^.FName:=TRazdelId.Value;
MyRecPtr^.MName:=TRazdelIdTema.Value;
MyRecPtr^.LName:='Razd';
MyRecPtr^.KName:=True;
nnor:=TreeView.Items.AddChildObject(nnod, TRazdelRazdel.Text, MyRecPtr);
TQuest.Filter:='IdRazdel='+IntToStr(TRazdelId.Value);
if TQuest.RecordCount>0 then
begin
TQuest.First;
while not TQuest.Eof do
begin
New(MyRecPtr);
MyRecPtr^.FName:=TQuestId.Value;
MyRecPtr^.MName:=TQuestIdRazdel.Value;
MyRecPtr^.LName:='Quest';
MyRecPtr^.KName:=TQuestFull.Value;
TreeView.Items.AddChildObject(nnor, TQuestQuestion.Text, MyRecPtr);
Inc(wnum);
Gauge.Progress:=wnum;
Application.ProcessMessages;
TQuest.Next;
end;
end;
TRazdel.Next;
end;
end;
TTema.Next;
end;
end;
TTema.Filter:='';
TRazdel.Filter:='';
TQuest.Filter:='';
Gauge.Visible:=False;
Application.ProcessMessages;
TreeView.SortType:=stText;
TreeView.Items.EndUpdate;
Application.ProcessMessages;
TreeView.Items.GetFirstNode;
GetLast(lastnod); //это восстановление позиции просмотра предыдущего запуска
TreeView.Selected:=lastnode;
Application.ProcessMessages;
end;
mihali4 вне форума Ответить с цитированием
Старый 31.10.2007, 01:03   #5
Aska
 
Аватар для Aska
 
Регистрация: 21.10.2007
Сообщений: 3
По умолчанию

огромное спасибо! с деревом справилась )))
Aska вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Скрыть-Отобразить с помощью VBA ZORRO2005 Microsoft Office Excel 5 01.09.2008 09:11
Подскажите, как лучше отобразить картинку! badfilin JavaScript, Ajax 0 12.05.2008 01:34
Сортировка двумерного массива произвольной длины. Visual Basic Pekc Помощь студентам 0 25.11.2007 19:30
отобразить query в 3-х dbgrid Nuts БД в Delphi 0 03.09.2007 18:19
Отобразить имеющиеся диски Prowler Win Api 4 22.02.2007 15:17