谁能帮我解释下这段Treeview的代码,特别是我打问号的几句,定给高分
树的结构和表中的字段如下:
公司机构【总人数】
- 一级部门department.dep
- 二级部门department.sdep
- 员工employee.name
department表和employee表是靠dep_id字段关联的,
employee表与experience、train、behave表都是靠num字段关联的。
相关代码如下:
private
{ Private declarations }
FNum: string;
Fdep_id: string;
procedure RefreshTreeView;
public
{ Public declarations }
end;
PIndexRecord = ^TIndexRecord;
TIndexRecord = packed record
num: string;
Dep_id: string;
Code: TTreeNode; ??
Next: PIndexRecord; ??
end;
var
EmpForm: TEmpForm;
Temp: PIndexRecord; ??
Flag: Boolean; ??implementationuses UnitDM;{$R *.dfm}var
FirstPointer, LastPointer, First, Last: PIndexRecord;
aqEmployee,ADQ2, ADQ3,ADQ4: TADOQuery;
procedure TEmpForm.RefreshTreeView;
var
Node0: TTreeNode;
Node1, Node2: array of TTreeNode;
i,Index1, Index2: Integer;
Temp, Temp1: PIndexRecord;
begin
dm.OpenInfo;
TreeView1.Items.Clear;
ADQ1:= TADOQUery.Create(nil);
ADQ2:= TADOQuery.Create(nil);
ADQ3:= TADOQuery.Create(nil);
ADQ4:= TADOQuery.Create(nil);
aqEmployee:=TADOQuery.Create(nil);
Index1:= 0;
ADQ1.Connection:= DM.ADOConnection1;
ADQ2.Connection:= DM.ADOConnection1;
ADQ3.Connection:= DM.ADOConnection1;
ADQ4.Connection:= DM.ADOConnection1;
aqEmployee.Connection:=DM.ADOConnection1; FillData; aqEmployee.Close;
aqEmployee.SQL.Clear;
aqEmployee.SQL.Add('select * from employee');
aqEmployee.Open;
DM.aqEmp.Close;
DM.aqEmp.SQL.Clear;
DM.aqEmp.SQL.Add('select * from employee');
DM.aqEmp.Open; Temp:= New(PIndexRecord);
Temp1:= New(PIndexRecord); FirstPointer:= Temp;
First:= Temp1; ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.text:='Select dep_id,dep From department where dep_id in ' + #13#10 +
'(select Min(dep_id) from department group by dep) ' + #13#10 +
'order by dep_id asc';
ADQ1.Open; if not ADQ1.Eof then
begin
TreeView1.AutoExpand := true;
TreeView1.ReadOnly := true;
Node0 := TreeView1.Items.AddFirst(nil, '公司机构[' + IntToStr(aqEmployee.RecordCount) + '人]');
end
else
Exit; SetLength(Node1, ADQ1.RecordCount); while not ADQ1.Eof do
begin
with dm.aqEmp do
begin
Filtered := false;
Filter := 'dep = ' + QuotedStr(adq1.FieldValues['dep']);
Filtered := true;
end;
Node1[Index1]:= TreeView1.Items.AddChild(Node0, ADQ1.FieldByName('dep').AsString+'[' + IntToStr(dm.aqEmp.RecordCount) + ']');
Node1[Index1].ImageIndex:= 0; ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM department WHERE dep = ''' + ADQ1.FieldByName('dep').AsString + '''');
ADQ2.Open; Index2:= 0;
if not ADQ2.IsEmpty then
begin
SetLength(Node2, ADQ2.RecordCount); while not ADQ2.Eof do
begin
Node2[Index2]:= TreeView1.Items.AddChild(Node1[Index1], ADQ2.FieldByName('sdep').AsString);
Node2[Index2].ImageIndex:= 0; Temp1.num:= ''; ??
Temp1.Dep_id:= ADQ2.FieldByName('dep_id').AsString; ?
Temp1.Code:= Node2[Index2]; ??
ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM employee WHERE dep_id = ''' + ADQ2.FieldByName('dep_id').AsString + '''');
ADQ3.Open; if not ADQ3.IsEmpty then
while not ADQ3.Eof do
begin
Temp.num:= ADQ3.FieldByName('num').AsString;
Temp.Dep_id:= ADQ3.FieldByname('dep_id').AsString;
Temp.Code:=
TreeView1.Items.AddChildObject(Node2[Index2], ADQ3.FieldByName('name').AsString,temp);
Temp.Code.ImageIndex:= 2;
ADQ3.Next;
Temp.Next:= New(PIndexRecord);
Temp:= Temp.Next;
end; Inc(Index2);
ADQ2.Next;
Temp1.Next:= New(PIndexRecord);
Temp1:= Temp1.Next;
end;
end; Inc(Index1);
ADQ1.Next; end;
ADQ1.Close;
ADQ2.Close;
ADQ3.Close;
LastPointer:= Temp;
Last:= Temp1;
TreeView1.Refresh; DataSource1.DataSet:= ADQ1;
DataSource2.DataSet:= ADQ2;
DataSource3.DataSet:= ADQ3;
DataSource4.DataSet:= ADQ4; for i := 0 to TreeView1.Items.Count - 1 do
if TreeView1.Items[i].Data <> nil then
begin
TreeView1.Selected := TreeView1.Items[i];
Exit;
end;
end;procedure TEmpForm.TreeView1Click(Sender: TObject);
var
Temp, Temp1: PIndexRecord;
Flag: Boolean; ??干吗用的
begin
Temp:= FirstPointer;
Temp1:= First;
Flag:= False; while Temp <> nil do
begin
if Temp.Code = TreeView1.Selected then
begin
Flag:= True; ??
Break;
end; Temp:= Temp.Next;
if Temp = LastPointer then
Break;
end; if Flag then
begin
ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp.num + '''');
ADQ1.Open;
LoadImage(ADQ1.FieldByName('Photo')); ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp.num + '''');
ADQ2.Open; ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp.num + '''');
ADQ3.Open; ADQ4.Close;
ADQ4.SQL.Clear;
ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp.num + '''');
ADQ4.Open; FNum:= Temp.num; ??
Fdep_id:= Temp.Dep_id; ??
end
else
begin
while Temp1 <> Last do
begin
if Temp1.Code = TreeView1.Selected then
begin
Flag:= True;
Break;
end; Temp1:= Temp1.Next;
end; if Flag then ??为什么要判断两次
begin
ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp1.num + '''');
ADQ1.Open; ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp1.num + '''');
ADQ2.Open; ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp1.num + '''');
ADQ3.Open; ADQ4.Close;
ADQ4.SQL.Clear;
ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp1.num + '''');
ADQ4.Open; FNum:= Temp1.num;
Fdep_id:= Temp1.Dep_id;
end;
end;end;
树的结构和表中的字段如下:
公司机构【总人数】
- 一级部门department.dep
- 二级部门department.sdep
- 员工employee.name
department表和employee表是靠dep_id字段关联的,
employee表与experience、train、behave表都是靠num字段关联的。
相关代码如下:
private
{ Private declarations }
FNum: string;
Fdep_id: string;
procedure RefreshTreeView;
public
{ Public declarations }
end;
PIndexRecord = ^TIndexRecord;
TIndexRecord = packed record
num: string;
Dep_id: string;
Code: TTreeNode; ??
Next: PIndexRecord; ??
end;
var
EmpForm: TEmpForm;
Temp: PIndexRecord; ??
Flag: Boolean; ??implementationuses UnitDM;{$R *.dfm}var
FirstPointer, LastPointer, First, Last: PIndexRecord;
aqEmployee,ADQ2, ADQ3,ADQ4: TADOQuery;
procedure TEmpForm.RefreshTreeView;
var
Node0: TTreeNode;
Node1, Node2: array of TTreeNode;
i,Index1, Index2: Integer;
Temp, Temp1: PIndexRecord;
begin
dm.OpenInfo;
TreeView1.Items.Clear;
ADQ1:= TADOQUery.Create(nil);
ADQ2:= TADOQuery.Create(nil);
ADQ3:= TADOQuery.Create(nil);
ADQ4:= TADOQuery.Create(nil);
aqEmployee:=TADOQuery.Create(nil);
Index1:= 0;
ADQ1.Connection:= DM.ADOConnection1;
ADQ2.Connection:= DM.ADOConnection1;
ADQ3.Connection:= DM.ADOConnection1;
ADQ4.Connection:= DM.ADOConnection1;
aqEmployee.Connection:=DM.ADOConnection1; FillData; aqEmployee.Close;
aqEmployee.SQL.Clear;
aqEmployee.SQL.Add('select * from employee');
aqEmployee.Open;
DM.aqEmp.Close;
DM.aqEmp.SQL.Clear;
DM.aqEmp.SQL.Add('select * from employee');
DM.aqEmp.Open; Temp:= New(PIndexRecord);
Temp1:= New(PIndexRecord); FirstPointer:= Temp;
First:= Temp1; ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.text:='Select dep_id,dep From department where dep_id in ' + #13#10 +
'(select Min(dep_id) from department group by dep) ' + #13#10 +
'order by dep_id asc';
ADQ1.Open; if not ADQ1.Eof then
begin
TreeView1.AutoExpand := true;
TreeView1.ReadOnly := true;
Node0 := TreeView1.Items.AddFirst(nil, '公司机构[' + IntToStr(aqEmployee.RecordCount) + '人]');
end
else
Exit; SetLength(Node1, ADQ1.RecordCount); while not ADQ1.Eof do
begin
with dm.aqEmp do
begin
Filtered := false;
Filter := 'dep = ' + QuotedStr(adq1.FieldValues['dep']);
Filtered := true;
end;
Node1[Index1]:= TreeView1.Items.AddChild(Node0, ADQ1.FieldByName('dep').AsString+'[' + IntToStr(dm.aqEmp.RecordCount) + ']');
Node1[Index1].ImageIndex:= 0; ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM department WHERE dep = ''' + ADQ1.FieldByName('dep').AsString + '''');
ADQ2.Open; Index2:= 0;
if not ADQ2.IsEmpty then
begin
SetLength(Node2, ADQ2.RecordCount); while not ADQ2.Eof do
begin
Node2[Index2]:= TreeView1.Items.AddChild(Node1[Index1], ADQ2.FieldByName('sdep').AsString);
Node2[Index2].ImageIndex:= 0; Temp1.num:= ''; ??
Temp1.Dep_id:= ADQ2.FieldByName('dep_id').AsString; ?
Temp1.Code:= Node2[Index2]; ??
ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM employee WHERE dep_id = ''' + ADQ2.FieldByName('dep_id').AsString + '''');
ADQ3.Open; if not ADQ3.IsEmpty then
while not ADQ3.Eof do
begin
Temp.num:= ADQ3.FieldByName('num').AsString;
Temp.Dep_id:= ADQ3.FieldByname('dep_id').AsString;
Temp.Code:=
TreeView1.Items.AddChildObject(Node2[Index2], ADQ3.FieldByName('name').AsString,temp);
Temp.Code.ImageIndex:= 2;
ADQ3.Next;
Temp.Next:= New(PIndexRecord);
Temp:= Temp.Next;
end; Inc(Index2);
ADQ2.Next;
Temp1.Next:= New(PIndexRecord);
Temp1:= Temp1.Next;
end;
end; Inc(Index1);
ADQ1.Next; end;
ADQ1.Close;
ADQ2.Close;
ADQ3.Close;
LastPointer:= Temp;
Last:= Temp1;
TreeView1.Refresh; DataSource1.DataSet:= ADQ1;
DataSource2.DataSet:= ADQ2;
DataSource3.DataSet:= ADQ3;
DataSource4.DataSet:= ADQ4; for i := 0 to TreeView1.Items.Count - 1 do
if TreeView1.Items[i].Data <> nil then
begin
TreeView1.Selected := TreeView1.Items[i];
Exit;
end;
end;procedure TEmpForm.TreeView1Click(Sender: TObject);
var
Temp, Temp1: PIndexRecord;
Flag: Boolean; ??干吗用的
begin
Temp:= FirstPointer;
Temp1:= First;
Flag:= False; while Temp <> nil do
begin
if Temp.Code = TreeView1.Selected then
begin
Flag:= True; ??
Break;
end; Temp:= Temp.Next;
if Temp = LastPointer then
Break;
end; if Flag then
begin
ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp.num + '''');
ADQ1.Open;
LoadImage(ADQ1.FieldByName('Photo')); ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp.num + '''');
ADQ2.Open; ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp.num + '''');
ADQ3.Open; ADQ4.Close;
ADQ4.SQL.Clear;
ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp.num + '''');
ADQ4.Open; FNum:= Temp.num; ??
Fdep_id:= Temp.Dep_id; ??
end
else
begin
while Temp1 <> Last do
begin
if Temp1.Code = TreeView1.Selected then
begin
Flag:= True;
Break;
end; Temp1:= Temp1.Next;
end; if Flag then ??为什么要判断两次
begin
ADQ1.Close;
ADQ1.SQL.Clear;
ADQ1.SQL.Add('SELECT * FROM employee WHERE num = ''' + Temp1.num + '''');
ADQ1.Open; ADQ2.Close;
ADQ2.SQL.Clear;
ADQ2.SQL.Add('SELECT * FROM experience WHERE num = ''' + Temp1.num + '''');
ADQ2.Open; ADQ3.Close;
ADQ3.SQL.Clear;
ADQ3.SQL.Add('SELECT * FROM train WHERE num = ''' + Temp1.num + '''');
ADQ3.Open; ADQ4.Close;
ADQ4.SQL.Clear;
ADQ4.SQL.Add('SELECT * FROM behave WHERE num = ''' + Temp1.num + '''');
ADQ4.Open; FNum:= Temp1.num;
Fdep_id:= Temp1.Dep_id;
end;
end;end;
num: string;
Dep_id: string;
Code: TTreeNode; ?? //对应的节点
Next: PIndexRecord; ??//指向下一个节点
end;Temp1.num:= ''; ??这里就是上面定义的记录
Temp1.Dep_id:= ADQ2.FieldByName('dep_id').AsString; ?
Temp1.Code:= Node2[Index2]; ?? Flag: Boolean; ??干吗用的 用于标识是否是要第一个节点算了,你还是好好去看一下记录类型和指针这些知识吧
TIndexRecord = packed record //链表结点记录类型
num: string; //元素1 员工编号?
Dep_id: string; //元素2 部门编号
Code: TTreeNode; //元素3 对应的Treeview结点,TreeView结点的类型为TTreeNode
Next: PIndexRecord; //元素4 链表的下一个结点
end;这样做的目的就是为了当选中某个Treeview结点时,从链表FirstPointer,First中找对应结点的员工编号,并显示相关的信息。Flag表示是否在链表中找到相应TreeNode,找到为true。由于有两个链表,当然查找两次了。其实不用这样做,把树结点的信息,比如Num,dep_id等信息绑定到树结点的Data。点击的时候直接从Data取信息就可以了。比如:
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls;type
TNodeType = (ntUnknow, ntDepartment, ntSDepartment, ntEmployee);
PNodeAttr = ^TNodeAttr;
TNodeAttr = record
NodeType: TNodeType;
ID: string;
end;
TForm1 = class(TForm)
TreeView1: TTreeView;
procedure FormCreate(Sender: TObject);
procedure TreeView1Click(Sender: TObject);
private
{ Private declarations }
function NodeAttr(Node: TTreeNode): TNodeType;
public
{ Public declarations }
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
function AddNode(AType: TNodeType; AParent: TTreeNode;
const AID, AText: string): TTreeNode;
var
PAttr: PNodeAttr;
begin
New(PAttr);
PAttr^.NodeType := AType;
PAttr^.ID := AID;
Result := TreeView1.Items.AddChild(AParent, AText);
Result.Data := PAttr;
end;
var
Node: TTreeNode;
begin
Node := AddNode(ntDepartment, nil, '1', '部门');
Node := AddNode(ntSDepartment, Node, '10', '部门二');
AddNode(ntEmployee, Node, '123456', '员工一');
end;function TForm1.NodeAttr(Node: TTreeNode): TNodeType;
begin
if Assigned(Node) then
Result := PNodeAttr(Node.Data)^.NodeType
else
Result := ntUnknow;
end;procedure TForm1.TreeView1Click(Sender: TObject);
begin
with TreeView1 do
begin
if NodeAttr(Selected) = ntEmployee then
ShowMessage('ID:' + PNodeAttr(Selected.Data)^.ID);
end;
end;end.