谁能帮我解决一下动态生成树的问题?

时间:2020-11-25 11:54:28
比如:
库表结构如下:
devClaNo(设备类别编号) priClaNo(父类编号) devClaName(设备类别名称)
1010100                1010               吊车
1011100                1011               办公桌
1010                   10                 机械设备
1011                   10                 办公设备
10                     1                  设备
现要根据设备类别编号对应的父类编号生成树,父类编号为1表示是根节点,要怎么实现,在线等待?

8 个解决方案

#1


一、指标树的建立 

具体方法是:创建一个数据库,设计指标表t_pub_index,包含index_id、parent_id、index_name字段,其它字段根据实际业务而定,指标名称index_name将在树型控件的节点上显示,index_id字段保存节点的唯一标识号,parent_id表示当前节点的父节点号,标识号组成了一个“链表”,记录了树上节点的结构。设计一窗体Frm_sys_index,其上放置TreeView控件tv_zb、Query控件Query1及其它指标属性编辑显示控件。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,用来显示指标或指标目录名称。Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构,该结构与数据库指标表相应域关联,如指标ID、上级节点ID。 

Query控件的表达式为: 

select index_id, parent_id, index_name from t_pub_index 

start with index_id=0 connect by prior index_id=parent_id 

其中start with 和connect by 是Oracle的SQL语句的保留字,使一条记录的parent_id列的值等于前一记录的index_id列的值,并以parent_id等于0的记录开始。 

建树的基本思路是: 

procedure TFrm_sys_index.createtree; 

var 

curValue: indexPointer; //指向与节点相联系的数据结构的指针 

curNode : TTreeNode; //当前节点 

curid : integer; //当前节点标识号 

begin 

curNode := nil; 

curid := -1; 

Query_index.Open; 

Query_index.first; 

while not Query_index.Eof do 

begin 

new(curValue); 

With curValue^ do 

将数据库指标表t_pub_index各字段值赋curValue 所指数据结构 

while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号 

begin 

curNode := curNode.parent; 

curid:= indexPointer(curNode.data).index_id; 

end; 

curNode := tv_zb.Items.AddChildObject(curNode, 

curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构 

curid := indexPointer(curNode.data).index_id; 

Query_index.next; 

end; 

Query_index.close; 

end; 

#2


这样思路,不知道行不行。。把priClaNo(父类编号,最好是整型)从小到大排序并取唯一的值,
 select distinct priclaNo from 表 order by priclaNo
然后从父类编号等于1的所有零件全部取出来,生成父类等于1的所有子树,
然后把父类编号下移一个,再把父类编号等于它的所有值,生成它的子树。
依次循环即可。只是这样一来,速度慢了点。

#3


完整的程序是不是这样的?为什么我老是内存报错?
 type
   myRec=record
     index_id:integer;
     parent_id:integer;
     index_name:string;
 end;
 indexPointer=^myRec;

procedure TxqFrm.FormCreate(Sender: TObject);
 var
curValue: indexPointer; //指向与节点相联系的数据结构的指针
curNode : TTreeNode; //当前节点
curid : integer; //当前节点标识号
begin
   curNode := nil;
    curid := -1;
    Query_index.Open;
    Query_index.first;
     while not Query_index.Eof do
        begin
          new(curValue);
         With curValue^ do
          //将数据库指标表t_pub_index各字段值赋curValue 所指数据结构
            begin
            index_id:=Query_index.FieldValues['devclano'];
            parent_id:=Query_index.FieldValues['priclano'];
            index_name:=Query_index.FieldValues['devclaname'];
            end;
            while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号
                 begin
                 curNode := curNode.parent;
                 curid:= indexPointer(curNode.data).index_id;
                 end;
            curNode := treeview1.Items.AddChildObject(curNode,
            curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构
            curid := indexPointer(curNode.data).index_id;
            Query_index.next;
        end;
        Query_index.close;


end;

#4


DEV有像有一个这样的Tree控件。

#5


推荐DevExpress DBTree Suite 1.31
delphi自带的TreeView数据多了,实在太慢了
我是没找到什么好的算法,只能用第三方了

#6


http://community.csdn.net/Expert/topic/3394/3394866.xml?temp=.8483698

http://community.csdn.net/Expert/topic/3409/3409102.xml?temp=.2862818

#7


你用的是什么数据库啊,如果是oracle 可以用

select * from 表名 where 1=1 start with priClaNo=1 connect by prior priClaNo=devClaNo

就OK了,
START WITH ...CONNECT BY 语句可以生成树性结构。

可以从任意一个子结点开始,生成子树,可以找到该结点的父亲。。。

速度绝对比在前台用循环快而且好写

#8


我倒,兄弟你怎么乱给分啊

#1


一、指标树的建立 

具体方法是:创建一个数据库,设计指标表t_pub_index,包含index_id、parent_id、index_name字段,其它字段根据实际业务而定,指标名称index_name将在树型控件的节点上显示,index_id字段保存节点的唯一标识号,parent_id表示当前节点的父节点号,标识号组成了一个“链表”,记录了树上节点的结构。设计一窗体Frm_sys_index,其上放置TreeView控件tv_zb、Query控件Query1及其它指标属性编辑显示控件。一个树的节点又包含文本(Text)和数据(Data)。Text为String类,用来显示指标或指标目录名称。Data则为无定形指针(Untyped Pointer),可以指向一个与节点相联系的数据结构,该结构与数据库指标表相应域关联,如指标ID、上级节点ID。 

Query控件的表达式为: 

select index_id, parent_id, index_name from t_pub_index 

start with index_id=0 connect by prior index_id=parent_id 

其中start with 和connect by 是Oracle的SQL语句的保留字,使一条记录的parent_id列的值等于前一记录的index_id列的值,并以parent_id等于0的记录开始。 

建树的基本思路是: 

procedure TFrm_sys_index.createtree; 

var 

curValue: indexPointer; //指向与节点相联系的数据结构的指针 

curNode : TTreeNode; //当前节点 

curid : integer; //当前节点标识号 

begin 

curNode := nil; 

curid := -1; 

Query_index.Open; 

Query_index.first; 

while not Query_index.Eof do 

begin 

new(curValue); 

With curValue^ do 

将数据库指标表t_pub_index各字段值赋curValue 所指数据结构 

while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号 

begin 

curNode := curNode.parent; 

curid:= indexPointer(curNode.data).index_id; 

end; 

curNode := tv_zb.Items.AddChildObject(curNode, 

curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构 

curid := indexPointer(curNode.data).index_id; 

Query_index.next; 

end; 

Query_index.close; 

end; 

#2


这样思路,不知道行不行。。把priClaNo(父类编号,最好是整型)从小到大排序并取唯一的值,
 select distinct priclaNo from 表 order by priclaNo
然后从父类编号等于1的所有零件全部取出来,生成父类等于1的所有子树,
然后把父类编号下移一个,再把父类编号等于它的所有值,生成它的子树。
依次循环即可。只是这样一来,速度慢了点。

#3


完整的程序是不是这样的?为什么我老是内存报错?
 type
   myRec=record
     index_id:integer;
     parent_id:integer;
     index_name:string;
 end;
 indexPointer=^myRec;

procedure TxqFrm.FormCreate(Sender: TObject);
 var
curValue: indexPointer; //指向与节点相联系的数据结构的指针
curNode : TTreeNode; //当前节点
curid : integer; //当前节点标识号
begin
   curNode := nil;
    curid := -1;
    Query_index.Open;
    Query_index.first;
     while not Query_index.Eof do
        begin
          new(curValue);
         With curValue^ do
          //将数据库指标表t_pub_index各字段值赋curValue 所指数据结构
            begin
            index_id:=Query_index.FieldValues['devclano'];
            parent_id:=Query_index.FieldValues['priclano'];
            index_name:=Query_index.FieldValues['devclaname'];
            end;
            while(curid <> curValue.parent_id) do //当前节点的标识号不等于当前记录的父节点号
                 begin
                 curNode := curNode.parent;
                 curid:= indexPointer(curNode.data).index_id;
                 end;
            curNode := treeview1.Items.AddChildObject(curNode,
            curValue^.index_name,curValue); //在当前节点上添加子节点,显示节点指标名称,所带指针指向一个与指标数据相联系的数据结构
            curid := indexPointer(curNode.data).index_id;
            Query_index.next;
        end;
        Query_index.close;


end;

#4


DEV有像有一个这样的Tree控件。

#5


推荐DevExpress DBTree Suite 1.31
delphi自带的TreeView数据多了,实在太慢了
我是没找到什么好的算法,只能用第三方了

#6


http://community.csdn.net/Expert/topic/3394/3394866.xml?temp=.8483698

http://community.csdn.net/Expert/topic/3409/3409102.xml?temp=.2862818

#7


你用的是什么数据库啊,如果是oracle 可以用

select * from 表名 where 1=1 start with priClaNo=1 connect by prior priClaNo=devClaNo

就OK了,
START WITH ...CONNECT BY 语句可以生成树性结构。

可以从任意一个子结点开始,生成子树,可以找到该结点的父亲。。。

速度绝对比在前台用循环快而且好写

#8


我倒,兄弟你怎么乱给分啊