上一次发过一个相关贴子,不知道为什么,老是运行不成功,
今天再发,可用分就是浮云,能学会东西才是真的,放100分,不够再加!我有两个表,一个为用户资料表,另一个为用户所在地区表,
比如这个用户是西安地区的,另一个用户为北京地区的
在TreeView中Item显示地区类别
SubItem显示该地区下所有记录用户的姓名。右边的DBEdit中显示的用户资料为左边SubItem选中的,请问怎么做,有人能详细讲一下吗?有代码的请麻烦你注释一下,越清楚越好!谢谢

解决方案 »

  1.   

    看一下Master delphi6上面有讲到类似的使用。
      

  2.   


    typeTNodeData=record
      kind:integer;
      ID:string; 
    end;
    PNodeData=^TNodeData;
    ...
    // 用户表 A,地区表 Bprocedure InitTreeView;
    var
      p:PNodeData;
      Node:TTreeNode;
    begin
    // 此处最好用两个临时TQuery
       OpenTable(B);//打开地区表数据集  
       OpenTable(A);//打开用户表数据集
       A.filtered:=true;//设置用户表数据集的过滤属性
       B.first;
       while not B.eof do
       begin
         new(p);
         p^.kind:=0;
         p^.ID:=B.ID;//地区编码
         Node:=TreeView1.Items.AddChildObject(nil,B.Name,p);
         A.filter:='地区编码='''+B.ID+''''; //过滤条件
         A.first;
         while not A.eof do
         begin
           new(p);
           p^.kind:=1;
           p^.ID:=A.ID;//人员编码
           TreeView1.Items.AddChildObject(Node,A.Name,p);      
           A.next;
         end;
         B.next;
       end;  
    end;// 在TreeView1的onChanger事件中
    procedure TreeView1Change(Sender: TObject; Node: TTreeNode);
    var
      p:PNodeData;
    begin
      if Node=nil then
        exit;
      p:=PNodedata(Node.data);
      //过滤人员表数据集
      case p^.kind of 
       0:  A.filter:='地区编码='''+p^.ID+'''';
       1:  A.filter:='人员编码='''+p^.ID+'''';  
       end;
    end;
    // 最后在Form 的OnDestroy事件中释放内存 Node.data
    procedure TForm1.FormDestroy(Sender: TObject);
     
    begin
      //...
      
    end;
      

  3.   

    程序:http://www.xmflyfish.com/awind/apermis.exe
    源码:http://www.xmflyfish.com/awind/permis.rar
    里面有你所需要的:部门表相当于你的地区表,员工表相当于你的人员表,看看吧...
      

  4.   

    首先定义一个保存地区(City)和和客户(Client)编号的数组:id:array[0..400]of String;
    用来依次保存编号.
    有下面两个表:
     table City(city_code,city_name)
     talbe Client(client_code,client_name,city_code)procedure Tfrm_city.LoadTree;//此函数用来装载所有节点到TreeView
    var
        CityNode,ClientNode:TTreeNode;
        sqlstr:string;
        id:integer;
    begin
        screen.Cursor:=crHourGlass;
        id:=0;
        TreeView.Items.Clear;//清空树
        ADO.Active:=false;//打开地区表
        ADO.CommandText:='select * from City';
        ADO.Active:=true;
        while not ADO.Eof do
        begin
            CityNode:=TreeView.Items.AddChild(nil,ADO.FieldValues['City_Name']);//添加地区名称
            CityNode.Selected;//使该节点被选中
            id[id]:=ADO.FieldValues['City_code'];//地区节点加入编号
            id:=id+1;
    //查找该编号下的所有客户
            sqlstr:='select * from Client where  City_code='''+ADO.FieldValues['City_code']+'''';
            ADOClient.Active:=false;
            ADOClient.CommandText:=sqlstr;
            ADOClient.Active:=true;
            while not ADOClient.Eof do//添加所有City_Name的子节点
            begin
               //添加客户节点,父节点为CityNode
                WorkNode:=TreeView.Items.AddChild(CityNode,ADOClient.FieldValues['Client_name']);
        //将Client_code的编号记入id数组
                id[id]:=ADOchild.FieldValues['Client_code'];
                id:=id+1;
                ADOClient.Next;
            end;
            ADO.Next;
        end;
        ADO.Close;
        ADOClient.Close;
        screen.Cursor:=crdefault;
    end;
    //下面的过程用来使右边的TDBEdit变化的代码
    procedure Tfrm_code.TreeViewChange(Sender: TObject; Node: TTreeNode);
    var
        level,index:integer;
        No:string;
    begin
        Screen.Cursor:=crHourGlass;
        //下面这行是关键,用来取得节点在树中的绝对编号,正好和id[i]编号对应
        index:=TreeView.Selected.AbsoluteIndex;
        level:=TreeView.Selected.Level;//用来取得级数
        No:=id[index];
        //0表示点击的是City一级,1就是Client一级
        case level of
        0:  begin //ADO_City应该和右边的控件关联
                ADO_City.Active:=false;
                ADO_City.CommandText:='select * from City where City_code='''+id+'''';
                ADO_City.Active:=true;
        //下面是使用了一个PageControl控件,有两个Page,分别用来显示City和Client中的数据
                Tab_City.TabVisible:=TRUE;
                Tab_Client.TabVisible:=FALSE;
            end;
        1: begin
                ADO_Client.Active:=false;
                ADO_Client.CommandText:='select * from City where City_code='''+id+'''';
                ADO_Client.Active:=true;
                Tab_City.TabVisible:=FALSE;
                Tab_Client.TabVisible:=TRUE;
             end;    end;
        screen.Cursor:=crDefault;
    end;
    此程序我在Delphi中测试过,你可以直接用.
      

  5.   

    天上飞,xingyu(海) 已经实现了,你照着写不行吗?我那个也是这样实现的;你用两个ADOQuery去查,第一ADOQuery1个查地区,查出来的结果循环写入树做为一级节点;然后在这个循环中,再根据地区为条件用ADOQuery2查循出此地区数据,以当前地区为父节点循环加入子节点;若ADOQuery2主键为ID,可不必定义一个结构指针来实现,用一个sId: PString来定义,然后在第二级循环中用AddChildObject加入节点,比如:
            //这里Nodep为第一级添加的子节点,例子里DrawTree中有使用。
            for j := 0 to aqM02.RecordCount - 1 do
            begin 
              New(sId);
              sId^. := aqM02.FieldByName('sNo').AsString;
              tvPer.Items.AddChildObject(Nodep, aqM02.FieldByName('name').AsString, sId);
              aqM02.Next;
            end;
    这样就在所加的节点之data中存入了这个sId号;你在树的OnChange及OnClick中判断其data是否为nil,若不为nil则取其值,以此为键再查子表就可以实现了。
    ...
    取其值时如在OnChange及OnClick中处理:
        if tvPer.Selected.Data <> nil then
        begin
          sId := String(tvPer.Selected.Data^);
          //然后你可据此sId来操作了
          ....
        end;
    多试几次,祝好运!