PB動態報表格式自由定義的實現

來源:互聯網
上載者:User
  在通常的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下調試通過。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.