如下表结构,通过sql语句或编程实现treeview中的树状关系。思前想后,没想出解决办法, 只好请教大家了,先行谢过!nProcessID sProcessName
01 清花
02 梳棉
03 并条
03.01 涤予并
03.02 棉予并
03.03 混一
03.04 混二
03.05 混三
04 粗纱
05 细纱
06 精梳
07 槽筒

解决方案 »

  1.   

    var
      strTmp:string;
      tList:Tstring;
      iPos,iIndex:integer;
    begin
    adoDataset.close;
    adoDataset.commandtext:='select * from tname order by nProcessID';
    adoDataset.open;
    tList:=TStringList.Create;
    while not  adoDataset.eof do 
    begin
      strTmp:=adoDataset.fields[0].asstring;
      iPos:=pos('.',strTmp);
      if iPos=0 then Node=nil
      else
      begin
        strTmp:=copy(strTmp,0,iPos-1);
        iIndex:=tnList.indexof(strTmp);
        if iIndex=-1 then Node=nil
        else node:=TTreeNode(tnList.objects[index]); 
      end;
        
      node:=tv.Items.AddChildFirst(Node,adoDataset.fields[1].asstring);
      tList.AddObject(adoDataset.fields[0].asstring,tn);
      adoDataset.next;
    end;
    end;这是两层的,另外,我假定你的数据是排好序的!
    如多层,你就在这里想想
    begin
        strTmp:=copy(strTmp,0,iPos-1);
        iIndex:=tnList.indexof(strTmp);
        if iIndex=-1 then Node=nil
        else node:=TTreeNode(tnList.objects[index]); 
      end;
      

  2.   

    //确保记录是用nProcessID来排过序的~~
    //测试如下代码~~function SubStrConut(mStr: string; mSub: string): Integer;
    { 返回子字符串出现的次数 }
    begin
      Result := (Length(mStr) -
        Length(StringReplace(mStr, mSub, '', [rfReplaceAll]))) div Length(mSub);
    end; { SubStrConut }procedure TForm1.Button1Click(Sender: TObject);
    var
      vStrings: TStrings;
      vStream: TStream;
    begin
      with Table1 do //Table1替换成相应的DataSet控件
      begin
        vStrings := TStringList.Create;
        vStream := TMemoryStream.Create;
        DisableControls;
        try
          while not Eof do
          begin
            vStrings.Add(StringOfChar(#9,
              SubStrConut(FieldByName('nProcessID').AsString, '.')) +
              FieldByName('sProcessName').AsString);
            Next;
          end;
          vStrings.SaveToStream(vStream);
          vStream.Position := 0;
          TreeView1.LoadFromStream(vStream);
        finally
          EnableControls;
          vStrings.Free;
          vStream.Free;
        end;
      end;
    end;
      

  3.   

    上面的代码还应该加上
    freeandnil(tList)
      

  4.   

    查询语句:
    select parent = (select max(nProcessID) from tProcess b where a.nProcessID like b.nProcessID + '%' and a.nProcessID <> b.nProcessID),
    nProcessID as child, sProcessName
    from tProcess a
      

  5.   

    为什么不用控件呢?
    DbTree控件对于你这种格式的数据不用写一行代码
    具体下载地址我忘记了,你查一下
      

  6.   

    在一个名为: Query1的TQuery控件中写入如下SQL:
    select parent = (select max(nProcessID) from tProcess b where a.nProcessID like b.nProcessID + '%' and a.nProcessID <> b.nProcessID),
    nProcessID as child, sProcessName
    from tProcess a
    order by Parent, Child程序如下:type
      PCustomNode = ^TCustomNode;
      TCustomNode = record
        NodeKey, NodeValue, NodeName: String;
      end;function TForm1.findParent(ANodeKey: String): TTreeNode;
    var
      i: Integer;
    begin
      Result := nil;  for i := 0 to TreeView1.Items.Count - 1 do
        if PCustomNode(TreeView1.Items[i].Data)^.NodeValue = ANodeKey then
        begin
          Result := TreeView1.Items[i];
          Break;
        end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      vNode: PCustomNode;
    begin
      Query1.Close;
      Query1.Open;  with Query1 do
      while (not IsEmpty) and (not Eof) do
      begin
        new(vNode);    vNode.NodeKey := FieldByName('parent').AsString;
        vNode.NodeValue := FieldByName('child').AsString;
        vNode.NodeName := FieldByName('sProcessName').AsString;    if FieldByName('parent').AsString = '' then
          TreeView1.Items.AddObject(nil, vNode.NodeValue + ' - ' + vNode.NodeName, vNode)
        else
          TreeView1.Items.AddChildObject(findParent(FieldByName('parent').AsString), vNode.NodeValue + ' - ' + vNode.NodeName, vNode);    Next;
      end;
    end;
      

  7.   

    对了,
    function findParent(ANodeKey: String): TTreeNode;
    应记得在Form1的private中记得声明.