用数据表的记录构造树(似乎简单,可表是没规律的还要求效率)(100分)

  • 主题发起人 主题发起人 sky_liuwang
  • 开始时间 开始时间
S

sky_liuwang

Unregistered / Unconfirmed
GUEST, unregistred user!

以下是表:
JGID,JG_NAME,PARERT_ID,TAG
1,QQQ总部,0,1
2,BBBB,1,1
3,CCCC,1,1
5,CHANGE,1,1
8,BBBb,3,1
9,BBs,10,1
10,CCC,11,1
11,BBBbc,12,1
12,BBs,2,0
13,NILL_JG,3,1
14,NOT_JG,3,0
16,Bas,5,0
17,新机构sdgfs,3,0
18,新机构18,1,1
19,新机构19,20,1
20,新机构20,1,1
21,新机构21,20,1
-------------------------
说明:
tag为0时记录无效
PARERT_ID是指向上级JG(机构)的
JGID---(int)
JG_NAME,---(varchar)PARERT_ID----(int),TAG----(char)
微软SQL 2000 DBSERVER
_______________________
各位大侠!谁肯搭救小弟?急!急!急!(主要是子节点的记录可能出现在父节点之前)小弟愿请客或其他感谢方式,拜托各位!(人现在北京)
人员表如下:
MEMBER_ID,NAME,GS_ID,TAG,AGE,SEX
1,JACK,15,1 ,21,1
2,MICK1,15,1 ,22,2
3,ROSE,3,1 ,22,2
4,TOM,42,1 ,44,1
5,DILL,46,1 ,21,1
6,TOM,5,1 ,22,2
7,ROSE@,20,1 ,22,1
8,MICKSS,16,1 ,55,2
9,HOSF,30,1 ,34,3
10,MIKEWWWWWWW,5,1 ,28,
11,EEEE,3,1 ,99,
12,XXXXX,3,1 ,22,
13,新员工13,15,1 ,,
14,新员工14,32,1 ,,
15,新员工15,46,1 ,,
16,新员工ttt,23,0 ,,
17,GOOD,1,,22,
18,HOW,44,0 ,43,
19,新员工,42,1 ,,
20,新员工,20,1 ,,
21,新员工21,20,1 ,,
22,新员工,18,1 ,,
tab_jg(机构表)和(人员表)tab_mbr为主从表
热心的可改写我的代码:如下:
unit main;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, DB, DBTables, Grids, DBGrids, Menus;

type
TForm1 = class(TForm)
Tab_JG: TTable;
Tab_MBR: TTable;
Database1: TDatabase;
DataSource1: TDataSource;
DBGrid2: TDBGrid;
DataSource2: TDataSource;
DBGrid1: TDBGrid;
Tree: TTreeView;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
PopupMenu1: TPopupMenu;
ADDJG: TMenuItem;
ADDRY: TMenuItem;
N3: TMenuItem;
DELNODE: TMenuItem;
N5: TMenuItem;
EDITNODE: TMenuItem;
N7: TMenuItem;
UNITE: TMenuItem;
Label5: TLabel;
Label6: TLabel;
test1: TMenuItem;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure FormShow(Sender: TObject);
procedure TreeClick(Sender: TObject);
procedure ADDJGClick(Sender: TObject);
procedure EDITNODEClick(Sender: TObject);
procedure test1Click(Sender: TObject);
procedure TreeEdited(Sender: TObject; Node: TTreeNode; var S: String);
procedure TreeEditing(Sender: TObject; Node: TTreeNode;
var AllowEdit: Boolean);
procedure Button1Click(Sender: TObject);
procedure ADDRYClick(Sender: TObject);
procedure DELNODEClick(Sender: TObject);
procedure TreeDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure UNITEClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure CopyNodeUnder(treeview:TTreeview; sourcenode,targetnode:ttreenode; tab1,tab2:Ttable; B_UNITE:BOOLEAN=FALSE);
procedure NodeUnite(treeview:TTreeView; sourcenode,targetnode:ttreenode; tab1,tab2:TTable);
Function DelSelectNode(tree1:TTreeView;tab1,tab2:TTable; node1:TTreenode):TTreeNode;
Function FindNodeByID(T:TTreeView; id:integer):TTreeNode;
Function GetLastSiblingNode(CurrentNode:TTreeNode):TTreeNode;
end;

type
Pjg = ^Rcd_jg;
Rcd_jg = record
jgid:integer;
jg_name:string[50];
parert_id:integer;
//tag_jg:char;
role:char;//区别机构标记
mbr_id:integer;
name:string[50];
gs_id:integer;
//tag_mbr:char;
age:integer;
sex:integer;
end;


var
Form1: TForm1;
B_UNITE:BOOLEAN=FALSE;
//是否合并标志(控制拖动是否是合并操做当B_UNITE=true时开始合并操做
//由procedure TForm1.UNITEClick()控制
//在procedure Tform1.CopyNodeUnder()和procedure TForm1.TreeDragDrop()用到
implementation

{$R *.dfm}
//=========================================================================
{得到当前结点CurrentNode的下一层的最后一个结点的最末端的结点}

Function Tform1.GetLastSiblingNode(CurrentNode:TTreeNode):TTreeNode;
var
LastSiblingNode:TTreeNode;
begin
LastSiblingNode:=CurrentNode;
repeat
result:=LastSiblingNode;
LastSiblingNode:=LastSiblingNode.GetLastChild;
until LastSiblingNode=nil;
end;

//=========================================================================

procedure Tform1.CopyNodeUnder(treeview:TTreeview;sourcenode,targetnode:ttreenode;tab1,tab2:Ttable;B_UNITE:BOOLEAN=FALSE);
var
newnode:ttreenode;
i:integer;
begin
if B_UNITE=false then
begin
newnode:=treeview.items.addchildfirst(targetnode,''); //建立目标项
newnode.assign(sourcenode); //复制源项属性并替换掉上边的newnode;
for i:=sourcenode.count-1 downto 0 do //递归调用,按倒序移动其所有子项
CopyNodeUnder (treeview,sourcenode.item,newnode,tab1,tab2,B_UNITE);
showmessage(sourcenode.Text);
treeview.items.delete(sourcenode); //删除源项
end
else begin
NodeUnite(treeview,sourcenode,targetnode,tab1,tab2);
end;
//注意:在此过程调用返回之处后使B_UNITE标志归位即B_UNITE:=FALSE;
end;

//=========================================================================

procedure Tform1.NodeUnite(treeview:TTreeView; sourcenode,targetnode:ttreenode; tab1,tab2:TTable);
var
newnode:TTreenode;
Item_index_begin,item_index_end:integer;
i:integer;

begin
Item_index_begin:=sourcenode.AbsoluteIndex; //得到选中结点的绝对索引号
item_index_end:=GetLastSiblingNode(sourcenode).AbsoluteIndex;//调用GetLastSiblingNode()返回末端结点
for i:=0 to sourcenode.Count-1 do //修改数据ip
begin
if pjg(sourcenode.Item.Data)^.role='j' then
begin
//注意:此处targetnode接受的一定是机构结点而sourcenode则不一定sourcenode.Item更不确定
pjg(sourcenode.Item.Data)^.parert_id:=pjg(targetnode.Data)^.jgid;
end
else begin
pjg(sourcenode.Item.Data)^.gs_id:=pjg(targetnode.Data)^.jgid;
end;
end;

if sourcenode.AbsoluteIndex < targetnode.AbsoluteIndex then
begin
for i:=Item_index_begin+1 to Item_index_end do //添加结点;注意:循环到Item_index_begin+1目的是过滤掉拖动时选中的哪个结点
begin
newnode:=treeview.items.addchildfirst(targetnode,''); //建立目标项
newnode.assign(treeview.Items); //复制源项属性并替换掉上边的newnode;
end;
end
else begin
for i:=Item_index_begin+1 to Item_index_end do //添加结点;注意:循环到Item_index_begin+1目的是过滤掉拖动时选中的哪个结点
begin
newnode:=treeview.items.addchildfirst(targetnode,''); //建立目标项
newnode.assign(treeview.Items[i+1]); //复制源项属性并替换掉上边的newnode;
end;
end;

//showmessage(sourcenode.Text);
treeview.items.delete(sourcenode);

//###############添加此结点使数据库无效 //该ip
end;

//=========================================================================
{ 此函数是删除结点 注意:进行递归调用时node1接受了childnode参数 }

Function TForm1.DelSelectNode(tree1:TTreeView;tab1,tab2:TTable; node1:TTreenode):TTreeNode;
var
childnode:TTreenode;
Item_index_begin,item_index_end:integer;
i:integer;//循环变量
//1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
begin
Item_index_begin:=node1.AbsoluteIndex; //得到node1选中结点)的绝对索引号
childnode:=node1.GetLastChild; //按倒序获得子结点//注意:可能此结点没有子点此时childnode=nil
item_index_end:=node1.AbsoluteIndex;//注:此时的node1就是(选中结点)的最后子层的最后子结点
while childnode<>nil do
begin
//item_index_end:=childnode.AbsoluteIndex;//得到node1(选中结点)的最后子层的最后子结点的绝对索引号
childnode:=DelSelectNode(tree1,tab1,tab2,childnode); //如子项不为空,进行递归调用
end;

for i:=item_index_end downto Item_index_begin do
//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
begin
//3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if pjg(tree1.Items.Data)^.role='j' then //判断结点类型role='j'是机构
begin
//4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
try
tab_jg.Open;
tab_jg.First;
tab_jg.MoveBy(pjg(node1.Data)^.jgid-1);
tab_jg.Edit;
tab_jg.FieldByName('tag').AsString:='0';
tab_jg.Post;
finally
//######################等待处理
end;//4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
else begin//以下处理结点类型role='r'即设置人员结点的数据表标志tag=0为失效
try
tab_mbr.Active:=TRUE;
//以下三句是取消tab_mbr与tab_jg的关联关系以便使moveby顺利定位tab_mbr记录
tab_mbr.MasterSource:=nil;
tab_mbr.MasterFields:='';
tab_mbr.IndexFieldNames:='member_id';
tab_mbr.First;
tab_mbr.MoveBy(pjg(node1.Data)^.mbr_id-1);//定位tab_mbr中要编辑的记录
tab_mbr.Edit;
tab_mbr.FieldByName('tag').AsString:='0';
tab_mbr.Post;
finally
//######################等待处理
end;
end;//3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

end;//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
result:=node1.parent.GetPrevChild(node1); //定位到该节点的上一节点
node1.delete; //删除树节点

end;//1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

//=========================================================================
{用于查找父结点的孩子在procedure TForm1.FormShow(Sender: TObject);被中调用}

Function TForm1.FindNodeByID(T:TTreeView; id:integer):TTreeNode;
var i:integer;
begin
result:=nil;
for i:=0 to T.Items.Count-1 do
if integer(pjg(T.Items.Data)^.jgid)=id then
begin
result := T.Items;
exit;
end;
end;
//=========================================================================

procedure TForm1.FormShow(Sender: TObject);
var
ParentNode,Node,Node2 : TTreeNode;
i:integer;//循环变量
Pdw:Pjg; //TREE上的组织结点指针
//Pry:pmbr;//TREE上的人员结点指针
begin
Tab_JG.Active:=TRUE;
Tab_MBR.Active:=TRUE;
Tab_JG.first;
Tab_MBR.First;
while not Tab_JG.eof do
begin
if Tab_JG.FieldByName('TAG').AsString='1' then //过滤掉数据表中被禁止的记录
begin
new(pdw);
pdw^.jgid:=Tab_JG.FieldByName('JGID').asInteger;
pdw^.jg_name:=Tab_JG.FieldByName('jg_name').AsString;
pdw^.parert_id:=tab_jg.fieldByName('PARERT_ID').AsInteger;
pdw^.role:='j'; //机构与人员的标志,j表示此结点是机构结点
ParentNode:=FindNodeByID(Tree,Tab_JG.FieldByName('parert_id').asInteger);
Node:=Tree.items.AddChildObject(ParentNode,Tab_JG.FieldByName('JG_NAME').asString,pdw);
for i:=0 to Tab_MBR.RecordCount-1 do
begin
if Tab_MBR.FieldByName('TAG').AsString='1' then //过滤掉数据表中被禁止的记录
begin
new(pdw);
pdw^.role:='r'; //机构与人员的标志,r表示此结点是人员结点
pdw^.mbr_id:=Tab_mbr.fieldbyname('member_id').AsInteger;
pdw^.name:=Tab_mbr.fieldbyname('name').AsString;
pdw^.gs_id:=Tab_mbr.fieldbyname('gs_id').AsInteger;
pdw^.age:=Tab_mbr.fieldbyname('age').AsInteger;
pdw^.sex:=Tab_mbr.FieldByName('sex').AsInteger;
Node2:=Tree.items.AddChildObject(node,Tab_MBR.FieldByName('NAME').asString,pdw);
//Tab_MBR.Next;
end;
Tab_MBR.Next; //注意:此句一定在if Tab_MBR.FieldByName('TAG').AsString<>'0' then外边
end;
end;
Tab_JG.Next;
end;
Tab_JG.first;
end;
//=========================================================================
{TREE信息的输出}

procedure TForm1.TreeClick(Sender: TObject);
var
node:Ttreenode;
begin
node:=tree.Selected;
if pjg(node.Data)^.role='j' then
begin
label3.Caption:='您选中的机构信息如下:';
label1.Caption:='机构序号: '+inttostr(pjg(node.Data)^.jgid);
label2.Caption:='机构名称: '+pjg(node.Data)^.jg_name;
label4.Caption:='上级机构序号: '+ inttostr(pjg(node.Data)^.parert_id);
label5.Caption:=''; //清空员工输出信息
Label6.Caption:='';
end else
if pjg(node.Data)^.role='r' then
begin
label3.Caption:='您选中的员工信息如下:';
label1.Caption:='姓名:'+pjg(node.Data)^.name;
//在MEMBER数据表中1代表男2代表女nill(sql中nill=0)及其他代表性别不明;
if pjg(node.Data)^.sex=2 then
label2.Caption:='女'
else if pjg(node.Data)^.sex=1 then
label2.Caption:='男'
else
label2.Caption:='性别不明';

label4.Caption:='年龄:'+inttostr(pjg(node.Data)^.age);
label5.Caption:='员工ID:'+inttostr(pjg(node.Data)^.mbr_id);
label6.Caption:='归属ID:'+inttostr(pjg(node.Data)^.gs_id);
end;
end;

//=========================================================================

procedure TForm1.ADDJGClick(Sender: TObject);
var
node:Ttreenode;
padd:Pjg;
index:integer;

begin
node:=tree.Selected;
new(padd);
if pjg(node.Data)^.role='j' then
begin
try
tab_jg.Open;
tab_jg.Last;
index:=tab_jg.FieldByName('jgid').asinteger;
tab_jg.Append;
Tab_JG['jgid']:=index+1;
Tab_JG.FieldByName('jg_name').AsString:='新机构';
Tab_jg.FieldByName('PARERT_ID').AsInteger:=pjg(node.Data)^.jgid;//得到选中结点的JGID就是增加结点的PARERT_ID
tab_jg.FieldByName('tag').AsString:='1';
tab_jg.Post;
padd^.jgid:=Tab_JG.FieldByName('JGID').asInteger;
padd^.jg_name:=Tab_JG.FieldByName('jg_name').AsString;
padd^.role:='j'; //机构与人员的标志,j表示此结点是机构结点
tree.Selected:=tree.Items.AddChildObject(node,'新机构',padd);
except
showmessage('sorry!Error');//####################待处理
end;
end else
showmessage('您只能在机构结点下增加新机构结点');

end;

//=========================================================================
{添加人员结点}
procedure TForm1.ADDRYClick(Sender: TObject);
var
node:Ttreenode;
paddry:Pjg;
index:integer;

begin
node:=tree.Selected;
new(paddry);
if pjg(node.Data)^.role='j' then
begin
try
tab_mbr.Open;
tab_mbr.MasterSource:=nil; //以下三句是取消tab_mbr与tab_jg的关联关系
tab_mbr.MasterFields:='';
tab_mbr.IndexFieldNames:='member_id';
Tab_mbr.Last;
index:=Tab_mbr.FieldByName('member_id').asinteger;
Tab_mbr.Append;
Tab_mbr['member_id']:=index+1;
Tab_mbr.FieldByName('name').AsString:='新员工';
Tab_mbr.FieldByName('GS_ID').AsInteger:=pjg(node.Data)^.jgid;//得到选中结点的JGID就是增加结点的PARERT_ID
Tab_mbr.FieldByName('tag').AsString:='1';
//Tab_mbr.FieldByName('SEX').AsString:='1';
Tab_mbr.Post;
paddry^.mbr_id:=Tab_mbr.FieldByName('member_id').asInteger;
paddry^.name:=Tab_mbr.FieldByName('name').AsString;
paddry^.role:='r'; //机构与人员的标志,r表示此结点是人员结点
tree.Selected:=tree.Items.AddChildObject(node,'新员工',paddry);
except
showmessage('sorry!Error');//++++++++++
end;
end else
showmessage('您只能在机构结点下增加人员结点');
end;

//=========================================================================


procedure TForm1.DELNODEClick(Sender: TObject);
var
sel_node:TTreeNode;
begin
sel_node:=tree.Selected;
if sel_node=tree.Items[0] then
MessageDlg('不允许删除此结点!',mtInformation,[mbyes],0)
else
if MessageDlg('确定删除吗? ' ,mtConfirmation, [mbYes, mbNo], 0) = mrYes then
DelSelectNode(tree,tab_jg,tab_mbr,sel_node);

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@
{-------------------------------------------------------------------------------
//1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if sel_node.HasChildren then
DelSelectNode(tree,tab_jg,tab_mbr,sel_node)
//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else begin
if pjg(sel_node.Data)^.role='j' then //判断结点类型role='j'是机构
begin
//3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
try
tab_jg.Open;
tab_jg.First;
tab_jg.MoveBy(pjg(sel_node.Data)^.jgid-1);
tab_jg.Edit;
tab_jg.FieldByName('tag').AsString:='0';
tab_jg.Post;
sel_node.Delete;
finally
//######################等待处理
end;//3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end
else begin//以下处理结点类型role='r'即设置人员结点的数据表标志tag=0为失效
try
tab_mbr.Active:=TRUE;
//以下三句是取消tab_mbr与tab_jg的关联关系以便使moveby顺利定位tab_mbr记录
tab_mbr.MasterSource:=nil;
tab_mbr.MasterFields:='';
tab_mbr.IndexFieldNames:='member_id';
tab_mbr.First;
tab_mbr.MoveBy(pjg(sel_node.Data)^.mbr_id-1);//定位tab_mbr中要编辑的记录
tab_mbr.Edit;
tab_mbr.FieldByName('tag').AsString:='0';
tab_mbr.Post;
sel_node.Delete;
finally
//######################等待处理
end;
end;//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

end;//1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--------------------------------------------------------------------------------}
end;


//=========================================================================


procedure TForm1.EDITNODEClick(Sender: TObject);
var
node:Ttreenode;
begin
node:=tree.Selected;
node.EditText;
end;

//=========================================================================

procedure TForm1.test1Click(Sender: TObject);
var
node:Ttreenode;
begin
node:=tree.Selected;
pjg(node.Data)^.jg_name:='xxxxxxxxxxxxxxxxxxxxxxxx';
end;

//=========================================================================


procedure TForm1.TreeEdited(Sender: TObject; Node: TTreeNode;
var S: String);
begin
try
if pjg(node.Data)^.role='j' then
begin
tab_jg.Open;
tab_jg.First;//+++++++++
//pjg(node.Data)^.jgid
tab_jg.MoveBy(pjg(node.Data)^.jgid-1);
tab_jg.Edit;
tab_jg.FieldByName('jg_name').AsString:=s;
tab_jg.Post;
pjg(node.Data)^.jg_name:=s;
end
else begin //##############################################################
tab_mbr.Active:=TRUE;
//tab_jg.Close; //以下三句是取消tab_mbr与tab_jg的关联关系以便使moveby顺利定位tab_mbr记录
tab_mbr.MasterSource:=nil;
tab_mbr.MasterFields:='';
tab_mbr.IndexFieldNames:='member_id';
tab_mbr.First;
tab_mbr.MoveBy(pjg(node.Data)^.mbr_id-1);//定位tab_mbr中要编辑的记录
tab_mbr.Edit;
tab_mbr.FieldByName('Name').AsString:=s;
tab_mbr.Post;
pjg(node.Data)^.name:=s; //使TREE结点的信息也同时改变
end;
except
s:=node.Text; //保证异常时结点恢复原样
if pjg(node.Data)^.role='j' then //以下保证树上的结点data信息恢复原样
pjg(node.Data)^.jg_name:=node.Text
else
pjg(node.Data)^.name:=node.Text;

end;
//label5.Caption:=pjg(node.Data)^.jg_name;
//label6.Caption:=pjg(node.Data)^.name;
end;

//=========================================================================

procedure TForm1.TreeEditing(Sender: TObject; Node: TTreeNode;
var AllowEdit: Boolean);
begin
allowedit:=true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
IF B_UNITE THEN
SHOWMESSAGE('TRUE')
ELSE
SHOWMESSAGE('FLASE');

end;


//=========================================================================

procedure TForm1.TreeDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
var
targetnode,sourcenode:TTreenode;
begin
targetnode:=tree.getnodeat(x,y);
if (Source=Sender) and (targetnode<>nil) then //保证移动在TreeView上,且目标节点不为空
begin
Accept:=true;
sourcenode:=tree.selected;
//以下代码防止用户将一个选项拖到其子项上(它会随着选项一起移动,导致死循环)
while (targetnode.parent<>nil) and (targetnode <> sourcenode) do
targetnode:=targetnode.parent;
if (targetnode = sourcenode) then Accept:=false;
end else
Accept:=false;
end;

//=========================================================================


procedure TForm1.TreeDragDrop(Sender, Source: TObject; X, Y: Integer);
var
targetnode,sourcenode:TTreenode;
//0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
begin
targetnode:=tree.getnodeat(x,y); //获得目标点
sourcenode:=tree.selected; //获得源结点
//showmessage('tree.selected'+sourcenode.Text);
//showmessage('tree.getnodeat(x,y): '+targetnode.Text);
//以下开始修改数据库当前结点的父结点号parent_id,gs_id使其等目标节点标识号;
//注意:在结点落下的过程中只须改变源结点sourcenode的上级机构ID(parert_id)
//或归属ID(gs_id)号即可(包括相应的指针)其子结点这些内容不变故数据表不变
//相应的指针数据由函数copynodeunder复制他们的结点的所有属性
//1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (B_UNITE=false) and (pjg(targetnode.Data)^.role='j') then
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
begin

if pjg(sourcenode.Data)^.role='j' then
begin
//开始修改jg表父节点号parent_id及相应的指针
try
tab_jg.Open;
tab_jg.First;//+++++++++
//pjg(sourcenode.Data)^.jgid
tab_jg.MoveBy(pjg(sourcenode.Data)^.jgid-1); //定位tab_jg表中要修改的记录
//以下两句修改tab_jg表使当前结点的parert_id等于目标结点的jgid
tab_jg.Edit;
tab_jg.FieldByName('parert_id').AsInteger:=pjg(targetnode.Data)^.jgid;
tab_jg.Post;
//修改选中节点parent_id的相应的指针内容
pjg(sourcenode.Data)^.parert_id:=pjg(targetnode.Data)^.jgid;
except
showmessage('sorry!ERROR');//####################待处理
end;
end
//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else begin
//开始修改member表gs_id及相应的指针
if pjg(targetnode.Data)^.role<>'r' then
//3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
begin
try
tab_mbr.Active:=TRUE;
//以下三句是取消tab_mbr与tab_jg的关联关系以便使moveby顺利定位tab_mbr记录
tab_mbr.MasterSource:=nil;
tab_mbr.MasterFields:='';
tab_mbr.IndexFieldNames:='member_id';
tab_mbr.First;
tab_mbr.MoveBy(pjg(sourcenode.Data)^.mbr_id-1);//定位tab_mbr表中要修改的记录
tab_mbr.Edit;
tab_mbr.FieldByName('gs_id').AsInteger:=pjg(targetnode.Data)^.jgid;
tab_mbr.Post;
//使选中节点gs_id的相应的指针内容的信息也同时改变
pjg(sourcenode.Data)^.gs_id:=pjg(targetnode.Data)^.jgid;
except
showmessage('sorry!ERROR');//####################待处理
end;
end //3~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else begin
//##################待处理结点显示问题(不用管相应的指针信息)
showmessage('SORRY!您不能把人员结点拖放到另一个人员结点下!');
end;//4~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
end;//2~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tree.items.beginupdate; //修改数据库当前结点的父结点号parent_id,gs_id使其等目标节点标识号结束准备启动移动过程
try
copynodeunder(tree,sourcenode,targetnode,tab_jg,tab_mbr,B_UNITE); //启动移动过程
tree.selected:=targetnode;
finally
tree.items.endupdate; //重新设置
B_UNITE:=FALSE;//调用Tform1.CopyNodeUnder过程返回之后使是否合并标志B_UNITE归位
end;

end //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
else if B_UNITE and (pjg(targetnode.Data)^.role='j') then //合并机构的情况
begin
tree.items.beginupdate; //准备启合并的动移动过程修改数据库当前结点的父结点号parent_id,gs_id在copynodeunde中调用NodeUnite过程来完成
try
copynodeunder(tree,sourcenode,targetnode,tab_jg,tab_mbr,B_UNITE); //启动移动过程
tree.selected:=targetnode;
finally
tree.items.endupdate; //重新设置
B_UNITE:=FALSE;//调用Tform1.CopyNodeUnder过程返回之后使是否合并标志B_UNITE归位
end;
end
else
showmessage('SORRY!不能完成此操作!可能是您操作有误'+#13#10+'您只能将人员或机构结点拖动到另外的机构结点下');

end;//0~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

procedure TForm1.UNITEClick(Sender: TObject);
begin
B_UNITE:=TRUE;//打开合并开关使拖动变为合并
end;

procedure TForm1.Button2Click(Sender: TObject);
var
node:Ttreenode;
begin
label1.Caption:=inttostr(tree.Selected.AbsoluteIndex);
node:=getlastSiblingnode(tree.Selected);
showmessage(node.Text);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
showmessage(inttostr(tree.Selected.count));
showmessage(Tree.Selected.Item[0].Text);
end;

end.
 
后退
顶部