有两个数据表 一个主表 一个子表
主表的主键是单别,单号 字表的主键是 单别,单号,序号
通过单别单号建立关联
主表的一个字段是商品的品号 生产主表的一个商品可以由几个其他的元件(品好)组成
元件品号对应的是子表的字段,但是子表的元件可能由其他一个或几个元件组成
请问如何用树状结构实现?有没有好用的空件????????????????

解决方案 »

  1.   

    这有个关于树比较全面的资料.
    你看看吧.
    看行不行.unit   dbtreeUnit; interface uses 
        Windows,   Messages,   SysUtils,   Variants,   Classes,   ComCtrls,   DB,   ADODB; {------------------------------------------------------------------------------- 
        过程名:         MakeTree 
        说明:           创建树 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TableName:   string;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;   TableName:   对应的表名;   TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   MakeTree(Query:   TADOQuery;   TableName:   string;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        过程名:         AddNode 
        说明:           增加树的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   AddNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:String); 
    procedure   AddRootNode(Query:   TADOQuery;   TreeView:   TTreeView;RootName:String); {------------------------------------------------------------------------------- 
        过程名:         AddChildNode 
        说明:           增加树的子节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} procedure   AddChildNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:string); {------------------------------------------------------------------------------- 
        过程名:         AddTreeNode 
        说明:           增加节点(内部使用的过程) 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView;   bj:   boolean   =   false 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树;bj:是否将焦点移到当前选择的节点 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   AddTreeNode(Query:   TADOQuery;   TreeView:   TTreeView;   bj:   boolean   =   false); {------------------------------------------------------------------------------- 
        过程名:         DelTree 
        说明:           删除节点(包括删除本节点下的所有子节点) 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TAdoQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   DelTree(query:   TAdoQuery;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        过程名:         Treechange 
        说明:           在树中选择了一个节点,将数据库的游标移动到所选择的节点所对应记录 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TADOQuery;   node:   TTreenode 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   Treechange(query:   TADOQuery;   node:   TTreenode); {------------------------------------------------------------------------------- 
        过程名:         Treeedit 
        说明:           树中的节点内容已经作了修改,将所修改的内容更新回数据库 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TADOQuery;   text:   string 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   Treeedit(query:   TADOQuery;   text:   string); {------------------------------------------------------------------------------- 
        过程名:         treeselect 
        说明:           数据库中的游标已经移动,将焦点移到树中对应的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   Tadoquery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   TreeSelect(query:   Tadoquery;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        函数名:         TreeFind 
        说明:           找出给定的内容,并移动数据库中的游标,同时将焦点移到树中对应的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             TreeView:   TTreeView;   text:   string 
        参数说明:   TreeView:   所使用的树   text:   要查找的内容 
        返回值:         True:找到  False:找不到 
    -------------------------------------------------------------------------------} 
      

  2.   

    这有个关于树比较全面的资料.
    你看看吧.
    看行不行.unit   dbtreeUnit; interface uses 
        Windows,   Messages,   SysUtils,   Variants,   Classes,   ComCtrls,   DB,   ADODB; {------------------------------------------------------------------------------- 
        过程名:         MakeTree 
        说明:           创建树 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TableName:   string;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;   TableName:   对应的表名;   TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   MakeTree(Query:   TADOQuery;   TableName:   string;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        过程名:         AddNode 
        说明:           增加树的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   AddNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:String); 
    procedure   AddRootNode(Query:   TADOQuery;   TreeView:   TTreeView;RootName:String); {------------------------------------------------------------------------------- 
        过程名:         AddChildNode 
        说明:           增加树的子节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} procedure   AddChildNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:string); {------------------------------------------------------------------------------- 
        过程名:         AddTreeNode 
        说明:           增加节点(内部使用的过程) 
        作者:             Along 
        日期:             2004.12.07 
        参数:             Query:   TADOQuery;   TreeView:   TTreeView;   bj:   boolean   =   false 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树;bj:是否将焦点移到当前选择的节点 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   AddTreeNode(Query:   TADOQuery;   TreeView:   TTreeView;   bj:   boolean   =   false); {------------------------------------------------------------------------------- 
        过程名:         DelTree 
        说明:           删除节点(包括删除本节点下的所有子节点) 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TAdoQuery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   DelTree(query:   TAdoQuery;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        过程名:         Treechange 
        说明:           在树中选择了一个节点,将数据库的游标移动到所选择的节点所对应记录 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TADOQuery;   node:   TTreenode 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   Treechange(query:   TADOQuery;   node:   TTreenode); {------------------------------------------------------------------------------- 
        过程名:         Treeedit 
        说明:           树中的节点内容已经作了修改,将所修改的内容更新回数据库 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   TADOQuery;   text:   string 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   Treeedit(query:   TADOQuery;   text:   string); {------------------------------------------------------------------------------- 
        过程名:         treeselect 
        说明:           数据库中的游标已经移动,将焦点移到树中对应的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             query:   Tadoquery;   TreeView:   TTreeView 
        参数说明:   Query:相关联的数据库;TreeView:   所使用的树 
        返回值:         无 
    -------------------------------------------------------------------------------} 
    procedure   TreeSelect(query:   Tadoquery;   TreeView:   TTreeView); {------------------------------------------------------------------------------- 
        函数名:         TreeFind 
        说明:           找出给定的内容,并移动数据库中的游标,同时将焦点移到树中对应的节点 
        作者:             Along 
        日期:             2004.12.07 
        参数:             TreeView:   TTreeView;   text:   string 
        参数说明:   TreeView:   所使用的树   text:   要查找的内容 
        返回值:         True:找到  False:找不到 
    -------------------------------------------------------------------------------} 
      

  3.   

    function   TreeFind(TreeView:   TTreeView;   text:   string):   boolean; implementation var 
        List:   TStringList;   //用于记录各个id及其在树中所对应的节点,从而实现快速查找 procedure   MakeTree(Query:   TADOQuery;   TableName:   string;   TreeView:   TTreeView); 
    begin 
        TreeView.Items.BeginUpdate; 
        list.Clear; 
        TreeView.items.clear; 
        if   query.Active   then   query.Close; 
        Query.SQL.Text   :=   'SELECT   *   FROM   '   +   TableName   +   '   ORDER   BY   PID,   ID'; 
        Query.Open; 
        query.DisableControls; 
        TreeView.Items.Clear; 
        list.Clear; 
        List.Sorted   :=   True; 
        query.First; 
        while   not   Query.Eof   do 
        begin 
            addtreenode(Query,   TreeView);   //依次增加所有的节点 
            Query.Next; 
        end; 
        TreeView.Items.EndUpdate; 
        query.EnableControls; 
        if   treeview.Items.Count   <   1   then   exit; 
        treeview.Select(treeview.Items.Item[0]); 
      //   treeview.SetFocus; 
    end; procedure   addtreenode(Query:   TADOQuery;   TreeView:   TTreeView;   bj:   boolean   =   false); 
    var 
        index:   integer; 
        Node:   TTreeNode; 
    begin 
        if   Query.FieldByName('PID').AsInteger   =   0   then   {   ParentID=0,顶层节点   } 
            Node   :=   TreeView.Items.AddChildObject(nil,   Query.FieldByName('nName').AsString,   query.GetBook) 
    //增加节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中 
        else 
        begin 
            Index   :=   List.IndexOf(Query.FieldByName('PID').AsString); 
            Node   :=   TreeView.Items.AddChildObjectFirst(TTreeNode(List.Objects[Index]), 
                Query.FieldByName('nName').AsString,   query.GetBook); 
    //增加子节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中 
        end; 
    //增加当前节点的信息到列表中,以实现在列表中快速查找节点的功能。 
        List.AddObject(Query.FieldByName('ID').AsString,   Node); 
        if   bj   then 
        begin 
            treeview.Select(node); 
      //       treeview.SetFocus; 
        end; 
    end;
    procedure   deltree(query:   TAdoQuery;   TreeView:   TTreeView); 
    var 
        node:   TTreenode; 
    //删除当前选择的节点下的所有节点(不删除当前选择的节点) 
        procedure   delnode(node:   TTreenode); 
        var 
            i:   integer; 
            childnode:   TTreenode; 
        begin 
            for   i   :=   0   to   node.Count   -   1   do 
            begin 
                childnode   :=   node.Item[i];   //取当前节点下的所有节点 
                query.GotoBook(childnode.Data);   //移到节点所对应的记录 
                list.Delete(list.IndexOf(query.FieldByName('ID').AsString));   //删除列表中的数据 
                query.Delete;   //删除对应的记录 
                if   node.HasChildren   then   delnode(childnode);   //有子节点则递归直到所有的数据删除完毕 
            end; 
        end; 
    {另一方法: 
    用一个递归: 
    procedure   doSearch(tn:   TTreeNode); 
    var   i:   ingeger;   
    begin 
     if   tn.HasChildren   then 
     begin 
      for   i   :=   tn.Count   -1   downto   0   do   doSearch(tn[i]);  
     end 
     else 
     begin 
       //这里是你对每个节电要做的事情 
     end; 
    end;} begin 
        node   :=   treeview.Selected; 
        if   node   =   nil   then   exit; 
    //删除当前选择的节点下的所有节点(不删除当前选择的节点) 
        delnode(node); 
    //删除当前选择的节点 
        query.GotoBook(node.Data); 
        list.Delete(list.IndexOf(query.FieldByName('ID').AsString)); 
        query.Delete; 
        node.Delete; 
        TreeView.SetFocus; 
    end; procedure   AddChildNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:string); 
    var 
        id:   integer; 
    begin 
        id   :=   query.FieldByName('ID').AsInteger;   //记下当前的节点编号 
        query.Append; 
        query.FieldByName('PID').AsInteger   :=   id;   //新增加的子节点的父节点编号即为id 
        query.FieldByName('nName').AsString   :=   nodeName; 
        query.post; 
        addtreenode(query,   treeview,   true); 
    end; procedure   AddNode(Query:   TADOQuery;   TreeView:   TTreeView;nodeName:String); 
    var 
        pid:   integer; 
    begin 
        pid   :=   query.FieldByName('pID').AsInteger;   //记下当前节点的父节点编号 
        query.Append; 
        query.FieldByName('PID').AsInteger   :=   pid;   //新增加的子节点的父节点编号即为pid 
        query.FieldByName('nName').AsString   :=   nodeName; 
        query.post; 
        addtreenode(query,   treeview,   true); 
    end; procedure   AddRootNode(Query:   TADOQuery;   TreeView:   TTreeView;RootName:String); 
    var 
        pid:   integer; 
    begin 
        pid   :=   query.FieldByName('pID').AsInteger;   //记下当前节点的父节点编号 
        query.Append; 
        query.FieldByName('PID').AsInteger   :=0;   //新增加的子节点的父节点编号即为pid 
        query.FieldByName('nName').AsString   :=   RootName; 
        query.post; 
        addtreenode(query,   treeview,   true); 
    end; 
    procedure   Treechange(query:   TADOQuery;   node:   TTreenode); 
    begin 
        query.GotoBook(node.Data); 
    end; procedure   TreeEdit(query:   TADOQuery;   text:   string); 
    begin 
        query.Edit; 
        query.FieldByName('nName').AsString   :=   text; 
        query.post; 
    end; procedure   treeselect(query:   Tadoquery;   TreeView:   TTreeView); 
    var 
        index:   integer; 
        Node:   TTreeNode; 
    begin 
        Index   :=   List.IndexOf(Query.FieldByName('ID').AsString); 
        Node   :=   TTreeNode(List.Objects[Index]); 
        treeview.Selected   :=   Node; 
        treeview.SetFocus; 
    end; function   TreeFind(TreeView:   TTreeView;   text:   string):   boolean; 
    var 
        i:   integer; 
    begin 
        Result   :=   false; 
        for   i   :=   0   to   treeview.Items.Count   -   1   do 
        begin 
            if   treeview.Items.Item[i].Text   =   text   then 
            begin 
                treeview.Select(treeview.Items.Item[i]); 
                treeview.SetFocus; 
                Result   :=   true; 
                exit; 
            end; 
        end; 
    end; initialization 
        List   :=   TStringList.Create; finalization 
        list.Free; end.