现在我有一个数据库Test
表结构和数据如入:
ID Name ParentID
1 中国人 00000000
2 浙江人 1
3 湖北人 1
4 杭州人 2
5 绍兴人 2
6 武汉人 3
7 荆门人 3
8 美国人 00000000
9 纽约人 8
10 华盛顿人8
11 曼哈顿人9
现在要根据他们的ID和ParentID的关系加载到树中,呈现层次关系请问有没有好的算法,不要用到TreeView的SelectChange事件,要求一次性加载。
高手帮忙啊!
表结构和数据如入:
ID Name ParentID
1 中国人 00000000
2 浙江人 1
3 湖北人 1
4 杭州人 2
5 绍兴人 2
6 武汉人 3
7 荆门人 3
8 美国人 00000000
9 纽约人 8
10 华盛顿人8
11 曼哈顿人9
现在要根据他们的ID和ParentID的关系加载到树中,呈现层次关系请问有没有好的算法,不要用到TreeView的SelectChange事件,要求一次性加载。
高手帮忙啊!
解决方案 »
- 这个STRING会结果显示什么 ?
- 消息的传递问题,请大家帮忙!
- delphi 发送短信问题,...........
- 编译时出错!
- ADO的简单问题
- 帮帮忙看看这句sql的问题,谢谢,急啊
- 今晨我的新发现:知道QQ如何把自己加为好友吗??
- 求一个字段(a8)的和,并将其存入一个变量中,用SQL语句写,请教!
- 我下载了一个做报表的东西叫做ereport??????/
- 用delphi5的nmpop3控件编写收邮件的程序,nmpop3.MailMessage.Body.Text多了一此如"=,<A>"之类的东东
- 关于delphi数据库同步更新的速度问题!急!!!在线=
- 如何取得某个数据源下对应的数据库?在线等
2、数据库结构
例如表“国家”可以是这样:
编号 名称
----------
01 中国
0101 吉林省
010101 长春市
010102 吉林市
0102 江苏省
010201 南京市
010202 常州市
02 美国
0201 密歇根州
020101 底特律市
0202 华盛顿州
020201 温哥华市
020202 西雅图市
03 澳大利亚
3、在 TreeView 中显示结构
procedure CreateTree;
const
ID_DEPT = 2;
var
nLevel: Integer;
pNodes: array[0..1023] of TTreeNode;
lpID, lpName: string;
begin
ADODataSet1.Close;
ADODataSet1.CommandText := 'SELECT * FROM [国家] ORDER BY [编号]';
ADODataSet1.Open;
pNodes[0] := nil;
TreeView1.Items.Clear;
with ADODataSet1.Recordset do
while not Eof do
begin
lpID := Fields['编号'].Value;
lpName := Fields['名称'].Value;
nLevel := Length(lpID) div ID_DEPT;
pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], lpName);
MoveNext;
end;
end;
4、短短 20 行,一次读取数据。有人可能问为什么把 pNodes 的大小设成 1024?你也可以设成 10000,随你便,不过 TreeView 如果有那么多节点早死机了。
Classes, ComCtrls, ADODB, SysUtils;type
PPNodedata=^TNodeData;
TNodeData = record
ID:integer;//节点编号
PID:Integer;//父节点编号
Name:string;//节点名称
child:PPNodedata;//孩子节点
brather:PPNodedata;//兄弟节点
end;
PNodeData = PPNodeData;
TTreeFill1 = class(TThread)
TV: TTreeView;
RootID:Integer;
ptr:PPNodeData;
root:PPNodeData;//根节点
PointNode:PPNodeData;
s:array[0..10000] of PPNodeData;
constructor Create(Root_Id:integer;ATreeView: TTreeView);
private
procedure AddTree(Node: TTreeNode; PN: PNodeData);
protected
procedure Execute; override;
end;implementationuses
U_Main, DateUtils;var count,nodeCount:Integer;
//----------
constructor TTreeFill1.Create(Root_Id:integer;ATreeView:TTreeView);
begin
TV:= ATreeView;
TV.Items.Clear;
RootID:=Root_Id;
inherited Create(False);
end;
//----------
procedure TTreeFill1.Execute;
var Query: TADOQuery;
i,j:Integer;
Node: TTreeNode;
begin
FreeOnTerminate := True;
TV.Items.Clear;
with Query do
begin
Query := TADOQuery.Create(nil);
Connection := frm_Main.ADOC_SQL;//需要更改
Close;
SQL.Clear;
SQL.Add('Select * from 部门表 order by 部门编号 ');
Open;
first;
count:=recordcount;
if count>0 then
begin
for i:=0 to recordcount-1 do
begin
new(PointNode);
PointNode^.child:=nil;
PointNode.brather:=nil;
PointNode^.ID:=fieldbyname('部门编号').AsInteger;
PointNode^.PID:=fieldbyname('父部门编号').AsInteger;
PointNode^.Name:=fieldbyname('部门名称').AsString;
s[i]:= PointNode;
next;
end;
end;
free;
end;
//------创建树----------
for i:=0 to count-1 do
begin
for j:=0 to count-1 do
if s[i]^.PID=s[j]^.ID then
begin
if s[j]^.child=nil then
s[j]^.child:=s[i]
else
begin
ptr:= s[j]^.child;
while (ptr.brather<>nil) do
ptr:=ptr^.brather;
ptr.brather:=s[i];
end;
end;
end;
for i:=0 to count-1 do
if s[i]^.ID=RootID then
begin
root:=s[i]; //根节点
break;
end;
Node:=TV.Items.AddObject(nil,Root^.Name,Root);//创建树的根节点
nodeCount:=0;
Node.ImageIndex := 0;
Node.SelectedIndex := 2;
AddTree(Node,root);
end;procedure TTreeFill1.AddTree(Node:TTreeNode;PN:PNodeData);
var
nNode: TTreeNode;
PNode,q: PNodeData;
begin
PNode:=PN;
if PNode.child<>nil then
begin
q:=PNode.child;
while (q<>nil) do
begin
nNode:=TV.Items.AddchildObject(Node,q^.Name,q);
nodeCount:=nodeCount+1;
AddTree(nNode,q);
q:=q^.brather;
end;
end;
end;end.
ModuleCode ModuleName ModuleLevel
---------------------------------------- ---------------------------------------- -----------
11 系统维护 1
21 基础资料 1
31 采购管理 1
31-31 采购收货单 2
31-31-101 采购收货单-开单 3
31-31-102 采购收货单-修改 3
31-31-103 采购收货单-删除 3
31-41 采购付款单 2
31-41-101 采购付款单-开单 3
31-41-102 采购付款单-修改 3
31-41-103 采购付款单-删除 3
31-51 采购退货单 2
31-51-101 采购退货单-开单 3
31-51-102 采购退货单-修改 3
31-51-103 采购退货单-删除 3
32 销售管理 1
{******************************************************************************}
--模块编码
2 SQL 语句如下,注意 ORDER BY ModuleCode
SELECT ModuleCode,ModuleName,ModuleLevel FROM SB_Modules ORDER BY ModuleCode
/*
SELECT ModuleCode,ModuleName,LeafModuleSign,ParentModuleCode,ModuleLevel FROM SB_Modules ORDER BY ModuleCode
*/
{******************************************************************************}3,代码如下procedure TfrmPurviewAssign.BuildCheckTree(pDataSet:TDataSet);
var
iLevel:Integer;
sCode,sName:string;
MyNode:array[0..10]of TTreeNode;//保存各级节点,最长支持 10 级(重点)
begin
Screen.Cursor:=crHourGlass;
ckTreePurview.Items.Clear;
//FIDList.Clear;
with pDataSet do
begin
First;
//以上是增加第一项
while not Eof do
begin
sCode:=Trim(FieldByName(Purviews.FModuleCode_FieldName).AsString);
sName:=Trim(FieldByName(Purviews.FModuleName_FieldName).AsString);
iLevel:=FieldByName(Purviews.FModuleLevel_FieldName).AsInteger;
if iLevel=1 then//确保代码符合标准
begin
MyNode[iLevel]:=ckTreePurview.Items.AddChild(nil,sName);
end
else
begin
MyNode[iLevel]:=ckTreePurview.Items.AddChild(MyNode[iLevel-1],sName);
end;
//MyNode[iLevel].ImageIndex:=iLevel;
//MyNode[iLevel].SelectedIndex:=iLevel-1;
Next;
end;
First;
end;
Screen.Cursor:=crDefault;
end;
但,可以说的是,先确定数据各据的LEVEL是算法的重点!