- 註冊時間
 - 2006-3-13 
 - 最後登錄
 - 2025-7-23 
 - 在線時間
 - 675 小時 
 - 閱讀權限
 - 200 
 - 積分
 - 417 
 - 帖子
 - 1109 
 - 精華
 - 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 執行動作的順序了. |   
 
  
 |