怎样根据数据库的内容动态部门树

dulei115 2003-09-20 10:11:43
数据库结构:
部门ID 部门名称 上级部门ID
1 总部门 -1
2 部门1 1
3 部门2 1
4 部门3 1
5 分部门1 2
6 分部门2 2
7 分部门3 2
8 子部门1 5
9 子部门1 5
。。。。。。。。。。。
我想用递规的方法生成Treeview,程序如下:
PROCEDURE newtreeview(部门ID,部门名称)
Begin
//Treeview1。。。添加部门名称;
//Treeview1。。。添加附带数据部门ID
ADOQuery1.close;
ADOQuery1.SQL.clear;
ADOQuery1.SQL.Text:=select * from 部门表 where 上级部门ID='+inttostr(部门ID)
ADOQuery1.open;
If ADOQuery1..recordcount>0 then
Begin
//Treeview1。。。准备添加子节点
ADOQuery1.First;
For i:=o to ADOQuery1.recordcount do
Begin
Newtreeview(ADOQuery1.FieldByName(‘ID’),
ADOQuery1.FieldByName(‘部门名称’))
ADOQuery1.next;
End;
End;
//Treeview如果有上层节点,则回到上层节点
End;
要求:当输入(1,总部门)时生成树为
总部门
部门1
分部门1
子部门1
子部门2
分部门2
分部门3
部门2
部门3
。。。
当输入(2,部门1)时生成树为
部门1
分部门1
子部门1
子部门2
分部门2
分部门3
(即生成自己部门和下属部门,且各名称附带数据为其ID号)
因为对Treeview不太熟悉,所以请高手帮忙改一下程序,
如果有更好的方法更好。


...全文
70 31 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhengtao1980 2004-03-22
  • 打赏
  • 举报
回复
我试了一下,如果递归调用,查询结果ADOQUERY1.RECORDCOUNT=0时怎么办,也就是说如果一个节点没有子节点了,IF以后的语句怎么能够得到执行呢,结果只能输出第一个分支啊
roczhao 2003-10-18
  • 打赏
  • 举报
回复
好好好,值得学习
webfly 2003-09-27
  • 打赏
  • 举报
回复
nil是什么意思?是不是添加到根上?
dulei115 2003-09-22
  • 打赏
  • 举报
回复
本贴正确答案:hmzgz81(哩翱)
PROCEDURE TForm1.newtreeview(Node:TTreeNode;ID,Name:String);
var
tmpNode : TTreeNode;
ADOquery1 : TADOQuery;
Begin
tmpNode := TreeView1.Items.AddChild(Node,Name);
ADOQuery1 := TADOQuery.Create(self);
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.close;
ADOQuery1.SQL.clear;
ADOQuery1.SQL.Text := 'select * from 部门表 where 上级部门ID='+ID;
ADOQuery1.open;
If ADOQuery1.recordcount > 0 then
Begin
ADOQuery1.First;
while not ADOQuery1.Eof do
Begin
Newtreeview(tmpNode,ADOQuery1.FieldByName('ID').AsString,
ADOQuery1.FieldByName('部门名称').AsString);
ADOQuery1.next;
End;
End;
End;
或者:zswangII(伴水清清)(职业清洁工)
function DataSetToTreeNode(mDataSet: TDataSet;
mFieldNameParent: string; //父节点标识字段名
mFieldNameTreeText: string; //节点文本字段名
mFieldNameTreeId: string; //节点标识字段名
mTreeView: TTreeView; mTreeNode: TTreeNode;
mParentText: string): Boolean;
var
vTreeNode: TTreeNode;
vFieldValues: Variant;
vFieldNames: string;
begin
Result := False;
if not Assigned(mDataSet) then Exit;
if not Assigned(mTreeView) then Exit;
if not mDataSet.Active then Exit;
vFieldNames := Format('%s;%s;%s',
[mFieldNameParent, mFieldNameTreeText, mFieldNameTreeId]);
mDataSet.Filtered := False;
mDataSet.Filter := Format('%s=%s', [mFieldNameParent, QuotedStr(mParentText)]);
mDataSet.Filtered := True;
if mDataSet.RecordCount = 0 then Exit;
mDataSet.First;
while not mDataSet.Eof do begin
vTreeNode := mTreeView.Items.AddChild(mTreeNode,
mDataSet.FieldByName(mFieldNameTreeText).AsString);
vFieldValues := mDataSet[vFieldNames];
DataSetToTreeNode(mDataSet, mFieldNameParent, mFieldNameTreeText,
mFieldNameTreeId, mTreeView, vTreeNode,
mDataSet.FieldByName(mFieldNameTreeId).AsString);
///////Begin 恢复位置
mDataSet.Filtered := False;
mDataSet.Filter := Format('%s=%s', [mFieldNameParent, QuotedStr(mParentText)]);
mDataSet.Filtered := True;
mDataSet.Locate(vFieldNames, vFieldValues, []);
///////End 恢复位置
mDataSet.Next;
end;
Result := True;
end;
//当前如下调用~~
begin
TreeView1.Items.Clear;
DataSetToTreeNode(Table1, '上级部门ID', '部门名称', '部门ID',
TreeView1, nil, '-1');
ADOTable1.Filter := '';
end;
dulei115 2003-09-22
  • 打赏
  • 举报
回复
谢谢! zswangII(伴水清清)(职业清洁工)
dulei115 2003-09-20
  • 打赏
  • 举报
回复
终于可以生成树了,谢谢hmzgz81(哩翱)
不过有个问题:节点从一开始就在第二层,怎样使它到第一层
还有:怎样使树展开一点(比如:展开第一层;全部展开)
hmzgz81 2003-09-20
  • 打赏
  • 举报
回复
PROCEDURE TForm1.newtreeview(Node:TTreeNode;ID,Name:String);
var
tmpNode : TTreeNode;
ADOquery1 : TADOQuery;
Begin
//Treeview1。。。添加部门名称;
//Treeview1。。。添加附带数据部门ID
tmpNode := TreeView1.Items.AddChild(Node,Name);
ADOQuery1 := TADOQuery.Create(self);
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.close;
ADOQuery1.SQL.clear;
ADOQuery1.SQL.Text := 'select * from 部门表 where 上级部门ID='+ID;
ADOQuery1.open;
If ADOQuery1.recordcount > 0 then
Begin
//Treeview1。。。准备添加子节点
ADOQuery1.First;
while not ADOQuery1.Eof do
Begin
Newtreeview(tmpNode,ADOQuery1.FieldByName('ID').AsString,
ADOQuery1.FieldByName('部门名称').AsString);
ADOQuery1.next;
End;
End;
End;
dulei115 2003-09-20
  • 打赏
  • 举报
回复
PROCEDURE TForm1.newtreeview(Node:TTreeNode;ID,Name:String);
var
tmpNode : TTreeNode;
ADOquery1 : TADOQuery;
Begin
//Treeview1。。。添加部门名称;
//Treeview1。。。添加附带数据部门ID
tmpNode := TreeView1.Items.Add(Node,Name);
ADOQuery1 := TADOQuery.Create(self);
ADOQuery1.Connection := ADOConnection1;
ADOQuery1.close;
ADOQuery1.SQL.clear;
ADOQuery1.SQL.Text := 'select * from 部门表 where 上级部门ID='+ID;
ADOQuery1.open;
If ADOQuery1.recordcount > 0 then
Begin
//Treeview1。。。准备添加子节点
tmpNode := tmpNode.getFirstChild;
//////////////////////////////////////////
现在的程序能生成树了,可是都在第一层,哪位懂Treeview控件的帮我改一下,我想应该是上面的一句的问题。谢谢了。
/////////////////////////////////////////
ADOQuery1.First;
while not ADOQuery1.Eof do
Begin
Newtreeview(tmpNode,ADOQuery1.FieldByName('ID').AsString,
ADOQuery1.FieldByName('部门名称').AsString);
ADOQuery1.next;
End;
End;
if tmpNode <> Treeview1.TopItem then
tmpNode := tmpNode.Parent;
//Treeview如果有上层节点,则回到上层节点
End;
zhboy 2003-09-20
  • 打赏
  • 举报
回复
兄弟,最好的方法是用递归,但是AdoQuery不能这样用,这样不会出正确结果
dulei115 2003-09-20
  • 打赏
  • 举报
回复
还是没出来,请高手指点。
uusong 2003-09-20
  • 打赏
  • 举报
回复
最好还是用递归了!
tiexinliu 2003-09-20
  • 打赏
  • 举报
回复
使用递归.每次创建当前部门的所有下级部门,包括下级的下级
procedure Tcustomer_treefrm.CreateSubTree_all(FNodeName: string; Node: TTreeNode = nil);
var
mLocalName: string;
TreeNode: TTreeNode;
Ads_Tmp: Tclientdataset;
p:pstr;
begin
ADS_Tmp := Tclientdataset.Create(Self);
ADS_Tmp.RemoteServer:=mainfrm.SocketConnection1;
ADS_Tmp.ProviderName:='datasetprovider3';
with ADS_Tmp do
begin
Close;
CommandText :='QUERY_customer_By_Parent_No_sec '+''''+FNodeName+''''+','+''''+userid+'''';;
Open;
First;
while not Eof do
begin
mLocalName := FieldbyName('ID').Asstring;
new(p);
p^:=mlocalName;
TreeNode :=self.tv_zb.Items.AddChildObject(Node, FieldByName('Name').AsString,p);
CreateSubTree_all(mLocalName, TreeNode);
Next;
end;
end;
Ads_Tmp.Free;
end;
PrgmLover 2003-09-20
  • 打赏
  • 举报
回复
PROCEDURE TForm1.newtreeview(Node:TTreeNode;ID,Name:String);
var
tmpNode: TTreeNode;
P: Pointer;
Begin
//Treeview1。。。添加部门名称;
//Treeview1。。。添加附带数据部门ID
tmpNode:=TreeView1.Items.Add(Node,Name);
ADOQuery1.close;
ADOQuery1.SQL.clear;
ADOQuery1.SQL.Text:=select * from 部门表 where 上级部门ID='+inttostr(部门ID)
ADOQuery1.open;
If ADOQuery1..recordcount>0 then
Begin
//Treeview1。。。准备添加子节点
ADOQuery1.First;
For i:=o to ADOQuery1.recordcount do
Begin
Newtreeview(tmpNode,ADOQuery1.FieldByName(‘ID’),
ADOQuery1.FieldByName(‘部门名称’))
ADOQuery1.next;
End;
End;
//Treeview如果有上层节点,则回到上层节点
End;

上边是按照搂主的思路添加的,建议使用TfctreeView. 建树的速度要快一些,并且存放附加字符串比较简便
雨后阳光2000 2003-09-20
  • 打赏
  • 举报
回复
仅供参考
雨后阳光2000 2003-09-20
  • 打赏
  • 举报
回复
procedure TFrameTree.LoadTree(treeDB:TDBDataSet);//初始化树
//initial tree when main form create
var
curID,nodeTxt:string;
level,chindex,cnode,num:integer;
mynode:array[0..6] of TTreenode;
begin
//初始化变量
Screen.Cursor:=crHourGlass;
tree.Enabled:=True;
tree.Items.Clear;
level:=0 ;
num:=1;
tree.items.clear;
//设置根节点
mynode[level]:=tree.items.add(Tree.Topitem,cTreeRootTxt);
mynode[level].ImageIndex:=1;
//遍历数据表,利用编码字段记录排序规律,依次添加树节点
with treeDB do
begin
try
if not Active then
open;
first;
while not Eof do
begin
curID:=trim(FieldByName('dwbm').AsString);
nodeTxt:=curID+'-'+trim(FieldByName('dwqc').AsString);
level:=GetNodeLevel(cTreeCodeFormat,curID);
//这里返回代码的层次数
if level>0 then
begin
//增加下一节点时,用添加子节点的方法可轻松实现节点间的层次关系。
//注意:这里的父节点是用当前节点的上一级节点mycode[level-1]
mynode[level]:=tree.items.addchild(mynode[level-1],nodeTxt);
if level>4 then
mynode[level].ImageIndex:=3
else
mynode[level].ImageIndex:=1;
// mynode[level].tag:=curID;
end;
next;
end;
finally;
close;
End;
mynode[0].expand(False);
Screen.Cursor:=crDefault;
end;
end;

function TFrameTree.GetNodeLevel(sFormat,sCode:string):integer;
var
i,level,iLen:integer;
begin
level:=-1 ;
iLen:=0;
if (sFormat<>'') and (sCode<>'') then
for i:=1 to Length(sFormat) do
begin
iLen:=iLen+StrToInt(sFormat[i]);
if Length(sCode)=iLen then
begin
level:=i;
break;
end;
end;
result:=level;
end;
dulei115 2003-09-20
  • 打赏
  • 举报
回复
自己改正一下:For i:=o to ADOQuery1.recordcount do
改为:For i:=1 to ADOQuery1.recordcount do
说明一下:本人知道可以用while not ADOQuery1.EOF do
所以请各位把重点放在Treeview的生成上面,不要太在意我写的语法。谢谢了。
zswangII 2003-09-20
  • 打赏
  • 举报
回复
begin
TreeView1.Items.Clear;
DataSetToTreeNode(ADOTable1, '上级部门ID', '部门名称', '部门ID',
TreeView1, nil, '-1');
ADOTable1.Filter := ''; //加上~~
end;
dulei115 2003-09-20
  • 打赏
  • 举报
回复
问题基本解决,随时准备结贴。
dulei115 2003-09-20
  • 打赏
  • 举报
回复
to zswangII(伴水清清)(职业清洁工)
好像把数据集都改了,ADOTable1对应的DBGrid1就显示一条记录了:1 总部门 -1
怎么回事?
dulei115 2003-09-20
  • 打赏
  • 举报
回复
to zswangII(伴水清清)(职业清洁工)
还没,一定会测的,如果有问题,我发个消息给你。
加载更多回复(11)
《Delphi 深度编程及其项目应用开发》 作 者: 李存斌 汪兵 编著 丛书名: 万水软件项目应用与实例开发丛书 出版社: 中国水利水电出版社 出 版: 2002-9----------简 介 本书是在总结作者多年Delphi开发经验的基础上编著而成。 全书分为基础篇和应用篇。基础篇结合示例论述了Delphi的深度编程技术,其中包括9章,分别为:理解Windows消息、进程与线程、自定义组件的编写、文件操作、创建DLL应用程序、两层数据库应用程序、多层数据库应用程序、Socket编程、串口编程;应用篇结合物资管理信息系统项目应用开发技术和经验,详细阐述了一般管理信息系统软件通用模块的开发,其中包括10章,分别为:物资管理信息系统概述及其总体框架设计、物资管理信息系统后台数据库设计、应用服务器的实现、客户端应用程序的设计、动态连接应用服务器的实现、通用权限管理模块的设计、通用查询组件和报表模块的制作、通用基础数据维护模块的设计、物资管理信息系统业务操作模块的设计、综合查询模块的设计。读者在具有一定Delphi知识的基础上,通过本书的学习,可快速提高Delphi的编程能力和实际开发水平。 本书适用于具有初步编程能力的读者,也可作为高校高年级学生毕业设计的指导书。中国水利水电出版社网站(www.waterpub.com.cn)上包括了书中示例和较为完整的物资管理信息系统的源代码文件,为读者的学习提供方便,同时也为相关软件开发人员的实际应用开发提供捷径和参考。 ----------目 录 丛书前言 前言 基础篇:Delphi深度编程技术 第1章 理解Windows消息 1.1 消息概述 1.2 Windows消息工作机理 1.3 Delphi的VCL消息系统处理原理 1.4 发送消息 1.4.1 Perform() 1.4.2 SendMessage()和PostNessage() 1.4.3 消息的发送 1.5 消息处理 1.6 消息过滤 第2章 进程与线程 2.1 进程与线程 2.1.1 进程概述 2.1.2 进程的直接创建 2.1.3 列举系统打开的进程 2.1.4 线程概述 2.2 进程间通讯(IPC) 2.2.1 利用WM_COPYDATA消息实现进程间通讯 2.2.2 利用内存映射文件实现进程间通讯 2.3 TThread对象 2.3.1 线程的创建 2.3.2 线程的挂起和恢复 2.3.3 线程的终止 2.3.4 与VCL同步 2.4 线程同步 2.4.1 临界区(CriticalSection) 2.4.2 互斥(Mutex) 2.4.3 信号量(Semaphore) 2.5 进程的优先级别 2.5.1 进程的优先级类 2.5.2 相对优先级 2.6 后台多线程数据查询实例 第3章 自定义组件的编写 3.1 组件的基本概念 3.1.1 属性 3.1.2 方法 3.1.3 事件 3.1.4 拥有关系 3.1.5 父子关系 3.2 组件创建实例 3.3 组件的高级技术--属性编辑器和组件编辑器 3.3.1 组件的属性编辑器 3.3.2 组件的组件编辑器 3.3.3 带有属性编辑器和组件编辑器的自定义组件实例 3.4 创建对话框组件 第4章 文件操作 4.1 文件的基本操作 4.1.1 文本文件 4.1.2 有类型文件 4.1.3 INI文件 4.1.4 无类型文件 4.1.5 文件的复制 4.2 内存映射文件 4.2.1 内存映射文件的应甩 4.2.2 映射文件的使用 4.3 内存映射文件的应用 第5章 创建DLL应用程序 5.1 DLL概述 5.2 DLL的创建 5.2.1 DLL项目文件 5.2.2 Exports关键字的使用 5.2.3 DLL中的变量 5.2.4 DLL实例:动态DLL中的窗体 5.3 DLL的调用 5.3.1 静态调用 5.3.2 动态调用 5.4 DLL的入口函数和出口函数 5.4.1 进程/线程的初始化和例程的终止 5.4.2 DLL入口/出口示例 5.5 利用DLL创建插件程序 5.5.1 插件程序的设计思想 5.5.2 插件应用程序的创建 5.5.3 创建调用插件程序的主程序 第6章 两层数据库应用程序 6.1 关系型数据库 6.1.1 关系型数据库概述 6.1.2 结构化查询语言(SQL) 6.2 数据库的连接 6.2.1 基于BDE的数据库连接 6.2.2 基于0DBC的数据库连接 6.2.3 基于AD0的数据库连接技术 6.3 TSession元件 6.4 1 DahBase组件 6.4.1 TDataBase组件的使用 6.4.2 用配置文件动态设置BDE 6.5 数据访问组件 6.5.1 TTable组件 6.5.2 TQuery组件 6.5.3 TStoredProc过程 6.6 数据感知组件 6.7 事务 第7章 多层数据库应用程序 7.1 一个简单的多层应用系统 7.1.1 服务器端应用程序的建立 7.1.2 客户端应用程序的建立 7.2 多层应用系统处理数据的原理 7.2.1 多层应用系统的结构 7.2.2 存取数据的运作原理 7.2.3 更新数据的运作原理 7.3 容错处理和负载平衡 7.4 Active Form 第8章 Socket编程 8.1 WinSock基础 8.1.1 TCP、UDP和IP协议 8.1.2 套接字(Socket) 8.1.3 客户/服务器模式 8.1.4 面向连接的协议套接字的调用 8.1.5 面向无连接协议的套接字的调用 8.2 利用Winsock API实现Socket编程 8.2.1 常用WinSockAPI函数 8.2.2 利用WinSockAPI实现Socket编程 8.3 利用组件实现Socket编程 8.3.1 TClientSocket组件 8.3.2 TServerSocket组件 8.3.3 远程抓屏示例 8.4 通讯中间件的制作 8.4.1 磁盘队列的实现 8.4.2 客户端和服务器端发送接收磁盘队列数据的套接字的建立 8.4.3 中间件的简单应用 第9章 串口编程 9.1 串口通信的基础知识 9.1.1 同步通信和异步通信 9.1.2 波特率和数据传输率 9.2 串口通信API 9.2.1 DCB数据结构 9.2.2 与串口通信相关的函数 9.3 利用API函数创建串口通信示例 9.3.1 发送数据部分设计(向串口写数据) 9.3.2 数据部分设计(从串口读数据) 9.3.3 程序的具体设计和实现 9.4 利用SPC0MM组件实现串口通信编程 9.4.1 SPCOMM组件的安装 9.4.2 SPCOMM组件的属性、方法和事件 9.4.3 利用SPCOMM通讯组件实现串口通讯的实例 应用篇:物资管理信息系统项目应用开发 第10章 物资管理信息系统概述及其总体框架设计 10.1 系统总体结构设计 10.2 物资管理信息系统需求定义和业务流程图 10.2.1 仓储管理 10.2.2 计划管理 10.2.3 合同管理 10.2.4 物资管理系统的业务流程 第11章 物资管理信息系统后台数据库设计 11.1 关系型数据库概述 11.1.1 关系型数据库 11.1.2 物资管理信息系统数据库的建立 11.2 物资管理信息系统数据结构的设计 11.2.1 权限管理数据结构的设计 11.2.2 仓储管理数据结构的设计 11.2.3 计划管理数据结构的设计 11.2.4 合同管理数据结构的设计 11.2.5 基础设置数据结构的设计 第12章 应用服务器的实现 12.1 创建应用服务器的实例 12.2 状态区编程 12.3 动态数据库的连接 12.4 远程数据模块的建立 第13章 客户端应用程序的设计 13.1 客户端应用程序系统流程和系统功能 13.1.1 系统流程 13.1.2 系统功能 13.2 构建客户端应用程序框架 第14章 动态连接应用服务器的实现 第15章 通用权限管理模块的设计 15.1 系统登录的设计 15.2 权限设计表中数据的维护 第16章 通用查询和报表组件的制作 16.1 通用查询组件的创建 16.2 通用报表模块的制作 第17章 通用基础数据维护模块的设计 17.1 界面设计 17.2 代码实现 17.2.1 以目录的格式显示部门档案数据 17.2.2 利用目录导航数据 17.2.3 利用目录操作数据 17.2.4 按表格的标题排序 17.2.5 打印部门档案 第18章 物资管理信息系统业务操作模块的设计 18.1 数据表的设置 18.2 收料单据主表显示区 18.3 具体的材料明细表显示区 18.4 数据操作区 第19章 综台查询模块的设计 19.1 数据源的设置 19.2 窗体样式设计 19.3 代码实现 19.3.1 查询数据 19.3.2 打印数据 19.3.3 全部浏览----------

5,928

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧