我想用adoqurey来实现“用树型结构表示科目代码的算法”,但是一直不能在treeview控件上添加子节点,我是这样做的:
unit main;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ImgList, ComCtrls, Grids, DBGrids, DB, ADODB, StdCtrls;type
  TfrmMain = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Splitter1: TSplitter;
    Panel3: TPanel;
    Splitter2: TSplitter;
    tvwCode: TTreeView;
    imgIcon: TImageList;
    tblCode: TADOQuery;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
  private
    { Private declarations }
    function LoadCode(crTbl:TADOQuery):Integer;
    function GetLevel(sFormat,sCode:String):Integer;
  public
    { Public declarations }
  end;var
  frmMain: TfrmMain;
  const
  SCodeFormat = '322222';   //科目代码结构
  SFirstNodeTxt   = '考试科目';implementation{$R *.dfm}function TfrmMain.LoadCode(crTbl:TADOQuery):Integer;
var NowID,sName,ShowTxt:String;
i,Level:Integer;
MyNode:array[0..6]of TTreeNode;
//保存各级节点,最长支持6级(重点)
beginScreen.Cursor:=crHourGlass;
Level:=0;With crTbl do
begin
try
if not Active then Open;
First;
tvwCode.Items.Clear;
//以下是增加第一项
MyNode[Level]:=tvwCode.Items.Add
(tvwCode.TopItem,SFirstNodeTxt);
MyNode[Level].ImageIndex:=0;
MyNode[Level].SelectedIndex:=0;
//以上是增加第一项While Not Eof do
begin
//
NowID:=Trim(FieldByName('aCode').AsString);
ShowTxt:=NowID+'  '+FieldByName('aName').AsString;Level:=GetLevel(SCodeFormat,NowID);
//返回代码的级数
//以下是增加子项
//以下用上一级节点为父节点添加子节点
if Level>0 then//确保代码符合标准
begin    Edit1.text:=inttostr(Level-1);
   MyNode[Level]:=tvwCode.Items.AddChild(MyNode[Level-1],ShowTxt);
   
   MyNode[Level].ImageIndex:=1;
   MyNode[Level].SelectedIndex:=2;
         
end;
Next;
end;
finally
Close;
end;
end;MyNode[0].Expand(False);//将首节点展开
Screen.Cursor:=crDefault;
end;
//以上函数将tree_Code表中的科目代码和科目代码名称显示出来
//下面函数的功能是返回一代码的级数,
//参数sFormat传递科目代码结构;
//参数sCode传递某一科目代码
function TfrmMain.GetLevel
(sFormat,sCode:String):Integer;
var i,Level,iLen:Integer;
begin
Level:=-1;//如果代码不符合标准,则返回-1
iLen:=0;
if (sFormat <> '')and(sCode <> '')then
for i:=1 to Length(sFormat) do
begin
iLen:=iLen+StrToInt(sFormat[i]);
if Length(sCode)=iLen then
begin
   Level:=i;
   Break;
end;
end;
Result:=Level;
end;
//上面函数的功能是返回一代码的级数
procedure TfrmMain.FormCreate(Sender: TObject);
begin
with tblCode do
begin
ConnectionString:='Provider=SQLOLEDB.1;Password=lj721891;Persist Security Info=True;User ID=sa;Initial Catalog=study;Data Source=LEGEND-3LI8VJ5O\WWW' ;
SQL.Add('select *from tree_data')  ;
Active:=true;
end;LoadCode(tblCode);
end;
procedure TfrmMain.btnCloseClick(Sender: TObject);
begin
Close;
end;end.

解决方案 »

  1.   

    我用Edit1.text:=inttostr(Level-1);来测试,level的值是否通过数据库查询返回合法值,经检验也是正确的,但就是MyNode[Level]:=tvwCode.Items.AddChild(MyNode[Level-1],ShowTxt);执行有问题,我确实没发现问题在那点,请指教
    tree_data表的字段名: 
    aname  char   20 
    acode  char   20    (建有索引)
      

  2.   

    表结构如下设计
    id name parentidparentid references id ,建立外键
      

  3.   

    如果可以事先知道每级的代码长度,可以用类似这样的编码
    001
    0010001
    001000101
    0010002如果不能事先指定,那么可以设置一个ParentID字段
      

  4.   

    其实关键是:select * from tree_data order by aCode