我有一数据表结构和数据如下:
ID         FatherID          Text
2           0                分类表
7           2                军事
8           2                文化
9           2                科技
10          7                武器
11          7                军队
12          10               手枪
13          8                历史现有我写一遍历函数如下:
procedure TMainForm.FormCreate(Sender: TObject);
var
RootNode:TTreeNode;
begin
  Application.OnHint := ShowHint;
  //初始化目录树-------------------------------------
   ADOQuery.Connection := ADOConnection;
   ADOQuery.SQL.Text :='select * from class';
   ADOQuery.Open;
   ADOQuery.First;
   RootNode := tree.Items.Add(nil,ADOQuery.FieldByName('text').AsString);
   RootNode.Data := Pointer(ADOQuery.FieldByName('id').AsInteger);   FillChild(ADOQuery,RootNode);
  //结束初始化目录树
end;procedure TMainForm.Fillchild(var Query: TADOQuery; Node: TTreeNode);
var
Id: Integer;
Tmp: TTreeNode;
i:integer;
begin
  if Node <> nil then
  begin
    Id := Integer(Node.Data);
    with Query do
    begin
      Filtered := False;
      Filter := ' fatherid = ' + inttostr(Id);
      Filtered := True;
      while  not eof do
      begin
        Tmp := Tree.Items.AddChild(Node,FieldByName('text').AsString);
        Tmp.Data := Pointer(FieldByName('Id').AsInteger);
        Fillchild(Query, Tmp);
        Next;
      end;
    end;
  end;
end;执行后只能得到如下:分类表
     -军事
           -武器
                 -手枪本意是执行后应该是这样的分类表
     -军事
          -武器
                -手枪 
     -文化
          -……
     -科技 
          -……
是我的函数写的有问题,请各位高手指教啊◎◎                        

解决方案 »

  1.   

    你在递归的时候好像query没有first吧
      

  2.   

    query记录集默认开始的就是第一条记录了
      

  3.   

    用递归的时候
    你不可以用用静态的TADOQuery
    改成动态的就可以了
      

  4.   

    不是那个TADOQuery 的问题,因为我的函数参数传递是按地址传递的。
      

  5.   

    你在递归的时候将query给Next了
    不能这样写
      

  6.   

    你在递归的函数中用的是全局的Query组件,想想在一次的递归返回后你的Query组件会是上一次的数据内容吗?应该用按值传送方式即将(var Query: TADOQuery; Node: TTreeNode)中的var关键字去掉
      

  7.   

    //下面是一个递归的例子(还没测试)
    procedure TMainForm.FormCreate(Sender: TObject);
    var
    RootNode:TTreeNode;
    begin
      Application.OnHint := ShowHint;
      //初始化目录树-------------------------------------
       tree.Items.Add(nil, '分类表');
       ADOQuery.Connection := ADOConnection;
       ADOQuery.SQL.Text :='select * from class where :FatherID';
       ADOQuery.Parameters[0].value:='0';
       ADOQuery.Open;
       ADOQuery.First;
       while not ADOQuery.Eof do
       begin
           AddRec(tree.Items.AddChild(tree.Items[0], ADOQuery.FieldByName('text').AsString), adoTemp.fieldbyname('[ID]').asstring);
           //RootNode := tree.Items.Add(nil,ADOQuery.FieldByName('text').AsString);
           //RootNode.Data := Pointer(ADOQuery.FieldByName('id').AsInteger);
           ADOQuery.Next;
       end;   //FillChild(ADOQuery,RootNode);
      //结束初始化目录树
    end;Procedure TMainForm.AddRec(Node:TTreeNode; str:string);
    var 
        aa : TADOQuery;
    begin
        aa := TAdoQuery.Create(nil);
        aa.Connection := ADOConnection;
        with aa do
        begin
            Close;
            Sql.Clear;
            Sql.Add('SELECT * FROM class WHERE FatherID=:FatherID');
            Parameters[0].value := str;
            Open;
        end;
        if aa.RecordCount > 0 then
        begin
            while not aa.eof do
            begin
                AddRec(tree.Items.AddChild(Node, aa.fieldbyname('[ID]').asstring), aa.fieldbyname('[ID]').asstring);
                aa.Next;
            end;
        end;
        aa.free;
    end;
      

  8.   

    递归里用动态建立一个adoquery,不要传递query进去。
      

  9.   

    我做的一个树型结构
    procedure TForm2.showlb;
    var
     node1, node:ttreenode;
     PNode:Pnodeinfo;
     //TreeView1: TTreeView;
     ds: TADODataSet;
     ds1: TADODataSet;
    // pBookMark:String;
    begin
     //node:=treeview1.TopItem;
    if not  ADODataSet1.Active then
       ADODataSet1.Active :=true;
       treeview1.Items.Clear ;
     ds:=Tadodataset.Create(self);
     ds.Connection :=DataModule4.ADOConnection1;
     ds1:=Tadodataset.Create(self);
     ds1.Connection :=DataModule4.ADOConnection1;
     ds.CommandText:='select 类别名,父类别编号,类别编号  from 类别表 where 父类别编号=0 order by 类别编号';
     ds.active:=true;
    // ds.first;// pnode.lbid:=trim(ds.FieldValues(2));
     while not ds.Eof do
     begin
       new(pnode);
        pnode.lbid:=trim(ds.fieldbyname('类别编号').asstring);
        pnode.lbpid:=trim(ds.fieldbyname('父类别编号').asstring);
        pnode.lbname:=trim(ds.fieldbyname('类别名').asstring);
       node:=treeview1.Items.AddObject(nil,pnode.lbname,pnode);
      ds1.CommandText:='select 类别名,父类别编号,类别编号  from 类别表 where 父类别编号='+pnode.lbid;
      ds1.active:=true;
      while not ds1.Eof do
      begin
      new(pnode);
        pnode.lbid:=trim(ds1.fieldbyname('类别编号').asstring);
        pnode.lbpid:=trim(ds1.fieldbyname('父类别编号').asstring);
        pnode.lbname:=trim(ds1.fieldbyname('类别名').asstring);
        treeview1.Items.AddChildObject(node,pnode.lbname,pnode);
        ds1.Next ;
     end;
        ds1.Close;
      ds.Next;
     end;
     ds.Close;
    end;
      

  10.   

    function TForm1.shownode(Fnode: ttreenode;
      p_id: string): boolean;
    var tempnode1:ttreenode;
    s_id:string;
     begin
    //*********动态创建查询控件
       i:=i+1;
       Tadoquery.Create(Self).Name :='adotemp' + IntToStr(i);
        with Tadoquery(FindComponent('adotemp' + IntToStr(i))) do
        begin
         Connection:=adoconn;//连接
         Parent := self;
      Close;
      SQL.Clear;
      SQL.Add('select * from data_node where prior_nodeid='+p_id);
    Open;   while(not Eof) do
           begin
          s_id:=FieldByName('node_id').asstring;//得到父节点id再次递归
           tempnode1:=tv.Items.AddChild(Fnode,trim(Fields.fieldbyname('node_name').AsString));//添加节点
           shownode(tempnode1,s_id);//递归
           Next;
        end;
           end;
    end;end;
      

  11.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, DB, ADODB, StdCtrls, ComCtrls, Grids, DBGrids;type
      TForm1 = class(TForm)
        ADOConnection1: TADOConnection;
        Button1: TButton;
        ADOQuery1: TADOQuery;
        Button2: TButton;
        PageControl1: TPageControl;
        TabSheet1: TTabSheet;
        TreeView1: TTreeView;
        TabSheet2: TTabSheet;
        DataSource1: TDataSource;
        ADOQuery1ID: TAutoIncField;
        ADOQuery1ParentID: TIntegerField;
        ADOQuery1Name: TWideStringField;
        DBGrid1: TDBGrid;
        Memo1: TMemo;
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure FormClose(Sender: TObject; var Action: TCloseAction);
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        procedure FillTreeView(TreeView: TTreeView);
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button2Click(Sender: TObject);
    begin
      Close;
    end;procedure TForm1.FillTreeView(TreeView: TTreeView);
      procedure CreateSubTree(FNodeName: string; Node: TTreeNode = nil);
      var
        mLocalName: string;
        TreeNode: TTreeNode;
        Ads_Tmp: TADODataSet;
      begin
        ADS_Tmp := TADODataSet.Create(Self);
        ADS_Tmp.Connection := ADOConnection1;
        with ADS_Tmp do
        try
          Close;
          CommandText := 'Select * from Type Where ParentID =' + FNodeName;
          Open;
          First;
          while not Eof do
          begin
            mLocalName := FieldbyName('ID').Asstring;
            TreeNode := TreeView.Items.AddChild(Node, FieldByName('Name').AsString);
            CreateSubTree(mLocalName, TreeNode); // 此处循环递归
            Next;
          end;
        finally
          ADS_Tmp.Free;
        end;
      end;
    begin
      TreeView.Items.BeginUpdate;
      TreeView.Items.Clear;
      with TreeView.Items.Add(nil, '所有目录') do
      begin
        ImageIndex := 1;
        SelectedIndex := 1;
      end;
      CreateSubTree('0', TreeView.Items[0]);
      TreeView.Items.EndUpdate;
      TreeView.Items[1].Selected := True;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      FillTreeView(TreeView1);
    end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
      ADOQuery1.Close;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      ADOQuery1.Open;
    end;end.