从表中的一个字段中生成树
要求:
1:速度快,这个表有百十万条记录
2:代码简练,不要超过10行
条件:
1:用DELPHI的TREEVIEW控件
2:表中的记录如下:
   001001001
   001001002
   001001003
   002001001
   002001002
   002001003
   003001001
   003001002
   003001003
树结构:
   根--001
     |     |--001
     |     .      | --001
     |     .      |--002
     |     .      | --003            
     |--002      .
     |      |--001
     |      .      |--001
     |      .      |--002
     |      .      |--003            
     |--003       .
     .     | --001
     .     .       |--001
     .     .       |--002
     .     .       |--003            
     .             .
     .
备注:
    分数一定给足500!!!!!!!!!!!!!!!!!!!!!!!!!11

解决方案 »

  1.   

    这个简单啊,对字符串的控制
    pos copy
     procedure TFrmRole.TreeExpanding(Sender: TObject; Node: TTreeNode;
      var AllowExpansion: Boolean);
    begin
      GetClass(Node);
      AllowExpansion:=True;
    endprocedure TFrmRole.GetClass(ANode: TTreeNode);
    var
      GoodTypeDataSet,HasChildDataSet:TClientDataSet;
      TempNode:TTreeNode;
      Node:TTreeNode;
      UPStr:String;
      UPID,ChildUPID:integer;
    begin
      Node:=ANode;  if (Node.GetFirstChild<>nil) then
        Exit;  GoodTypeDataSet:=TClientDataSet.Create(nil);
      HasChildDataSet:=TClientDataSet.Create(nil);  if Node.Level=1  then {Get Dept's Child  @_@*Snake_Eye*@_@ }
        begin
          UPStr:=Copy(Node.Text,1,Pos(' ',Node.Text)-1);
          UPID:=StrToint(UPStr);
          GoodTypeDataSet.Data:=MyComDept.GetBigClass(UPID,_Mode_ID_,_Organ_ID_);
          while not GoodTypeDataSet.Eof do
           begin
             TempNode:=Tree.Items.AddChild(Node,Trim(GoodTypeDataSet.FieldByName('TYPE_NO').AsString)+' '
                            +Trim(MyComGoodTpyeAndOrg.GetTpyeName(GoodTypeDataSet.FieldByName('TYPE_NO').AsString)));
             TempNode.HasChildren:=True;
             TempNode.ImageIndex:=2;
             TempNode.SelectedIndex:=3;
             GoodTypeDataSet.Next;
           end;
        end
      else   {Class's Child @_@*Snake_Eye*@_@ }
        begin
           UPStr:=Trim(Copy(Node.Text,1,Pos(' ',Node.Text)-1));
           UPID:=MyComGoodTpyeAndOrg.GetTypeID(UPStr);
           GoodTypeDataSet.Data:=MyComGoodTpyeAndOrg.GetChildGoodType(UPID,_Mode_ID_,2);
           while not GoodTypeDataSet.Eof do
           begin
            TempNode:=Tree.Items.AddChild(Node,GoodTypeDataSet.FieldByName('TYPE_NO').AsString+' '
                             +Trim(GoodTypeDataSet.FieldByName('TYPE_NAME').AsVariant));
            if Node.Level=2 then
              begin
               TempNode.ImageIndex:=4;
               TempNode.SelectedIndex:=5;
              end
            else if Node.Level=3 then
              begin
               TempNode.ImageIndex:=6;
               TempNode.SelectedIndex:=7;
              end;        ChildUPID:=GoodTypeDataSet.FieldByName('TYPE_ID').AsInteger;
            HasChildDataSet.Data:=MyComGoodTpyeAndOrg.GetChildGoodType(ChildUPID,_Mode_ID_,2);
            if HasChildDataSet.RecordCount<>0 then
              TempNode.HasChildren:=True;
            GoodTypeDataSet.Next;
           end;
        end;
      GoodTypeDataSet.Free;
      HasChildDataSet.Free;
    end;。。
       if Tree.Selected.Level=0 then
          SaveParent.Enabled:=true
       else
          SaveParent.Enabled:=False;
      

  2.   

    上面是我写的
    楼主只要在 procedure TFrmRole.TreeExpanding(Sender: TObject; Node: TTreeNode;
    里面写东西主要是对你的字符串分析(这个简单)就是对它Tree.Selected.text
    取的当前的接点:
    Tree.Selected.Level=0,1,2,3,写点东西也可以
    这样就搞定了,注意TempNode.HasChildren:=True;的设置。
      

  3.   

    可以全部按查询方式显示,
    点击根目录转载001,002,003甚至还有004,009等等
    用SQL语句:
    SELECT distinct SUBSTRING(编号, 1, 3)
    FROM Table1
    ORDER BY 编号
    转载到树状列表
    点击001或其他还可以分类
    SELECT distinct SUBSTRING(编号, 1, 6)
    FROM Table1
    Where 编号 Like 001%
    ORDER BY 编号
    转载到树状列表
    001
    |-001001
    |-001002
    |-001003
    依次类推
      

  4.   

    千万不要在开始的时候全部把数据读出来放入TreeView,否则好像就要死机了一样
      

  5.   

    (To) readersm68(地主) 这个方法可以试试
    请大家多多发表自己的见解
      

  6.   

    readersm68(地主) 的办法应该是比较好的了.
      

  7.   

    我也有一种方法(一下子全部添加所有的节点):
    1、用SQL语句取所有的数据:select * from TableName order by 编号
       这样就保证所有的子节点都在父节点的后面
    2、用一个while循环来将所有的节点添加到树中
    3、在添加时的语句为:tmpNode:=TreeView1.Items.AddChild(FindParent(当前记录编号),编号);
    4、FindParent的实现比较简单:
       result:=nil;如果找不到父节点则这个节点就是第一级
       for i:=TreeView1.Items.Count-1 downto 0 do
         if TreeView1.Items[i].Text=Copy(传过来的编号,1,Length(TreeView1.Items[i].Text)) then
           result:=TreeView1.Items[i];
    5、因为在取数据时我已经用Order by 编号了,所以保证了父节点会比子节点先添加这是用于开始要将所有的记录全部添加时最好的算法了。
      

  8.   

    (To)haoco(程序员) Very good !
    这个方法比较适合,这样的上面的数据表结构
    但是
    代码可能超过10行
    因为处于对表结构的设计
    和对TREEVIEW了解这个题目10行代码肯定可以解决
    我们大家不妨来个评比:
    到底是表结构采用那种有父接点的形式号还是采用这种表结构
    还有要考虑TREEVIEW的实现发发
      

  9.   

    haoco(程序员) 
    对于需要对节点进行添加、删除的话,程序较复杂,我用过。如果数据量大,会影响效率。
      

  10.   

    帖主:
        你是说如果表结构换一下(用一个字段来记录它对应的父节点的编号)就用不了我 的那个算法?FindParent()将当前记录用来记录对应父节点的字段值传进去不就行了吗?
      

  11.   

    to readersm86(地主):
       你说这个算法在添加、删除时较复杂?复杂在哪里?你是不是添加、删除节点时又重画这棵树?