Sql数据生成TreeView问题(树的遍历)?(200分)

  • 主题发起人 苦中求乐
  • 开始时间

苦中求乐

Unregistered / Unconfirmed
GUEST, unregistred user!
有如下表结构:
字段含义: 编码 名称 父编码 父层次
字段名: Bm Mc FBm FCc
类型: Char char char integer
长度: 30 50 30
举例如下:
Bm Mc FBm Fcc
001 a 0 1
002 b 0 1
003 c 0 1
001001 aa 001 2
001002 ab 001 2
001003 ac 001 2
001001001 aaa 001001 3
001001002 aab 001001 3
形成树如下:
a--|
| |---aa
| | |---aaa
| | |---aab
| |---ab
| |---ac
b
|
c
先在想在窗体创建时一次性将所有节点都添加到树上,该如何遍历此树上的所有节点?
我曾用多个数据集的方法实现,但效率不是很理想,能不能用一个QUERY返回所有数据,然后进行遍历呢?
 
如果用Oracle数据库倒可以
 
呵呵,Oracle用Connected By
其它的要写个过程而已。
 
以下是我的一个应用,你不妨参考以下
const
iCodeLen=6;//代码长度
sCodeFormat='1121';//代码级长
{$R *.dfm}
function TFd_sys_dept.f_appendcode():Boolean;
begin
with DS_Deptdo
begin
if DataSet.Active then
begin
DataSet.Insert;
DataSet['bmbh']:=Trim(Edit_id.Text);
DataSet['bmmc']:=Trim(Edit_code.Text);
DataSet.Post;
DataSet.Close;
MisData.P_CloseTable;
MisData.P_OpenTable;
Fd_sys_dept.LoadCode(AQ_Dept);
Result:=True;
exit;
end
else
Result:=False;
end;
end;

function TFd_sys_dept.f_updatecode():Boolean;
begin
with DS_Deptdo
begin
if DataSet.Active then
begin
DataSet.Edit;
DataSet['bmbh']:=Trim(Edit_id.Text);
DataSet['bmmc']:=Trim(Edit_code.Text);
DataSet.Post;
DataSet.Close;
MisData.P_CloseTable;
MisData.P_OpenTable;
Fd_sys_dept.LoadCode(AQ_Dept);
Result:=True;
exit;
end
else
Result:=False;
end;
end;

function TFd_sys_dept.f_deletecode():Boolean;
begin
with DS_Deptdo
begin
if DataSet.Active then
begin
DataSet.Delete;
DataSet.Close;
MisData.P_CloseTable;
MisData.P_OpenTable;
Fd_sys_dept.LoadCode(AQ_Dept);
Result:=True;
exit;
end
else
Result:=False;
end;
end;

function TFd_sys_dept.LoadCode(crAQuery: TADOQuery):Integer;
var
Level,i :Integer;
NowId,ShowTxt :String;
sid,scode :String;
MyNode:array[0..6] of TTreeNode;
begin
Screen.Cursor:=crHourGlass;
Level:=0;
try
if not crAQuery.Active then
crAQuery.Open;
if (crAQuery.RecordCount = 0) then
begin
MessageDlg('打开参数库失败!', mtInformation,[mbOk], 0);
exit;
end;
TreeView1.Items.Clear;
// remove any existing nodes
//以下是增加第一项
MyNode[Level]:=TreeView1.Items.Add(TreeView1.TopItem, '部门代码');
MyNode[Level].ImageIndex:=0;
MyNode[Level].SelectedIndex:=0;
//以上是增加第一项
crAQuery.First;
while (not crAQuery.Eof)do
begin
sid:=crAQuery['bmbh'];
//此处不能使用AsString;
scode:=crAQuery['bmmc'];
NowId:=Trim(sid);
if Length(sid)<iCodeLen then
begin
i:=iCodeLen-Length(sid);
sid:=sid+StringOfChar(' ',i);
ShowTxt:=sid+scode;
Level:=MyGetLevel(sCodeFormat,NowId);
//返回代码的级数
//以下是增加子项
//以下用上一级节点为父节点添加子节点
if Level>0 then
//确保代码符合标准
begin
MyNode[Level]:=TreeView1.Items.AddChild(MyNode[Level-1], ShowTxt);
MyNode[Level].ImageIndex:=1;
MyNode[Level].SelectedIndex:=2;
end;
//以上是增加子项
crAQuery.Next;
end;
end;
finally
crAQuery.First;
end;
MyNode[0].Expand(False);
TreeView1.FullExpand;
Screen.Cursor:=crDefault;
end;

function TFd_sys_dept.MyGetLevel(sFormat,sCode:String):Integer;
var
i,Level,iLen:Integer;
begin
Level:=-1;
iLen:=0;
if ((Trim(sFormat)<>'') and (Trim(sCode)<>'')) then
for i:=1 to Length(sFormat)do
begin
iLen := iLen + StrToInt(sFormat);
if Length(sCode) = iLen then
begin
Level:=i;
Break;
end;
end;
Result:=Level;
end;

procedure TFd_sys_dept.FormCreate(Sender: TObject);
begin
LoadCode(AQ_Dept);
end;

procedure TFd_sys_dept.TreeView1Change(Sender: TObject;
Node: TTreeNode);
var
sselect:String;
begin
sselect:=Trim(TreeView1.Selected.Text);
if sselect = '部门代码' then
exit;
StatusBar1.SimpleText := sselect;
with AQ_Deptdo
begin
Filtered := false;
if (Length(LeftStr(sselect,iCodeLen)) = 1) then
Filter := ''
else
Filter := 'bmbh = ' + QuotedStr(Trim(LeftStr(sselect,iCodeLen)));
Filtered := true;
Edit_id.Text:=DS_Dept.DataSet['bmbh'];
Edit_code.Text:=DS_Dept.DataSet['bmmc'];
end;
end;

procedure TFd_sys_dept.BitBtn4Click(Sender: TObject);
begin
Close;
end;

procedure TFd_sys_dept.FormClose(Sender: TObject;var Action: TCloseAction);
begin
Fd_sys_dept:=nil;
Action := caFree;
end;
 
这容易,从头到尾一直添加就行了。
 
呵,这程序我前不久刚写过,我把我的稍改了一下,另数据库设计有个建议,有父编码 就没必要有父层次了
如不太清楚的话加我qq:222428,交个朋友:)
先定义一个结构
type
ptreeRec = ^Tree_Rec;
TRee_Rec = record
Bm,mc,fbm: string;
//fcc: string;
end;

mAllRec: array of Tree_Rec;

//把库中所有数据加入此结构数组
setlength(mAllRec,qry.recordcount);
while not(qry.eof)do
begin
//此处是库中数据写入mAllRec的语句
end;

AddHisChild(TreeView_ywzt, tempNode, mAllRec, mAllRec[0].fbm);
//执行此语句就行了
procedure TformTBDB.AddHisChild(Treeview1: TTreeview;
RootTreeNode: TTreeNode;
myarray: array of Tree_Rec;
Myfbm: string);
var i: integer;
tempNode: TTreeNode;
ptree: ptreerec;
begin
for i := 0 to high(myArray)do
begin
if Tree_R.Bm = Myfbm then
begin
tempNode := TreeView_ywzt.Items.AddChild(RootTreeNode, Tree_R.mc);
{new(ptree);
ptree^.bm := Tree_R.bm;
ptree^.mc := Tree_R.mc;
tempNode.Data := ptree;} //此语句可不用,主要是向节点加入信息的

AddHisChild(RootTreeNode, tempNode, mAllRec, mAllRec.fbm);//递归调用
end;
end;
end;
 
参考 treeview.loadfromfile方法,你就会明白了
 
多人接受答案了。
 
顶部