程序如下:结果是递归时一遍以后返回上一个循环时结果集QryTmptype没有结果了,造成只有一个循环到底的树,请大家分析一下
  PNodeInfo=^TNodeInfo;    //指针类型,存储对应节点信息
    TNodeInfo=Packed Record
       NodeId:String;        //节点
       NodeName:string;      //节点名称
       ParentId:string;      //父节点
    end;procedure TForm1.CreateTree(Id: integer; ParentNode: TTreeNode ;DTree:TTreeView);
var
    MyNode:TTreeNode;
    TmpNodeInfo:PNodeInfo;
begin
    //QryTmp前面已定义
    QryTmp.SQL.Clear;
    QryTmp.SQL.Add('Select id,code,name From directory');
    qrytmp.sql.add(' where code='+IntToStr(Id)+' Order by Id');
    QryTmp.Open;
    MyNode:=nil;
    while not QryTmp.Eof do
    begin
      New(TmpNodeInfo);
      TmpNodeInfo.Nodeid:=Trim(QryTmp.Fields[0].AsString);
      TmpNodeInfo.Parentid:=Trim(QryTmp.Fields[1].AsString);
      TmpNodeInfo.Nodename:=Trim(QryTmp.Fields[2].AsString);
      MyNode:=DTree.Items.AddChildObject(ParentNode,QryTmp.Fields[2].AsString,TmpNodeInfo);  //把所有节点当作子节点遍历
      CreateTree(QryTmp.Fields[0].AsInteger,MyNode,dtree); //递归调用
      QryTmp.Next;
    end;  
end;

解决方案 »

  1.   

    程序如下:结果是递归时一遍以后返回上一个循环时结果集QryTmp没有结果了,造成只有一个循环到底的树,请大家分析一下(上面有误)
      

  2.   

    SORRY我是初学者!
    不过帮你UP
      

  3.   

    你上面的程序在进行调用程序本身的时候,qrytmp的结果就发生了改变。
    如果想用递归的话,你要再procedure TForm1.CreateTree(Id: integer; ParentNode: TTreeNode ;DTree:TTreeView);加一个实参,类型是tcustomadodatase,然后在递归过程中调用不同的query控件进行查询。
    下面是一个不是用递归做出来的建树的例子:
    procedure Tcpya_app.FormCreate(Sender: TObject);
    begin
      datamodule2.tree.close;
      datamodule2.tree.sql.clear;
      datamodule2.tree.sql.add('select name from plat order by name');
      datamodule2.tree.Active:=true;
      datamodule2.tree.Open;
      while not datamodule2.tree.Eof do
        begin
         with tv.Items do
      begin
         MyTreeNode1 := Add(nil,trim(datamodule2.tree.fields[0].asstring));
          with datamodule2 do
          begin
           child.close;
           child.SQL.Clear;
           child.SQL.Add('select comp from dalei where plat='''+Trim(datamodule2.tree.Fields[0].asstring)+''''+' order by comp');
           child.Active:=true;
           child.Open;
           While Not child.Eof do
           begin
                TV.Items.AddChild(mytreenode1,trim(child.Fields[0].AsString));
                child.Next;
                end; end;
           datamodule2.tree.Next;
       end;
       end;
    end;
      

  4.   

    procedure Tf_dselect.FormShow(Sender: TObject);
    var
      ss: String;
      i: Integer;
    begin
      try
        Cq(aq1);
        Cq(aq2);
        aq1.Connection:= d_dbs.Ac;
        aq2.Connection:= d_dbs.Ac;
        aq1.SQL.Add('select * from dept');
        aq2.SQL.Add('select * from dept');
        aq1.Open;
        aq2.Open;
        while not aq1.Eof do begin
          ss:= aq1.FieldByName('d_upid').AsString;
          if (ss <> 'D00000') and (aq1.Lookup('d_id', ss, 'd_id') = NULL) then aq1.Delete else aq1.Next;
        end;
        aq1.Connection:= nil;
        aq2.Connection:= nil;
        ss:= 'D00000';
        tv.Items.Clear;
        with aq1 do begin
          if RecordCount < 1 then Exit;
          First;
          while not Eof do begin
            if FieldByName('d_upid').AsString = ss then begin
              tv.Items.AddChild(tv.Selected, FieldByName('d_name').AsString);
              Delete;
            end
            else Next;
          end;
          while RecordCount > 0 do begin
            for i:= 0 to tv.Items.Count - 1 do begin
              tv.Items[i].Selected:= True;
              ss:= aq2.Lookup('d_name', tv.Selected.Text, 'd_id');
              if ss = NULL then break;
              First;
              while not Eof do begin
                if FieldByName('d_upid').AsString = ss then begin
                  tv.Items.AddChild(tv.Selected, FieldByName('d_name').AsString);
                  Delete;
                end
                else Next;
              end;
            end;
          end;
        end;
        for i:= tv.Items.Count -1 downto 0 do tv.Items[i].Selected:= True;
      except
        on E: Exception do sLogAdd('E', self.Name + '.FormShow', E.Message);
      end;
      Cq(aq1);
      Cq(aq2);
    end;
    aq1,aq2为tadoquery控件
      

  5.   

    不是太清楚不过你每次都Clear那么递归返回后的Next应该会无用了把……
      

  6.   

    加一个实参,类型是tcustomadodataset,它可以是table、也可以是query
      

  7.   

    因为树每一层需要有一个独立的query,你的QryTmp因是即使动态create 一个新的而不是像你的只得一个。
      

  8.   

    看看我写的,没有问题,也是递归.
    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;
      

  9.   

    http://www.csdn.net/Develop/Read_Article.asp?Id=13651
    看这个很好用
      

  10.   

    看来我不出手没人能发现这个问题了!!!!!!!!!!!!!!在代码的最后一个end之前加上QryTmp.Free;
    OK
      

  11.   

    看来我不出手没人能发现这个问题了!!!!!!!!!!!!!!在代码的最后一个end之前加上QryTmp.Free;
    OK
      

  12.   

    问题结束,各位想做的朋友要记住:应该动态生成query 否则递归时上次的查询将被关闭。