数据结构如下:
=========================================================
classid classname parentclass
A 輔料 NULL
B 工程零配件 NULL
C 固定資產 NULL
D 雜項 NULL
A-01 日常輔料 A
A-02 生產輔料 A
A-03 彩印輔料 A
A-04 辦公輔料 A
A-01-001 布碎 A-01
A-01-002 手套  A-01
A-01-003 掃把 A-01
A-01-004 書寫品 A-01
A-01-005 衛生品 A-01
A-01-006 用具 A-01
A-01-001-0002 小布碎 A-01-001
A-01-001-0003 大布碎 A-01-001
A-01-002-0001 工業膠手套  A-01-002
A-01-002-0002 線手套 A-01-002
A-01-002-0003 家用膠手套 A-01-002
A-01-002-0004 家用膠手套-2 A-01-002
A-01-002-0005 無紡布鞋套 A-01-002
A-01-003-0001 金絲掃把 A-01-003
A-01-003-0002 拖把 A-01-003
A-01-003-0003 竹掃把 A-01-003
A-01-004-0001 油性箱頭筆 A-01-004
A-01-004-0002 水性箱頭筆 A-01-004
A-01-004-0003 毛筆 A-01-004
A-01-004-0004 進口箱頭筆 A-01-004
A-01-004-0005 無塵粉筆 A-01-004
A-01-005-0001 洗衣粉 A-01-005
A-01-005-0002 肥皂 A-01-005
A-01-005-0003 毛巾 A-01-005
A-01-005-0004 口罩 A-01-005
A-01-005-0005 無紡布口罩 A-01-005
A-01-005-0006 紙口罩 A-01-005
A-01-005-0007 活性碳口罩 A-01-005
A-01-006-0001 雕刻刀片 A-01-006
A-01-006-0002 膠水瓶 A-01-006
A-01-006-0003 膠桶 A-01-006
A-01-006-0004 水瓢 A-01-006
A-01-006-0005 雞毛掃 A-01-006
A-01-006-0006 刷子 A-01-006
A-01-006-0007 刀片 A-01-006
A-01-006-0008 噴壺 A-01-006
A-01-006-0009 保安刀片 A-01-006
A-01-006-0010 垃圾斗 A-01-006
A-01-006-0011 雕刻刀架 A-01-006
A-01-006-0012 吸咀 A-01-006
A-01-006-0013 菜刀 A-01-006
A-01-006-0014 一次性膠杯 A-01-006
A-01-006-0015 耳塞 A-01-006
A-01-006-0016 膠盆 A-01-006
A-02-002 樹脂板 A-02
A-02-003 生粉 A-02
A-02-004 燃油 A-02
A-02-005 膠水 A-02
A-02-006 包裝帶  A-02
A-02-007 釘線 A-02
A-02-008 啤具 A-02
A-02-009 化工品 A-02
A-02-011 其它 A-02
A-02-012 膠紙 A-02
A-02-013 海綿 A-02
A-02-014 四色水墨 A-02
A-02-015 雜色水墨 A-02
A-02-016 黑色水墨 A-02
A-02-017 特殊水墨 A-02
A-02-018 水墨添加劑 A-02
A-02-019 BASE料 A-02
A-02-020 弧形模具 A-02
A-02-002-0001 3.94mm樹脂板1 A-02-002
A-02-002-0002 9.6mm橡膠版  A-02-002
==================================================================
我用树形TTreeView把它显示出来怎么要20几秒,才7000条数据呀,我写的算法如下,大家看怎么改。

解决方案 »

  1.   

    function TgoodsClassFrm0.FindNode(classID: string): TTreeNode;
    var
      b, e: integer; //begin,end,mid
      found: boolean;
      str: string;
    begin
      if CompareText(Mstr(classTree.Items.Item[mid + 1].Text,
        '(', ')'), classID) = 0 then
      begin
      result := classTree.Items.Item[mid + 1];
       exit;
       end;  found := false;
      //mid:=0;
      b := mid + 1;
      e := classTree.Items.Count - 1;
      while (b <= e) and (not found) do
      begin //2
        {if CompareText(Mstr(classTree.Items.Item[b].Text,
          '(', ')'), classID) = 0 then
        begin mid:=b; found := true; break; end; }
        mid := (b + e) div 2;
        //str := ;
        str := Mstr(classTree.Items.Item[mid].Text, '(', ')');
        if CompareText(str, classID) < 0 then
          b := mid + 1;// else
          if CompareText(str, classID) = 0 then
            found := true ;//else
            if CompareText(str, classID) > 0 then
              e := mid - 1; //comparestr
      //end; //case
      end; //2
      if found then result := classTree.Items.Item[mid]
      else result := nil;
    end;procedure TgoodsClassFrm0.createTree;
    var
      root, node: TTreeNode;
      classID, classN, pclass: string;
    label go;
    begin //1
      root := classTree.Items.AddFirst(nil, '┮Τだ摸');
      with adosp, classTree.Items {purchdm.Query1} do
      begin
        close;
        //sql.Clear;
        //sql.Add('select classID, className,parentclass from goodsClass union all-- order by parentclass,classid');
        //sql.Append(' select full_id,prod_name,parentclass=fclass_id+''-''+sclass_id+''-''+tclass_id  from Product');
        //sql.Append(' order by parentclass, classid');
        //sql.Add('exec aget');
        open;
        mid := 0;
        node := root;
        while not eof do
        begin
          //classID := trim(fieldbyname('classID').AsString);
          //classN := trim(fieldbyname('className').AsString);
          pclass := trim(fieldbyname('parentclass').AsString);
          if pclass = 'A-02-016' then
            msg1(pclass);
          if fieldbyname('parentclass').IsNull then
            goto go;
          if pclass = Mstr(node.Text, '(', ')') then
            goto go;
          //if Mstr(Item[newn.Index + 1].Text, '(', ')') = pclass then
          //begin
          //  mid := newN.Index + 1;
          //  node := Item[mid];
          //end
          //else
          node := FindNode(trim(fieldbyname('parentclass').AsString));      go: AddChild(node, '(' + trim(fieldbyname('classID').AsString) +
            ') ' + trim(fieldbyname('className').AsString));
          //inc(mid);
          //newn.Index
          next;
        end;    close;
        //createProduct;
      end;
      root.Expand(false);
    end; //1
      

  2.   

    不要一次加载,先加载最上层的在treeview的onclick中根据 selected 节点查找数据库,加载子目录
      

  3.   

    干嘛非要一次性加载完成?这样很难保证效率了,自己写这种代码的基本思想就是随需临时挂子项目,或者你可以找一些DBTreeView看看他们的效率是否有所提高
      

  4.   

    程序没看不过treeview的确比较慢,不过想想7000条记录一次加到treeview中的确很可怕。
      

  5.   

    像这种代码还有什么地方可以改进最好是一次加完不是我就只是在TTreeView中加节点,不管层次关系,就7000数据怎么也要3.5秒是不是有什么问题
      

  6.   

    不过完全没有一次加载的必要,如果有的话你说说如果是你要通过程序遍历treeview,你完全可以去遍历数据库
    如果你要交互操作treeview,完全可以在交互的时候加载
      

  7.   

    query1的sql语句为
    select parentclass from table
    query1.open
    while not quer1.eof do
      begin
        //query2的sql语句为
       s_sql:='select * from table where        parentclass=query1.fields[0].asstring;
    query2.open
    while not query2.eof 
    begin
      //加载数据
      next;
    end;
    next
      end;
      

  8.   

    //TreeView处理成文本是这样的,子节点比父节点多一个制表符(#9)~~
    A 輔料
    A-01 日常輔料
    A-01-001 布碎
    A-01-001-0002 小布碎
    A-01-001-0003 大布碎
    A-01-002 手套 
    A-01-002-0001 工業膠手套 
    A-01-002-0002 線手套
    A-01-002-0003 家用膠手套
    A-01-002-0004 家用膠手套=2
    A-01-002-0005 無紡布鞋套
    A-01-003 掃把
    A-01-003-0001 金絲掃把
    A-01-003-0002 拖把
    A-01-003-0003 竹掃把
    A-01-004 書寫品
    A-01-004-0001 油性箱頭筆
    A-01-004-0002 水性箱頭筆
    A-01-004-0003 毛筆
    A-01-004-0004 進口箱頭筆
    A-01-004-0005 無塵粉筆
    .................................................
    //按照这种思想,看成字符串的处理~~
    //根据编号的规律-都是以“-”分隔~~
    //可以写出如下代码,请调试~~//....function SubStrCount( //计算子字符串的个数
      mStr: string; //源字符串
      mSub: string; //子串
      mIgnoreCase: Boolean = False //是否忽略大小写
    ): Integer; //返回子字符串出现的次数
    var
      vReplaceFlags: TReplaceFlags;
    begin
      vReplaceFlags := [rfReplaceAll];
      if mIgnoreCase then Include(vReplaceFlags, rfIgnoreCase);
      Result := (Length(mStr) - Length(
        StringReplace(mStr, mSub, '', vReplaceFlags))) div Length(mSub);
    end; { SubStrCount }//....
    var
      vADOQuery: TADOQuery; //查询表用
      vStringList: TStringList; //文本处理
      vMemoryStream: TMemoryStream; //内存处理
    begin
      vADOQuery := TADOQuery.Create(nil);
      vStringList := TStringList.Create;
      vMemoryStream := TMemoryStream.Create;
      try
        //vADOQuery.ConnectionString := '??'; //TODO : 设置连接字符传
        vADOQuery.SQL.Text :=
    'SELECT classID,className'#13#10 +
    'FROM Product'#13#10 +
    'ORDER BY classId'#13#10;
        vADOQuery.Open; //打开表,用classId排序
        //--vADOQuery.DisableControls; //如果有相关数据控件需要如此处理
        //--try
        ///////Begin 将记录处理成文本
        while not vADOQuery.Eof do
        begin
          vStringList.Add(
            StringOfChar(#9,
              SubStrCount(vADOQuery.FieldByName('classID').AsString, '-') //“-”的数量表示节点的深度
            ) +
            vADOQuery.FieldByName('className').AsString);
          vADOQuery.Next;
        end;
        ///////End 将记录处理成文本
        //--finally
          //--vADOQuery.EnableControls;
        //--end;
        ///////Begin 内存存储
        vStringList.SaveToStream(vMemoryStream);
        vMemoryStream.Position := 0;
        TreeView1.LoadFromStream(vMemoryStream);
        ///////End 内存存储
      finally
        vADOQuery.Free;
        vStringList.Free;
        vMemoryStream.Free;
      end;
    end;
    //....
      

  9.   

    這樣的代碼夠簡單了吧﹐可是怎么還要7.5秒
    ===========================================================
    procedure TgoodsClassFrm0.createTree;
      function FindNode(classID: string): TTreeNode;//查找父節點
      var
        b: integer;
      begin
        result := nil;
        for b := classTree.Items.Count - 1 downto 0 do
        begin
          if Mstr(classTree.Items.Item[b].Text, '(', ')') = classid then
          begin
            result := classTree.Items.Item[b];
            break;
          end;
        end;
      end;
    var
      root, node: TTreeNode;
    begin
      root := classTree.Items.AddFirst(nil, '所有物料分類');
      with classTree.Items, purchdm.Query1 do
      begin
        close;
        sql.Clear;
        sql.Add('exec aget');
        open;
        node := root;
        while not eof do
        begin
          if trim(fieldbyname('parentclass').AsString) <> Mstr(node.Text, '(', ')') then
            node := FindNode(trim(fieldbyname('parentclass').AsString));      AddChild(node, '(' + trim(fieldbyname('classID').AsString) +
            ') ' + trim(fieldbyname('className').AsString));
          next;
        end;
        close;
      end;
      root.Expand(false);
    end; //1==============================================================================
    還有什么可以改的
      

  10.   

    zswangII(伴水清清)(一贴不灌,何以灌天下?) :::原來*不是混出來的﹐真好﹐在2.5秒左右了
    謝謝﹐結貼