Re: recursive treeview fill - problem
- From: Rob Kennedy <me3@xxxxxxxxxxx>
- Date: Thu, 23 Nov 2006 23:04:02 -0600
Anwendungsprogrammierer@xxxxxx wrote:
i got a table with this layout:
id__ name parent_id__
it stores data to recursively fill a treeview.
Now I wrote a function like that to fill the tree, but it does not seem
to work right, it adds one empty item below every node. I cant find the
flaw - pls help.
first call is filltree(nil,'')
I've begun by fixing the indentation. Sloppy code is buggy code.
procedure TMain.FillTree(N : TTreeNode; Parent : String);
var x, rsC : _recordset;
TreeParent, treechild : TTreeNode;
cmd : string;
begin
With self.navTree.Items do
Begin by removing the "with" statement. It can lead to nothing but problems.
begin
if n =nil then begin
// clear nodes
clear;
cmd:='SELECT id__,name, parent_id__ FROM tbl_Entries WHERE
parent_id__ is NULL';
If the parent_id__ field is always going to be null in the result, why select it?
x:=dblayer.Execute(cmd);
while not x.EOF do begin
application.ProcessMessages;
if x.Fields.Item[2].Value = null then begin
Doesn't the field object have an IsNull property you could check instead?
And aren't you guaranteed that the field will be null since that was the condition in the WHERE clause?
treeparent:=add(nil,x.Fields.Item[1].Value);
cmd:='SELECT id__,name, parent_id__ FROM tbl_Entries WHERE
parent_id__ =''' + x.Fields.Item[0].Value + '''';
You shouldn't need to select the parent_id__ field here, either. You already know exactly what it's value is going to be, so don't make the database send that value back to you for every record it finds.
rsc:=dblayer.Execute(cmd);
Are you sure your database system allows you to initiate a query while another one from the same thread is still open? Once you assign rsc, are you sure x is still valid?
while not rsc.EOF do begin
if rsc.Fields[2].Value ='' then
application.ProcessMessages
Will that condition ever be true? Field 2 is for parent_id__, right? You've selected that field and required it to be equal to the id__ field of the parent. Will the ID ever be an empty string?
else begin
showmessage(rsc.Fields.Item[0].value +
':'+rsc.Fields.Item[1].value);
TreeChild :=
AddChild(TreeParent,rsc.Fields.Item[1].value);
FillTree(TreeChild,rsc.Fields.item[0].value);
end;
if not rsc.EOF then rsc.MoveNext;
Get rid of the condition. You already know EOF is False, or you wouldn't be inside the loop in the first place. Just call MoveNext directly.
end;
end;
if not x.EOF then x.movenext;
Same here.
end;
end
else begin
if parent='' then exit;
cmd:='SELECT id__,name, parent_id__ FROM tbl_Entries WHERE
parent_id__ =''' + parent + '''';
rsc:=dblayer.Execute(cmd);
repeat
Your two loops above where both "while" loops. Now you're using a "repeat" loop, which is guaranteed to run at least once. I suspect this is why you end up with too many items in your tree.
TreeChild := AddChild(n,rsc.Fields.Item[1].value);
FillTree(TreeChild,rsc.Fields.Item[0].Value);
A recursive call that executes a query will have the same problems as a nested query above. Make sure your database tool allows that.
if not rsc.EOF then rsc.movenext;
until rsc.EOF
end;
end;
end;
I think the main "then" branch is doing too much. It should only have one loop, just like the "else" branch. As it is now, the "then" branch is responsible for filling two tiers of the tree instead of just one. That means you've duplicated code for populating the non-parent levels of the tree.
--
Rob
.
- References:
- recursive treeview fill - problem
- From: Anwendungsprogrammierer
- recursive treeview fill - problem
- Prev by Date: DBGrid scroll bars
- Next by Date: AV when calling setlength on a dynamic array of boolean
- Previous by thread: recursive treeview fill - problem
- Next by thread: DBGrid scroll bars
- Index(es):
Relevant Pages
|