关于把数据库中的数据转换到Treeview中 ( 积分: 50 )

  • 主题发起人 主题发起人 wzquan
  • 开始时间 开始时间
W

wzquan

Unregistered / Unconfirmed
GUEST, unregistred user!
我从数据库中取出一些数据,只有3列,格式如下:
字段1 字段2 字段3
zyq001 2 2
zyq001 2 45
zyq001 2 24
zyq001 5 12
zyq001 5 14
zyq002 16 90
zyq002 16 91
zyq002 17 98
如何把上面的数据填写到treeview中(重复的值只显示一次如下面所示)
zyq001
2
2
45
24
5 12
5 14
.......
我自己用多位数组通过查重,把数据写到数组中,再通过数组写道Treeview中,感觉比较麻烦,各位有没有什么好的方法?请不惜赐教
 
呵呵,给你贴段代码,速度是较高的啦

procedure TfrmTestSpeedMain.LoadTreeOf_7;
var
List :TStringList;
iIndex, iParentID, iID, iFail :integer;
sCaption :string;
Node : TTreeNode;
begin
// 循环一次加到树上,加子时查树,使用内存列表 非常快
// 数据集必须是排序的,否则子节点加不完整
{
算法出处说明: 根据数据表的内容生成TreeView树状结构,通常的做法就是从顶级开始,
然后逐项递归查询遍历生成。这种方法在实现上容易做到,也很容易想到,但是效率比
较低,因为数据库的检索(SQL语句需要解释执行,而且是对数据库文件进行操作)还是比
较耗时的,尤其是树的层次较多,节点较多的情况。这里我要介绍的方法是以空间换取
时间,只进行一次数据库检索,提取出全部数据,然后一次生成TreeView树状结构。
通过SQL语句,让返回的记录按照父节点ID、节点ID进行排序,这样保证每次当前要添加
的节点记录的父节点都已经添加到了TreeView树中,剩下的工作就是如何在TreeView树中
找到父节点。这里我采用了一个排序的TStringList列表,通过排序列表采用二分查找的
快速性能,就能够很快地查找到当前要添加节点的父节点,从而插入到TreeView树的正确
位置。
}

List := TStringList.Create;
try
List.Sorted := True; // 内存数据 排序加快查询

AdoQuery.Sql.Text := 'select top ' + IntToStr(fLoadCount) +
' FID,FParentID,FCaption from '+ TreeTable;
if chkOrderBy.Checked then
AdoQuery.Sql.Text := AdoQuery.Sql.Text + ' order by FParentID,FCaption';
AdoQuery.Active := True;
iFail := 0;
while not AdoQuery.Eof do
begin

iParentID := AdoQuery.FieldByName('FParentID').AsInteger;
iID := AdoQuery.FieldByName('FID').AsInteger;
sCaption := AdoQuery.FieldByName('FCaption').AsString;
if iParentID = 0 then // 根节点
begin
Node := tv.Items.AddObject(nil,sCaption ,Pointer(0));
Node.StateIndex := iID;
List.AddObject(IntToStr(iID),Node);
end
else // 子节点
begin
iIndex := List.IndexOf(IntToStr(iParentID)); // 查询当前记录的父是否加到节点上了
//ToDo: 排序了,应父节点都加上去了吧?
if iIndex <> -1 then
begin
Node := tv.Items.AddChildObject(TTreeNode(List.Objects[iIndex]),
sCaption ,Pointer(iID));
Node.StateIndex := iID;
List.AddObject(IntToStr(iID),Node);
end
else
Inc(iFail);
end;
if Self.Tag <> 1 then break;
lblLog.Caption := '正在加载... ' + IntToStr((tv.Items.Count+1)*100 div fLoadCount) + ' %';
Application.ProcessMessages;

AdoQuery.Next;
end;

if iFail >0 then
mLog.Lines.Add(' LoadTreeOf_7 存在不能连接的父子节点 数量:' +
IntToStr(iFail));
finally
List.Free;
end;
end;
要在合适位置加上BeginUpdate及endupdate
 
给分了
我回家和我的算法比较一下吧。
我也是采用一次读出数据的方法。
adoquery1.sql.append('select distinct zyqdm,zxz,zrz from ydtable where (ny>=''200601'' and ny<=''200612'') and zyqdm In (select zyqdm from zyqdmtable)');
把数据读出来,通过循环,把父节点、子节点、子子节点分别放到三个数组中,其中父节点为动态一维数组,子节点为动态二维数组,子子节点为三维动态数组。
在子节点数组中,arrayson(I,J) I-代表的是父节点的ID,J-代表本级节点ID
在子子节点中,ArrayLittleSon(I,J,K) I-代表父节点ID,J-代表子节点ID,K-代表本级节点ID
然后通过循环,把数据写到Treeview中。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
749
SUNSTONE的Delphi笔记
S
S
回复
0
查看
756
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
后退
顶部