Pb從入坑到放棄(三)資料視窗

2023-07-10 12:01:52

寫在前面

資料視窗是Pb的一個特色控制元件,有了資料視窗對於pb來說可謂如虎添翼。

對資料庫中的資料操作,幾乎都可以在資料視窗中完成。

使用資料視窗可以簡單檢索資料、以圖形化的方式顯示資料、繪製功能強大的資料統計報表。

一、 資料視窗畫板

資料視窗畫板由Design, Preview, Control List, Data, Properties和 Column Specification 6個試窗構成

1.1 Design 視窗

Design 是一個非常重要的視窗 ,使用選單 Design→Options 來改變 Design 視窗的外觀

1.1.1 General tab頁設定

Snap to Grid:選中該屬性時,在資料視窗中的部件自動和網格對齊, 建議都選中

Show Grid:是否顯示網格。

-- 未選中 -- 選中後

Show Ruler:顯示標尺。

-- 未選中 -- 選中

X, Y:網格之間的間距,單位是資料視窗屬性中設定的單位

Show Edges:是否顯示邊框。主要針對欄位、標籤、文字等而言

Retrieve on Preview:是否在預覽時檢索

1.1.2 Generation tab頁設定

Presentation Style:在該下拉選單框中可以選擇要設定哪種型別的資料視窗。下面的
其他操作都是針對選中的那種型別的資料視窗而言的。
Background Color:設定資料視窗的背景顏色。
Text 組框: border 可以設定 text 部件的邊框型別, color 可以設定文字的顏色。
Columns 組框: border 可以設定欄位的邊框型別, color 可以設定欄位中文字的顏

1.1.3 Prefixes tab頁設定

設定資料視窗中放置部件時命名的預設字首

1.2 Preview 視窗

可以預覽資料視窗的外觀,並顯示相應表中對應的資料

在該視窗中可以進行各種資料操作,包括資料過濾、資料排序、增加資料、刪除資料、檢索資料、查詢資料以及翻頁等

這些操作都可以在滑鼠右鍵彈出選單中完成

1.2.1 查詢資料
--撥出選單 -- 查詢內容
1.2.2 翻頁
-- 撥出選單 --撥出選單
  • first page(翻到第一頁)
  • prior page(前一頁)
  • next page(下一頁)
  • last page(最後一頁)
1.2.3 增加、刪除資料

在資料視窗中增加或者刪除資料,得首先設定資料視窗相應的屬性,

允許修改的欄位Tab Order 值不能為 0

-- --

1.3 Control List 視窗

Control List 是資料視窗中所有的部件構成的一個列表

1.4 Data 視窗

顯示的是資料視窗物件中的資料,很多操作和 Preview 視窗中的都相同 .

該視窗側重於對應表中各個欄位的取值,而 Preview 視窗側重於資料視窗物件的顯示效果

1.5 Properties 視窗

屬性視窗顯示的是當前選中物件的屬性,可以對這些屬性進行修改

1.6 Column Specification 視窗

是一個比較重要的視窗,在該視窗中可以增加、刪除、修改列的初始值、檢驗表示式或者校驗資訊

舉個栗子:

假設 empno的位數是 10,如果位數不正確,則應該提醒使用者。

Validation Expression列為欄位 empno輸入校驗表示式:
len(empno) = 10
Validation message 中輸入:'員工編號必須為 10 位! '
當程式執行時,會自動校驗使用者輸入的內容是否位數為 10 位,否則顯示輸入的資訊

二、資料視窗的資料來源

Pb提供的 Quick Select(快速選擇型別)、 SQL Select( SQL 選擇型別)、 Query(查詢型別)、 External
(外部型別) 和 Stored Procedure(儲存過程型別) 5種資料來源

2.1 Quick Select 資料來源

快捷資料來源,是經常使用的一種資料來源,可以快速地建立資料視窗 。

使用這種資料來源,只能從一個資料表或者檢視中選取資料

需要從多個資料表中選取資料而且還想使用這種資料來源時,只能建立對應的檢視

-- --

2.2 SQL Select 資料來源

選擇這種資料來源時,SQL語句設計是圖形化的,也可以手工輸入SQL語句

-- ①選擇資料來源 --②選擇表
--③ 選擇欄位 -- SQL語法和圖形化切換
-- ④ 定義檢索條件

2.3 Query 資料來源

PB可以將特定的 SQL 語句儲存為 Query 物件, 不同的 Query 資料來源的資料視窗都可以使用這些已經儲存
Query物件來作為資料來源,增強了 SQL 語句的重用性

--① 新建Query資料來源物件 --② 使用Query 資料來源

2.4 External 資料來源

是一種比較特殊的資料來源,可以彌補其他四種資料來源的不足

當和不存在於資料庫中的資料打交道或者要利用資料視窗的某些特性但不進行資料處理時,這兩種情況下都可以使用 External 資料來源的資料視窗

--① 指定資料來源 -- ② 設定資料型別及長度

2.5 Stored Procedure(儲存過程)

可以直接使用資料庫中已經建立好的儲存過程作為資料來源

SQL 語句無需網上傳送,可以減少網路通訊量及網上傳輸 SQL 語句的時間, 所以執行效率比其他資料來源的資料視窗要高

-- ① 選擇資料來源 --② 選擇資料庫中建立好的儲存過程

2.6 Web Service 資料來源

這是PB 11.5 以後新加的資料來源

--① 選擇Web Service 資料來源 --②輸入WebService的WSDL檔案的地址
--③ 選擇WebService介面 --④ 選擇WebService 介面方法

三、資料視窗顯示樣式

3.1 Grid 顯示樣式

資料視窗佈局整齊,但不能靈活地安排欄位、標籤、表頭的佈局

欄位橫向排列在 detail band 中,標籤橫向排列在 header band 中,和欄位相對應,欄位和欄位之
間有格線分隔,類似於電子試算表 。

如下圖所示

3.2 Tabular 顯示樣式

欄位、標籤的佈局和 Grid 顯示樣式的資料視窗相同,都是橫向排列的,但是欄位之間沒有格線分隔。

欄位和標籤的佈局可以隨意調整,在 header band 中的標籤可以隨意拖放到 detail band 中,

detail band 中的欄位也可以拖放到 header band 中

3.3 Group 顯示樣式

資料視窗可以指定按那個(或那些)欄位進行分組,可以用指定的分組條件將資料分組顯示,並且允許為每組指定一些計算。

例如:要顯示各部門員工的薪資資料,可以按部門分組

-- ①按部門分組 -- ②分組後資料

3.4 Freedom 顯示樣式

這種顯示樣式的資料視窗佈局也很靈活,可以隨意安排欄位和標籤的位置

-- ① 選擇Freeform -- ②錄入表單資訊

3.5 Label 顯示樣式

如果使用者想要生成郵件標籤,可以使用 Label 顯示樣式的資料視窗來實現

在嚮導的指引下,可以設定標籤的一些引數。

可以指定標籤的大小,包括三方面的設定: Label 本身的大小、Label 之間的邊框、 Label 的佈局順序。

在 Label 組框中,引數「 Across」指橫向顯示的標籤數目, 「 Down」表示一頁中豎向顯示的標籤數目

-- --

3.6 N-up 顯示樣式

可以在同一頁上顯示多列相同欄位的一種特殊的顯示樣式 .

可以設定每行重複顯示欄位的次數 ,預設是2

這裡我們每行顯示2列員工編號和員工姓名

-- ① 選擇N-up樣式 -- ②設定每行顯示列數

3.7 CrossTab 顯示樣式

通過CrossTab 顯示樣式我們可以製作出下圖所示的交叉報表

--① 選擇CrossTab 顯示樣式 --② 設定行分類、列分類

最終顯示效果

3.8 Graph 顯示樣式

Graph 顯示樣式 可以顯示餅圖、柱狀圖、折線圖等

Graph 顯示樣式的資料視窗時,三個主要引數是

  • Category 顯示在橫向座標軸上的欄位
  • Values 顯示在縱向座標軸上的欄位
  • Series 橫向座標軸上同組比較時的分組標準
-- ① 選擇Graph 樣式 -- ② 選擇橫向、縱向座標
--③ 選擇圖表樣式及設定標題

我們這裡選擇柱狀圖顯示,一共又17種樣式可以選擇,感興趣的小夥伴可以都試試

3.9 Composite 顯示樣式

這種樣式的資料視窗可以將多種型別的、多個邏輯上毫不相關的資料視窗放置到一起,是一種比較靈活的

我們把前面製作好的柱狀圖和表格放到一起

-- ① 選擇Composite 顯示樣式 -- ② 選擇要展示的報表

最終顯示效果

3.10 RichText 顯示樣式

這種樣式的資料視窗使資料庫中的資料和文字可以在一起排版,可以方便地將資料庫中的資料和文字內容一起形成文
檔、報告 。

-- ① 選擇RichText 顯示樣式 -- ② 選擇文書處理工具

最終顯示效果

3.11 OLE 2.0 顯示樣式

OLE 物件連結和嵌入 。使用它可以將其他軟體的功能引入到 PB開發的應用程式中

使用這種顯示樣式的資料視窗,可以借鑑其他軟體的強大功能,彌補 PB在某些專業性較強領域中的不足或空白

-- ① 選擇OLE 樣式 -- ② 設定分組

3.12 TreeView 顯示樣式

該樣式可以按照樹形結構顯示資料,我們以empdept表為例,以dept_name 欄位進行分組

-- ① 選擇TreeView 樣式 -- ② 選擇dept_name分組

最終效果

四、資料視窗物件介紹

資料視窗用帶( Band)將其分隔成四部分 ,一個標準的報表一般由題頭、資料、頁尾、總計四部分構成,分別對應資料視窗的 Header, Detail,
Summary 和 Footer 四部分

描述
Header 出現在每頁的頂端,用於顯示標題和列的題頭。
放置表頭、報表日期等一些能夠方便查閱的內容, 即使這部分欄位的 Tab Order 值不為 0、 DisplayOnly 屬性為 False 也不允許使用者編輯,並且也只能顯示多條記錄中的一條
Detail 包含了資料視窗物件的主體,顯示了各行的資料和相關的標籤。
放置資料、表格,程式執行時,資料視窗自動處理該區域,根據資料庫中的資料顯示一條或者多條資料
Summary 出現在每頁的底端,用來顯示文字和頁號
放置頁內小計、頁號等頁尾方面的內容
Footer 出現在 DataWindow 物件的最後一頁,用來為整個資料視窗物件顯示總計和總和
放置總計、製表人等需要在表格最後放置的內容

五、資料視窗常用函數

函數 引數 說明
dw_1.insertrow(row) row 設定插入位置
成功時返回插入成功的行號,失敗返回-1
insertrow(0) 表示在最後一行插入一行
插入空行
dw_1.deleterow(row) row 要刪除的行號
成功時返回1,失敗時返回-1
deleterow(0) 代表刪除當前行
刪除行
dw_1.retrieve() dw_1.retrieve(引數1,引數2,引數3...) 檢索資料
dw_1.update(accept,resetflag) accept:預設為true,執行之前呼叫
resetflag:預設為true,資料視窗自動重置更新標誌
成功返回1,失敗返回-1
修改或更新操作
dw_1.setsort(format) format: A 升序,D降序
成功時返回1,失敗時返回-1
設定排序
dw_1.sort() 成功是返回1,失敗時返回-1 按照當前資料視窗 的排序規則進行排 序
dw_1.setfilter(format) format:是字串,可以使用欄位名或欄位號定義
成功時返回1,失敗時返回-1
例1:dw_1.setfilter("sal> 5000 and age < 10000")
例2:dw_1.setfilter(#3>5000)
例3:dw_1.setfilter("")
設定資料視窗的過 濾條件
dw_1.filter() 對資料視窗進行過 濾
dw_1.reset() 成功返回1,失敗返回-1 清除資料視窗的所 有資料
dw_1.scroll(number) number:捲動的行數
引數為正數的時候向下捲動,為負數時向上捲動
成功返回控制元件第一行顯示的資料行號,失敗時返回-1
設定捲動的行數
dw_1.scrolltorow(row) row 指定的行號
成功返回1,失敗返回-1
捲動到指定行
dw_1.scrollpriorpage() 捲動到上一頁
dw_1.ScrollNextPage() 捲動到下一頁
dw_1.scrollpriorrow() 捲動到上一行
dw_1.scrollnextrow() 捲動到下一行
dw_1.getrow() 沒有當前行時返回0,失敗返回-1,成功返回當前行號 獲得當前行的行號
dw_1.getcolumn() 沒有當前列時返回0,失敗返回-1,成功返回當前列的 列號 獲取當前列的列號
dw_1.setrow(row) row 指定的行號
成功返回1,失敗返回-1
設定當前行
dw_1.setcolumn(column) coumn 列號或列名
成功返回1,失敗返回-1

例:設定當前列為第5列
dw_1.setcolumn(5)

例:設定當前列為age列
dw_1.setcolumn("age")
設定當前列
dw_1.setrowfocusindicator(f,x,y) f 用於指示當前行的視覺化圖示
x x座標
y y座標
成功返回1,失敗返回-1

例:設定手形圖示
dw_1.setrowfocusindicator(Hand!)

例2:設定圖片控制元件p_arrow為指示圖示
dw_1.setrowfocusindicator(p_arrow)
設定用於指示當前 行的視覺化圖示
dw_1.rowcount() 無資料時返回0,失敗返回-1 獲得資料視窗總行 數
dw_1.modifiedcount() 返回被修改但未更新的資料行數
無資料時返回0,失 敗返回-1
獲得資料視窗中被 修改,但未更新的 資料行數。(不包 括新插入的行)
dw_1.deletedcount() 無資料時返回0,失敗返回-1 獲得資料視窗中做 了刪除標記,未做 update操作的數 據行數
dw_1.filteredcount() 無資料時返回0,失敗返回-1 獲得被過濾掉的數 據行數
dw_1.accepttext() 將還在編輯中的數 據,傳送到資料窗 口控制元件
dw_1.gettext() 獲得編輯控制元件中的 文字
dw_1.settext(text) 成功返回1,失敗返回-1 設定編輯控制元件中的 文字
dw_1.GetItemDate (row,column,dwbuffer,originalvalue) row 指定資料行的行號
column: 指定的資料列
dwbuffer: 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值

例:取資料視窗dw_1第3行first_day欄位的日期型變數 dw_1.getitemdate(3,"first_day")
獲取指定欄位的日 期型變數
dw_1.GetItemDateTime(row,column,dwbuffer,originalvalue) row: 指定資料行的行號
column: 指定的資料列
dwbuffer 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值
獲取指定欄位的日 期時間型變數
dw_1.GetItemTime(row,column,dwbuffer,originalvalue) row 指定資料行的行號
column: 指定的資料列
dwbuffer 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值
獲取指定欄位的時 間型變數
dw_1.GetItemString(row,column,dwbuffer,originalvalue) row 指定資料行的行號
column: 指定的資料列
dwbuffer 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值
獲得指定欄位的字 符串變數
dw_1.GetItemNumber(row,column,dwbuffer,originalvalue) row 指定資料行的行號
column: 指定的資料列
dwbuffer: 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值
獲得指定欄位的數 值型變數
dw_1.GetItemDecimal(row,column,dwbuffer,originalvalue) row 指定資料行的行號
column: 指定的資料列
dwbuffer 指定讀取資料的緩衝區
originalvalue 為true時,返回原始緩衝區的值,為 false時返回當前值
獲得指定欄位的小 數型變數
dw_1.sharedata(dwsecondary) 成功返回1,失敗返回-1 資料視窗控制元件資料 共用,保持同步更 新
dw_1.sharedataoff() 成功返回1,失敗返回-1 關閉資料視窗之間 的共用關係
dw_1.print() 成 功返回1,失敗返回-1 列印資料視窗
dw_1.printcancel() 成功返回1,失敗返回-1 取消資料視窗的打 印
dw_1.getitemstatus (row,colum,dwbuffer) row: 指定資料的行號
column: 指定的資料列
dwbuffer: 指定讀取資料的緩衝區,預設為主緩衝區, 返回一個dwitemstatus列舉變數

例:取資料視窗dw_1第5行work欄位在filter緩衝區的 狀態 l_status l_status = dw_1.getitemstatus(5,'work',filter!)
獲取指定欄位的狀 態
dw_1.setitemstatus (row,colum,dwbuffer,status) row: 指定資料的行號
column: 指定的資料列
dwbuffer :指定讀取資料的緩衝區,預設為主緩衝區, 返回一個dwitemstatus列舉變數 status 列舉變數

例:設定資料視窗dw_1第5行party欄位在主緩衝區的 狀態為notmodified
l_status l_status = dw_1.setitemstatus(5,'salary',primary!,notmodified!)
設定指定欄位的狀 態
dw_1.setitem(row,column,value) row: 指定的行
column :指定的列
value: 賦值的內容
為指定欄位賦值
dw_1.getvalidate(column) column 定義檢驗規則的欄位(序號或欄位名)。返回 指定欄位的有效性檢驗規則 獲取當前某些欄位 的有效性檢驗規則
dw_1.setvalidate(column,rule) column 定義檢驗規則的欄位(序號或欄位名) rule 新的有效性檢驗規則
成功返回1,失敗返回-1
設定當前某些欄位 的有效性檢驗規則

六、資料視窗使用技巧

6.1 資料視窗的增刪改查

6.1.1 將編輯的資料放到主緩衝區
dw_1.accepttext()
6.1.2 增加一行資料
dw_1.insertrow(0)
6.1.3 刪除一行資料
dw_1.deleterow(row)
6.1.4 更新資料
dw_1.update()
  • 在使用update() 函數將修改的資料儲存到資料庫中時,必須要設定資料視窗的修改屬性。

  • 資料視窗只能修改一個資料表

  • 當增加、刪除或者重新選擇了欄位時, PB將資料視窗的修改屬性置為不允許,這時也應該進行手工設定

單項 Rows→Update Properties 進行修改屬性的設定

  • Allow Updates : 選中該選項,才允許繼續進行其他屬性的設定
  • Table to Update :要被更新的表
  • Where Clause for Update/Delete
選項 說明
Key Columns 單使用者應用程式或者使用者都以加鎖方式存取資料庫時可以選中該選項
只使用在「 Unique Key Column(s)」列表框中指定的惟一列進行資料更新
Key and Updateable Columns 預設的修改方式
用主鍵列和可以修改的列來建立 where 子句
Key and Modified<br/>Columns 上面兩種方法的折中
用主鍵和資料發生了變化的列來產生 where 子句
  • Key Modification
選項 說明
Use Delete then Insert 先刪除原有主鍵值,然後再使用新的主鍵值插入一個完整的行
Use Update 通過Update語句修改資料
  • Updatable Columns : 需要修改的列
  • Unique Key Column(s) : 唯一能夠確定一行的列
6.1.5 查詢資料
dw_1.settransobject(sqlca)
dw_1.retrieve()

6.2 資料視窗更新多個表

思路: 動態修改資料視窗的Update屬性

舉個栗子: dw_1資料視窗中包含兩張表的欄位,emp(員工資訊表),dept(部門表)

select dept.deptno,dept.dname,
emp.empno,emp.ename
from emp,dept
where emp.deptno = dept.deptno

在建立資料視窗時設定為 dept 表可修改

Int li_update
li_update = dw_1.Update(True,False) //接受最後一個欄位內容,並且不清除行修改標誌
// 如果對 Department 表的修改成功,下一步就要修改另一個表 Employee
If li_update = 1 Then
    //首先,關掉對 dept 表的修改
    dw_1.ModIfy('dept_dname.Update = "No"')
    dw_1.ModIfy('dept_deptno.Update = "No"')
    dw_1.ModIfy('dept_deptno.Key = "No"')
    //使 emp 表成為新的可修改表
    dw_1.dwModIfy('DataWindow.Table.UpdateTable = ~'emp~' ')
    dw_1.ModIfy('emp_empno.Update = "Yes"')
    dw_1.ModIfy('emp_ename.Update = "Yes"')
    dw_1.ModIfy('emp_empno.Key = 'Yes' ' )
    //然後修改 Employee 表
    li_update = dw_1.Update()
    If li_update = 1 Then
    Commit Using SQLCA;
Else
    MessageBox("修改錯誤! ", "資料修改錯誤,錯誤程式碼"&
    + String(SQLCA.SqlDBCode) + "~r~n 錯誤原因: "+ SQLCA.SqlErrText)
    Rollback Using SQLCA;
    End If
    //恢復資料視窗開始時的屬性,以便下一次使用者單擊「儲存」按鈕時
    //程式能夠正確執行
    dw_1.ModIfy('dept_dname.Update = "Yes"')
    dw_1.ModIfy('dept_deptno.Update = "Yes"')
    dw_1.ModIfy('dept_deptno.Key = "Yes"')
    dw_1.ModIfy('DataWindow.Table.UpdateTable = ~'dept~' ')
    dw_1.ModIfy('emp_empno.Update = "No" ')
    dw_1.ModIfy('emp_ename.Update = "No" ')
    dw_1.ModIfy('emp_empno.Key = "No" ')
Else
    MessageBox('部門表更新失敗,回滾更改為部門')
    Rollback Using SQLCA;
End If

6.3 設定欄位唯讀

① 方法一

將tab order 設定為0

② 方法二

dw_1.modify("cname.tabsequence = 0 ")  

③ 方法三

dw_1.modify( "meno.edit.displayonly=yes")

④ 方法四

dw_1.modify("code_course.protect= 1")

6.4 切換資料視窗資料來源

dw_1.dataobject = "資料視窗名"

6.5 隱藏資料視窗重新整理過程

dw_1.setredraw(false) //不重新整理
dw_1.setredraw(true) //重新整理

6.6 資料視窗共用資料

dw_2.sharedata(dw_1)

6.7 資料視窗SQL中傳遞 in 的引數

select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,emp.sal,emp.comm  from emp where emp.empno in (傳入的引數)
//在傳給資料視窗時,in中的內容必須是陣列型別
string[] arr_in
arr_in[1]='7369'
arr_in[2]='7499'
arr_in[3]='7521'
dw_1.retrieve(ls_in)

6.8 獲取當前資料視窗的sql

dw_1.getsqlselect()

6.9 設定當前資料視窗的sql

dw_1.setsqlselect(sql)

6.10 呼叫子資料視窗

integer rtncode
datawindowchild dwc_child
rtncode = dw_1.getchild("主視窗欄位", dwc_child)
if rtncode = 1 then
	messagebox('',dwc_child.getitemstring(1,'子視窗欄位'))
else
	messagebox('提示','未獲取到子資料視窗!')
end if

6.11 判斷資料視窗是否被修改

//判斷資料視窗是否修改,建議寫在closequery事件中
if dw_1.modifiedcount() + dw_1.deletedcount() > 0 then
	messagebox('提示','資料視窗已經修改,是否儲存?')
else
	messagebox('提示','資料視窗沒有修改,正常退出')
end if

6.12 資料視窗重置

dw_1.reset()

6.13 資料視窗重新分組

//重新分組,在我們處理過濾和排序後,如果是分組視窗可能會破壞分組規則
//所以我們要進行重新分組,重新分組一般都是在filter()或sort()後面
dw_1.groupcalc()

6.14 獲得資料視窗的狀態

//(可選狀態:datamodified! new! newmodified! notmodified!)
//當第一次使用retrieve()函數從資料庫中讀取資料時,所有在資料視窗緩衝區的記錄與欄位都是屬於
NotModified!狀態。
//當時資料被修改過後,被修改過的記錄狀態標誌與欄位狀態標誌都會被改成DataModified!
//當增加一筆資料時,增加資料的欄位狀態標誌為NotModified!,記錄狀態標誌為New!.
//當我們在增加的欄位中填上資料後,欄位狀態標誌為DataModified!記錄狀態標誌為NewModified!
if dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = datamodified! then
	messagebox('1:已修改資料','datamodified!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = new! then
	messagebox('2:已增加資料','new!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = newmodified! then
	messagebox('3:已填寫資料','newmodified!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = notmodified! then
	messagebox('4:未修改資料','notmodified!')
end if

6.15 設定資料視窗狀態

//(可選狀態:datamodified! new! newmodified! notmodified!)
dw_1.setitemstatus(1,dw_1.deletedcount(),primary!,notmodified!)

6.16 查詢資料視窗中第一個被選中的行

dw_1.getselectedrow(0)

6.17 資料視窗查詢(find)

//dw_1.find(查詢條件表示式,開始行, 結束行), 如果表示式成立,那麼就返回符合條件的行號
dw_1.find('id=8',1,10)

6.18 資料視窗過濾

① 列名過濾

dw_1.setfilter("isnull(列名)")
dw_1.filter()

②條件過濾

dw_1.setfilter("列名='" + 列值 + "'")
dw_1.filter()

③ 清除過濾

//方法一
dw_1.setfilter('')
dw_1.filter()
//方法二
dw_1.setfilter('1=1')

④ sql語句過濾

sql = 'select * from 表名 where isnull(欄位名 , ''空'') = ''空'' ' ;

6.19 資料視窗分頁

增加一個計算列
計算列必須放在detail段
expression中輸入:ceiling(getrow()/20) 這裡表示每頁20條資料

這裡20還可以用全域性函數取代,這樣可以允許使用者任意設定每頁多少行。

定義分組,選擇選單rows->create group...

按計算列欄位分組,並一定將check box-->new page on group break選中

將此計算列設為不可視

然後新增以下按鈕,完成分頁功能

①首頁

dw_1.scrolltorow(0)
dw_1.setrow(0)

② 上一頁

dw_1.scrollpriorpage()

③ 下一頁

dw_1.scrollnextpage()

④ 最後一頁

dw_1.scrolltorow(dw_1.rowcount())
dw_1.setrow(dw_1.rowcount())

6.20 資料視窗排序

① 正序排列

dw_1.setsort("列名 a")
dw_1.sort()

② 倒序排列

dw_1.setsort("列名 d")
dw_1.sort()

③ 雙擊排序

string ls_old_sort, ls_column
char lc_sort
if right(dwo.name,2) = '_t' then
    ls_column = left(dwo.name, len(string(dwo.name)) - 2)
    ls_old_sort = this.describe("datawindow.table.sort")
    if ls_column = left(ls_old_sort, len(ls_old_sort) - 2) then
    	lc_sort = right(ls_old_sort, 1)
        if lc_sort = 'a' then
            lc_sort = 'd'
        else
            lc_sort = 'a'
        end if
		this.setsort(ls_column + " " + lc_sort)
	else
		this.setsort(ls_column + " a")
	end if
	this.sort()
end if

6.21 資料視窗獲取焦點

dw_1.setfocus()
dw_1.setrow("資料行號")
dw_1.setcolumn("欄位名")

6.22 資料視窗行相關

① 行處理

dw_1.rowcount() //獲取總行
dw_1.getrow() //獲取當前行
dw_1.setrow(1) //設定當前行
dw_1.scrolltorow() //捲動到目標行
dw_1.selectrow(1, true) //將第一行變成選中狀態
dw_1.isselected(1) //檢查第一行是否被選擇

② 點選高亮顯示

Ⅰ 在資料視窗的click事件中,寫入以下程式碼

if row > 0 then
    this.selectrow(0,false)
    this.selectrow(row,true)
end if

Ⅱ在資料視窗rowfocuschanged事件中,寫入以下程式碼

if currentrow > 0 then
    selectRow(0, false)
    selectRow(currentrow, true)
    scrolltorow( currentrow )
end if

③ 隔行變色

Ⅰ 開啟資料視窗
Ⅱ. 右鍵 detail
Ⅲ. 找到右側 color 屬性右側的小圖示
Ⅳ. 在表示式中輸入以下程式碼

if ( mod( getrow() , 2) = 1 , rgb(255,255,255) , rgb(235,255,235) )

④ 自增行

Ⅰ. 新增計算列, page n of n
Ⅱ. 選擇 getrow()

⑤ 設定每頁列印行數

Ⅰ. 新增計算列 page n of n ,輸入公式: ceiling(getrow()/20)
Ⅱ. 選擇選單 rows->create group ,建立分組,選擇剛才建立的公式列page_1

Ⅲ. 建立完分組後,選擇右側屬性, new page on group break 打上勾即可
Ⅳ. 如果需要最後一頁不足補空行

long ll_pagerow = 6 //每頁列印行數
long ll_count, ll_row
ll_count = dw_1.retrieve()
//取得現有報表的總行數
ll_count = ll_pagerow - mod(ll_count, ll_pagerow)
if ll_count < ll_pagerow then
    for ll_row = 1 to ll_count
        dw_print.insertrow(0) //補足空行
    next
end if

⑥ 移動行

//移動行
//(primary!主緩衝區 delete!刪除緩衝區 filter!過濾緩衝區)
//dw_name.rowsmove(開始行,結束行,緩衝區,要移動到的另一視窗名,在哪一行前面插入,插入哪個緩衝區)
//rowsmove還可以在同一資料視窗的不同緩衝區進行移動行
//如:從刪除緩衝區移動行到主緩衝區實現恢復功能:
dw_1.deleterow(1) //刪除第1行
dw_1.rowsmove(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //恢復第1行

⑦ 複製行

//複製行(primary!主緩衝區 delete!刪除緩衝區 filter!過濾緩衝區)
//dw_name.rowscopy(開始行,結束行,緩衝區,要複製到的另一視窗名,在哪一行前面插入,插入哪個緩衝區)
//rowscopy( )--基本用法和移動行差不多
dw_1.deleterow(1) //刪除第1行
dw_1.rowscopy(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //複製第1行

6.23 列處理

① 獲得資料視窗所有的列名

integer li_index
for li_index = 1 to integer(dw_1.object.datawindow.column.count)
	messagebox(string(li_index),dw_1.describe("#" + string(li_index) + ".name"))
next

② 獲得欄位對應的dbname

integer li_index
for li_index = 1 to integer(dw_1.object.datawindow.column.count)
	messagebox(string(li_index),dw_1.describe("#" + string(li_index) +".dbname"))
next

③ 複製列

dw_1.object.欄位名.primary = dw_1.object.欄位名.primary

④ 獲取顯示列

describe('DataWindow.Table.GridColumns')

6.24 資料視窗中實現核取方塊

① 在資料視窗的sql中,新增多選框欄位

'0' as checkbox

② 設定欄位的 edit 屬性為 checkbox ,並勾選3d look

③ 設定(data value for on = 1),設定(data value for off = 0)

④ 再dw_1資料視窗的click事件中寫

if dwo.name = "checkbox" then
	if dw_1.rowcount() = 0 then
	else
        if dw_1.object.checkbox[1] = "1" then
            for row = 1 to dw_1.rowcount()
                dw_1.object.checkbox[row] = "0"
            next
        else
            for row = 1 to dw_1.rowcount()
                dw_1.object.checkbox[row] = "1"
            next
		end if
	end if
end if

⑤ 判斷是否選中

long i
if dw_1.rowcount() = 0 then return 0
for i = 1 to dw_1.rowcount()
    if dw_1.getitiemstring(i, "checkbox") = '1' then
        messagebox('提示資訊',‘第’+string(i)+'行被選中')
    end if
next

6.25 資料視窗轉datastore

datastore lds_data
lds_data = create datastore
//給範例化後的datastore變數關聯資料視窗物件
lds_data.dataobject = 'd_data'
//給資料儲存物件指定事務物件
lds_data.settransobject(sqlca)
    
//接下來就和操作普通資料視窗一樣了
long ll_row
ll_row = lds_data.insertrow(0)
lds_data.object.name[ll_row] = '張三'

6.26 動態資料視窗

① 資料視窗賦值與取值

//1 賦值
dw.setitem(行, '列名稱', 值)
dw.object.列名[行號] = 值
    
//2 取值
dw_1.object.欄位名[行數] //直接取值
dw_1.object.欄位名.text //文字方塊
dw_1.GetItemString(行數,列名) //字串
dw_1.GetItemNumber(行數,列名) //數值
dw_1.GetItemDate(行數,列名) //日期
dw_1.GetItemDateTime(行數,列名) //日期時間
dw_1.GetItemDecimal(行數,列名) //小數

② 通過describe 獲取資料視窗中的各種屬性

dw_1.Describe("#1.name")  //獲取欄位名稱  title
dw_1.Describe("title.ColType")  //獲取欄位型別  char(100)
dw_1.Describe("title.background.color") // 獲取欄位背景顏色 536870912
dw_1.Describe("title.background.mode") //獲取欄位背景模式 1
dw_1.Describe("title.edit.Autohscroll") //獲取欄位是否允許自動橫向捲動 yes
dw_1.Describe("title.key")  //獲取欄位是否為主鍵 no
dw_1.Describe("title.protect") //獲取欄位中的資料保護 0
dw_1.Describe("title.SlideLeft") //獲取欄位的滑動屬性(當左面空白時是否向左滑動)  no
dw_1.Describe("title.slideup") //獲取欄位的滑動屬性(當上面出現空白時是否向上滑動) no
dw_1.Describe("title.tabsequence") // 獲取欄位的TabOrder值    15
dw_1.Describe("title.update")  //獲取欄位是否可以修改 yes
dw_1.Describe("title.validation") // 獲取欄位的校驗規則
dw_1.Describe("title.expression") // 獲取欄位的表示式
dw_1.Describe("Evaluate('LookupDisplay(sex)',1)")  // 獲取顯示值的屬性
    

③ 通過modify 修改資料視窗中的各種屬性

dw_1.modify("title.background.mode='1'")  // 修改欄位背景模式
dw_1.modify("title.background.color = '0'") //修改欄位背景顏色
dw_1.modify("title.criteria.dialog = yessex.criteria.override_edit =yes")  //修改檢索規則
dw_1.modify("title.edit.required = yes") //修改欄位為必須輸入
dw_1.modify("title.format = 'yyyy-mm-dd'")  // 修改欄位顯示格式為日期格式
dw_1.modify("title.key = yes") // 修改欄位為主鍵
dw_1.modify("title.protect ='1~tif(isrownew(),0,1)'")  //修改欄位的保護屬性

④ 程式執行中動態建立資料視窗

方法Ⅰ

string str_dwsyntax,str_lag
//獲得資料視窗1的語法
str_dwsyntax=dw_1.object.datawindow.syntax
//根據資料視窗1的語法動態生成資料視窗2的語法
dw_2.create(str_dwsyntax)
//對資料視窗2的內容作區域性修改
str_lag="stu_id_t.font.height='-12' stu_id_t.font.face='楷體_GB2312'"
//字型變12號字型,由宋體改為楷體
dw_2.modify(str_lag)
dw_2.settransobject(sqlca)
dw_2.retrieve()

方法Ⅱ

在程式中使用系統函數LibraryExport()得到某個已經存在的資料視窗物件的原始碼

方法Ⅲ

在PB開發環境的庫管理畫筆(Library Painter)中使用移出功能(右鍵→Export)將某個資料視窗物件的語法儲存到文字檔案中

方法Ⅳ

//連線預設事務sqlca
sqlca.dbms = "O84 Oracle8/8i (8.x.4+)"
SQLCA.LogPass = '資料庫密碼'
SQLCA.ServerName = ‘伺服器IP’
SQLCA.LogId = '資料庫使用者名稱'
SQLCA.AutoCommit = False
SQLCA.DBParm = "PBCatalogOwner='hb_zh'"
sqlca.autocommit = false
sqlca.dbparm = ""
connect using sqlca;
string dw_sql,dw_style
string dw_syntax,dw_syntax_error,dw_create_error
//設定資料視窗sql
dw_sql = "select * from 表名"
//設定資料視窗風格
dw_style = "style(type=grid)"
//構造sql資料來源
dw_syntax = sqlca.syntaxfromsql(dw_sql, dw_style, dw_syntax_error)
//判斷sql資料來源是否有錯誤
if len(dw_syntax_error) > 0 then
	messagebox("提示", "構造sql資料來源錯誤: " + dw_syntax_error)
	return
end if
//通過sql資料來源建立dw_1資料視窗
dw_1.create(dw_syntax,dw_create_error)
//判斷dw_1資料視窗在建立中是否有錯誤
if len(dw_create_error) > 0 then
	messagebox("提示", "建立資料視窗錯誤: " + dw_create_error)
	return
end if
//檢索資料
dw_1.settransobject(sqlca)
dw_1.retrieve()

以上用到的SyntaxFromSQL()函數和Create() 函數具體說明如下

6.27 資料視窗匯入匯出

① 資料視窗匯入

//dw_1.importfile(匯入的檔案型別, 檔名, 檔案的開始行 , 檔案的結束行, 檔案的開始列, 檔案的結束列, 資料視窗的開始列 )
//因為匯出的資料視窗都有標題,所以我們這邊從第2行開始匯入
dw_1.importfile(text!,'1.txt',2,10,1,10,1) //匯入txt檔案
dw_1.importfile(excel!,'1.xls',2,10,1,10,1) //匯入xls檔案
dw_1.importfile(excel!,'1.xlsx',2,10,1,10,1)//匯入xlsl檔案
dw_1.importfile(csv!,'1.csv',2,10,1,10,1)//匯入csv檔案

② 資料視窗匯出

//dw_name.saveas(名字可含路徑,另存為的型別,是否顯示列標題)
dw_1.saveas("1.txt",text!,true) //另存為txt檔案
dw_1.saveas("1.xls",excel!,true) //另存為xls檔案
dw_1.saveas("1.xlsx",excel!,true) //另存為xlsl檔案
dw_1.saveas("1.csv",csv!,true) //另存為csv檔案

6.28 資料視窗快捷鍵

//1、新建事件
//事件名 keydown
//event ID pbm_dwnkey(選擇這個就可以了,其他引數它會自己設定)

//2、在此事件中,寫入以下程式碼
if key = KeyEnter! then Send(Handle(this),256,9,0)

6.29 設定datawindow的當前行指示圖示

//在datawindow中建立一個計算列,expression為'',並將該計算列移動為datawindow的第一個列,在
//datawindow控制元件的rowfocuschanged事件中寫入程式碼:
SetRowFocusIndicator(hand!) //小手指樣式
setrowfucsindicator(p_1) //自定義圖片樣式

6.30 列印datawindow的內容到檔案中

//資料視窗列印出pdf
dw_1.object.datawindow.print.filename ="c:/temp.pdf"
dw_1.print()

6.31 將Grid風格改成自由格式

在DW的editsource中將processing=1的1改為0

6.32 資料視窗自動調整大小

在資料窗所在視窗的Resize事件下編寫程式碼

Resize(dw_datamon,this.Workspacewidth()-50,this.Workspaceheight()-50)

6.33 一個報表中要有一個計算域,是幾個NUM型列相加,加的時候幾個列中有一為空就加不出來

方法Ⅰ

設定此資料列的初使值為0.0。但必需在資料視窗物件中設,即選選單Rows中的Column Specifications……選項,在Initial Value列中寫上0.0即可

方法Ⅱ

計算列公式採用如下:

 // A + B + C
if(isnull(A), 0,A) + if(isnull(B), 0,B) + if(isnull(C), 0,C)  

6.34 動態生成的報表中怎麼修改各個帶區的寬度、位置?

// 改變detail區的高度:
dw_1.Modify("DataWindow.detail.Height=200")

6.35 動態生成的報表中增加文字(標題),或對標題列的文字進行修改

//對標題列文字的更改(文字名為dept_name_t)
dw_1.modify("dept_name_t.text = '單位名稱'")

6.36 動態生成的報表中動態增加計算列

string ls_modrow
dw_1.Modify("DataWindow.summary.Height=64")
ls_modrow = 'Create compute(band=summary font.charset="0" font.face="MS Sans Serif" font.family="2" font.height="-8" font.pitch="2" font.weight="400" background.mode="1" background.color="536870912" color="0" x="9" y="4" height="52" width="297" format="[general]" expression="count(dept_id for all)" alignment="1" border="0" crosstab.repeat=no )~r~n'
dw_1.modify( ls_modrow )

6.37 動態修改grid資料視窗中格線是否可見,並在detail區增加加一條線

dw_1.Modify("DataWindow.Grid.Lines='1' ")
dw_1.Modify("DataWindow.detail.Height=332")
ls_line = 'Create line(band=detail background.mode="2" background.color="16777215" pen.style="0" pen.width="5" pen.color="0" x1="37" y1="320" x2="1458" y2="316" )~r~n'
dw_1.modify( ls_line )

6.38資料視窗中新增一計算域,統計一下性別為男的記錄數

//新增一個計算列
sum( if( stu_sex ='男', 1, 0 )) 

6.39 資料視窗中資料自動折行

在PowerBuilder應用程式的開發過程中, 使用DataWindow時, 經常會遇到某列的資料太長, 不能同時全部顯示的情況. 若採用自動水平捲動, 操作起來又不夠簡便,那麼我們將如何實現列資料多行顯示, 即實現列資料的自動折行呢?

① 在DataWindow Painter中開啟此DataWindow物件

②在需設定自動折行的列上雙擊滑鼠, 彈開此列的屬性視窗

③ 選擇Position標籤, 選中Autosize Height 多選框

④ 選擇Edit標籤, 不選中Auto Horz Scroll多選框

⑤ 單擊OK按鈕, 儲存所做的修改

⑥ 點中Detail Band (即寫有Detail的灰色長帶), 單擊滑鼠右鍵, 選擇Properties... 選單項
⑦ 選中Autosize Height多選框
⑧ 單擊OK按鈕, 儲存所做的修改
⑨ 儲存此DataWindow

注意:連在一起的漢字(中間沒有標點或空格分隔), 系統將認為是一個單詞, 不會自動進行折行, 英文也是如此……DW視窗折行如果有漢字的話就必需中間加空格才會折行,否則怎樣設定都不行。例如你如果想在第20位折行,就先判斷第20位是否是個漢字,如不是就在第20位後加空格,如果是漢字就在第19位加空格。判斷是否是漢字可以用它的ASCII碼是否大於127來判斷

6.40 連續頁數列印多個資料窗

① 建立一個全域性變數

 integer g_int_page=0

② 建立一個全域性函數f_setpage()

 return g_int_page

③ 在資料視窗物件中加入一計算域gs_pagenum

 //利用全域性涵數來傳遞全域性變數
page() + f_setpage()

④ 在每一個資料視窗控制元件的printend事件中改變全域性變數的值,以使計算域的值發生變化

g_int_page=dw_1.getitemnumber(dw_1.rowcount(),"gs_pagenum")

⑤ 當所有視窗列印完畢後將全域性變數恢復

g_int_page=0

6.41 動態實現列印不固定的資料列

做一個程式,其中的一個功能是:

例如:資料庫。僱員(序號,姓名,年齡,性別,出生年月,學歷,職務,工資,等等)。

客戶要求在程式的執行中進行選擇(對錶的項任意選),然後列印出來。

如選擇姓名,年齡,出生。則列印姓名,年齡,出生。

又如選擇姓名,工資。則列印姓名,工資。我不知道如何去實現

方法Ⅰ

建資料視窗物件時,選用Grid風格(Grid風格資料視窗的欄位寬度可以隨意拖動,如同Excel),不需要列印的欄位可以隨時將其寬度拖動為零

方法Ⅱ

用列表框顯示出所有的列,可以多選高亮列。通過Modify函數動態定義選中列的位置,寬度以及是否可見等屬性