如题:我想通过Treeview读取数据表table1的数据显示出来.注意:(不使用递归方法,并且不限定深度)大至表结构及信息如下:
表 table1
id(节点编码) name(节点名称) parentid(父节点编码)
01            公司01                      0
02            公司02                      0
0101          公司01财务部01              01
0102          公司01财务部02              01
0201          公司02财务部01              02
0202          公司02财务部02              02
010101        公司01财务部01小张01        0101 
010201        公司01财务部02小张01        0102 

解决方案 »

  1.   

    关键看你的数据库,如果是SQL Server2005或Oracle,可以用分析函数搞定
      

  2.   

    我用的是sql server2000,如合作啊?
      

  3.   

    我想你不想用“递归方法”是因为“不限定深度”是吧,数据量大会运行好长时间。
    如果是考虑到这个原因,那好办。
    资源管理器就不说了,他的树结构算是不限定深度了吧,但是它打开的速度很快,你展开一个未打开过的文件夹时,鼠标成了busy状态了。方法不过就是在打开的时候才建立子节点。
    我在程序中就是如此设计:每个节个加个状态值,展开子节点时,在Expanding事件里判断需不需要建子节点。为了显示有没有+号表示子节点有子子节点,有的话就加上一个就行,等要展开时再重新读取。
    procedure TreeViewExpanding(Sender: TObject; Node: TTreeNode; var AllowExpansion: Boolean);
    begin
      if (Node = nil) then
        Exit;
      if (not PMainTreeData(Node.Data).ExpendedFlag) then
         //建子节点
    end;
      

  4.   

    to haoqingqlm(木头:
    1、“打开时建立子节点“是不是在节点展开事件中再对数据库进行操作,然后取出当前节点下相关的字节点的信息并建之,你说的是这个意思吧(不是一次建好,而是通过点击操作分批建立)
    2、如果通过(1)操作来进行,展开所有的节点后,数据保存载哪里?是在内存里嘛?如果不是再内存里,那每次展开收缩是不是仍然要对树进行操作(访问数据库)
    说的可能不清楚,望见凉
      

  5.   

    to haoqingqlm(木头:
     不好意思,还想问个小问题
    PMainTreeData(Node.Data).ExpendedFlag与PMainTreeData(Node.Data)^.ExpendedFlag
    有什么区别啊?老是看到有人用(只知道与指针有关),就是不晓的其中的奥妙啊!
      

  6.   

    我用过的一个函数,根据编码规则来生成Treeview,如果你要根据父子节点来生成,那网上示例很多。
    procedure TForm1.CreateTreeView(Nodes: TTreeNodes; DataSet: TCustomADODataSet;
      const NodeCode, NodeName: string);
    var
      ALevel, AOldLevel, i: Integer;
      ANewStr: string;
      AParentNode: TTreeNode;
      function GetBufStart(ANodeCodeStr: string; var ALevel: Integer): string;
      begin
        ALevel := Length(ANodeCodeStr) div 3;
        Result := DataSet.FieldByName(NodeName).AsString;
      end;
    begin
      AOldLevel := 0;
      AParentNode := nil;
      Nodes.BeginUpdate;
      with DataSet do
      begin
        while not Eof do
        begin
          ANewStr := GetBufStart(FieldByName(NodeCode).AsString, ALevel);
          if (ALevel > AOldLevel) or (AParentNode = nil) then
          begin
            if ALevel - AOldLevel > 1 then
              raise Exception.Create('Invalid TreeNode Level');
          end
          else
          begin
            for i := AOldLevel downto ALevel do
            begin
              AParentNode := AParentNode.Parent;
              if (AParentNode = nil) and (i - ALevel > 0) then
                 raise Exception.Create('Invalid TreeNode Level');
            end;
          end;
          AParentNode := Nodes.AddChildObject(AParentNode, ANewStr, GetBookMark);
          AOldLevel := ALevel;
          Next;
        end;
      end;
      Nodes.EndUpdate;
    end;
      

  7.   

    用这个试试。
    TQxNodeData=class(Tobject)
      public
        QxID:integer;
        QXName:string;
      end;
    procedure TForm1.FormCreate(Sender: TObject);
    var
      LastNode:TTreeNode;
      nodeLst: TTreeNodes;
      lastActID,CurRowParentID:integer;
      tmpQX:TQxNodeData;
    begin
      nodeLst:=TreeView1.Items;
      AdoQuer_Pub.SQL.Clear;
      AdoQuer_Pub.SQL.Add('SELECT ActionID,ActionName,ActionQXBh,ParentNodeID,PowerGroup,Description,OrderNo,VState FROM bsMenuAction  order by ParentNodeID');
      AdoQuer_Pub.Open;
      LastNode:=nil;
      lastActID:=0;
      while Not AdoQuer_Pub.Eof do
      begin
        tmpQX:=TQxNodeData.Create;
        tmpQX.QxID:=AdoQuer_Pub.FieldByName('ActionID').AsInteger;
        tmpQX.QXName:=AdoQuer_Pub.FieldByName('ActionName').AsString;
        CurRowParentID:=AdoQuer_Pub.FieldByName('ParentNodeID').AsInteger;
        if CurRowParentID<>LastActID then
        begin
          LastNode:=GetParentNode(CurRowParentID);
        end;
        if Assigned(LastNode) then
          LastActID:=TQxNodeData(LastNode.Data).QxID
        else
          LastActID:=0;
        Nodelst.AddChildObject(LastNode,tmpQX.QXName,tmpQX);
        AdoQuer_Pub.Next;
      end;
    end;function TForm1.GetParentNode(AParentID: Integer): TTreeNode;
    var
      tmp:TTreeNode;
    begin
      Result:=nil;
      if AParentID>0 then
      begin
        tmp:=TreeView1.TopItem;
        while Assigned(tmp) do
        begin
          if TQxNodeData(tmp.Data).QxID=AParentID then
          begin
            Result:=tmp;
            Break;
          end
          else
            tmp:=tmp.GetNext;
        end;
      end;
    end;
      

  8.   

    本人写了一个,看看如何
    type
      TChildData = record
        ChildID: string;
        Name: string;
        ParentID: string;
      end;function CreateTree: Boolean;
    var
      ChildData: PChildData;
      i : integer;
    begin
      Result := False;
      try
      with TV.Items do
      begin
        Clear;
        aQuery.Close;
        aQuery.SQL.Clear;
        aQuery.SQL.Add('select ChildID, ParentID, Name from Userfun ');
        aQuery.SQL.Add('order by ParentID, ChildID');
        aQuery.Open;
      end;
      while not aQuery.Eof do
      begin
          New(ChildData);
          ChildData^.ChildID := aQuery.FieldByName('ChildID').AsString;
          ChildData^.Name := aQuery.FieldByName('Name').AsString;
          ChildData^.ParentID := aQuery.FieldByName('ParentID').AsString;
          if aQuery.FieldByName('ParentID').AsString = '' then
             TV.Items.AddObject(nil, ChildData^.Name, ChildData)
          else
          begin
             for i := 0 to TV.Items.Count-1 do
             begin
                 if PChildData(TV.Items[i].Data)^.ChildID = ChildData^.ParentID then
                    TV.Items.AddChildObject(TV.Items[i],ChildData^.Name, ChildData);
             end;
          end;
          aQuery.Next;
      end;
      Result := True;
      except
        on E:Exception do
        begin
          ShowMessage('Error');
          Abort;
        end;
      end;
    end;