如何优化程序(关于树型结构)急!急!急!(100分)

  • 主题发起人 主题发起人 月影沙秋
  • 开始时间 开始时间

月影沙秋

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在数据表结构如下:
ID dwtydm dwmc dm1(上级结点代码) bblx
1 111111111 aaaaaaaaa 333333333
2 222222222 bbbbbbbbb 333333333
3 333333333 ccccccccc 777777777 1|汇总表
4 444444444 ddddddddd 666666666
5 555555555 eeeeeeeee 666666666
6 666666666 fffffffff 777777777 1|汇总表
7 777777777 ggggggggg 1|汇总表
8 999999999 hhhhhhhhh 777777777
9 000000000 iiiiiiiii

要生成树型结构,只显示dwmc的内容
我现在的程序是:
procedure TForm1.Button1Click(Sender: TObject);
var
s1,s2,ss,str:shortstring;
i,j,n1,p,zdjd,n2:integer;
node1:ttreenode;
txt,txt1,txt2:tstrings;
t1,t2:ttime;
begin
t1:=time;
txt:=tstringlist.Create;
txt1:=tstringlist.Create;
txt.Clear;
txt1.Clear;
txt2:=tstringlist.Create;
txt2.Clear;
form1.ADOQuery1.Close;
form1.ADOQuery1.SQL.Text:='select count(dwtydm) as d from dwqkb';
form1.ADOQuery1.open;
zdjd:=form1.ADOQuery1.Fieldbyname('d').AsInteger;
/////
TreeView1.Items.Clear;
form1.ADOQuery1.Close;
form1.ADOQuery1.SQL.Text:='select dwtydm,dwmc from dwqkb where (dm1='''')or(dm1 is null) order by dm1 desc';//or(jd='+inttostr(zdjd)+')';
form1.ADOQuery1.open;
n1:=form1.ADOQuery1.RecordCount;
/////
/////////
form1.ADOQuery1.First;
while not form1.ADOQuery1.Eof do
begin
application.ProcessMessages;
ss:=trim(ADOQuery1.fieldbyname('dwtydm').AsString)+'|'+trim(ADOQuery1.fieldbyname('dwmc').AsString);
txt.Add(ss);
txt2.Add(ss);
ADOQuery1.Next;
end;

txt2.SaveToFile('c:/jjbb.txt');
TreeView1.LoadFromFile('c:/jjbb.txt'); ///// 添加一级结点

while n1<>zdjd do
begin ////1
for i:=0 to n1-1 do //将树型结点循环一遍
begin ///2
application.ProcessMessages;
node1:=TreeView1.Items.Item;
s1:=TreeView1.Items.Item.Text;
if not AnsiContainsStr(txt1.Text,s1) then
begin ////3
p:=pos('|',s1);
str:=copy(s1,1,p-1);
form1.ADOQuery1.First;
form1.ADOQuery1.Close;
form1.ADOQuery1.SQL.Text:='select dwtydm,dwmc from dwqkb where (dm1='''+str+''')';//and(jd='+inttostr(j)+')';
form1.ADOQuery1.open;
if form1.ADOQuery1.RecordCount<>0 then
begin ///4
form1.ADOQuery1.First;
while not form1.ADOQuery1.Eof do
begin ///5
application.ProcessMessages;
ss:=trim(ADOQuery1.fieldbyname('dwtydm').AsString)+'|'+trim(ADOQuery1.fieldbyname('dwmc').AsString);
TreeView1.Items.AddChildFirst(node1,ss);
txt.Add(ss);
ADOQuery1.Next;
end; ///5
end; ///4
txt1.Add(s1);
end; ///3
end;//2
n1:=txt.Count;
end; //1
txt.Destroy;
txt1.Destroy;
txt2.Destroy;
t2:=time;
showmessage(timetostr(t2-t1));

end;
功能 可以实现,但数据多了太慢,请各前辈帮忙把程序优化一下,换程序也行,只要能实现在功能就行.在此先行谢过!!
 
你可以试试cxGrid控件
 
//建议用一List加快查询速度
//代码如下: Copy 别人的
unit unit_treepublic;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, ComCtrls, DB, ADODB,graphics,dialogs;

{-------------------------------------------------------------------------------
过程名: MakeTree
说明: 创建树
作者: Along
日期: 2004.12.07
参数: Query: TADOQuery; TableName: string; TreeView: TTreeView
参数说明: Query:相关联的数据库; TableName: 对应的表名; TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure MakeTree(Query: TADOQuery; TableName: string; TreeView: TTreeView);

{-------------------------------------------------------------------------------
过程名: AddNode
说明: 增加树的节点
作者: Along
日期: 2004.12.07
参数: Query: TADOQuery; TreeView: TTreeView
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
{procedure AddNode(Query: TADOQuery; TreeView: TTreeView);}

{-------------------------------------------------------------------------------
过程名: AddChildNode
说明: 增加树的子节点
作者: Along
日期: 2004.12.07
参数: Query: TADOQuery; TreeView: TTreeView
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure AddChildNode(Query: TADOQuery; TreeView: TTreeView);

{-------------------------------------------------------------------------------
过程名: AddTreeNode
说明: 增加节点(内部使用的过程)
作者: Along
日期: 2004.12.07
参数: Query: TADOQuery; TreeView: TTreeView; bj: boolean = false
参数说明: Query:相关联的数据库;TreeView: 所使用的树;bj:是否将焦点移到当前选择的节点
返回值: 无
-------------------------------------------------------------------------------}
procedure AddTreeNode(Query: TADOQuery; TreeView: TTreeView; bj: boolean = false);

{-------------------------------------------------------------------------------
过程名: DelTree
说明: 删除节点(包括删除本节点下的所有子节点)
作者: Along
日期: 2004.12.07
参数: query: TAdoQuery; TreeView: TTreeView
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure DelTree(query: TAdoQuery; TreeView: TTreeView);

{-------------------------------------------------------------------------------
过程名: Treechange
说明: 在树中选择了一个节点,将数据库的游标移动到所选择的节点所对应记录
作者: Along
日期: 2004.12.07
参数: query: TADOQuery; node: TTreenode
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure Treechange(query: TADOQuery; node: TTreenode);

{-------------------------------------------------------------------------------
过程名: Treeedit
说明: 树中的节点内容已经作了修改,将所修改的内容更新回数据库
作者: Along
日期: 2004.12.07
参数: query: TADOQuery; text: string
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure Treeedit(query: TADOQuery; text: string);

{-------------------------------------------------------------------------------
过程名: treeselect
说明: 数据库中的游标已经移动,将焦点移到树中对应的节点
作者: Along
日期: 2004.12.07
参数: query: Tadoquery; TreeView: TTreeView
参数说明: Query:相关联的数据库;TreeView: 所使用的树
返回值: 无
-------------------------------------------------------------------------------}
procedure TreeSelect(StrList:string; TreeView: TTreeView);

{-------------------------------------------------------------------------------
函数名: TreeFind
说明: 找出给定的内容,并移动数据库中的游标,同时将焦点移到树中对应的节点
作者: Along
日期: 2004.12.07
参数: TreeView: TTreeView; text: string
参数说明: TreeView: 所使用的树 text: 要查找的内容
返回值: True:找到  False:找不到
-------------------------------------------------------------------------------}
function TreeFind(TreeView: TTreeView; text: string): boolean;

procedure TreeSearchDraw(ADOquery:TADOQuery;TreeView:TTreeView;StrSearch:string;Node:TTreenode); {TreeView符合查询条件的记录变色}



var fjid,bh,mc:string;
implementation

var
List: TStringList; //用于记录各个dq_dqbh及其在树中所对应的节点,从而实现快速查找

procedure MakeTree(Query: TADOQuery; TableName: string; TreeView: TTreeView);
begin
TreeView.Items.BeginUpdate;
list.Clear;
TreeView.items.clear;
if query.Active then query.Close;
Query.SQL.Text := 'SELECT * FROM ' +TableName+' ORDER BY '+fjid+','+BH;
Query.Open;
query.DisableControls;
TreeView.Items.Clear;
list.Clear;
List.Sorted := True;
query.First;
while not Query.Eof do
begin
addtreenode(Query, TreeView); //依次增加所有的节点
Query.Next;
end;
TreeView.Items.EndUpdate;
query.EnableControls;
if treeview.Items.Count < 1 then exit;
treeview.Select(treeview.Items.Item[0]);
// treeview.SetFocus;
end;

procedure addtreenode(Query: TADOQuery; TreeView: TTreeView; bj: boolean = false);
var
index: integer;
Node: TTreeNode;
begin
if Query.FieldByName(fjid).AsInteger = 0 then { ParentID=0,顶层节点 }
Node := TreeView.Items.AddChildObject(nil, Query.FieldByName(mc).AsString, query.GetBookmark)
//增加节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中
else
begin
Index := List.IndexOf(Query.FieldByName(fjid).AsString);
Node := TreeView.Items.AddChildObjectFirst(TTreeNode(List.Objects[Index]),
Query.FieldByName(mc).AsString, query.GetBookmark);
//增加子节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中
end;
//增加当前节点的信息到列表中,以实现在列表中快速查找节点的功能。
List.AddObject(Query.FieldByName(bh).Asstring, Node);
if bj then
begin
treeview.Select(node);
treeview.SetFocus;
end;
end;

procedure deltree(query: TAdoQuery; TreeView: TTreeView);
var
node: TTreenode;
//删除当前选择的节点下的所有节点(不删除当前选择的节点)
procedure delnode(node: TTreenode);
var
i: integer;
childnode: TTreenode;
begin
for i := 0 to node.Count - 1 do
begin
childnode := node.Item; //取当前节点下的所有节点
query.GotoBookmark(childnode.Data); //移到节点所对应的记录
list.Delete(list.IndexOf(query.FieldByName(bh).AsString)); //删除列表中的数据
query.Delete; //删除对应的记录
if node.HasChildren then delnode(childnode); //有子节点则递归直到所有的数据删除完毕
end;
end;
{另一方法:
用一个递归:
procedure doSearch(tn: TTreeNode);
var i: ingeger;  
begin
 if tn.HasChildren then
 begin
  for i := tn.Count -1 downto 0 do doSearch(tn); 
 end
 else
 begin
   //这里是你对每个节电要做的事情
 end;
end;}

begin
node := treeview.Selected;
if node = nil then exit;
//删除当前选择的节点下的所有节点(不删除当前选择的节点)
delnode(node);
//删除当前选择的节点
query.GotoBookmark(node.Data);
list.Delete(list.IndexOf(query.FieldByName(bh).AsString));
query.Delete;
node.Delete;
TreeView.SetFocus;
end;

procedure AddChildNode(Query: TADOQuery; TreeView: TTreeView);
var
dq_dqbh: integer;
begin
dq_dqbh := query.FieldByName(bh).AsInteger; //记下当前的节点编号
query.Append;
query.FieldByName(mc).AsString := '新建子节点';
query.FieldByName(fjid).AsInteger := dq_dqbh; //新增加的子节点的父节点编号即为dq_dqbh

//query.FieldByName('dq_bz').AsString:='af';
query.post;
addtreenode(query, treeview, true);
end;

{procedure AddNode(Query: TADOQuery; TreeView: TTreeView);
var
dq_dqbh: integer;
begin
dq_dqbh := query.FieldByName(fjid).AsInteger; //记下当前节点的父节点编号
query.Append;
query.FieldByName(mc).AsString := '新建节点';
query.FieldByName(fjid).AsInteger := dq_dqbh; //新增加的子节点的父节点编号即为dq_fjdq_dqbh

//query.FieldByName('dq_bz).AsString:='af';
query.post;
addtreenode(query, treeview, true);
end;}

procedure Treechange(query: TADOQuery; node: TTreenode);
begin
query.GotoBookmark(node.Data);
end;

procedure TreeEdit(query: TADOQuery; text: string);
begin
query.Edit;
query.FieldByName(mc).AsString := text;
query.post;
end;

procedure treeselect(StrList:string; TreeView: TTreeView);
var
index: integer;
Node: TTreeNode;
begin
Index := List.IndexOf(StrList);
Node := TTreeNode(List.Objects[Index]);
treeview.Selected := Node;
treeview.SetFocus;

//查看 List 值
{ for index:= 0 to list.Count -1 do
begin
ShowMessage(list.Strings[index]);
end; }

end;

function TreeFind(TreeView: TTreeView; text: string): boolean;
var
i: integer;
begin
Result := false;
for i := 0 to treeview.Items.Count - 1 do
begin
if treeview.Items.Item.Text = text then
begin
treeview.Select(treeview.Items.Item);
treeview.SetFocus;
Result := true;
exit;
end;
end;
end;


procedure TreeSearchDraw(ADOquery:TADOQuery;TreeView:TTreeView;StrSearch:string;Node:TTreenode); {TreeView符合查询条件的记录变色}
var Index:integer;
begin
if ADOquery.Active = false then
exit;

ADOQuery.First;
while not ADOQuery.Eof do
begin
Index:=list.IndexOf(inttostr(ADOQuery.fieldbyname(StrSearch).AsInteger));
if node = ttreenode(list.Objects[Index]) then
TreeView.Canvas.Font.Color := clBlue;
ADOQuery.Next;
end;

end;



initialization
List := TStringList.Create;

finalization
list.Free;

end.
 
你们的都太复杂了为何不用递归!
下面函数实现你的功能,调用时
DBtotree('dm1 is null',TreeView1,nil); // 当dm1没有就为 Null 时
或 DBtotree('dm1='''''',TreeView1,nil); // 当dm1没有就为 空 时
数据库不同,可能需要把 单引号换成双引号 包括函数部分也是


procedure DBtotree(parastr:string;tree:TTreeView;nod:TTreenode);
var
Qu:TADODataSet;
conn: TADOConnection;
Anod: TTreenode;
begin
conn:=Form1.ADOConn;//建立好的数据库联接
Qu:=TADODataSet.Create(nil);
try
Qu.Connection:=Conn;
Qu.CommandText:='select * from dwqkb where '+parastr;
Qu.Open;
Qu.First;
if Qu.RecordCount>0 then
begin
while not Qu.Eof do
begin
Anod:=tree.Items.AddChild(nod,qu.FieldByName('dwmc').AsString);
DBtotree('dm1='''+qu.FieldByName('dwtydm').AsString+'''',tree,Anod);
//这里关键,用才建好的节点作为初始节点,将多层变为了双层
qu.Next;
end; // end while not Qu.Eof
end; // end if Qu.RecordCount>0
finally
Qu.Free;
end;
end;

是不是很简单呀?呵呵!
 
呵呵,如果动不动就换控件,那就失去讨论的意义了:)
1。TreeView的Items有个方法BeginUpdate和EndUpdate可以避免在装载TreeView的时候,触发节目刷新,记住,必须配套使用。
2。不是优化,但是是基本代码审查:) 不要在TForm1的实现中使用Form1变量。

Good Luck!
 
bmsr:
再次请教你那个递归怎么个用法,我怎么实现不了.谢谢!!
 
把你的错误贴出来看看, 你什么信息都不给我,我怎么帮你呢?
或者你说说我上面代码你不明白的地方?
 
后退
顶部