delphi 中如何从数据库中读取数据自生成TreeView,只有两个字段,数据库结构如下。急急!!

我的数据库结构如下:
UnitId      UnitName
01          中国 (根节点)
0101        河北省(二级树)
010101      河北省沧州市(三级树)
01010101    河北省沧州市沧县(四级树)
0102        北京市(二级树)
010201      北京市海淀区(三级树)
01020101    北京市海淀区唐家岭村(四级树)
01020102    北京市海淀区小牛房村(四级树)
010202      北京市朝阳区(三级树)
01020201    北京市朝阳区奥运村(四级树)
0103        天津市(二级树)
010301      天津市大港区(三级树)
01030101    天津市大港区某地 (四级树)

需要这样进行判断
当Unitid的长度为4生成二级树
当Unitid的长度为6并且前4位与Unitid的长度为4数值相等生成三级树
当Unitid的长度为8并且前6位与Unitid的长度为6数值相等生成四级树

 

procedure CreateTree;
const
  ID_DEPT = 2;
var
  nLevel: Integer;
  pNodes: array[0..1023] of TTreeNode;
  lpID, lpName: string;
begin
  ADODataSet1.Close;
  ADODataSet1.CommandText := 'SELECT * FROM [国家] ORDER BY [编号]';
  ADODataSet1.Open;
  pNodes[0] := nil;
  TreeView1.Items.Clear;
  with ADODataSet1.Recordset do
    while not Eof do
    begin
      lpID := Fields['编号'].Value;
      lpName := Fields['名称'].Value;
      nLevel := Length(lpID) div ID_DEPT;
      pNodes[nLevel] := TreeView1.Items.AddChild(pNodes[nLevel - 1], lpName);
      MoveNext;
    end;
end;
unit dbtreeUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, ComCtrls, DB, ADODB;

{-------------------------------------------------------------------------------
  过程名:    MakeTree
  说明:     创建树
  作者:      Along
  日期:      2004.12.07
  参数:      Query: TADOQuery; TableName: string; TreeView: TTreeView
  参数说明: Query:相关联的数据库; TableName: 对应的表名; TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure MakeTree(Query: TADOQuery; TableName: string; TreeView: TTreeView);

{-------------------------------------------------------------------------------
  过程名:    AddNode
  说明:     增加树的节点
  作者:      Along
  日期:      2004.12.07
  参数:      Query: TADOQuery; TreeView: TTreeView
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure AddNode(Query: TADOQuery; TreeView: TTreeView;nodeName:String);
procedure AddRootNode(Query: TADOQuery; TreeView: TTreeView;RootName:String);

{-------------------------------------------------------------------------------
  过程名:    AddChildNode
  说明:     增加树的子节点
  作者:      Along
  日期:      2004.12.07
  参数:      Query: TADOQuery; TreeView: TTreeView
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}

procedure AddChildNode(Query: TADOQuery; TreeView: TTreeView;nodeName:string);

{-------------------------------------------------------------------------------
  过程名:    AddTreeNode
  说明:     增加节点(内部使用的过程)
  作者:      Along
  日期:      2004.12.07
  参数:      Query: TADOQuery; TreeView: TTreeView; bj: boolean = false
  参数说明: Query:相关联的数据库;TreeView: 所使用的树;bj:是否将焦点移到当前选择的节点
  返回值:    无
-------------------------------------------------------------------------------}
procedure AddTreeNode(Query: TADOQuery; TreeView: TTreeView; bj: boolean = false);

{-------------------------------------------------------------------------------
  过程名:    DelTree
  说明:     删除节点(包括删除本节点下的所有子节点)
  作者:      Along
  日期:      2004.12.07
  参数:      query: TAdoQuery; TreeView: TTreeView
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure DelTree(query: TAdoQuery; TreeView: TTreeView);

{-------------------------------------------------------------------------------
  过程名:    Treechange
  说明:     在树中选择了一个节点,将数据库的游标移动到所选择的节点所对应记录
  作者:      Along
  日期:      2004.12.07
  参数:      query: TADOQuery; node: TTreenode
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure Treechange(query: TADOQuery; node: TTreenode);

{-------------------------------------------------------------------------------
  过程名:    Treeedit
  说明:     树中的节点内容已经作了修改,将所修改的内容更新回数据库
  作者:      Along
  日期:      2004.12.07
  参数:      query: TADOQuery; text: string
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure Treeedit(query: TADOQuery; text: string);

{-------------------------------------------------------------------------------
  过程名:    treeselect
  说明:     数据库中的游标已经移动,将焦点移到树中对应的节点
  作者:      Along
  日期:      2004.12.07
  参数:      query: Tadoquery; TreeView: TTreeView
  参数说明: Query:相关联的数据库;TreeView: 所使用的树
  返回值:    无
-------------------------------------------------------------------------------}
procedure TreeSelect(query: Tadoquery; TreeView: TTreeView);

{-------------------------------------------------------------------------------
  函数名:    TreeFind
  说明:     找出给定的内容,并移动数据库中的游标,同时将焦点移到树中对应的节点
  作者:      Along
  日期:      2004.12.07
  参数:      TreeView: TTreeView; text: string
  参数说明: TreeView: 所使用的树 text: 要查找的内容
  返回值:    True:找到  False:找不到
-------------------------------------------------------------------------------}
function TreeFind(TreeView: TTreeView; text: string): boolean;

implementation

var
  List: TStringList; //用于记录各个id及其在树中所对应的节点,从而实现快速查找

procedure MakeTree(Query: TADOQuery; TableName: string; TreeView: TTreeView);
begin
  TreeView.Items.BeginUpdate;
  list.Clear;
  TreeView.items.clear;
  if query.Active then query.Close;
  Query.SQL.Text := 'SELECT * FROM ' + TableName + ' ORDER BY PID, ID';
  Query.Open;
  query.DisableControls;
  TreeView.Items.Clear;
  list.Clear;
  List.Sorted := True;
  query.First;
  while not Query.Eof do
  begin
    addtreenode(Query, TreeView); //依次增加所有的节点
    Query.Next;
  end;
  TreeView.Items.EndUpdate;
  query.EnableControls;
  if treeview.Items.Count < 1 then exit;
  treeview.Select(treeview.Items.Item[0]);
 // treeview.SetFocus;
end;

procedure addtreenode(Query: TADOQuery; TreeView: TTreeView; bj: boolean = false);
var
  index: integer;
  Node: TTreeNode;
begin
  if Query.FieldByName('PID').AsInteger = 0 then { ParentID=0,顶层节点 }
    Node := TreeView.Items.AddChildObject(nil, Query.FieldByName('nName').AsString, query.GetBookmark)
//增加节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中
  else
  begin
    Index := List.IndexOf(Query.FieldByName('PID').AsString);
    Node := TreeView.Items.AddChildObjectFirst(TTreeNode(List.Objects[Index]),
      Query.FieldByName('nName').AsString, query.GetBookmark);
//增加子节点,并将本节点所对应的记录标签数据放到节点所提供的附加数据中
  end;
//增加当前节点的信息到列表中,以实现在列表中快速查找节点的功能。
  List.AddObject(Query.FieldByName('ID').AsString, Node);
  if bj then
  begin
    treeview.Select(node);
 //   treeview.SetFocus;
  end;
end;

procedure deltree(query: TAdoQuery; TreeView: TTreeView);
var
  node: TTreenode;
//删除当前选择的节点下的所有节点(不删除当前选择的节点)
  procedure delnode(node: TTreenode);
  var
    i: integer;
    childnode: TTreenode;
  begin
    for i := 0 to node.Count - 1 do
    begin
      childnode := node.Item[i]; //取当前节点下的所有节点
      query.GotoBookmark(childnode.Data); //移到节点所对应的记录
      list.Delete(list.IndexOf(query.FieldByName('ID').AsString)); //删除列表中的数据
      query.Delete; //删除对应的记录
      if node.HasChildren then delnode(childnode); //有子节点则递归直到所有的数据删除完毕
    end;
  end;
{另一方法:
用一个递归:
procedure doSearch(tn: TTreeNode);
var i: ingeger;  
begin
 if tn.HasChildren then
 begin
  for i := tn.Count -1 downto 0 do doSearch(tn[i]); 
 end
 else
 begin
   //这里是你对每个节电要做的事情
 end;
end;}

begin
  node := treeview.Selected;
  if node = nil then exit;
//删除当前选择的节点下的所有节点(不删除当前选择的节点)
  delnode(node);
//删除当前选择的节点
  query.GotoBookmark(node.Data);
  list.Delete(list.IndexOf(query.FieldByName('ID').AsString));
  query.Delete;
  node.Delete;
  TreeView.SetFocus;
end;

procedure AddChildNode(Query: TADOQuery; TreeView: TTreeView;nodeName:string);
var
  id: integer;
begin
  id := query.FieldByName('ID').AsInteger; //记下当前的节点编号
  query.Append;
  query.FieldByName('PID').AsInteger := id; //新增加的子节点的父节点编号即为id
  query.FieldByName('nName').AsString := nodeName;
  query.post;
  addtreenode(query, treeview, true);
end;

procedure AddNode(Query: TADOQuery; TreeView: TTreeView;nodeName:String);
var
  pid: integer;
begin
  pid := query.FieldByName('pID').AsInteger; //记下当前节点的父节点编号
  query.Append;
  query.FieldByName('PID').AsInteger := pid; //新增加的子节点的父节点编号即为pid
  query.FieldByName('nName').AsString := nodeName;
  query.post;
  addtreenode(query, treeview, true);
end;
procedure AddRootNode(Query: TADOQuery; TreeView: TTreeView;RootName:String);
var
  pid: integer;
begin
  pid := query.FieldByName('pID').AsInteger; //记下当前节点的父节点编号
  query.Append;
  query.FieldByName('PID').AsInteger :=0; //新增加的子节点的父节点编号即为pid
  query.FieldByName('nName').AsString := RootName;
  query.post;
  addtreenode(query, treeview, true);
end;


procedure Treechange(query: TADOQuery; node: TTreenode);
begin
  query.GotoBookmark(node.Data);
end;

procedure TreeEdit(query: TADOQuery; text: string);
begin
  query.Edit;
  query.FieldByName('nName').AsString := text;
  query.post;
end;

procedure treeselect(query: Tadoquery; TreeView: TTreeView);
var
  index: integer;
  Node: TTreeNode;
begin
  Index := List.IndexOf(Query.FieldByName('ID').AsString);
  Node := TTreeNode(List.Objects[Index]);
  treeview.Selected := Node;
  treeview.SetFocus;
end;

function TreeFind(TreeView: TTreeView; text: string): boolean;
var
  i: integer;
begin
  Result := false;
  for i := 0 to treeview.Items.Count - 1 do
  begin
    if treeview.Items.Item[i].Text = text then
    begin
      treeview.Select(treeview.Items.Item[i]);
      treeview.SetFocus;
      Result := true;
      exit;
    end;
  end;
end;

initialization
  List := TStringList.Create;

finalization
  list.Free;

end.

这是一个单元,直接使用就行!

 

posted on 2020-02-14 00:39  癫狂编程  阅读(489)  评论(0编辑  收藏  举报

导航

好的代码像粥一样,都是用时间熬出来的