有两个表:
主表:DictflMaster (fl_dalei) 大类25类
明细表:DictFlSlave(flmx_flh,flmx_flmc,flmx_top)明细纪录大约10万条
按主表大类分类,大类下放明细表小类。
现已经实现从sqlServer 库加载,只是速度太慢(50秒),(奔四、256MB、win2000 联想机)。
****************************************************
如何更快加载Treeview呢?要求能够在1-5秒之内加载。
****************************************************源码如下:
------------------------------------------------------------------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ComCtrls, Db, ADODB, Grids, DBGrids, Gauges, ExtCtrls;type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Query: TADOQuery;
TreeView: TTreeView;
BitBtn1: TBitBtn;
QueryTemp: TADOQuery;
EditCount: TEdit;
Gauge: TGauge;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.BitBtn1Click(Sender: TObject);
var
TmpNode ,TmpNode1 : Ttreenode ;
TmpNodeTxt ,TmpBegin,TmpEnd : string ;
FlagLen ,i : integer ;
begin
with Query do
begin
close ;
sql.clear ;
sql.add(' select * from DictflMaster order by fl_dalei '); // where fl_dalei like ''%a%''
open ;
TmpNode := TreeView.Items.AddChild(nil,'档案类别') ;
TmpNode1 := TmpNode ;
first ;
while not eof do
begin
TmpNode := TreeView.Items.AddChild(TmpNode,Fieldbyname('fl_dalei').asstring) ;//头节点
EditCount.text := '1' ; //初始为第一级
TmpNodeTxt := Fieldbyname('fl_dalei').asstring ;//读取该夫接点名称
TmpNodeTxt := copy(TmpNodeTxt,2,1) ; //换算为字母
with QueryTemp do
begin
close ;
sql.clear ;
sql.add(format(' select count(*) tmpcount from DictFlSlave '
+' where flmx_flh like ''%s'' ',[TmpNodeTxt+'%']));
open ;
Gauge.MaxValue := fieldbyname('tmpcount').asinteger ;
close ;
sql.clear ;
sql.add(Format(' select flmx_top,flmx_flh,flmx_flmc from DictFlSlave '
+' where flmx_flh like ''%s'' ORDER BY flmx_flh ',[TmpNodeTxt+'%']));
open ;//读出头接点下的结果集;
first ;//置顶;
next ;
while not eof do
begin
FlagLen := Fieldbyname('flmx_top').asinteger ;
TmpBegin:= Fieldbyname('flmx_flh').asstring ;
TmpEnd := Fieldbyname('flmx_flmc').asstring ;
if FlagLen = Strtoint(EditCount.text) then //如果等于上级接点级别,为同级
TmpNode := TmpNode.Parent
else if FlagLen < Strtoint(EditCount.text) then
for i := 0 to Strtoint(EditCount.text) - FlagLen do //如果小于上级接点级别,则循环找父级
TmpNode := TmpNode.Parent ;
TmpNode := TreeView.Items.AddChild(TmpNode,'['+TmpBegin+']'+TmpEnd) ;//写接点
EditCount.text := inttostr(FlagLen) ;//记录上一接点的级别
Gauge.Progress := Gauge.Progress + 1;
next ;
end;
end ;
next ;
TmpNode := TmpNode1 ;//返回最高级 ;
end;
end;
end;end.
主表:DictflMaster (fl_dalei) 大类25类
明细表:DictFlSlave(flmx_flh,flmx_flmc,flmx_top)明细纪录大约10万条
按主表大类分类,大类下放明细表小类。
现已经实现从sqlServer 库加载,只是速度太慢(50秒),(奔四、256MB、win2000 联想机)。
****************************************************
如何更快加载Treeview呢?要求能够在1-5秒之内加载。
****************************************************源码如下:
------------------------------------------------------------------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ComCtrls, Db, ADODB, Grids, DBGrids, Gauges, ExtCtrls;type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Query: TADOQuery;
TreeView: TTreeView;
BitBtn1: TBitBtn;
QueryTemp: TADOQuery;
EditCount: TEdit;
Gauge: TGauge;
procedure BitBtn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.DFM}procedure TForm1.BitBtn1Click(Sender: TObject);
var
TmpNode ,TmpNode1 : Ttreenode ;
TmpNodeTxt ,TmpBegin,TmpEnd : string ;
FlagLen ,i : integer ;
begin
with Query do
begin
close ;
sql.clear ;
sql.add(' select * from DictflMaster order by fl_dalei '); // where fl_dalei like ''%a%''
open ;
TmpNode := TreeView.Items.AddChild(nil,'档案类别') ;
TmpNode1 := TmpNode ;
first ;
while not eof do
begin
TmpNode := TreeView.Items.AddChild(TmpNode,Fieldbyname('fl_dalei').asstring) ;//头节点
EditCount.text := '1' ; //初始为第一级
TmpNodeTxt := Fieldbyname('fl_dalei').asstring ;//读取该夫接点名称
TmpNodeTxt := copy(TmpNodeTxt,2,1) ; //换算为字母
with QueryTemp do
begin
close ;
sql.clear ;
sql.add(format(' select count(*) tmpcount from DictFlSlave '
+' where flmx_flh like ''%s'' ',[TmpNodeTxt+'%']));
open ;
Gauge.MaxValue := fieldbyname('tmpcount').asinteger ;
close ;
sql.clear ;
sql.add(Format(' select flmx_top,flmx_flh,flmx_flmc from DictFlSlave '
+' where flmx_flh like ''%s'' ORDER BY flmx_flh ',[TmpNodeTxt+'%']));
open ;//读出头接点下的结果集;
first ;//置顶;
next ;
while not eof do
begin
FlagLen := Fieldbyname('flmx_top').asinteger ;
TmpBegin:= Fieldbyname('flmx_flh').asstring ;
TmpEnd := Fieldbyname('flmx_flmc').asstring ;
if FlagLen = Strtoint(EditCount.text) then //如果等于上级接点级别,为同级
TmpNode := TmpNode.Parent
else if FlagLen < Strtoint(EditCount.text) then
for i := 0 to Strtoint(EditCount.text) - FlagLen do //如果小于上级接点级别,则循环找父级
TmpNode := TmpNode.Parent ;
TmpNode := TreeView.Items.AddChild(TmpNode,'['+TmpBegin+']'+TmpEnd) ;//写接点
EditCount.text := inttostr(FlagLen) ;//记录上一接点的级别
Gauge.Progress := Gauge.Progress + 1;
next ;
end;
end ;
next ;
TmpNode := TmpNode1 ;//返回最高级 ;
end;
end;
end;end.
10万条记录,你想想吧,网络传输也得有一会吧
动态建树吧procedure TMDTreeView.BuildTreeDevice(Node: TTreeNode);
function getSQL(Node: TTreeNode): string;
begin
result := 'SELECT TB1.ID,TB1.NAME,TB1.CODE';
if Node = nil then
result := result + ' FROM ' + FMasterTableName + ' TB1 WHERE TB1.PARENTID=-1'
else
begin
result := result + ',TB1.Code FROM ' + FMasterTableName + ' TB1 WHERE TB1.PARENTID=' + IntToStr(Node.StateIndex);
if FMasterFilter >= 0 then
result := result + ' AND TB1.CLASS=' + IntToStr(FMasterFilter);
if FUseDispIndex then
result := result + ' ORDER BY TB1.DISPINDEX'
else
result := result + ' ORDER BY TB1.ID';
end; end;
var
lNewNode: TTreeNode;
lNode: TTreeNode;
MDData: PMDData;
str:String;
begin
str:=getSQL(node);
clientDataset.Close;
clientdataset.CommandText := getSQL(Node);
clientDataset.Open;
Items.BeginUpdate;
while not ClientDataSet.Eof do
begin
new(MDData);
lNewNode := Items.AddChild(Node, ClientDataSet.FieldValues['NAME']);
MDData^.CODE := ClientDataSet.FieldByname('Code').AsString;
lNewNode.Data := MDData;
lNewNode.StateIndex := ClientDataSet.FieldValues['ID'];
if lNewNode.Parent=nil then
begin
LNewNode.ImageIndex :=0;
LNewNode.SelectedIndex :=0;
end
else
begin
lNewNode.ImageIndex := MasterStartImage;
lNewNode.SelectedIndex := MasterStartImage;
end;
New(MDData);
lNode := items.Addchild(lNewNode, 'newnode');
lNode.Data := MDData; ClientDataSet.Next;
end; items.EndUpdate;
if items.Count =0 then
begin
//new(MDData);
lNewNode := Items.AddChild(Node, '树');
items.Addchild(lNewNode, 'newnode');
lNewNode.StateIndex :=0;
end;
if Node = nil then
begin
Selected := lNewNode;
Selected.Expand(false);
end;
end;
用上面的动态的来吧,一层一层的来
数据库是那位高人设计的啊,
我的经验是少用like,本身就慢,另外,数据还是是 select * from 增加网络传输压力!3,10万条记录,什么也不错,从头到尾,移动得耗时多少?
一会给你改造一下!等着!
这位大哥,你觉得如何改造呢?
在下洗耳恭听。
主表DictFlMaster一共25条纪录,两个字段。
明细表表结构:
flmx_flh varchar (50) 主键
flmx_flmc varchar(100)
flmx_top int(2)
很强的Google可以找到,速度很快的
这个控件中有一个OnExpanded和OnExpanding事件,各位怎么不用呢.
首先加载根节点,其他不管,加入的时候设置Node的HasChild=true,
在上面的OnExpandIng事件中在加载该节点的子节点,以此类推.没有必要一次加载嘛,
这个控件中有一个OnExpanded和OnExpanding事件,各位怎么不用呢.
首先加载根节点,其他不管,加入的时候设置Node的HasChild=true,
在上面的OnExpandIng事件中在加载该节点的子节点,以此类推.没有必要一次加载嘛,
可以提高一定的速度。
的意见。
UP
判断用户是否在本计算机上第一次登录?
Y:创建多层分类,以XML格式存放在Appliation path\users\username\category.xml
N:
读取Appliation path\users\username\category.xml,得到本地文件日期;
从数据库中检索,判断是否有更新?
Y:重新创建分类列表
N:启动这样不是很适合分类改动特别大的程序。
这样一来,第一次启动程序的时候会比较慢,以后的启动中,直接读取本地文件会快很多。
至于数据库的设计,如下:
CID int
CNAME varchar(80)
PARENTID int读取是循环+递归xml文件片断如下:
<?xml version="1.0" encoding="GB2312"?>
<CateGory>
<DateTag>
2004-7-16 13:22:10.233
</DateTag>
<Tree>
<!--Category tree-->
</Tree>
</CateGory>大概就是这样了,我只是提供了一个思路,具体的代码太长啦。
顺便提一句,这些代码都是封装在一个TUserSession类中了。