TreeView 在多表格中使用 |
尚未結案
|
casper wu
一般會員 發表:1 回覆:4 積分:1 註冊:2003-12-26 發送簡訊給我 |
各位高手們 請教一個問題
若今天我有二個以上的table...結構如下:
TABLE1 DATA
------------
PK NO1 1111
NAME1
DESC1
------------
TABLE2
------------
PK NO2 2222
FK N01 1111
NAME2
DESC2
------------
TABLE3
------------
PK N03 3333
FK NO2 2222
NAME3
DESC3 若我想使用TREEVIEW
成為
1111
|--2222
|--3333
請問該怎麼做呢???????? SOS
|
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
Hi: 建議你將 Table 簡化為兩個,再用遞迴函數,動態產生 TQuery 來建立這棵『樹』
procedure TForm1.Button1Click(Sender: TObject); var MyTreeNode: TTreeNode; procedure QueryDetails(ParentID : Integer ; TreeNode : TTreeNode); var Details : TQuery; MyTreeNode: TTreeNode; begin Details := TQuery.Create(Self); Details.DatabaseName := QRY_CSQ_OUTLINES.DatabaseName; Details.Close; Details.SQL.Clear; Details.SQL.Add('SELECT CREATION_DATE,' #13 ' CREATED_BY,' #13 ' LAST_UPDATE_DATE,' #13 ' LAST_UPDATED_BY,' #13 ' OUTLINE_ID,' #13 ' ENTRY_SEQUENCE,' #13 ' LINE_TYPE_CODE,' #13 ' LANGUAGE_CODE,' #13 ' PROMPT,' #13 ' DESCRIPTION,' #13 ' SUB_OUTLINE_ID,' #13 ' QUESTION_ID' #13 'FROM CSQ_OUTLINE_ENTRIES' #13 'WHERE OUTLINE_ID = ' IntToStr(ParentID)); Details.Open; WHILE NOT Details.Eof DO BEGIN MyTreeNode := TreeView1.Items.AddChild(TreeNode,Details.FieldByName('DESCRIPTION').AsString); MyTreeNode.Text := Details.FieldByName('DESCRIPTION').AsString; QueryDetails(Details.FieldByName('SUB_OUTLINE_ID').AsInteger,MyTreeNode); Details.Next; END; end; begin TreeView1.Items.Clear; QRY_CSQ_OUTLINES.Close; QRY_CSQ_OUTLINES.ParamByName('P_OUTLINE_ID').AsString := '1'; QRY_CSQ_OUTLINES.Open; WHILE NOT QRY_CSQ_OUTLINES.Eof DO BEGIN MyTreeNode := TreeView1.Items.AddChild(NIL,QRY_CSQ_OUTLINES.FieldByName('DESCRIPTION').AsString); QueryDetails(QRY_CSQ_OUTLINES.FieldByName('OUTLINE_ID').AsInteger,MyTreeNode); QRY_CSQ_OUTLINES.Next; END; end;-------------------------------- 小弟才疏學淺,若有謬誤請不吝指教 --------------------------------
------
Fishman |
casper wu
一般會員 發表:1 回覆:4 積分:1 註冊:2003-12-26 發送簡訊給我 |
|
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls; type TMyRec = record PK_No,FK_No,Name,Desc : string; end; type PMyRec = ^TMyRec; TForm1 = class(TForm) TreeView1: TTreeView; Button1: TButton; Button2: TButton; procedure Button1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } FMyRec : array of TMyRec; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var MyTreeNode1: TTreeNode; tRec:PMyRec; begin with TreeView1.Items do begin Clear; { remove any existing nodes } // ¥[¤J¤@Ó Root Node tRec := @FMyRec[0]; MyTreeNode1 := AddObject(nil,tRec^.PK_No,tRec ); // ¥[¤J¤@Ó Parsent Node tRec := @FMyRec[1]; AddChildObject(MyTreeNode1,tRec^.PK_No,tRec ); // ¦A¥[¤J¤@Ó Parsent Node tRec := @FMyRec[2]; AddChildObject(MyTreeNode1,tRec^.PK_No,tRec ); end; end; procedure TForm1.FormDestroy(Sender: TObject); begin // ¦^¦¬°}¦C SetLength(FMyRec,0); end; procedure TForm1.FormCreate(Sender: TObject); begin // ªì©l¤Æ°}¦C SetLength(FMyRec,3); // ¦s¤J FMyRec[0].PK_No := '1111'; FMyRec[1].FK_No := '0'; FMyRec[0].Name := 'Name1'; FMyRec[0].Desc := 'Desc1'; FMyRec[1].PK_No := '2222'; FMyRec[1].FK_No := '1111'; FMyRec[1].Name := 'Name2'; FMyRec[1].Desc := 'Desc2'; FMyRec[2].PK_No := '3333'; FMyRec[2].FK_No := '1111'; FMyRec[2].Name := 'Name3'; FMyRec[2].Desc := 'Desc3'; end; procedure TForm1.Button2Click(Sender: TObject); var MyRec: PMyRec; begin MyRec := TreeView1.Items[0].Data; ShowMessage(MyRec.Name); end; end.說明: 以上範例只示範利用 TreeView 存入 Record Data (我想應該是符合你的要求),然後顯示 TreeNode (Button1), Button2 示範如何取出存入 TreeNode 的值 假設您從資料庫中讀出您所敘述的值,那您要對自己的資料結構定義一個可以 完整 travel 的演算法,這樣您很容易便可以將 leave Node 填入對應的 Parent Node 內,只要 Travel 完,那 TreeView 便會呈現正確的樹狀結果 |
Fishman
尊榮會員 發表:120 回覆:1949 積分:2163 註冊:2006-10-28 發送簡訊給我 |
|
casper wu
一般會員 發表:1 回覆:4 積分:1 註冊:2003-12-26 發送簡訊給我 |
|
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
|
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
引言: 感謝SouthWind 我的資料全部來自於資料庫中... 因為資料來自於七個表格 且為關聯性的表格 所以希望在每展一階的情況下才去呼叫子階展開.. 感激不盡啊我猜你應該是需要 Travel 演算法,因為不知道您資料庫是用何實作的.. 寫一些 Pesudo Code 希望能對您有些幫助... 承襲 Fishman 的想法 .. Query1 => Table1 , Query1 => Table2 .... Query1 => Table7 Query1.Close; Query1.SQL.Clear; Query1.SQL := 'SELECT * FROM Table1'; Query1.Open; while Not Query1.Eof do begin Query2.Close; Query2.SQL.Clear; Query2.SQL := 'SELECT * FROM Table2 WHERE FK_NO=' Query1.FieldByName('PK_NO').AsString; Query2.Open; // Add Node Info // if you want to add Record or Object,Plz use AddObject TreeNode1 := TreeView1.Add(nil,Query1.FieldByName('PK_NO').AsString); while Not Query2.Eof do begin Query3.Close; Query3.SQL.Clear; Query3.SQL := 'SELECT * FROM Table2 WHERE FK_NO=' Query1.FieldByName('PK_NO').AsString; Query3.Open; // Add Node Info // if you want to add Record or Object,Plz use AddChildObject TreeNode2 := TreeView1.AddChild(TreeNode1,Query2.FieldByName('PK_NO').AsString); while Not Query2.Eof do begin // Query3 -> Query4 -> Query5 -> Query6 -> Query7 end; end; end;註解 : // Query3 -> Query4 -> Query5 -> Query6 -> Query7 是模仿上面兩個迴圈,一直寫到 Query7 .. (嗯,應該發現了,這個方法很蠢..) 說明 : 這個方法並不好,很不彈性(固定成七個迴圈),所以你可以改寫成類似的 > 利用 |
seaturn99
版主 發表:69 回覆:427 積分:214 註冊:2003-08-25 發送簡訊給我 |
casper wu 您好: 補充一個方便 Coding 的做法,您可以建一個上述七個表格的"關係表格"..
Ex: RelationTable
-------------------------
PK_NO => 此表格自己的 PK
Parent_NO => 紀錄上層的 PK_No
FromTable => 紀錄是從哪個表格來的 (若有需要的話)
-------------------------
Parent_NO + FromTable 要 Unique 這樣就不用打破原來的表格,只要在增加/刪除資料時,將各表格的關係對應寫入
RelationTable 就可以了,這樣就有 Tree 的資料結構 ... 套用一般對付 Tree 的遞迴方法,就會簡單多了... 希望對您有所幫助...
|
casper wu
一般會員 發表:1 回覆:4 積分:1 註冊:2003-12-26 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |