请问要怎麼接著下子節点?应该加入些什麼code?第二階必須回找BOM_NO
资料结構如下:
BOM_NO ITM PRD_NO ID_NO
A-> 1 B B->
A-> 2 C C->
A-> 3 D
B-> 1 B01 B01->
B-> 2 B02
B01-> 1 B11
C-> 1 C01
C-> 2 C02 以及我寫好的code:unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DB, ADODB, ComCtrls, StdCtrls;type  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    TV: TTreeView;
    ADOConnection1: TADOConnection;
    QYTF: TADOQuery;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function AddChildNode(node: TTreeNode; itm: integer; stype: string): TTreeNode;
  end;var
  Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
Rootnode,Newnode: TTreeNode;
begin
TV.Items.Clear;
TV.Items.BeginUpdate;
with qytf do begin
  sql.clear;
  sql.add('select * from TF_BOM T where BOM_NO like'+QuotedStr(edit1.Text+'%'));
  close;
  open;
  Rootnode:=TV.items.add(nil,qytf.fieldbyname('BOM_NO').ASString);
  TV.SetFocus();  while not eof do begin
  Newnode:=TV.Items.AddChild(rootnode,qytf.fieldbyname('PRD_NO').AsString);
  next;
  end;  end;
  TV.Items.Item[0].Expanded:=true;
  TV.Items.EndUpdate;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  adoconnection1.connected:=false;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
   try
   adoconnection1.connected:=true;
   except
   showmessage('無法連線!!');
   end;
end;end.
看了很多帖子,試了很多次還是做不出來~
菜鳥一個,麻烦各位给予指教

解决方案 »

  1.   

    先读第一级节点,将主键值保存到data中,然后在treeview的expangding事件中读取上级id为data中值的下一级,依次类推
      

  2.   

    搂主要把你的问题描述清楚,而且是繁体。
    构建树么,一般2种方法
    1、如果数据量不大, 一次性把数据拿到客户端,用Filter过滤出根记录,然后逐层构造树节点,这种方法都有成熟的方法或控件。
    2、如果数据量很大,又是只读的,那就应该先使用Where把根记录查询出来,然后再根据用户的操作取相应的子节点。
      

  3.   


    TO bdmn~
    能否提供例子給我??我剛接觸Delphi
    不太懂
    TO baseyueliang
    數據量有一萬多筆資料..只要讀
    我需要給用戶自行在edit輸入查詢值,由sql查詢到資料建立樹出來
    樹的結構需要由用戶自行輸入商品代號(為根節點)
    商品之下有母件跟子件,但母件之下也有子件
    母件下的子件code我不知道該如何寫
      

  4.   

    1:建表sqlCREATE TABLE tb(BOM_NO varchar(10),ITM int,PRD_NO varchar(10),ID_NO varchar(10))
    INSERT tb SELECT 'A',1,'B','B'
    UNION ALL SELECT 'A',2,'C','C'
    UNION ALL SELECT 'A',3,'D',''
    UNION ALL SELECT 'B',1,'B01','B01'
    UNION ALL SELECT 'B',2,'B02',''
    UNION ALL SELECT 'B01',1,'B11',''
    UNION ALL SELECT 'C',1,'C01','' 
    UNION ALL SELECT 'C',2,'C02',''/*
    select * from  tb--结果
    BOM_NO ITM    PRD_NO   ID_NO A 1 B B
    A 2 C C
    A 3 D
    B 1 B01 B01
    B 2 B02
    B01 1 B11
    C 1 C01
    C 2 C02
    */
    2:数据表的理解:
     表中PRD_NO字段是子件名称,BOM_NO是子件对应的母件,其中如果ID_NO 不为空时该子件也 是一个母件3:目的:展开这个BOM表4:DELPHI的实现代码:{
    实现要点:
    1.用两个ADOQUERY控件,ADOQUERY1操作最外层,ADOQUERY2操作深层在递归函数中使用.
    2.定义两个为(TStringList型)局部变量,以便查找节点的位置.
    3.按钮代码以下:
    }
    procedure TForm1.Button1Click(Sender: TObject);
    var
    node,nodeb:TTreeNode;
    begin
     if trim(edit1.Text)<>'' then
      with adoquery1 do begin
        close;
        sql.Text:='select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(edit1.Text));
        open;
        if not IsEmpty then begin
            TreeView1.Items.Clear;
            TreeView1.Items.BeginUpdate;
            str:=TStringList.Create;
            sl:=TStringList.Create;
            node:=TreeView1.Items.AddChild(nil,FieldByName('bom_no').AsString);
        while not eof do begin
              nodeb:=TreeView1.Items.AddChild(node,FieldByName('prd_no').AsString);
              str.AddObject(FieldByName('prd_no').AsString,nodeb);
              if not FieldByName('id_no').IsNull then begin
              Fstr(FieldByName('id_no').AsString);
              end;
          next;
        end;
        TreeView1.Items.Item[0].Expanded:=true;
        TreeView1.Items.EndUpdate;
        sl.Free;
       end;
      end;
    end;{递归函数的代码:}procedure TForm1.Fstr(s: string);
    var
    sv:string;
    i:integer;
    nodec:TTreeNode;
    begin
     with adoquery2 do begin
       close;
       sql.Text:= 'select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(s));
       open;
       if not IsEmpty then  begin
         while not eof do begin
         nodec:=TTreeNode(str.Objects[str.IndexOf(FieldByName('bom_no').AsString)]);
         TreeView1.Items.AddChild(nodec,FieldByName('prd_no').AsString);
         if not FieldByName('id_no').IsNull then
         sl.Add(FieldByName('id_no').AsString);
         next;
        end;
          if sl.Count>0 then begin
          if sl.IndexOf(s)>=0 then  sl.Delete(sl.IndexOf(s));
          for i := sl.Count - 1 downto 0 do begin
            Fstr(sv);
          end;
         end;
       end;
     end;
    end;
    5:全部代码:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, DB, ADODB, ComCtrls;type
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        Button1: TButton;
        DataSource1: TDataSource;
        ADOConnection1: TADOConnection;
        ADOQuery1: TADOQuery;
        Edit1: TEdit;
        ADOQuery2: TADOQuery;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
       str:TStringList;
       sl:TStringList;
       procedure Fstr(s:string);
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
    node,nodeb:TTreeNode;
    begin
     if trim(edit1.Text)<>'' then
      with adoquery1 do begin
        close;
        sql.Text:='select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(edit1.Text));
        open;
        if not IsEmpty then begin
            TreeView1.Items.Clear;
            TreeView1.Items.BeginUpdate;
            str:=TStringList.Create;
            sl:=TStringList.Create;
            node:=TreeView1.Items.AddChild(nil,FieldByName('bom_no').AsString);
        while not eof do begin
              nodeb:=TreeView1.Items.AddChild(node,FieldByName('prd_no').AsString);
              str.AddObject(FieldByName('prd_no').AsString,nodeb);
              if not FieldByName('id_no').IsNull then begin
              Fstr(FieldByName('id_no').AsString);
              end;
          next;
        end;
        TreeView1.Items.Item[0].Expanded:=true;
        TreeView1.Items.EndUpdate;
        sl.Free;
       end;
      end;
    end;procedure TForm1.Fstr(s: string);
    var
    sv:string;
    i:integer;
    nodec:TTreeNode;
    begin
     with adoquery2 do begin
       close;
       sql.Text:= 'select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(s));
       open;
       if not IsEmpty then  begin
         while not eof do begin
         nodec:=TTreeNode(str.Objects[str.IndexOf(FieldByName('bom_no').AsString)]);
         TreeView1.Items.AddChild(nodec,FieldByName('prd_no').AsString);
         if not FieldByName('id_no').IsNull then
         sl.Add(FieldByName('id_no').AsString);
         next;
        end;
          if sl.Count>0 then begin
          if sl.IndexOf(s)>=0 then  sl.Delete(sl.IndexOf(s));
          for i := sl.Count - 1 downto 0 do begin
            Fstr(sv);
          end;
         end;
       end;
     end;
    end;end.6:附注:本人学识有限加上文化水平只有初中,故此说明得不好请见谅!
      

  5.   

    TO GDTOPONE
    非常感謝你看的懂我所表達的~
    我先測試您所提供的Code,如遇到問題,就麻煩你多指教

      

  6.   

    to GDTOPONE
    1.因為資料有上萬筆,能以什麼方式可以簡短查詢時間??
    2.code出現錯誤訊息
    procedure TForm1.Fstr(s: string);
    var
    sv:string;
    i:integer;
    nodec:TTreeNode;
    begin
     with qy2 do begin
       close;
       sql.Text:= 'select * from tf_bom where bom_no='+QuotedStr(trim(s));
       open;
       if not IsEmpty then  begin
         while not eof do begin
         nodec:=TTreeNode(str.Objects[str.IndexOf(FieldByName('bom_no').AsString)]);
         TreeView1.Items.AddChild(nodec,FieldByName('prd_no').AsString);  
         //從上面這行就出現 List index out of bounds(-1)的錯誤訊息
         if not FieldByName('id_no').IsNull then
         sl.Add(FieldByName('id_no').AsString);
         next;
        end;
          if sl.Count>0 then begin
          if sl.IndexOf(s)>=0 then  sl.Delete(sl.IndexOf(s));
          for i := sl.Count - 1 downto 0 do begin
            Fstr(sv);
          end;
         end;
       end;
     end;
    end;
      

  7.   


    USE [MES]
    GO
    /****** Object:  UserDefinedFunction [dbo].[FIND_CID_BOM]    Script Date: 04/09/2009 14:15:22 ******/
    SET QUOTED_IDENTIFIER ON
    GO
    --查询指定节点及其所有子节点的函数 
    -- ================================================
    /*
    标题:查询指定节点及其所有子节点的函数
    作者:北方男生(天南地北天涯浪子浪跡天涯,秋去冬來秋水伊人望穿秋水)
    时间:2009-01-21
    地点:广东東莞
    */
    -- =================================================
    --BOM_TYP
    --BP_NO
    --PARN_ITM
    --PARN_LITM
    --PARN_TYP
    --PARN_DSC
    --CHLD_ITM
    --CHLD_LITM
    --CHLD_DSC
    --QYT
    --ECO_NO
    --CHLD_STK_TYP--31010555201
    --15140016000
    --15110661000
    --select top 1* from sc_xlrbb where lh='21000138201'
    --SELECT A.* FROM RES_BOM_LH A,FIND_CID_BOM('15140016000') B WHERE A.PARN_LITM=B.PARN_LITM ORDER BY A.PARN_LITM
    --SELECT * FROM Find_LH_BOM('15140016000')
    --SELECT * FROM Get_ChldLH_BOM('15140016000')
    --select * from (select parn_litm  from res_bom_lh union select chld_litm from res_bom_lh)as t where parn_litm='10320403200'ALTER FUNCTION [dbo].[FIND_CID_BOM](@ID NVARCHAR(50)) RETURNS @T_LEVEL TABLE(PARN_LITM NVARCHAR(50),LEVEL INT)
    AS
    BEGIN
      DECLARE @LEVEL INT
      SET @LEVEL=1
      INSERT INTO @T_LEVEL SELECT @ID,@LEVEL
      WHILE @@ROWCOUNT>0
      BEGIN
    SET @LEVEL=@LEVEL+1
    INSERT INTO @T_LEVEL SELECT A.PARN_LITM,@LEVEL
    FROM RES_BOM_LH A,@T_LEVEL B
    WHERE A.CHLD_LITM=B.PARN_LITM AND B.LEVEL=@LEVEL-1
      END
      RETURN
    END
      

  8.   


    USE [MES]
    GO
    /****** Object:  UserDefinedFunction [dbo].[FIND_PID_BOM]    Script Date: 04/09/2009 14:15:46 ******/
    SET QUOTED_IDENTIFIER ON
    GO
    --查询指定节点及其所有父节点的函数
    -- ================================================
    /*
    标题:查询指定节点及其所有父节点的函数
    作者:北方男生(天南地北天涯浪子浪跡天涯,秋去冬來秋水伊人望穿秋水)
    时间:2009-01-16
    地点:广东東莞
    */
    -- =================================================
    --21000131101
    --SELECT A.* FROM RES_BOM_LH A,FIND_PID_BOM('31010555201') B WHERE A.PARN_LITM=B.PARN_LITM ORDER BY A.PARN_LITM
    ALTER FUNCTION [dbo].[FIND_PID_BOM](@ID NVARCHAR(50)) RETURNS @T_LEVEL TABLE (PARN_LITM NVARCHAR(50))
    AS
    BEGIN
    INSERT INTO @T_LEVEL SELECT @ID
    SELECT @ID=CHLD_LITM FROM RES_BOM_LH WHERE PARN_LITM=@ID AND CHLD_LITM IS NOT NULL
    WHILE @@ROWCOUNT>0
    BEGIN
    INSERT INTO @T_LEVEL SELECT @ID SELECT @ID=CHLD_LITM FROM RES_BOM_LH WHERE PARN_LITM=@ID AND CHLD_LITM IS NOT NULL
    END
    RETURN
    END
      

  9.   


    TO KYE_JUFEI..
    不好意思~~我看不懂..
    我是以ADOConnection連結sql資料庫建立Treeview做查詢
      

  10.   

    抱歉!这几天太忙,没时间回复,现在再发一次全部代码,希你认真参考一下:unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, DB, ADODB;type
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        Button1: TButton;
        ADOConnection1: TADOConnection;
        ADOQuery1: TADOQuery;
        ADOQuery2: TADOQuery;
        Edit1: TEdit;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
       str:TStringList;{--------------------------------这里是要声明变量的}
       sl:TStringList;
       procedure Fstr(s:string);  end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
    node,nodeb:TTreeNode;
    begin
     if trim(edit1.Text)<>'' then
      with adoquery1 do begin
        close;
        sql.Text:='select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(edit1.Text));
        open;
        if not IsEmpty then begin
            TreeView1.Items.Clear;
            TreeView1.Items.BeginUpdate;
            str:=TStringList.Create;
            sl:=TStringList.Create;
            node:=TreeView1.Items.AddChild(nil,FieldByName('bom_no').AsString);
        while not eof do begin
              nodeb:=TreeView1.Items.AddChild(node,FieldByName('prd_no').AsString);
              str.AddObject(FieldByName('prd_no').AsString,nodeb);
              if not FieldByName('id_no').IsNull then begin
              Fstr(FieldByName('id_no').AsString);
              end;
          next;
        end;
        TreeView1.Items.Item[0].Expanded:=true;
        TreeView1.Items.EndUpdate;
        sl.Free;
        str.Free;
       end;
      end;
    end;
    procedure TForm1.Fstr(s: string);
    var
    sv:string;
    i:integer;
    nodec:TTreeNode;
    begin
     with adoquery2 do begin
       close;
       sql.Text:= 'select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(s));
       open;
       if not IsEmpty then  begin
         while not eof do begin
         nodec:=TTreeNode(str.Objects[str.IndexOf(FieldByName('bom_no').AsString)]);
         TreeView1.Items.AddChild(nodec,FieldByName('prd_no').AsString);
         if not FieldByName('id_no').IsNull then
         sl.Add(FieldByName('id_no').AsString);
         next;
        end;
          if sl.Count>0 then begin
          if sl.IndexOf(s)>=0 then  sl.Delete(sl.IndexOf(s));
          for i := sl.Count - 1 downto 0 do begin
            Fstr(sv);
          end;
         end;
       end;
     end;
    end;
    end.
    另:本代码是经过测试才发的.
      

  11.   

    GDTOPONE大大..
    我再次測試過你的代碼..依舊出現同樣的錯誤訊息
      List index out of bounds(-1)
      

  12.   


    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, DB, ADODB;type
      TForm1 = class(TForm)
        TreeView1: TTreeView;
        Button1: TButton;
        ADOConnection1: TADOConnection;
        ADOQuery1: TADOQuery;
        ADOQuery2: TADOQuery;
        Edit1: TEdit;
        ListBox1: TListBox;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
       str:TStringList;{--------------------------------ÕâÀïÊÇÒªÉùÃ÷±äÁ¿µÄ}
       sl:TStringList;
       procedure Fstr(s:string);  end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
    var
    node,nodeb:TTreeNode;
    begin
     if trim(edit1.Text)<>'' then
      with adoquery1 do begin
        close;
        sql.Text:='select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(edit1.Text));
        open;
        if not IsEmpty then begin
            TreeView1.Items.Clear;
            TreeView1.Items.BeginUpdate;
            str:=TStringList.Create;
            sl:=TStringList.Create;
            node:=TreeView1.Items.AddChild(nil,trim(edit1.Text));
         while not eof do begin
              nodeb:=TreeView1.Items.AddChild(node,FieldByName('prd_no').AsString);
              str.AddObject(FieldByName('prd_no').AsString,nodeb);
              if not FieldByName('id_no').IsNull then begin
              Fstr(FieldByName('id_no').AsString);
              end;
          next;
         end;
        TreeView1.Items.Item[0].Expanded:=true;
        TreeView1.Items.EndUpdate;
        sl.Free;
        str.Free;
       end;
      end;
    end;
    procedure TForm1.Fstr(s: string);
    var
    sv:string;
    i:integer;
    nodec,noded:TTreeNode;
    begin
     with adoquery2 do begin
       close;
       sql.Text:= 'select bom_no,prd_no,id_no from tb where bom_no='+QuotedStr(trim(s));
       open;
       if not IsEmpty then  begin
         while not eof do begin
            nodec:=TTreeNode(str.Objects[str.IndexOf(s)]);
            noded:=TreeView1.Items.AddChild(nodec,FieldByName('prd_no').AsString);
           str.AddObject(FieldByName('prd_no').AsString,noded);
           if trim(fieldByName('id_no').AsString)<>'' then begin
            if trim(FieldByName('prd_no').AsString)<>'' then  begin
             sl.Add(trim(FieldByName('prd_no').AsString));
            end;
           end;
         next;
        end;
               if sl.Count>0 then begin
                if sl.IndexOf(s)>=0 then  begin
                  sl.Delete(sl.IndexOf(s));
                end;
                  for i := sl.Count - 1 downto 0 do begin
                    sv:=sl.Strings[i];
                    Fstr(sv);
                  end;
               end;
       end;
     end;
    end;
    end.
      

  13.   

    TO GDTOPONE
    抱歉~這陣子有事情在忙碌
    我這就來試試看