数据库的字段为cCode和cText想动态生成TreeView,cCode的编码规则为第一级为0001,然后第二级的代码为0001.0001,中间有个‘.'作为分割符。想实现的效果如下:    0001:北京
          0001.0001:海淀
          0001.0002:怀柔
          0001.0003:通县
    0002:上海
          0002.0001:浦东
          0002.0002:浦西
    0003:天津
          0003.0001:和平
          0003.0002:南开向大家请教,谢谢!
    

解决方案 »

  1.   

    如果已经确定了4位数一级的话,那个‘。’作为分隔符已经毫无必要了,因为长度就可以确定级数数据和程序如下,测试OK  0001:北京
      00010001:海淀
      00010002:怀柔
      00010003:通县
      0002:上海
      00020001:浦东
      00020002:浦西
      0003:天津
      00030001:和平
      00030002:南开procedure Tform1.createtree(ado1: tadoquery; name, code: string; tree: Ttreeview; code_len: integer; maxlevel: integer);
    var
      cur_level, treeindex: integer;
      current_parent_index: array of integer;
    begin
      setlength(current_parent_index, maxlevel);
      treeindex := 0; //这个是当前treeview的item的AbsoluteIndex
      ado1.First;
      while not ado1.Eof do
      begin
        if length(ado1.FieldByName(code).AsString) = code_len then
        begin
          tree.Items.Add(nil, ado1.fieldbyname(name).AsString);
          current_parent_index[0] := treeindex; //
        end
        else
        begin
          cur_level := length(ado1.FieldByName(code).AsString) div code_len; //确定是第几级
          tree.Items.AddChild(tree.Items[current_parent_index[cur_level - 2]], ado1.fieldbyname(name).AsString);
          current_parent_index[cur_level - 1] := treeindex;
        end;
        treeindex := treeindex + 1;
        ado1.Next;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      treeindex: integer;
      current_parent_index: array[1..15] of integer;
    begin
      adoquery1.Active := false;
      adoquery1.SQL.Clear;
      adoquery1.SQL.Add('select name,code from test1 order by code');
      adoquery1.Active := true;
      createtree(adoquery1, 'name', 'code', treeview1, 4, adoquery1.RecordCount);
    end;
      

  2.   

    如果你是严格按照顺来的,那就很简单,根据规则依次添加父子节点就行了,如果是乱的,最好先添加最顶级节点,然后再添加下级节点,添加下级时根据编号规则去treeview上找父节点,treeview的node.data可以存储一些标识,以便你查找
      

  3.   

    直接用控件吧!
    cxDBTreeView
      

  4.   

    給你一個例子:(CX版的)
    自定義過程:
    procedure TRES_BOM_VIEW_F.CREATETREEVIEWMODEL;
    var
      iLoop:Integer;
      Master,MasterNode:TTreeNode;
    begin
      adoq_getop.Close;
      //SELECT distinct PARN_TYP FROM WWW where parn_typ<>'.' and parn_typ is not null order by PARN_TYP desc
      adoq_getop.SQL.Text:='SELECT distinct PARN_TYP FROM WWW where parn_typ<>''.'' and parn_typ is not null order by PARN_TYP desc';
      adoq_getop.Open;
      adoq_getop.First;
      cx_TV.Items.BeginUpdate;
      cx_TV.Items.Clear;
      Master:=cx_TV.Items.Add(nil,'昆盈BOM表檢視');
      while not adoq_getop.Eof do
      begin
        if adoq_getop.FieldByName('PARN_TYP').AsString<>'' then
        begin
          Screen.Cursor:=crSQLWait;
          MasterNode:=cx_TV.Items.AddChild(Master,VarToStr(adoq_getop.FieldValues['PARN_TYP']));
          Application.ProcessMessages;
          qry_op.Close;
          qry_op.SQL.Text:='SELECT DISTINCT PARN_LITM FROM WWW WHERE PARN_TYP='''+ VarToStr(adoq_getop.FieldValues['PARN_TYP'])+''' GROUP BY PARN_LITM';
          qry_op.Open;
          for iLoop:=0 to qry_op.RecordCount -1 do
          begin
            cx_TV.Items.AddChild(MasterNode,VarToStr(qry_op.FieldValues['PARN_LITM']));
            qry_op.Next;
          end;
          Application.ProcessMessages;
          cx_TV.Items.EndUpdate;
          Screen.Cursor:=crDefault;
        end;
        adoq_getop.Next;
        Application.ProcessMessages;
      end;
     {
      ThreadTView:=cx_TV;
      ViewThread:=TExpandLH.Create;
      ViewThread.Resume;
      }
    end;點擊按鈕生成TREE:
    procedure TRES_BOM_VIEW_F.btnSB_SearchClick(Sender: TObject);
    begin
      inherited;
      try
        RES_LOADING_F:=TRES_LOADING_F.Create(Self);
        RES_LOADING_F.Label1.Caption:='正在檢索相關數據......';
        RES_LOADING_F.Show;
        RES_LOADING_F.Update;
        CREATETREEVIEWMODEL;
      finally
        RES_LOADING_F.Close;
      end;
    end;
      

  5.   

    把每条数据设父结点(根结点的父结点为空),首先加根结点、再加第一级结点、依次第二级结点repeat
      读入数据
      找到父结点,
      加入为子结点
      标记该结点 
    util 数据全部加入
      

  6.   

    create table test_t(ccode varchar2(20),ctext varchar2(20));
    insert into test_t
    select '0001','北京' from dual
    union
    select '0001.0001','海淀' from dual
    union
    select '0001.0002','怀柔' from dual
    union
    select '0001.0003','通县' from dual
    union
    select '0002','上海' from dual
    union
    select '0002.0001','浦东' from dual
    union
    select '0002.0002','浦西' from dual
    union
    select '0003','天津' from dual
    union
    select '0003.0001','和平' from dual
    union
    select '0003.0002','南开' from dualunit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, ComCtrls, DB, ADODB;type
      pTVInfo = ^TTVInfo;
      TTVInfo = record
        ccode: String;
        ctext: String;
      end;type
      TForm1 = class(TForm)
        ADOConnection1: TADOConnection;
        ADOQuery1: TADOQuery;
        TreeView1: TTreeView;
        Button1: TButton;
        ADOQuery2: TADOQuery;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
        FTVInfo: pTVInfo;
      public
        { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
      function AddTreeNode(vTVInfo: pTVInfo;pNode: TTreeNode): TTreeNode;
      var
        vNode: TTreeNode;
      begin
        if pNode=nil then
        begin
          vNode := TreeView1.Items.Add(nil,FTVInfo.ctext);
          vNode.Data := FTVInfo;
        end else
        begin
          vNode := TreeView1.Items.AddChild(pNode,FTVInfo.ctext);
          vNode.Data := FTVInfo;
        end;
        result := vNode;
      end;
    var
      pNode: TTreeNode;
    begin
      with adoquery1 do
      begin
        close;
        sql.Text := ' select ccode,ctext from test_t where length(ccode)=4 order by to_number(ccode)';
        Open;
        while not eof do
        begin
          new(FTVInfo);
          FTVInfo.ccode := FieldByName('ccode').AsString;
          FTVInfo.ctext := FieldByName('ctext').AsString;
          pNode := AddTreeNode(FTVInfo,nil);
          with adoquery2 do
          begin
            close;
            sql.Text := ' select ccode,ctext from test_t where substr(ccode,1,4)=:ccode and length(ccode)<>4 order by to_number(ccode)';
            parameters.ParamByName('ccode').Value := FTVInfo.ccode;
            open;
            while not eof do
            begin
              new(FTVInfo);
              FTVInfo.ccode := FieldByName('ccode').AsString;
              FTVInfo.ctext := FieldByName('ctext').AsString;
              AddTreeNode(FTVInfo,pNode);
              Next;
            end;
          end;
          Next;
        end;
      end;
    end;end.