在通常的Server/ClIEnt方式MIS開發中,總是有沒完沒了的報表需要制作,調試報表花費的時間也是最多而且乏味,還常常不能滿足客戶的要求。要是能夠讓用戶自己調整報表的格式和內容,然後將它保存下來,程序下次啟動時它自動調用保存了的報表格式那有多好。本人通過如下方法最終實現了用的要求。
PB(PowerBuilder)有一種以PSR結尾的特殊的保存報表的文件格式(本文簡稱作PSR文件)。根據數據窗口可以直接讀取PSR文件生成報表的原理,程序通過生成PSR文件,實現動態報表格式的保存。
一、實現原理:
PB中的報表其實就相當於是數據窗口。
第一步,動態報表的實現。通過設置數據窗口對象(dataobject)中文本、列等的Resizeable和moveable屬性為1來實現對象位置的拖動控制,通過數據窗口的Modify函數實現對象值的更改(包括增加和刪除)。
第二步,報表格式的保存。在一個應用當中,數據窗口對象的名稱總是唯一的,將每一個數據窗口對象轉化成PSR文件存於數據庫表中。在窗口打開時,程序先校驗報表格式是否存在。如果存在,先將報表格式讀取出來放在一個臨時文件當中,然後設置數據窗口(datawindow)的數據對象(dataobject)為這個報表文件,然後提取數據;如果不存在,直接提取數據即可。
二、實現過程:
1、建立一個數據庫表用以保存報表格式文件。
表名:dyn_report
DwobjectVarchar2(20)數據窗口對象名稱Primary key
RptitleVarchar2(80)報表的標題名稱
MemoLong raw 報表格式
2、建立一個窗口w_temp。 定義實例變量如下:
string is_dwtype,is_dwobject //保存報表中對象的類型及名稱
控件名稱 控件含義
Dw_print數據窗口對象
Cb_exit退出按鈕
Cb_savereport 報表格式保存按鈕
3、在窗口的OPEN事件中加入如下代碼, 校驗報表格式是否存在,如果存在讀取定義好的報表格式到數據窗口。
blob emp_pic
long ll_handle
string ls_dwobject,ls_reportfile,ls_path
ls_dwobject = dw_print.dataobject
//判斷是否存在該數據窗口的報表格式
select count(*) into:ll_count from dyn_report where dwobject =:ls_dwobject;
if ll_count>0 then
//讀取報表格式文件到大文本變量
selectblob memo into:emp_pic from dyn_report where dwobject =:ls_dwobject;
//創建psr臨時文件到硬盤
ls_reportfile = ’\temp7089.psr’
ll_handle = FileOpen(is_reportfile,StreamMode!,write!,LockWrite!,Replace!)
FileWrite(ll_handle,emp_pic)
FileClose(ll_handle)
dw_print.dataobject = ls_reportfile
dw_print.settransobject(sqlca)
else
Dw_print.settransobject(sqlca)
End if
Dw_print.retrIEve()
4、報表格式的保存。通過Cb_savereport按鈕的clicked實現。
string ls_filename
long ll_count
blob Emp_id_pic
ls_filename = "temp70201.psr"
//保存報表格式到硬盤臨時文件
dw_print.saveas(ls_filename,PSReport! ,false)
sqlca.autocommit = true
select count(*) into :ll_count from dyn_report where dwobject =:is_dwobject;
if ll_count =0 then
insert into dyn_report(dwobject,rptitle)
values(:is_dwobject,:ls_filename,:ls_path);
end if
//從硬盤臨時文件讀取數據保存到數據庫表中
emp_id_pic = of_readbmpfile(ls_filename)//該函數將二進制文件內容讀到大文本對象中
//更新數據庫
UPDATEBLOB dyn_report SET memo = :Emp_id_pic where dwobject = :is_dwobject;
sqlca.autocommit = false
5、動態報表的實現。通過數據窗口dw_print的clicked事件捕獲數據窗口中對象,並將對象名存放在實現變量is_dwobject中,為下一步修改報表作准備。
string ls_type,ls_dwoname
//得到對象類型和名稱
ls_type = trim(upper(dwo.type))
ls_dwoname = trim(dwo.name)
is_dwtype = ls_type
choose case ls_type
case "TEXT","CommandButton","GROUPBOX"
is_dwobject = ls_dwoname
//設置為可以拖動和改變大小,其它類同
this.modify(ls_dwoname+".Resizeable=’"+"1’")
this.modify(ls_dwoname+".moveable="+"1")
case "LINE" //直線對象不能通過設置Resizeable和moveable屬性進行調整,必須通過其它路徑
is_dwobject = ls_dwoname
case "RECTANGLE","ELLIPSE","GRAPH","BITMAP"
is_dwobjec
您正在看的Sybase教程是:PB動態報表格式自由定義的實現。t = ls_dwoname
this.modify(ls_dwoname+".Resizeable=’"+"1’")
this.modify(ls_dwoname+".moveable=’"+"1’")
case "COLUMN","COMPUTE"
is_dwobject = ls_dwoname
this.modify(ls_dwoname+".Resizeable=’"+"1’")
this.modify(ls_dwoname+".moveable=’"+"1’")
end choose
然後再通過modify()函數可以實現基本的動態報表操作,這一類的文章較多,PB中也有大量的例子可直接使用,在此這不再累述。
6、在cb_exit按鈕的clicked()事件中加入:close(parent)。
7、在應用的open事件中加入: open(w_temp)。然後保存並運行,大功告成啦!
8、本程序在PB7.0加Oracle8.05下調試通過。