一个困惑很久很久的问题,希高手给我看看(100分)

  • 主题发起人 主题发起人 wangchengwu
  • 开始时间 开始时间
W

wangchengwu

Unregistered / Unconfirmed
GUEST, unregistred user!
一个access(data)包括一个表(mytable)表中一字段(name),问怎样利用adoquery,treeview等来建立一棵树,显示name字段值,并添加两个button,对数据库表的字段值name进行添加、删除。
 
只有一个字段怎么创建树?怎么着也该有几个字段才好形容出一个层次信息来。
procedure Tfm_ProjectTree.MakeTree(TreeType: Integer);
{TreeType是树类型,例如根据年份,工程类型,赋予编号与否
等分类构成树}
var
MyTreeNode,MyTreeNode1,MyTreeNodeSub,MyTreeNodeSub1: TTreeNode;
begin
//进入更新状态
//TreeView1显示树,TreeView2记录id
TreeView1.Items.BeginUpdate;
TreeView2.Items.BeginUpdate;
TreeView1.Items.Clear;
TreeView2.Items.Clear;
ADODataSet1.Close;
ADODataSet1.CommandText:='Select Count(id) as Num From Multi_Project';
ADODataSet1.Open;
MyTreeNode := TreeView1.Items.Add(nil, '工程资料台帐['+ADODataSet1.FieldByName('Num').AsString+']');
MyTreeNode.ImageIndex:=0;
MyTreeNode1 := TreeView2.Items.Add(nil, '工程资料台帐');
ADODataSet1.Close;
ADODataSet1.CommandText:='Select 工程年份,Count(id) as Num From Multi_Project Group By 工程年份';
ADODataSet1.Open;
if ADODataSet1.RecordCount>0 then
begin
Repeat
MyTreeNodeSub:=TreeView1.Items.AddChild(MyTreeNode,ADODataSet1.FieldByName('工程年份').AsString+'年资料['+ADODataSet1.FieldByName('Num').AsString+']');
MyTreeNodeSub.ImageIndex:=1;
MyTreeNodeSub.SelectedIndex:=1;
MyTreeNodeSub.HasChildren:=True;
MyTreeNodeSub1:=TreeView2.Items.AddChild(MyTreeNode1,ADODataSet1.FieldByName('工程年份').AsString);
ADODataSet1.Next;
Until ADODataSet1.Eof;
end;
ADODataSet1.Close;
TreeView1.Items.EndUpdate;
TreeView2.Items.EndUpdate;
end;
//=====================

procedure Tfm_ProjectTree.TreeView1Expanding(Sender: TObject;
Node: TTreeNode; var AllowExpansion: Boolean);
var
MyTreeNodeSub,MyTreeNodeSub1: TTreeNode;
begin
if ((Node.Level=1) and (Node.Count=0)) then
//如果点击的是年份,并且年份节点下无子节点
begin
try
ADODataSet1.Close;
ADODataSet1.CommandText:='select 工程类型,Count(id) As Num from Multi_Project Where 工程年份='+Copy(Node.Text,1,4)+' Group By 工程类型';
ADODataSet1.Open;
if ADODataSet1.RecordCount>0 then
begin
Repeat
MyTreeNodeSub:=TreeView1.Items.AddChild(Node,ADODataSet1.FieldByName('工程类型').AsString+'['+ADODataSet1.FieldByName('Num').AsString+']');
MyTreeNodeSub.ImageIndex:=2;
MyTreeNodeSub.SelectedIndex:=2;
MyTreeNodeSub.HasChildren:=True;
MyTreeNodeSub1:=TreeView2.Items.AddChild(TreeView2.Items.Item[Node.AbsoluteIndex],ADODataSet1.FieldByName('工程类型').AsString);
ADODataSet1.Next;
Until ADODataSet1.Eof;
end;
Except
Application.MessageBox('此类工程尚未赋予工程编号。请先在【传票处理】模块中赋予工程编号。','',Mb_Ok+Mb_IconInformation);
end;
end; {年份节点结束}

if ((Node.Level=2) and (Node.Count=0)) then
//如果点击的是类型,并且类型节点下无子节点
begin
TreeView1.Items.BeginUpdate;
TreeView2.Items.BeginUpdate;
ADODataSet1.Close;
ADODataSet1.CommandText:='Select id,工程年份,工程类型,工程编号 From Multi_Project Where 工程年份='+Copy(Node.Parent.Text,1,4)+' And 工程类型='''+Copy(Node.Text,1,6)+''' Order By 工程编号';
ADODataSet1.Open;
if ADODataSet1.RecordCount>0 then
begin
Repeat
MyTreeNodeSub:=TreeView1.Items.AddChild(Node,ADODataSet1.FieldByName('工程年份').AsString+ADODataSet1.FieldByName('工程类型').AsString+ADODataSet1.FieldByName('工程编号').AsString);
MyTreeNodeSub.ImageIndex:=3;
MyTreeNodeSub.SelectedIndex:=3;
MyTreeNodeSub1:=TreeView2.Items.AddChild(TreeView2.Items.Item[Node.AbsoluteIndex],ADODataSet1.FieldByName('id').AsString);
ADODataSet1.Next;
Until ADODataSet1.Eof;
end;
TreeView1.Items.EndUpdate;
TreeView2.Items.EndUpdate;
end; {类型节点结束}

if (Node.Level=3) then
//点击的是具体的工程名称编号,则调阅出详细资料来
begin
end;
end;
 
其实很简单,主要明白如果从数据库取数据来建树就OK啦

[blue]1. 库表要增加两个字段,分别是id(主健), parent_id(指向父id)[/blue]

[blue]2. 准备一个sql语句,用于提取相关数据[/blue]
select * from mytable where id=:v_id order by parent_id, id

[blue]3. 定义一个record和pointer[/blue]
type
PNodeInfo = ^NodeInfo;
NodeInfo = record
id, p_id: integer;
end;

[blue]4. 写一个递归函数,用于建树[/blue]
procedure BuildTree();

//[green]内部函数,创建树节点[/green]
function CreateNode(parentnode: TTreeNode; id, p_id: integer;
name: string): TTreeNode;
var
lpNodeInfo: PNodeInfo;
begin
//[green]准备object数据[/green]
new(lpNodeInfo);
lpNodeInfo.id := id;
lpNodeInfo.p_id := p_id;
//[green]创建一个节点[/green]
result := treeview.items.AddChildObject(parentnode, name, lpNodeInfo);
end;

//[green]内部递归函数,建立所有树节点[/green]
procedure addNodes(parentnode: TTreeNode);
var
id, i: integer;
node: TTreeNode;
query: TQuery;
begin
//[green]准备查询条件[/green]
if parentnode=nil then id=0 else id=PNodeInfo(parentnode.data)^.id;

//[green]从数据库取数据[/green]
query := TQuery.Create(nil);
query.Connection := gConnection; //[green]gConnection为一个全局数据库连接变量[/green]
query.sql.add([red]<上边提到的sql语句>[/red]);
query.ParamByName('v_id').value := id; //[green]赋上条件值[/green]
query.open;
query.first;

//[green]把一条一条记录顺序变成树节点[/green]
while not query.eof do
begin
node := CreateNode(parentnode, query.fieldbyname('id').asInteger,
query.fieldbyname('parent_id').asInteger, query.fieldbyname('name').asString);

//[green]调用自身,进行递归[/green]
addNodes(node);

query.next;
end;

query.close;
query.free;
end;

begin
addNodes(nil); //[green]从第一层开始建树[/green]
end;

[blue]5.两个按钮的功能就是对treeview的节点进行操作,增加或者删除,同时赋予节点数据[/blue]
PNodeInfo(node.data)^.id := ???
...

[blue]6.按照节点的数据保存到数据库中。[/blue]

看看这样的回答,您是否满意,满意就给点分吧,哈哈
 
接受答案了.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部