论坛里有很多这个问题的旧贴 一般来说,有以下几方面问题: 1、树的加载 树结构以二维表的形式存在于数据库中,表结构如下:id,parentid,name,... 对于这种结构的树展开,好像除了通过查询运用递归的方式展树之外,少有更好的办法。 (当然,如果树只有一个根节点,通过改变表结构,既改变树的存储方式,可以不用N多的查询,大大加快速度),这里是一段展树(BOM)的代码: 声明指针,用以保存额外数据: type pchar=^str; str=record mcaption:string; tcaption:string; num:integer;。。 function TForm1.ShowTree(TNode: TTreeNode; s: string): boolean; var QR:TADOQuery; TmpNode:TTreeNode; p:pchar; begin QR:=TADOQuery.Create(self); if TNode=nil then //判断是否顶层接点 ; begin new(p); p^.mcaption:=''; p^.tcaption:=s; p^.num:=1; TNode:=Treeview1.Items.AddChildObject(TNode,p^.tcaption,p); end; with QR,treeview1 do begin Items.BeginUpdate; close; connection:=ADOCONNECTION1; SQL.Clear; SQL.Add('select MD003,MD006 from BOMMD where MD001=:NN'); parameters[0].Value:=s; open; ACTIVE; first; while not eof do begin new(p); p^.mcaption:=s; p^.tcaption:=QR.fieldbyname('MD003').AsString; P^.num:=QR.fieldbyname('MD006').AsInteger; TmpNode:=Items.AddChildObject(TNode,p^.tcaption,p); ShowTree(TmpNode,p.tcaption);//此处递归; next; end; Items.EndUpdate; end; QR.free; end;2、树的拖放的问题: 这关系到鼠表拖放的编程,以下是代码: procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer); var targetnode,sourcenode:ttreenode; begin targetnode:=treeview1.GetNodeAt(x,y); sourcenode:=treeview1.Selected; treeview1.Items.BeginUpdate; try copytree(treeview1,targetnode,sourcenode); targetnode.Selected; finally treeview1.Items.EndUpdate; end; end;procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var targetnode,sourcenode:ttreenode; begin targetnode:=treeview1.GetNodeAt(x,y); if (sender=source) and (targetnode<>nil) then begin accept:=true; sourcenode:=treeview1.Selected; while (targetnode.Parent<>nil) and (targetnode<>sourcenode) do targetnode:=targetnode.Parent; if targetnode=sourcenode then accept:=false; end else accept:=false; end; 3、节点的删除: 可以通过递归删除选中节点及其所有子节点,并删除对应数据库数据: procedure TForm1.detree(node: ttreenode); var tnode:ttreenode; i:integer; s1,s2:string; begin if node.HasChildren then begin for i:=node.Count-1 downto 0 do begin if node.Item[i].HasChildren then detree(node.Item[i]); s1:=pchar(node.Item[i].Data)^.mcaption; s2:=pchar(node.Item[i].data)^.tcaption; with form1.pub do begin close; sql.Clear; sql.Add('delete BOMMD where MD001=:AA and MD003=:BB'); parameters[0].Value:=s1; parameters[1].Value:=s2; ExecSQL; end; node.Item[i].Delete; end; end; node.Delete; end; 当然,还有关于树的添加等,比较简单的。
一般来说,有以下几方面问题:
1、树的加载
树结构以二维表的形式存在于数据库中,表结构如下:id,parentid,name,...
对于这种结构的树展开,好像除了通过查询运用递归的方式展树之外,少有更好的办法。
(当然,如果树只有一个根节点,通过改变表结构,既改变树的存储方式,可以不用N多的查询,大大加快速度),这里是一段展树(BOM)的代码:
声明指针,用以保存额外数据:
type
pchar=^str;
str=record
mcaption:string;
tcaption:string;
num:integer;。。
function TForm1.ShowTree(TNode: TTreeNode; s: string): boolean;
var
QR:TADOQuery;
TmpNode:TTreeNode;
p:pchar;
begin
QR:=TADOQuery.Create(self);
if TNode=nil then //判断是否顶层接点 ;
begin
new(p);
p^.mcaption:='';
p^.tcaption:=s;
p^.num:=1;
TNode:=Treeview1.Items.AddChildObject(TNode,p^.tcaption,p);
end;
with QR,treeview1 do
begin
Items.BeginUpdate;
close;
connection:=ADOCONNECTION1;
SQL.Clear;
SQL.Add('select MD003,MD006 from BOMMD where MD001=:NN');
parameters[0].Value:=s;
open;
ACTIVE;
first;
while not eof do
begin
new(p);
p^.mcaption:=s;
p^.tcaption:=QR.fieldbyname('MD003').AsString;
P^.num:=QR.fieldbyname('MD006').AsInteger;
TmpNode:=Items.AddChildObject(TNode,p^.tcaption,p);
ShowTree(TmpNode,p.tcaption);//此处递归;
next;
end;
Items.EndUpdate;
end;
QR.free;
end;2、树的拖放的问题:
这关系到鼠表拖放的编程,以下是代码:
procedure TForm1.TreeView1DragDrop(Sender, Source: TObject; X, Y: Integer);
var
targetnode,sourcenode:ttreenode;
begin
targetnode:=treeview1.GetNodeAt(x,y);
sourcenode:=treeview1.Selected;
treeview1.Items.BeginUpdate;
try
copytree(treeview1,targetnode,sourcenode);
targetnode.Selected;
finally
treeview1.Items.EndUpdate;
end;
end;procedure TForm1.TreeView1DragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
targetnode,sourcenode:ttreenode;
begin
targetnode:=treeview1.GetNodeAt(x,y);
if (sender=source) and (targetnode<>nil) then
begin
accept:=true;
sourcenode:=treeview1.Selected;
while (targetnode.Parent<>nil) and (targetnode<>sourcenode) do
targetnode:=targetnode.Parent;
if targetnode=sourcenode then
accept:=false;
end
else
accept:=false;
end;
3、节点的删除:
可以通过递归删除选中节点及其所有子节点,并删除对应数据库数据:
procedure TForm1.detree(node: ttreenode);
var
tnode:ttreenode;
i:integer;
s1,s2:string;
begin
if node.HasChildren then
begin
for i:=node.Count-1 downto 0 do
begin
if node.Item[i].HasChildren then
detree(node.Item[i]);
s1:=pchar(node.Item[i].Data)^.mcaption;
s2:=pchar(node.Item[i].data)^.tcaption;
with form1.pub do
begin
close;
sql.Clear;
sql.Add('delete BOMMD where MD001=:AA and MD003=:BB');
parameters[0].Value:=s1;
parameters[1].Value:=s2;
ExecSQL;
end;
node.Item[i].Delete;
end;
end;
node.Delete;
end;
当然,还有关于树的添加等,比较简单的。
根据库读出来
我有实际例子
[email protected]
[email protected]
[email protected]
直接下载请到:
http://www.myjinsui.com/down/sort.asp?classid=9
数据库中重要的只有两样,
1、编码、(可以是定长编码如,“222”为三级树,每级两位编码,
01 一级
0101 二级
010101 三级
也可以是不定长,用规定符号将每级编码分开,
01 一级
01-1 二级
01-1-111 三级
01-332 二级
01-332-1 三级 (两个二级编码长度不一样)2、编码名:(节点名)(1)增加同级节点和下级节点,其实就是增加编码,我没写,你可以自己加上去;(2)并且在该节点上可以增加用户记录也很简单,就不说了。