我的代码如下:
 procedure tform3.showtree();
var
pnode1,pnode,curnode:ttreenode;
pcode,code,pname,name:string;
i,count,order:integer;
begin
 adoquery1.Close;
 adoquery1.SQL.Clear;
 adoquery1.SQL.Add('select a.*,b.* from 物料清单 a, 物料主文件 b');
 adoquery1.SQL.Add('where (a.物料编号=b.物料编号)');
 adoquery1.SQL.Add('order by a.低层码,a.父项编号');
 adoquery1.Open;
   while not adoquery1.Eof do
 begin
  pcode:=adoquery1.fieldbyname('父项编号').AsString;
  code:=adoquery1.fieldbyname('物料编号').AsString;
  name:=adoquery1.fieldbyname('物料名称').AsString;
  adoquery2.Close;
  adoquery2.SQL.Clear;
  adoquery2.SQL.Add('select 物料名称 from 物料主文件 where 物料编号='''+pcode+'''');
  adoquery2.Open;
  pname:=adoquery2.fieldbyname('物料名称').AsString;
  count:=treeview1.Items.Count;
  for i:=1 to count do
   begin
   pnode1:=treeview1.Items.Item[i-1];
     if (pnode1.Text=pname) then ///////////////问题在这里:这个条件好象不充分?才导致出现我下述的问题?/////////////
       begin
       //创建子节点
       pnode:=treeview1.Items.AddChild(pnode1,name);
       pnode.Expanded:=true;
       //根据创建顺序储存数据信息
       order:=order+1;
       mytable[order,1]:=pcode;
       mytable[order,2]:=code;
       mytable[order,3]:=name;
       //储存树节点的节点数据
       mynodetable[order]:=pnode;       end;
   end;
   //处理下一条记录
 adoquery1.Next;会出现如下的问题:如果在物料主文件里有两个编码不一样的,名称是同样的物料,显示在树上的结构
                  将会出现如下的问题:例如在物料主文件里有两个组件原料:
物料编号,物料名称           
112           我爱你          (注:这个是个组件)
333           我爱你        (注:这个只是个物料)
如果我想在树上显示 物料编号为  333这个物料信息时,它就显示112组件的信息给我,如果如何做才不会出现这种情况?是不是  if (pnode1.Text=pname) then  这个条件不充分?那如何解决?谢谢你们。在线等呀,再谢谢啦

解决方案 »

  1.   

    procedure TForm1.Button1Click(Sender: TObject); //给节点一个指针的记录类型。记录编号
    var
      i:integer;
      p:^string;
    begin
      for i := 0 to 2 do
      begin
        new(p);
        p^:=inttostr(i);
        treeview1.Items.AddObject(nil,'我爱你',p);
      end;
    end;procedure TForm1.TreeView1DblClick(Sender: TObject);//双击的时候显示编号
    var
      p:^string;
    begin
      p:=TreeView1.Selected.Data;
      showmessage(p^);
    end;
      

  2.   

    记得在关闭窗体、清空树或重新生成树的时候将节点的指针记录类型的内存给释放掉。
    procedure TForm1.cleartree(tree: TTreeview);
    var
      i:integer;
    begin
      for  i:=0 to tree.Items.Count-1 do
      begin
        if tree.Items[i].Data<>nil then
          Dispose(tree.Items[i].Data);
      end;
      tree.Items.Clear;
    end;
      

  3.   

    诶, hmzgz81(哩翱) ,你可能还不太看懂我的意思呀,请问你能否帮我改改我的代码吗?
    英雄,高手,谁能救我呀?
      

  4.   

    不就是意思嘛!!
       pnode1:=treeview1.Items.Item[i-1];
         if (pnode1.date=物品编号) then 你是不是根据树节点的string来确定是不是父节点,再在这个节点生成他的子树吗??改成用后台的指针记录类型(记录编号)来判断是不是你要的节点。
      

  5.   

    这位高手说的有点道理:但我不会,谁能帮他完善一下,也就是根据他的意思帮我改改我的代码呀,在线等……
    核心问题根本就不在这里count:=treeview1.Items.Count;pnode1:=treeview1.Items.Item[i-1];pnode:=treeview1.Items.AddChild(pnode1,name);组合起来就出错了。
    1、你首先获取了TreeView的总节点数,然后通过此进行循环
    2、但是当你插入一个节点后实际上Count已经发生变化,I实际也发生了变化,所以立即进入了死循环状态
    3、但是你采用的是Count控制,所以死循环马上跳出了,所以不容易发现解决方案
    1、通过while进行控制
    while I < TreeView.Items.Count do
    2、当找到一个条件插入一个节点后,I值加一
    3、另外,你最好通过Data控制数据,否则当物料名称重复的时候就乱套了