Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 29.05.2015, 00:30
mariyaprigoda mariyaprigoda вне форума
Прохожий
 
Регистрация: 29.05.2015
Сообщения: 2
Версия Delphi: Delphi7
Репутация: 10
По умолчанию Рекурсивное заполнение TreeView из БД

Добрый день, очень прошу помощи! Помогите, очень срочно, мучаюсь два дня! На Делфи пишу впервые, просмотрела много тем, так и не нашла своей ошибки. Пишу на Delphi7.
Задача: Заполнить рекурсивно дерево TreeView из БД FireBird, данные заполняются из таблицы Catalogi, где поля id_cat, name, opisanie, id_rod_cat. SQL запрос в IBQuery_output: select * from CATALOGI where CATALOGI.ID_ROD_CAT= : parent;
Ошибка в следующем: заполняю я в обратном порядке, рекурсивно, но заполняет только последний подкаталог, а на выше уровня подкаталог не поднимается .

Текст программы:

Код:
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Buttons, IBDatabase, DB, IBQuery, IBCustomDataSet, IBTable,
  ComCtrls, Menus, Grids, DBGrids;
 
type
 TInfoC = class
  id: integer;
  id_parent:integer;
  NameC  : string;
  end;
 PTInfoC = ^TInfoC;
 
  TForm1 = class(TForm)
    TreeView1: TTreeView;
    IBTable1: TIBTable;
    IBQuery_output: TIBQuery;
    IBDatabase1: TIBDatabase;
    DataSource_output: TDataSource;
    IBTransaction1: TIBTransaction;
    IBQuery_new_cat: TIBQuery;
    DataSource_new_cat: TDataSource;
    SpeedButton1: TSpeedButton;
    SpeedButton2: TSpeedButton;
    DBGrid1: TDBGrid;
     procedure FormCreate(Sender: TObject);
    //procedure SpeedButton1Click(Sender: TObject);
    procedure TreeBuild(T:TTreeNode);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var    InfoC: TInfoC;
        U: TInfoC;
    Catalog: TTreeNode;
    dop:integer;
 
    sss:string;
begin
 
IBQuery_output.Active:=true;
IBQuery_output.Params.ParamByName('parent').Value:=0;
IBQuery_output.Close;
IBQuery_output.Open;
IBQuery_output.Active:=true;
DBGrid1.Repaint();
DBGrid1.DataSource.DataSet.First;
while not DataSource_output.DataSet.Eof do
      begin
     //InfoC.id:=0;
          if ((DBGrid1.Columns[0].Field.AsInteger=1 )and (DBGrid1.Columns[3].Field.AsInteger=0)) then begin
              //Catalog:=TreeView1.Items.Add(nil,DBGrid1.Columns[1].Field.Text);
              //if (InfoC<>nil) then
              //begin
                  InfoC:=TInfoC.Create;
                  InfoC.id:=DBGrid1.Columns[0].Field.AsInteger ;
                  InfoC.NameC:=DBGrid1.Columns[1].Field.AsString;
                  InfoC.id_parent:=0;
                  Catalog:=TreeView1.Items.AddObject(nil,DBGrid1.Columns[1].Field.Text, @InfoC);
 
                  //sss := PTInfoC(Catalog.Data)^.NameC;
                  //ShowMessage(sss) ;
          end;
                   DataSource_output.DataSet.Next;
               end;
 
               TreeBuild(Catalog);
             //    //ïåðåõîä íà ñëåäóþùóþ çàïèñü â òàáëèöå
              // öèêë
 
end;
 
procedure TForm1.TreeBuild( T: TTreeNode);
var     InfoC :TInfoC;
ttt:^TInfoC;
 NewInfoC :array of TInfoC;
     Catalogs, C : TTreeNode;
    dop,i,parent,countlist:integer;
    index_first, index_last: integer;
    sss:string;
    cT:TTreeNode;
begin
 
parent := (PTInfoC(T.data))^.id;
IBQuery_output.Active:=false;
IBQuery_output.Params.ParamByName('parent').AsInteger:=parent;
IBQuery_output.Close;
IBQuery_output.Open;
IBQuery_output.Active:=true;
DBGrid1.Repaint();
if IBQuery_output.RecordCount>0 then begin
SetLength(NewInfoC,  IBQuery_output.RecordCount);
i:=0;
 while not DataSource_output.DataSet.Eof do
  begin
  if ( DBGrid1.Columns[3].Field.AsInteger=parent) then begin
      NewInfoC[i]:=TInfoC.Create;
      NewInfoC[i].id:=DBGrid1.Columns[0].Field.AsInteger ;
      NewInfoC[i].NameC:=DBGrid1.Columns[1].Field.AsString;
      NewInfoC[i].id_parent:=parent;
 
      TreeView1.Items.AddChildObject(T,DBGrid1.Columns[1].Field.Text, @NewInfoC[i]) ;
      i:=i+1;
  end ;
  DataSource_output.DataSet.Next;
 end; //while
   cT:= (T.getFirstChild);
 
   while cT<>nil do begin
          //  TreeBuild(cT);
            cT:=cT.getNextSibling;
    end;
 end; //if
end;
 
end.
MAD: читаем правила

Последний раз редактировалось M.A.D.M.A.N., 29.05.2015 в 08:04.
Ответить с цитированием
  #2  
Старый 29.05.2015, 19:31
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,105
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А точно надо рекурсивно?
Вообще, я обычно в таком случае делаю LazyLoad. Т.е. изначально заполняется только верхний уровень (where parent is null), а при раскрытии узла подгружается только этот узел. Фокус в том, что когда создаешь узел ему надо создать фейкового ребенка, что бы была возможность этот узел раскрывать. При раскрытии узла этот подузел удаляется и создаются нормальные, загруженные из БД.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
mariyaprigoda (30.05.2015)
  #3  
Старый 30.05.2015, 10:13
mariyaprigoda mariyaprigoda вне форума
Прохожий
 
Регистрация: 29.05.2015
Сообщения: 2
Версия Delphi: Delphi7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
А точно надо рекурсивно?
Вообще, я обычно в таком случае делаю LazyLoad. Т.е. изначально заполняется только верхний уровень (where parent is null), а при раскрытии узла подгружается только этот узел. Фокус в том, что когда создаешь узел ему надо создать фейкового ребенка, что бы была возможность этот узел раскрывать. При раскрытии узла этот подузел удаляется и создаются нормальные, загруженные из БД.
Спасибо за идею, но я в это новичок, может есть пример?? Буду очень благодарна
Ответить с цитированием
  #4  
Старый 30.05.2015, 21:40
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,105
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Готового примера под рукой нет.
Тебе нужно событие OnExpanding, в еотором надо почистить текущий нод и создать новые, считав из БД.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 04:18.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025