id parent caption
1 0 A
2 1 B
3 1 C
4 1 D
5 2 E
6 5 F
7 3 G
1 0 A
2 1 B
3 1 C
4 1 D
5 2 E
6 5 F
7 3 G
解决方案 »
- delphi 调用 java写的webservice服务,用了axis2
- 实时通讯软件怎么做?
- Server Application 的问题!
- 圣诞节,你Delphi8了吗?
- 怎样才能把一个硬盘上的文件整个的存入数据库,又怎样提取。在线等待。
- 帮我出一个好的人事查询建议
- 如何操作 RAW 类型的字段,ORacle7中,Varchar2 最大允许的长度是多少(今天揭帖)
- 各位高手请教一下用dbgrid和Tquery进行数据的修改怎么做??急急急急急,十万火急!
- 您常去或曾对您有过帮助的Delphi的网站!200大洋
- 求救!!!!!!!MSSQL写BYTE,给50分
- 关于 WAP 空间的申请
- 关于主form和application的handle的区别!!!
Id word ParentId RootID
1 A 0 1
2 B 1 1
3 C 1 1
4 D 1 1
5 E 2 1
6 G 2 1
7 F 5 1 现在的问题就是如何用Treeview控件将数据以层次的关系反应出来
表结构其实很简单
ID SX 这是两个重要字段,其他的都不重要unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, ADODB, ComCtrls;type
tmydata=class
node:string[3];
parent:string[3];
ps:real;
name:string;
added:boolean;
end;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Query1: TADOQuery;
TreeView1: TTreeView;
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
Query2: TADOQuery;
procedure loaddatasfromquery;
function addanode(adata:tmydata):ttreenode;
procedure BuildTree;
procedure calacanodemoney(anode:ttreenode);
procedure Button1Click(Sender: TObject); private
{ Private declarations }
public end;var
Form1: TForm1;
mydatas:tlist;implementation{$R *.DFM}procedure TForm1.loaddatasfromquery;
var
adata:tmydata;
i:integer;
begin
if not assigned(mydatas) then
mydatas:=tlist.create
else
begin
for i:=0 to mydatas.count-1 do
begin
adata:=mydatas[i];
adata.free;
end;
mydatas.clear;
end;
if not query1.active then query1.open;
query1.first;
while not query1.eof do
begin
adata:=tmydata.create;
adata.node:=query1.fieldbyname('id').asstring;
adata.parent:=query1.fieldbyname('sx').asstring; adata.added:=false;
mydatas.add(adata);
query1.next;
end;
query1.close;
end; function tform1.addanode(adata:tmydata):ttreenode;
var
anode:ttreenode;
i:integer;
begin
anode:=nil;
if adata.added then
begin
anode:=treeview1.items.getfirstnode();
while adata<>tmydata(anode.data) do
anode:=anode.getnext();
result:=anode;
exit;
end;
if trim(adata.parent) <>'' then
for i:=0 to mydatas.count-1 do
if tmydata(mydatas[i]).node=adata.parent then
begin
anode:=addanode(tmydata(mydatas[i]));
break;
end;
result:=treeview1.items.addchildobject(anode,adata.node,adata);
adata.added:=true;
end;procedure TForm1.BuildTree;
var
i : integer;
begin
TreeView1.Items.BeginUpdate;
TreeView1.Items.Clear;
LoadDatasFromQuery;
for i := 0 to MyDatas.Count - 1 do
if not TMyData(MyDatas[i]).Added then AddANode(MyDatas[i]);
TreeView1.Items.EndUpdate;end;procedure TForm1.calacanodemoney(anode:ttreenode);
var
achild:ttreenode;
adata,cdata:tmydata;
scale:real;
begin
adata:=anode.data;
case(anode.level) of
1: scale:=20;
2: scale:=5;
3: scale:=5;
4: scale:=5;
5: scale:=10;
end;
achild:=anode.getfirstchild;
while achild<>nil do
begin
if achild.haschildren then calacanodemoney(achild);
query1.open;
if Query1.Locate('ID',VarArrayOf([adata.node]),[]) then
begin
Query1.Edit;
Query1.FieldByName('Ps').asfloat:=adata.ps;
Query1.post;
end;
achild:=achild.getnextsibling;
end;
end;procedure TForm1.Button1Click(Sender: TObject);
var
aNode : TTreeNode;
begin
BuildTree;
aNode:=TreeView1.items.getfirstnode;//找到第一个顶结点
// if Assigned(aNode) then ShowMessage(aNode.text);
showmessage(anode.text);
while Assigned(aNode) do
begin
if aNode.HasChildren then CalacANodeMoney(aNode);
end;
end;end.
递归建树,我程序里的,希望你能看的懂:
procedure TMDIChild.LoadTreeView;
var
strsql,tid:string;
begin
try DataModule3.ADOTable3.open;
DataModule3.ADOTable3.Locate('DTname',RzComboBox1.Text,[lopartialkey]);
tid:=inttostr(DataModule3.ADOTable3.FieldByName('id').value);
strsql:='select * from T where TypeID='+tid;
DQ.Active :=false;
DQ.SQL.Clear ;
DQ.SQL.Add(strsql);
DQ.Active :=true;
DQ.Filtered :=true;
DQ.Filter := 'Parent=0';
U_DiGui(0,RzTreeView1.TopItem );//从当前0层开始递归建树
except
showmessage('字典里没有数据!');
end;
end;
procedure TMDIChild.U_DiGui(parentID:Cardinal;ParentNode:TTreeNode);
var
tmpTBData:array of TableData;
i,j:integer;
tmpNode:TTreeNode;begin
j:=DQ.RecordCount;
setlength(tmpTBData,j);//保存递规上一层结点值
for i:=0 to j-1 do begin
tmpTBData[i].ID := Cardinal(DQ.fieldbyname('ID').value);
tmpTBData[i].Name := DQ.fieldbyname('Name').value;
tmpTBData[i].ParentID := Cardinal(DQ.fieldbyname('Parent').value);
DQ.Next;
end;
for i:=0 to j-1 do begin //递规调用建立所有结点
tmpNode:=RzTreeView1.Items.AddChild(ParentNode,tmpTBData[i].Name);
// tmpNode.ImageIndex:=2;
new(pData);
pData^.ID:=tmpTBData[i].ID;
tmpNode.Data:=pData;
DQ.Filter := 'Parent=' + IntToStr(Integer(tmpTBData[i].ID));
if DQ.RecordCount >0 then begin
U_DiGui(tmpTBData[i].ID,tmpNode );
end;
end;
end;
TTreeView.SaveToStream();
TTreeView.LoadFromStream();
仅仅显示ID NAME PARENT 三个字段是最好的设计.
如果为了其他地方的方便,可以考虑加"所在的层次","根ID"两个字段,看需要.
仅仅显示ID NAME PARENT 三个字段是最好的设计.
如果为了其他地方的方便,可以考虑加"所在的层次","根ID"两个字段,看需要.
在添加节点的时候将表中的数据按照 parentid 排序返回记录集,添加的每一个
ID保存在TTreeNode的Data属性中。
用TreeView来实现,也不难,你记得保存自已的父结点.
记得不要每次更新的时候都重画树;
表的结构中画树只需要两个字段,一个标志其本身的ID,另外一个标志她的上级节点的ID,根节点的上级赋一个特殊的值
以后在记录定位时只要用MoveBy(n),查询速度也很理想。所做过的树数据实例是把一辆火车逐级分解成另件,至少有一万条记录,只是在读入时有等待,其它操作都正常。