- 註冊時間
- 2006-3-13
- 最後登錄
- 2025-1-10
- 在線時間
- 673 小時
- 閱讀權限
- 200
- 積分
- 417
- 帖子
- 1107
- 精華
- 0
- UID
- 2
  
|
若 Master 與 Detail 都是使用 TQuery, 則當 Master 進入編輯狀態時,
Detail 資料表會被 Refresh (Close 然後 Open), 導致 detail 的
cursor 會跑到第一筆記錄(Delphi 3,4 皆如此),這對程式有什麼影響呢?
1.你不能夠在 MasterQuery.AfterPost 中寫 DetailQuery.Post 及
DetailQuery.ApplyUpdates, 這樣沒用, 而且 DetailQuery 中剛編
輯的資料都會消失. 相反的,你必須在 MasterQuery.BeforePost 中
撰寫儲存 DetailQuery 的程式碼(或者在 DetailQuery.BeforeClose
中撰寫也可以). 這和一般認為應該先儲存 Master 再儲存 Detail
的觀念剛好相反. 使用 TTable 則沒有這個情形.
以下範例擷取自 Delphi online help, 示範在 DetailTable 的
BeforeClose 事件中更新主細目資料表:
procedure TForm1.DetailBeforeClose(DataSet: TDataSet);
begin
if Master.UpdatesPending or Detail.UpdatesPending then
begin
if Master.UpdateStatus = usInserted then
Database1.ApplyUpdates([Master, Detail])
else
Database1.ApplyUpdates([Detail, Master])
end;
end;
2.首先, 假設我們有這樣子的操作介面: 一個 master grid 及多個
detail grid (你可能會用 PageControl 和一些按鈕一次開啟一個
detail query 以加快速度), 而且這兩個 Grid 是同時顯示在同一個
視窗, 你希望能夠以下列任何一種方式來編輯 detail 記錄:
a) 雙擊 detail grid 或者以一個Edit按鈕開啟一個資料編輯視窗。
b) DBNavigator。
c) 直接在 detail grid 中編輯
假設 detail 有三筆資料, 目前 cursor 停留在第二筆, 你可能會撰
寫類似的程式碼:
MasterQuery.Edit;
DetailQuery.Edit;
你希望在使用者編輯 detail 資料時要由程式強制讓 master query
進入 edit 狀態, 但是你會發現每次都是編輯到 DetailQuery 的第
一筆紀錄, 原因就如之前所說, detail query 被 refresh 而將
cursor 移至第一筆記錄.
解決之道有兩種:
a.由於這種問題只發生於 detail 也使用 TQuery 來存取的情形, 也
就是說你可 將 detail table 都改用 TTable 來存取,ie. master
table 以 TQuery 存取, detail tables 以 TTable 存取. 但使用
TTable 做 detail 也有缺點:
你不能任意指定其排序欄位, 它一定是用 foreign key 排序.
b.使用 TBookmark. 在 master query 進入編輯狀態前記住目前
detail query 的 cursor 位置, 並於 master query 進入編輯狀
態後將 detail 的 cursor 移回先前記錄的位置. 加入此程式碼的
最佳位置應該會是 detail query 的 BeforeEdit 事件. 這個方法
實作上並不困難, 也保留了較大的彈性.
3.當 master query 及 detail query 都處於編輯狀態, 你希望當執行
MasterQuery.Cancel 時也同時取消 detail query 的編輯狀態, 不
幸的是每當 master query 要 cancel 時會去尋找所有連結的資料集
, 如果連結的資料集在編輯狀態中就會將他們儲存, 即使你在master
query 的 BeforeCancel 中執行 DetailQuery.Cancel 也沒用, 因為
剛才所說的動作是在 BeforeCancel 事件之前就執行的。
解決之道: 不要用資料感知元件, 如 TDBNavigator, 改用一般的 Button 來執行取消動作, 如此便可完全掌握 master 與 detail 執行動作的順序了. |
|