Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
ВнизПередать TTReeNode Найти похожие ветки
← →
YurikGL © (2004-08-18 12:39) [0]Что-то не могу сообразить, как правильно решить следующую задачу.
Есть база объектов, которые связанны однонаправленными связями многие ко многим друг с другом. Циклов нет. Необходимо построить от определенной точки получившееся дерево. Использую для этого рекурентную функцию вида
Procedure RecurForTree(IdSborka:longint;Node:TTreeNode);
var
List:TMyListForTree;
s:string;
i:longint;
Rec:TSborkaRecForTree;
NLocal:TTreeNode;
Begin
List:=TMyListForTree.Create;
ADODataSetvr.Free;
ADODataSetvr:=TSimpleDataSet.Create(self);
ADODataSetvr.Connection:=DataModule1.ADOConnection1;
s:="select IerhLink.IdSborkaChild,IerhLink.CountS, Sborki.naimenovan From IerhLink, Sborki where IerhLink.IdSborkaParent="+IntToStr(IdSborka)+" and IerhLink.IdSborkaChild=Sborki.idSborka";
ADODataSetvr.Dataset.CommandText:=s;
ADODataSetvr.Active:=true;
ADODataSetvr.First;
if ADODataSetvr.RecordCount>0 then
repeat
NLocal:=TreeView1.Items.AddChild(Node,ADODataSetvr.Fields[2].Value);
List.MyAdd(ADODataSetvr.Fields[0].Value,NLocal);
ADODataSetvr.Next;
Until ADOdatasetvr.EOF;
if List.Count>0 then
for i:=0 to List.Count-1 do begin
Rec:=TSborkaRecForTree(List.items[i]);
recurForTree(Rec.IdSborka,Rec.Node);
end;
List.Free;
End;
TSborkaRecForTree = class
IdSborka:longint;
Node:TTreeNode;
constructor Create(S1:longint;Node:TTreeNode);
end;
TMyListForTree = class (TList)
procedure MyAdd (S1:longint;Node:TTreeNode);
destructor Destroy; override;
end;
Пытаюсь запустить
recurForTree(DataModule1.ADODataSetSborkiAll.Fields[0].value,TreeView1.Items.Add(nil,DataModule1.ADODataSetSborkiAll.Fie lds[2].value));
При этом объект второго уровня вложенности вкладывается в первый, а третьего создается в корне. Посмотрел через watch вижу, что при вызове recurForTree(Rec.IdSborka,Rec.Node); процедура получает nil в качестве параметра Node:TTreeNode.
Как быть?
← →
clickmaker © (2004-08-18 12:42) [1]видимо условие if ADODataSetvr.RecordCount>0 не выполнилось
← →
Digitman © (2004-08-18 12:45) [2]
> многие ко многим
> получившееся дерево
что-то как-то не вяжется понятие "сетевая структура" (см. "многие ко многим") и "древовидная стуктура" (см. "получившееся дерево", читай - "многие к одному")
← →
YurikGL © (2004-08-18 20:04) [3]
> видимо условие if ADODataSetvr.RecordCount>0 не выполнилось
Нет, оно выполняется корректно. ИМХО проблема в том, что TTreeNode - указатель.
> Digitman © (18.08.04 12:45) [2]
Пример.
Изделие А состоит из элементов А1 и AB. Изделие B состоит из элементов B1 и AB Элемент A1 состоит из подэлементов С1 и С2
Элемент B1 состит из C1 и С3.
Рисунок, если получится.
A B
| \ | \
A1 AB B1
| \/ \|
C2 C1 C3
Общая структура - однонаправленный граф (сеть) и связи и многие ко многим т.к. многие один элемент более нижнего уровня может содержатся во многих элементах более высокого уровня и наоборот.
Теперь необходимо выделить дерево от некоей вершины. Например, если выделять от А то получим
А
| \
А1 АB
| \ | \
C1 C2 C3
Все это выполняется с помощью рекурентной фукции которая делает следующее.
Делаем select по детям (функция использовалась раньше для сбора общей статистики, поэтому там осталось CountS - количество элементов) Потом этот селект переливаем в в созданный в рамках фунции список. И применяем эту функцию ко всем элементам списка. Таким образом во всех иттерациях используется один и тот же датасет.
Но все это к делу не относится.
З.Ы. После того, как я написал вопрос у провайдера отключили электричество :-). Сейчас пишу из дома.
← →
YurikGL © (2004-08-19 13:45) [4]Мастера, где вы?
Хотя бы примерчик рекурсивного заполнения TreeView-а посмотреть
← →
Digitman © (2004-08-19 13:58) [5]
> YurikGL © (18.08.04 20:04) [3]
> однонаправленный граф
ах вон оно что !
теперь понятно
у тебя сам SELECT-запрос, думается, неверно составлен, оттого и проблемы
← →
Семен Сорокин © (2004-08-19 13:59) [6]покажи код процедуры:
procedure MyAdd (S1:longint;Node:TTreeNode);
← →
Семен Сорокин © (2004-08-19 14:02) [7]и еще:
TSborkaRecForTree = class
IdSborka:longint;
Node:TTreeNode;
constructor Create(S1:longint;Node:TTreeNode);
end;
constructor TSborkaRecForTree.Create(S1:longint;Node:TTreeNode);
begin
inherited;
IdSborka := S1;
self.Node := Node
end;
← →
YurikGL © (2004-08-19 14:03) [8]
> Digitman © (19.08.04 13:58) [5]
В случае поиска всех листьев дерева он работал.
Constructor TSborkaRecForTree.Create(S1:longint;Node:TTreeNode);
Begin
IdSborka:=S1;
Node:= Node;
inherited Create;
End;
Procedure TMyListForTree.MyAdd(S1:longint;Node:TTreeNode);
Var
Sb:TSborkaRecForTree;
Begin
Sb:=TSborkaRecForTree.Create(S1,Node);
Add(Sb);
End;
Destructor TMyListForTree.Destroy;
Var
i:longint;
Begin
For i:=0 to Count-1 do
TMyListForTree(Items[i]).Free;
Inherited Destroy;
End;
← →
Семен Сорокин © (2004-08-19 14:04) [9]
> YurikGL © (19.08.04 14:03) [8]
прям стелепатировал :) см. [7]
← →
NAlexey © (2004-08-19 14:04) [10]А там все просто:
procedure WalkThroughTree(TreeNodes: TTreeNodes);
var
I: Integer;
begin
for I := 0 to TreeNodes.Count - 1 do
begin
ShowMessage(TreeNodes[I].Text);
if TreeNodes[I].HasChildren then
WalkThroughTree(TTreeNodes(TreeNodes[I]));
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
WalkThroughTree(TreeView1.Items);
end;
← →
YurikGL © (2004-08-19 14:11) [11]
> self.Node := Node
Секунд 30 соображал почему так. Спасибо большое. Помогло.
← →
YurikGL © (2004-08-19 14:13) [12]
> Node:= Node;
Это я конечно круто написал :-)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.09.05;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c