一个表结构记录如下.
ID(Int +) ParId(Int) Name (varchar) Type (Varchar)
  1          0         总电表         电表
  2          0         总水表         水表
  3          1         分电表1        
  4          1         分电表2        
  5          3         用户表         
实现如下树结构:
   |--电表
   |    |--总电表
   |        |
   |        |-分电表1
   |        |     |---用户表
   |        |      
   |        |-分电表2
   |
   |--水表--总水表
目的:
   系统目前只要有两个类型的表(电表和水表)所以首节点可以固定
   二级节点,(PARID=0)
   三级以下的节点,就是以ID和PARID的关系来对应的.
如果得到以上的树结构呢...

解决方案 »

  1.   

    用节点的data属性,存储该节点的唯一id,具体实现,只要有父亲节点的id,使用递归,不用管层次,移动后只要把当前节点的父节点更新即可:自己写的程序中的一段,参考一下吧
    type
      pstr=^string;
      Tmainfrm = class(TForm)
        ClientDataSet1: TClientDataSet;
        DataSource1: TDataSource;
        ClientDataSet2: TClientDataSet;
        DataSource2: TDataSource;
        pnl_back: TPanel;
        pnl_hand: TPanel;
        Label2: TLabel;
        Panel1: TPanel;
        Label3: TLabel;
        Label4: TLabel;
        Label5: TLabel;
        BitBtn2: TBitBtn;
        DateTimePicker1: TDateTimePicker;
        DateTimePicker2: TDateTimePicker;
        pnl_data: TPanel;
        DBGrid2: TDBGrid;
        pnl_left: TPanel;
        TreeView1: TTreeView;
        Panel2: TPanel;
        Panel3: TPanel;
        Panel4: TPanel;
        pnl_top_main: TPanel;
        lb_caption2: TLabel;
        lb_caption: TLabel;
        pnl_color: TPanel;
        pnl_color2: TPanel;
        pnl_color3: TPanel;
        ClientDataSet3: TClientDataSet;
        ClientDataSet4: TClientDataSet;
        Splitter2: TSplitter;
        Splitter1: TSplitter;
        Panel5: TPanel;
        MainMenu2: TMainMenu;
        N1211: TMenuItem;
        M1: TMenuItem;
        N1: TMenuItem;
        H1: TMenuItem;
        Label1: TLabel;
        ToolBar1: TToolBar;
        ClientDataSet5: TClientDataSet;
        SocketConnection1: TSocketConnection;
        N2: TMenuItem;
        N3: TMenuItem;
        DataSource3: TDataSource;
        ImageList1: TImageList;
        ImageList2: TImageList;
        ImageList3: TImageList;
        procedure BitBtn1Click(Sender: TObject);
        procedure FormShow(Sender: TObject);
        procedure TreeView1Click(Sender: TObject);
        procedure N3Click(Sender: TObject);
        procedure TreeView1Expanded(Sender: TObject; Node: TTreeNode);
        procedure TreeView1Collapsed(Sender: TObject; Node: TTreeNode);
      private
        procedure genallcustomer(var i_level:integer);
        function initial:boolean;
        { Private declarations }
      public
        { Public declarations }
      end;var
      mainfrm: Tmainfrm;
      cus_str:string;
    implementationuses person;{$R *.dfm}
    function Tmainfrm.initial:boolean;
    begin
      self.DateTimePicker1.DateTime:=now;
      self.DateTimePicker2.DateTime:=now;
    end;
    procedure Tmainfrm.genallcustomer(var i_level:integer);
    var
      TNode:TTreeNode;
      TFistrNode:TTreeNode;
      TregionNode:TTreeNode;
      I,J:Integer;
      Fid,Fregion,Fname:string;
      P:pstr;
    begin
      With self.ClientDataSet3 Do
      Begin
        Close;
        CommandText:='SELECT Customer_Name,Region,Customer_No FROM Customer WHERE Customer_Level=:var1';
        Params.ParamByName('var1').Value:='1';
        Try
          open;
        Except
        End;
      End;
        TFistrNode:=self.TreeView1.Items.AddChild(nil,'中鑫公司客户列表');
        Fid:='000000';
        Fname:='中鑫公司';
        new(p);
        p^:=Fid;
        TregionNode:=self.TreeView1.Items.AddChildObject(TFistrNode,Fname,p);
      For I:=0 To self.ClientDataSet3.RecordCount-1 Do
      Begin    Fid:=self.ClientDataSet3.Fields[2].Value;
        Fregion:=self.ClientDataSet3.Fields[1].Value;
        Fname:=self.ClientDataSet3.Fields[0].Value;
        new(p);
        p^:=Fid;
        TregionNode:=self.TreeView1.Items.AddChildObject(TFistrNode,Fname,p);
        With self.ClientDataSet4 Do
        Begin
          Close;
          commandtext:='SELECT Customer_Name,Region,Customer_No FROM Customer WHERE     Region=:var1 and Customer_Level<>:var2';
          Params.ParamByName('var1').Value:=Fregion;
          Params.ParamByName('var2').Value:='1';
          Try
            open;
          Except
          End;
          For J:=0 To self.ClientDataSet4.RecordCount-1 Do
          Begin
            Fid:=self.ClientDataSet4.Fields[2].Value;
            Fname:=self.ClientDataSet4.Fields[0].Value;
            new(p);
            p^:=Fid;
            Tnode:=self.TreeView1.Items.AddChildObject(TregionNode,Fname,p);
            self.ClientDataSet4.Next;
          End;
        End;
        self.ClientDataSet3.Next;
      End;
      self.ClientDataSet4.Close;
      self.ClientDataSet3.Close;
      //--self.TreeView1.AutoExpand:=true;
    end;procedure Tmainfrm.BitBtn1Click(Sender: TObject);
    var
      str1,str2:string;
    begin
    //  showmessage(cus_str);
      self.BitBtn2.Enabled:=false;
      self.ClientDataSet2.Close;
      self.ClientDataSet2.CommandText:='exec Query_All_About_End_Seller_my :var1,:var2,:var3,:var4,:var5,:var6,:var7,:var8,:var9';
      with self.ClientDataSet2.Params do
      begin
        ParamByName('var1').Value:='';
        ParamByName('var2').Value:='0109';
        ParamByName('var3').Value:=cus_str;
        ParamByName('var4').Value:='';
        ParamByName('var5').Value:=formatdatetime('yyyymmdd',self.DateTimePicker1.Date);
        ParamByName('var6').Value:=formatdatetime('yyyymmdd',self.DateTimePicker2.Date);
        ParamByName('var7').Value:='0';
        ParamByName('var8').Value:=str1;
        ParamByName('var9').Value:=str2;
      end;
      self.ClientDataSet2.Open;
      self.DBGrid2.DataSource:=self.DataSource2;
      self.BitBtn2.Enabled:=true;
    end;procedure Tmainfrm.FormShow(Sender: TObject);
    VAR
      fa:integer;
    begin
      fa:=1;
      cus_str:='all';
      genallcustomer(fa);
      initial;
    end;procedure Tmainfrm.TreeView1Click(Sender: TObject);
    var
      TTNode:TTreeNode;
    begin
      TTNode:=self.TreeView1.Selected;
      if TTNode.Level=0 then
      begin
        cus_str:='all';
        exit;
      end;
      cus_str:=Pstr(TTnode.Data)^;
     // showmessage(cus_str);
    end;end.
      

  2.   

    上边的有点乱,这是整理的一个过程:procedure Tcustomer_treefrm.CreateSubTree_all(FNodeName: string; Node: TTreeNode = nil);
    var
      mLocalName: string;
      TreeNode: TTreeNode;
      Ads_Tmp: Tclientdataset;
      p:pstr;
    begin
      ADS_Tmp := Tclientdataset.Create(Self);
      ADS_Tmp.RemoteServer:=mainfrm.SocketConnection1;
       ADS_Tmp.ProviderName:='datasetprovider3';
      with ADS_Tmp do
      begin
        Close;
        CommandText :='QUERY_customer_By_Parent_No_sec '+''''+FNodeName+''''+','+''''+userid+'''';;
        //SELF.Memo1.Lines.Add(commandtext);
        Open;
        First;
        while not Eof do
        begin
          mLocalName := FieldbyName('ID').Asstring;
          new(p);
          p^:=mlocalName;
          TreeNode :=self.tv_zb.Items.AddChildObject(Node, FieldByName('Name').AsString,p);
          CreateSubTree(mLocalName, TreeNode);
          Next;
        end;
      end;
      Ads_Tmp.Free;
    end;