如何将数据库中的数据放在TreeView控件中分层次显示

时间:2022-09-21 19:16:25
如何将数据库中的数据放在TreeView控件中分层次显示
急急急!在线等待!

4 个解决方案

#1


type
  PNodeInfo=^TNodeInfo;    //指针类型,存储对应节点信息
    TNodeInfo=Packed Record
       NodeId:String;        //节点
       NodeName:string;      //节点名称
       ParentId:string;      //父节点
    end;

procedure TForm1.CreateTree(Id: integer; ParentNode: TTreeNode ;DTree:TTreeView);
var
    QryTmp:TadoQuery;
    MyNode:TTreeNode;
    TmpNodeInfo:PNodeInfo;
begin
    QryTmp:=TadoQuery.Create(self);
    QryTmp.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=VOD.MDB;Persist Security Info=False';
    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;
    QryTmp.Free;
  
end;

#2


楼上的,手真快啊:)

#3


根据数据库表中记录自动构造一棵结构树的一种高效算法
www.lvyin.net  2002-4-19 绿荫网络



一、前言:
    在好多场合下,都存在着很多像树一样的结构;如公司机构、军队职务、图书管理等,甚至好多论坛上的信息都是以树形的结构显示出来的。由于这样的结构存在无限子类、无限级别、信息多变的特点。无法由一开始就设计好一种结构,而往往这种结构是随时都可能改变的。这样,就需要有一种可以根据一批信息自动构造一棵结构树的算法。
    当今绝大多数信息是以数据库的形式保存起来的,下面我们就以数据库为操作源,以Delphi为编程工具,介绍一种根据数据库表中记录自动构造一棵结构树的一种高效算法。



二、数据库表结构设计:
    数据库表的结构设计关系到构造树的难易程序与速度,所以数据库表结构一定要设计合理,巧妙!在本算法中,数据库表结构关系到构造树的有三个字段,它们分别是:

 


字 段 名
 
 

代 表 意 义
 
 字段类型 
 

其它说明
 

 
 

NodeID
 
 结点自身ID号 
 

自动编号
 
 

关键字
 

 
 

NodeName 
 
 

结点名称
 
 

字符类型
 
 

不能为空
 

 
 

PNodeID
 
 父结点ID号 
 

长整形
 
 不能为空,默认值为0表示为一级结点 

#4


http://www.csdn.net/Develop/Read_Article.asp?Id=13651


六、源代码:
unit BuildTreeUnit;
 
interface
 
uses
  DB, ADODB, ComCtrls;
 
// 定义树结点对数据库表记录对应的结构体
type
  PNode = ^TNode;
  TNode = record
    FID:integer;    // 记录的ID号
    FBM:TBookMark;  // 定位记录的指针(书签)
end;
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
 
implementation
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
  { 以下子函数为在表中查找第一个PNode=AIndex的记录}
  function FindKey(AIndex: integer; FFirst:boolean): boolean;
  begin
    Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
  end;
  { 以下函数在FindKey的基础上找出下一个符合的记录}
  function FindNext(AIndex: integer): boolean;
  begin
    DataSet.Next;
    if DataSet.Eof then
      Result:=false
    else
      Result:=DataSet.FieldValues[ParentField]=AIndex;
    if not Result then DataSet.Prior;
  end;
  { 以下函数据构造当前结点的一级子树 }
  function GetChildNode(index: integer; ANode: TTreeNode):integer;
  var
    MyNode:PNode;
    Node:TTreeNode;
  begin
    if FindKey(index,true) then
    begin
      new(MyNode);
      with DataSet do
      begin
        MyNode^.FID :=FieldValues[SelfField];
        MyNode^.FBM :=GetBookmark;
      end;
      Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
      Node.Data:=MyNode;
      Result:=1;
      while FindNext(index) do
      begin
        new(MyNode);
        with DataSet do
        begin
          MyNode^.FID :=FieldValues[SelfField];
          MyNode^.FBM :=GetBookmark;
        end;
        Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
        Node.Data:=MyNode;
        Result:=Result+1;
      end;
    end
    else
      Result:=0;
  end;
  { 以下函数据以ANode 为结当,构造一棵属于自己的子树}
  procedure BuildMe(AIndex: integer; ANode: TTreeNode);
  var
    NodeNum:integer;
    Node:TTreeNode;
    i:integer;
  begin
    NodeNum:=GetChildNode(AIndex,ANode);
    if NodeNum>0 then
    begin
      if ANode=nil then Node:=TV.Items.GetFirstNode
      else
        Node:=ANode.getFirstChild;
      for i:=1 to NodeNum do
      begin
        BuildMe(PNode(Node.Data)^.FID,Node);
        Node:=ANode.GetNextChild(Node);
      end;
    end;
  end;
  // 组合部份
begin
  if (DataSet=nil) or (DataSet.Active =false) then
    Result:=false
  else if (TV=nil) then
    Result:=false
  else begin
    TV.Items.Clear;
    BuildMe(0,nil);
    Result:=true;
  end;
end;
 
end.

#1


type
  PNodeInfo=^TNodeInfo;    //指针类型,存储对应节点信息
    TNodeInfo=Packed Record
       NodeId:String;        //节点
       NodeName:string;      //节点名称
       ParentId:string;      //父节点
    end;

procedure TForm1.CreateTree(Id: integer; ParentNode: TTreeNode ;DTree:TTreeView);
var
    QryTmp:TadoQuery;
    MyNode:TTreeNode;
    TmpNodeInfo:PNodeInfo;
begin
    QryTmp:=TadoQuery.Create(self);
    QryTmp.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=VOD.MDB;Persist Security Info=False';
    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;
    QryTmp.Free;
  
end;

#2


楼上的,手真快啊:)

#3


根据数据库表中记录自动构造一棵结构树的一种高效算法
www.lvyin.net  2002-4-19 绿荫网络



一、前言:
    在好多场合下,都存在着很多像树一样的结构;如公司机构、军队职务、图书管理等,甚至好多论坛上的信息都是以树形的结构显示出来的。由于这样的结构存在无限子类、无限级别、信息多变的特点。无法由一开始就设计好一种结构,而往往这种结构是随时都可能改变的。这样,就需要有一种可以根据一批信息自动构造一棵结构树的算法。
    当今绝大多数信息是以数据库的形式保存起来的,下面我们就以数据库为操作源,以Delphi为编程工具,介绍一种根据数据库表中记录自动构造一棵结构树的一种高效算法。



二、数据库表结构设计:
    数据库表的结构设计关系到构造树的难易程序与速度,所以数据库表结构一定要设计合理,巧妙!在本算法中,数据库表结构关系到构造树的有三个字段,它们分别是:

 


字 段 名
 
 

代 表 意 义
 
 字段类型 
 

其它说明
 

 
 

NodeID
 
 结点自身ID号 
 

自动编号
 
 

关键字
 

 
 

NodeName 
 
 

结点名称
 
 

字符类型
 
 

不能为空
 

 
 

PNodeID
 
 父结点ID号 
 

长整形
 
 不能为空,默认值为0表示为一级结点 

#4


http://www.csdn.net/Develop/Read_Article.asp?Id=13651


六、源代码:
unit BuildTreeUnit;
 
interface
 
uses
  DB, ADODB, ComCtrls;
 
// 定义树结点对数据库表记录对应的结构体
type
  PNode = ^TNode;
  TNode = record
    FID:integer;    // 记录的ID号
    FBM:TBookMark;  // 定位记录的指针(书签)
end;
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
 
implementation
 
function BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,SelfName,ParentField:String):boolean;
  { 以下子函数为在表中查找第一个PNode=AIndex的记录}
  function FindKey(AIndex: integer; FFirst:boolean): boolean;
  begin
    Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
  end;
  { 以下函数在FindKey的基础上找出下一个符合的记录}
  function FindNext(AIndex: integer): boolean;
  begin
    DataSet.Next;
    if DataSet.Eof then
      Result:=false
    else
      Result:=DataSet.FieldValues[ParentField]=AIndex;
    if not Result then DataSet.Prior;
  end;
  { 以下函数据构造当前结点的一级子树 }
  function GetChildNode(index: integer; ANode: TTreeNode):integer;
  var
    MyNode:PNode;
    Node:TTreeNode;
  begin
    if FindKey(index,true) then
    begin
      new(MyNode);
      with DataSet do
      begin
        MyNode^.FID :=FieldValues[SelfField];
        MyNode^.FBM :=GetBookmark;
      end;
      Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
      Node.Data:=MyNode;
      Result:=1;
      while FindNext(index) do
      begin
        new(MyNode);
        with DataSet do
        begin
          MyNode^.FID :=FieldValues[SelfField];
          MyNode^.FBM :=GetBookmark;
        end;
        Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
        Node.Data:=MyNode;
        Result:=Result+1;
      end;
    end
    else
      Result:=0;
  end;
  { 以下函数据以ANode 为结当,构造一棵属于自己的子树}
  procedure BuildMe(AIndex: integer; ANode: TTreeNode);
  var
    NodeNum:integer;
    Node:TTreeNode;
    i:integer;
  begin
    NodeNum:=GetChildNode(AIndex,ANode);
    if NodeNum>0 then
    begin
      if ANode=nil then Node:=TV.Items.GetFirstNode
      else
        Node:=ANode.getFirstChild;
      for i:=1 to NodeNum do
      begin
        BuildMe(PNode(Node.Data)^.FID,Node);
        Node:=ANode.GetNextChild(Node);
      end;
    end;
  end;
  // 组合部份
begin
  if (DataSet=nil) or (DataSet.Active =false) then
    Result:=false
  else if (TV=nil) then
    Result:=false
  else begin
    TV.Items.Clear;
    BuildMe(0,nil);
    Result:=true;
  end;
end;
 
end.