TreeView生成树形结构,数据库结构比较特别,本人是通过递归画树的方式,画TreeView树,但是不成功,请各位高手不吝赐教;

时间:2021-01-11 12:40:35
数据控件不多,就是通过TreeView控件、ADOQuery控件、ADOConnection控件,提取数据库中的相关信息,并在TreeView中画出树形结构,数据库字段fnumber、fname,本人是想通过递归,把fnumber字段的前两位为01的所有产品全部筛选出来,并生成树形结构显示在TreeView控件中,本人程序中无报错的地方,递归也无问题,但就是生成不了树形结构,请各位高手不吝赐教!!!
fnumber     fname
01          产成品
01.001      一号库
01.001.01   西红柿
01.001.02   大葱 
02          半成品库          
代码如下:
type
    dw=record
    dwid:string;
    dwname:string;
    lbid:string;
  end;
  pdw=^dw;
  xm=record
    xmid:string;
    xmname:string;
    ysje:real;
  end;
  pxm=^xm;
  Tcpchanliang = class(TForm)
    Button1: TButton;
    TreeView1: TTreeView;
    ADOQuery_cp: TADOQuery;
    DateTimePicker1: TDateTimePicker;
    function getupid(ndwid:string):string;
    procedure dwdg(id:string;node:TTreeNode);
    procedure FormShow(Sender: TObject);  //单位递归画树函数
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  cpchanliang: Tcpchanliang;
  gloabnode:TTreenode;  //单位node全局变量
  s_dw,s_xm:integer;
  w_dw:array of dw;    //单位数组
  p_dw:pdw;   //单位指针
  gdate:Tdatetime;   //年,月,日
  gdwid:String;//[21];//登录单位ID
implementation
  uses unit3;
{$R *.DFM}
function Tcpchanliang.getupid(ndwid:string):string; //取上一级id
var
  str1:string;
begin
  str1:=copy(ndwid,1,length(ndwid)-3); //初始化str1变量
  result:=str1;
end;
procedure Tcpchanliang.dwdg(id:string;node:TTreeNode);  //递归画树(dxtreeview1中的树)
var
  i:integer;
  mynode:TTreeNode;
begin
  for i:=0 to s_dw-1 do
    begin
        if getupid(w_dw[i].dwid)=id then
        begin
          new(p_dw);
          p_dw^.dwid:=w_dw[i].dwid;
          p_dw^.dwname:=w_dw[i].dwname;
          mynode:=TreeView1.Items.AddChild(node,w_dw[i].dwname);
          mynode.Data:=p_dw;
          dwdg(w_dw[i].dwid,mynode);
        end;
    end;
end;
procedure Tcpchanliang.FormShow(Sender: TObject);
var
  i:integer;
begin
  ADOQuery_cp.Connection:=DataModule3.acper;
  treeview1.Items.Clear;
  DateTimePicker1.Datetime:=now;
  gdate:=DateTimePicker1.Datetime;
  ADOQuery_cp.Close;
  ADOQuery_cp.SQL.clear;
  ADOQuery_cp.SQL.text:='select fnumber,fname from t_item where   fitemclassid=''4'' and left(FFullNumber,len(''01''))=''01'' order by fnumber';
  showmessage('ADOQuery_cp.SQL.text='+ADOQuery_cp.SQL.text);
  ADOQuery_cp.Open;
  s_dw:=ADOQuery_cp.RecordCount;
  if s_dw=0 then exit;
  setlength(w_dw,s_dw);
  for i:=0 to s_dw-1 do
    begin
      w_dw[i].dwid:=ADOQuery_cp.Fields[0].AsString;
      w_dw[i].dwname:=ADOQuery_cp.Fields[1].AsString;
      ADOQuery_cp.Next;
    end;
  ADOQuery_cp.First;
  dwdg(getupid('01'),nil);
  //theflag:=true;
  gloabnode:=Treeview1.Items.GetFirstNode;
  gloabnode.Selected:=true;
end;
end.

5 个解决方案

#1


最好别用递归,把你的数据循环一遍,就可以完成树形结构的显示

#2


procedure TfrmMain.ReadNode(ownNode: TTreeNode; NodeId: string);
//OwnNode:Pater node  NodeId:self nodeid;
var
  curNode: TtreeNode;
  curID, curName: string;
  adoquery: TAdoQuery;
  myid: pmyid;
begin
  adoquery := Tadoquery.create(parent);
  adoquery.Connection := AdoCon;
  adoquery.sql.text := 'select * from tree1 where up_id=''' + NodeID + '''';
  with adoquery do
  begin
    open;
    first;
    while not eof do
    begin
      curID := FieldByName('id').AsString;
      curName := fieldByName('Crop_name').AsString;
      new(myid);
      myid^.nodeid := curID;
      myid^.nodename := curName;
      curNode := treeview1.Items.AddChildObject(ownNode, curName, myid);
      ReadNode(curNode, curid);
      next;
    end;
    close;
    free;
  end;
end;


procedure TfrmMain.LoadData;
var
  CurNode: TTreeNode;
  MyID: pMyID;
begin
  new(MyID);
  MyID^.nodeid := '0';
  CurNode := Treeview1.Items.AddChildObject(nil, '中華人民共和國', MyID); //?入根??
  ReadNode(CurNode, '0');
end;

procedure TFrmMain.FormShow(Sender: TObject);
begin
  loaddata;
end;



procedure TFrmMain.btn1Click(Sender: TObject);
begin
//重載目錄樹
  TreeView1.Items.Clear;

//TreeView1.Free;
  loaddata;
end;

#3


个人觉得递归麻烦
通过循环数据库就可以实现的

#4


非常感谢各位大侠的帮助,我已经解决了,我用的比较笨的办法,先画父节点的树,然后再画子节点的树

#5


up

#1


最好别用递归,把你的数据循环一遍,就可以完成树形结构的显示

#2


procedure TfrmMain.ReadNode(ownNode: TTreeNode; NodeId: string);
//OwnNode:Pater node  NodeId:self nodeid;
var
  curNode: TtreeNode;
  curID, curName: string;
  adoquery: TAdoQuery;
  myid: pmyid;
begin
  adoquery := Tadoquery.create(parent);
  adoquery.Connection := AdoCon;
  adoquery.sql.text := 'select * from tree1 where up_id=''' + NodeID + '''';
  with adoquery do
  begin
    open;
    first;
    while not eof do
    begin
      curID := FieldByName('id').AsString;
      curName := fieldByName('Crop_name').AsString;
      new(myid);
      myid^.nodeid := curID;
      myid^.nodename := curName;
      curNode := treeview1.Items.AddChildObject(ownNode, curName, myid);
      ReadNode(curNode, curid);
      next;
    end;
    close;
    free;
  end;
end;


procedure TfrmMain.LoadData;
var
  CurNode: TTreeNode;
  MyID: pMyID;
begin
  new(MyID);
  MyID^.nodeid := '0';
  CurNode := Treeview1.Items.AddChildObject(nil, '中華人民共和國', MyID); //?入根??
  ReadNode(CurNode, '0');
end;

procedure TFrmMain.FormShow(Sender: TObject);
begin
  loaddata;
end;



procedure TFrmMain.btn1Click(Sender: TObject);
begin
//重載目錄樹
  TreeView1.Items.Clear;

//TreeView1.Free;
  loaddata;
end;

#3


个人觉得递归麻烦
通过循环数据库就可以实现的

#4


非常感谢各位大侠的帮助,我已经解决了,我用的比较笨的办法,先画父节点的树,然后再画子节点的树

#5


up