PowerBuilder的資料視窗對象是其特有的智能對象,其封裝性好、功能強大、表現形式豐富多樣,為此,許多MIS開發人員對PowerBuilder推崇備至,將其視為首選開發工具。
一般情況下,一個資料視窗只能更新一個資料庫表,但在MIS開發過程中,我們經常遇到這種情況:一個資料視窗中由兩個或更多個資料庫表作為資料來源,並需要對其進行錄入或修改,如何給出多表更新的通用解決方案就成為MIS開發人員不容迴避的問題。筆者在某管理資訊系統的開發過程中,嘗試了幾種雙表更新的解決方案,選出一種比較好的方案,以饗讀者。
一、具體步驟
1. 在資料視窗建立時,選擇SQL Select,顯示風格可以是Tabular、Grid或FreeForm中的任一種。選出兩表需要錄入或修改的列,其中兩表的主鍵和非空列必須選中,確定選擇條件,建立串連關係。
2. 在選單“Rows/Update”中選擇第一個表的全部資料項目為可更新項。
3. 把兩表需要修改項的Tab Order數值改為非0值,使其在資料視窗中成為可修改項。
為了使方案具有通用性,建立全域函數f—update—2table,有五個參數:dw—obj、table1、table2、key1、key2,分別代表所要更新的資料視窗、兩表表名和兩表主鍵列名,其中dw—obj為DataWindow類型,其餘四參數均為String類型。該函數傳回值為Boolean型,返回True表示成功,返回False表示失敗。
二、函數思路
1. 先針對第一個資料庫表調用Update函數更新。注意參數的使用:第一個參數作用是控制資料視窗更新前是否強制性調用AcceptText(),在資料視窗更新前通過有效性驗證;第二個參數是控制更新標誌的複位,為True時更新標誌複位,為False時更新標誌不複位。
2. 更改資料視窗的UpdateTable屬性,使其指向第二個表,並把第一個表的各資料項目Update屬性和主鍵列的Key屬性改為No,接著把第二個表的各資料項目Update屬性和主鍵列的Key屬性改為Yes。本文來自http://bianceng.cn(編程入門)
3. 調用Update函數更新第二個表。
4. 兩表更新成功後,把兩表的列屬性、主鍵屬性改回到初始狀態,以便為下一次的兩表更新調用做好準備。
三、程式清單
// ColName:資料視窗列名
// Name1[],Name2[]:兩資料庫表選中項列名
// n1,n2:兩資料庫表選中項數量
// i:迴圈計數器
// Columns:資料視窗總列數
String ColName,Name1[],Name2[]
Integer Columns,i,n1=0,n2=0
//下面程式:找出dw—obj的兩表列名賦給Name1[],Name2[]
Columns=Integer(dw—obj.Describe(″DataWindow.Column.Count″))
FOR i=1 TO columns
ColName=Upper(dw—obj.Describe(″#″+String(i)+″.Name″))
IF Left(ColName,Len(Table1))=Table1 and ColName〈〉Key1 THEN
n1=n1+1
Name1[n1]=ColName
END IF
IF Left(ColName,Len(Table2))=Table2 and ColName〈〉Key2 THEN
n2=n2+1
Name2[n2]=ColName
END IF
NEXT
// 下面程式:儲存dw—obj,確定傳回值(True:成功,False:失敗)
IF dw_obj.Update(True,False)=1 THEN
FOR i=1 TO n1
dw—obj.Modify(Name1[i]+″.Update=No″)
NEXT
dw—obj.Modify(Key1+″.Key=No″)
dw—obj.Modify(″DataWindow.Table.Update
Table=′ ″+Table2+″ ′ ″)
FOR i=1 TO n2
dw—obj.Modify(Name2[i]+″.Update=Yes″)
NEXT
dw—obj.Modify(Key2+″.Key=Yes″)
IF dw—obj.Update()=1 THEN
Commit;
FOR i=1 TO n1
dw—obj.Modify(Name1[i]+″.Update=Yes″)
NEXT
dw—obj.Modify(Key1+″.Key=Yes″)
dw—obj.Modify(″DataWindow.Table.UpdateTable=′ ″+Table1+″ ′ ″)
FOR i=1 TO n2
dw—obj.Modify(Name2[i]+″.Update=No″)
NEXT
dw—obj.Modify(Key2+″.Key=No″)
return True
ELSE
Rollback;
return False
END IF
ELSE
Rollback;
return False
END IF
四、調用方法
假設視窗名為w—update,資料視窗為dw—1,資料庫表名和主鍵名分別為t1、t2、k1、k2,放置“存檔”按鈕,按鈕Clicked事件的Script語句如下:
dw_1.AcceptText()
IF dw—1.ModifiedCount()〉0 or dw_1.DeletedCount()〉0 THEN
IF MessageBox(″提示資訊″,″是否存檔?″,Question!,YesNo!)=1 THEN
IF f—update—2table(dw—1,″t1″,″t2″,″k1″,″k2″) THEN
Commit;
ELSE
Rollback;
END IF
END IF
END IF
綜上所述,可以看出,該方案具有很好的可擴充性,稍加修改即可解決多表作為資料來源的資料視窗的同步更新問題。