Ttreeview控件的使用!(80分)

  • 主题发起人 主题发起人 Free_sky
  • 开始时间 开始时间
F

Free_sky

Unregistered / Unconfirmed
GUEST, unregistred user!
我有一个八层结构的树形图!用数据库里的(id)来标识节点!
要求在增加的时候,id的值根据制定好的规则来添加。然后用(dbgrid)显示出
刚加的记录来添加完其他的值!大概如下:这段代码有问题,请高手帮忙写一个!
增加节点的代码如下!请指点!
type
TTemp=record
vid:string;
vname:string;
end;
PTemp=^TTemp;

procedure TForm1.N4Click(Sender: TObject);
var
InsertNode,SelectNode:TtreeNode;
str,code:string;
ATemp:PTemp;
begin
treeview1.MultiSelect :=false;
SelectNode:=treeview1.Selected;
case SelectNode.Level of
0:
with query1 do
try
treeview1.Items.BeginUpdate;
InsertNode:=treeview1.Items.AddChild(treeview1.Selected,'Name');
treeview1.Items.EndUpdate;
treeview1.Selected.Expand(true);
insertNode.Focused:=true;
InsertNode.EditText ;
try
close;
sql.Clear;
SQL.Add('insert into TempMx(id,DB0) values (:vid,:vname) ');
ParambyName('vname').asstring:='0';
query3.Close;
query3.SQL.Clear;
query3.SQL.Add('select MAX(DISTINCT ID) AS Expr1 FROM TempMx WHERE ({ fn LENGTH(ID) } = 3)');
query3.Open;
if query3.FieldByName('Expr1').AsString='' then
begin
ParambyName('vid').asstring:='101';
end
else
begin
ParambyName('vid').AsString:=inttostr(strtoint(query3.FieldByName('Expr1').AsString)+1);
end;
ExecSql;
treeview1.Update;
query2.Close;
query2.SQL.Clear;
query2.SQL.Add('select * from TempMx where id="'+query1.ParambyName('vid').asstring+'" order by id');
query2.Open;
except
MessageDlg('增加新节点失败!',mtInformation,[mbOk],0);
end;
finally
free;
end;
1:
with query1 do
try
ATemp:=new(PTemp);
ATemp^.vid :=trim(fieldbyname('id').AsString);
code:=Ptemp(SelectNode.Data)^.vid;
treeview1.Items.BeginUpdate;
InsertNode:=treeview1.Items.AddChildObject(SelectNode,'Name',ATemp);
treeview1.Items.EndUpdate;
treeview1.Selected.Expand(true);
insertNode.Focused:=true;
InsertNode.EditText ;
try
close;
sql.Clear;
SQL.Add('insert into TempMx(id,DB1,SID) values (:vid,:vname,:id) ');
ParambyName('vname').asstring:='1';
ParambyName('id').AsString :=code;
query3.Close;
query3.SQL.Clear;
query3.SQL.Add('select MAX(DISTINCT ID) AS Expr1 FROM TempMx WHERE ({ fn LENGTH(ID) } = 6) AND (SUBSTRING(ID, 1, 3) = "'+code+'")');
query3.Open;
if query3.FieldByName('Expr1').AsString='' then
begin
ParambyName('vid').asstring:=code+'201';
end
else
begin
ParambyName('vid').AsString:=inttostr(strtoint(query3.FieldByName('Expr1').AsString)+1);
end;
ExecSql;
treeview1.Update;
query2.Close;
query2.SQL.Clear;
query2.SQL.Add('select * from TempMx where id like ("'+copy(code,1,3)+'"+"%") order by id');
query2.Open;
query2.edit;
except
MessageDlg('增加新节点失败!',mtInformation,[mbOk],0);
end;
finally
free;
end;
end;
。。。。。。
下面还有几层,大体一样!
 
with query1 do
try
......
try
......
except
......
end;
finally
free; // ?????????
end;

你把query1 free掉了? 怎么没见你创建query1的代码呀?
 
treeview的问题我已经回答了好多次
你可以查一下,
如果不行的话
我可以帮你
 
query1我是用来插入记录的!
to:tokey我解决不了啦,你帮我啊!
给我发程序也行!
fu-jun-luo2sina.com
谢谢
 
TreeView就那么几个方法,慢慢用吧
 
我来猜测一下你错误的情况:
你第一次选菜单插入成功
再选菜单插入出现access violation错误。 对不对呀?
我们来跟踪一下第二次选菜单时发生了什么:

procedure TForm1.N4Click(Sender: TObject);
var
InsertNode,SelectNode:TtreeNode;
str,code:string;
ATemp:PTemp;
begin
treeview1.MultiSelect :=false;
SelectNode:=treeview1.Selected;
case SelectNode.Level of
0: // 假设你第二次插入的仍然是0级
with query1 do
try
treeview1.Items.BeginUpdate;
InsertNode:=treeview1.Items.AddChild(treeview1.Selected,'Name');
treeview1.Items.EndUpdate;
treeview1.Selected.Expand(true);
insertNode.Focused:=true;
InsertNode.EditText ;
try
close; // 注意: 第一次调用时执行过query1.free了, 所以此地肯定出现access violation错误, 跳转到except部分
sql.Clear;
SQL.Add('insert into TempMx(id,DB0) values (:vid,:vname) ');
ParambyName('vname').asstring:='0';
query3.Close;
query3.SQL.Clear;
query3.SQL.Add('select MAX(DISTINCT ID) AS Expr1 FROM TempMx WHERE ({ fn LENGTH(ID) } = 3)');
query3.Open;
if query3.FieldByName('Expr1').AsString='' then
begin
ParambyName('vid').asstring:='101';
end
else
begin
ParambyName('vid').AsString:=inttostr(strtoint(query3.FieldByName('Expr1').AsString)+1);
end;
ExecSql;
treeview1.Update;
query2.Close;
query2.SQL.Clear;
query2.SQL.Add('select * from TempMx where id="'+query1.ParambyName('vid').asstring+'" order by id');
query2.Open;
except
MessageDlg('增加新节点失败!',mtInformation,[mbOk],0); // 会显示此信息
end;
finally
free; // 不管是否出错, 此句都执行, 调用的是query1.free, 再次产生access violation错误...
end;
....

我猜得对不对?
 
to:pear1
真的,是这个问题,不过这个解决了后还有个问题,也是你说的
access violation错误...,问题好象出在code:=Ptemp(SelectNode.Data)^.vid;
这里。
 
下面那段代码里漏了给insertnode.data分配内存了吧?
0:
with query1 do
try
treeview1.Items.BeginUpdate;
InsertNode:=treeview1.Items.AddChild(treeview1.Selected,'Name');
//// 应该加上下面几句吧?
InsertNode.Data := GetMem(SizeOf(TTemp));
with PTemp(InsertNode.Data)^ do
begin
vid := ?????;
vname := ??????;
end;
////
treeview1.Items.EndUpdate;
treeview1.Selected.Expand(true);
insertNode.Focused:=true;
InsertNode.EditText ;
try
close;
 
to pear1:
InsertNode.Data := GetMem(SizeOf(TTemp));
不能这样分配内存吧!
如果你在增加节点的时候,需要调用父节点的data你怎么做呢?
麻烦你了!
 
ATemp := New(PTemp);?
>>New(ATemp);
 
To:varphone
这没什么区别啊 !
 
---->InsertNode.Data := GetMem(SizeOf(TTemp));
---->不能这样分配内存吧!
为什么不能这样分配?

---->如果你在增加节点的时候,需要调用父节点的data你怎么做呢?
这也正是我想问你的呀。 根据你原来的代码, 父节点的data根本就是nil. 调用Ptemp(SelectNode.Data)^.vid;
当然会出错。

而现在我这段代码加在Level=0时, 也就是增加最高层节点时就分配好内存了。 后面增加节点至少访问0层父节点的data没问题。(具体后面几层增加节点的代码还没仔细看)
 
procedure GetMem(var P: Pointer; Size: Integer);
InsertNode不能这样得到内存。
有这样的一个error提示(Error creating cursor Handle)
指针我用的很少,现在都快晕了。
 
写错了:
应该是
insertnode.data := allocmem(SizeOf(TTemp));
 
to:Pear1
我根据您说的把程序改成如下,没有输入问题,也没有了讨厌的错误提示。
但是code还是没有值啊!急坏了。
1:
with query1 do
try
new(ATemp);
ATemp^.vid :=trim(fieldbyname('id').AsString);
SelectNode.Data:=allocmem(sizeof(TTemp));
code:=Ptemp(SelectNode.Data)^.vid;
showmessage(code);
treeview1.Items.BeginUpdate;
InsertNode:=treeview1.Items.AddChildObject(SelectNode,str,ATemp);
treeview1.Items.EndUpdate;
treeview1.Selected.Expand(true);
insertNode.Focused:=true;
InsertNode.EditText ;
try
close;
sql.Clear;
SQL.Add('insert into TempMx(id,DB1,名称) values (:vid,:vname,:id) ');
ParambyName('vname').asstring:='1';
ParambyName('id').asstring:=str;
query3.Close;
query3.SQL.Clear;
query3.SQL.Add('select MAX(DISTINCT ID) AS Expr1 FROM TempMx WHERE ({ fn LENGTH(ID) } = 6) AND (SUBSTRING(ID, 1, 3) = "'+code+'")');
query3.Open;
if query3.FieldByName('Expr1').AsString='' then
begin
ParambyName('vid').asstring:=code+'201';
end
else
begin
ParambyName('vid').AsString:=inttostr(strtoint(query3.FieldByName('Expr1').AsString)+1);
end;
ExecSql;
treeview1.Update;
query2.Close;
query2.SQL.Clear;
query2.SQL.Add('select * from TempMx where id like ("'+copy(code,1,3)+'"+"%") order by id');
query2.Open;
query2.edit;
except
MessageDlg('增加新节点失败!',mtInformation,[mbOk],0);
end;
finally
end;
 
多人接受答案了。
 
后退
顶部