psr

 
在通常的Server/Client方式MIS開發中,總是有沒完沒了的報表需要製作,

調試報表花費的時間也是最多而且乏味,還常常不能滿足客戶的要求。要
是能夠讓用戶自己調整報表的格式和內容,然後將它保存下來,程序下次啓

動時它自動調用保存了的報表格式那有多好。本人通過如下方法最終實現
了用的要求。
PB(PowerBuilder)有一種以PSR結尾的特殊的保存報表的文件格式(本

文簡稱作PSR文件)。根據數據窗口可以直接讀取PSR文件生成報表的原理

,程
序通過生成PSR文件,實現動態報表格式的保存。  
  一、實現原理:  

  PB中的報表其實就相當於是數據窗口。     第一步,動態報表的實現

。通過設置數據窗口對象(dataobject)中文本、列等的Resizeable和
moveable屬性爲1來實現對象位置的拖動控制,通過數據窗口的Modify函數

實現對象值的更改(包括增加和刪除)。

  第二步,報表格式的保存。在一個應用當中,數據窗口對象的名稱總是

唯一的,將每一個數據窗口對象轉化成PSR文件存於數據庫表中。在窗口打
開時,程序先校驗報表格式是否存在。如果存在,先將報表格式讀取出來放

在一個臨時文件當中,然後設置數據窗口(datawindow)的數據對象
(dataobject)爲這個報表文件,然後提取數據;如果不存在,直接提取數據即

可。  

  二、實現過程:

     1、建立一個數據庫表用以保存報表格式文件。  
表名:dyn_report  
Dwobject   Varchar2(20)   數據窗口對象名稱   Primary   key  
Rptitle   Varchar2(80)   報表的標題名稱  
Memo   Long   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_dwobject   =   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下調試通過。

 

本文來自CSDN博客,轉載請標明出處:

http://blog.csdn.net/builderwfy/archive/2010/09/23/5901563.aspx

發佈了18 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章