本文介紹了我和同事通過使用AMDP + XLSX Workbench縮短報表開發周期、分離數據查詢處理邏輯和前端展示工作的經驗。歡迎討論。
前言
最近接到了一套人力資源報表的開發需求,需要以EXCEL表格的方式輸出,且包含大量sheet頁,每個sheet相當於一個獨立的報表。
這種情況下,如果讓同一個人開發所有內容,將會花費較長的開發周期,因此,要將程序分解成若干個部分,最好每個報表(sheet)都是一個獨立的子模塊,讓不同的人同時開發。
對於這類報表,我們之前的做法是,使用OLE輸出EXCEL文件,在report程序中,使用邏輯數據庫獲取數據,引入常用的OLE方法,為每個sheet創建一個include文件,實現不同sheet的代碼分離。
代碼類似這樣:
REPORT zhr_report . ************************************************************************ * INCLUDES ************************************************************************ INCLUDE zhr_report_top. "//數據定義 INCLUDE zhr_report_s01. "//選擇屏幕``````````` INCLUDE z_ole_excel_hr. "//通用EXCEL操作子程序 INCLUDE zhr_report_m01. "//事件 INCLUDE zhr_report_f01. "//通用模塊 INCLUDE zhr_report_ex01. "//Sheet1 INCLUDE zhr_report ex02. "//Sheet2 INCLUDE zhr_report_ex03. "//Sheet3 INCLUDE zhr_report_ex04. "//Sheet4
INCLUDE zhr_report_ex05. "//Sheet5
示意圖:
通過將通用的OLE方法封裝到一個包含文件中,並使sheet頁的處理放到不同的包含文件,可以使對它們的同時編輯成為可能。但是,這種做法也是有問題的:
- 包含文件不是單獨的程序,這意味着只要有一個include文件中有語法錯誤,語法檢查時就會給出提示,從而無法激活整個程序。
- 命名空間相同,這意味着定義子程序或FORM名時,很容易發生沖突
- 只能通過增加包含文件實現程序的橫向擴展,較難實現程序的縱向擴展。通用部分一旦確定,再想修改會比較困難。
- OLE的性能較差。
為了解決這些問題,我們引入了AMDP + XLSX Workbench的報表開發模式。
改進后的模式示意圖:
本文鏈接:http://www.cnblogs.com/hhelibeb/p/8422711.html
名詞解釋
AMDP
全稱ABAP-Managed Database Procedure,一種ABAP on HANA的實現方式,提供了在ABAP中運行SQL Script的可能,並且與ABAP中的類和數據類型有良好的集成。之前的有關AMDP的文章:
ABAP中的AMDP(ABAP-Managed Database Procedures )
XLSX Workbench
一種可視化表單生成工具,相比復雜的OLE,可以用少量代碼+一些拖拽和配置來生成EXCEL報表,性能更好。按XLSX Workbench的文檔介紹,它有九大特性:
- 無需ABAP編程技能
- 可視化設計方式
- 高性能
- 支持后台處理
- 強大的表單格式特性支持
- 支持公式
- 支持圖片
- 支持圖表
- 支持樹
官方文檔:https://sites.google.com/site/sapxlwb/home
代碼例子
注意,本部分內容會假設讀者已經有使用AMDP的XLSX Workbench的初步經驗(至少是能輸出Hello World的水平)。如果不是這樣的話,可能會對其中的某些內容感到困惑。
1,首先,創建一個接口ZIF_XLSX_REPORT。
INTERFACE zif_xlsx_report PUBLIC . METHODS get_dataCHANGING !data TYPE sflight_t RAISING cx_amdp_error . ENDINTERFACE.
接口包含一個get_data方法,方法有一個參數data,它數據類型,即為將要輸出給XLSX Workbench表單的的數據類型。
2,為接口創建實現類。
為接口創建一個實現類,在方法ZIF_XLSX_REPORT~GET_DATA中調用AMDP類方法,進行數據處理后,將得到的數據填充進chaging參數data中。
CLASS zcl_xlsx_report1 DEFINITION PUBLIC FINAL CREATE PUBLIC . PUBLIC SECTION. INTERFACES zif_xlsx_report . PROTECTED SECTION. PRIVATE SECTION. ENDCLASS. CLASS ZCL_XLSX_REPORT1 IMPLEMENTATION. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_XLSX_REPORT1->ZIF_XLSX_REPORT~GET_DATA * +-------------------------------------------------------------------------------------------------+ * | [<-->] DATA TYPE SFLIGHT_T * | [!CX!] CX_AMDP_ERROR * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD zif_xlsx_report~get_data. "調用AMDP類的方法 "數據處理 ENDMETHOD. ENDCLASS.
3,在report程序中調用各個實現類。
這是關鍵的一步:在report程序中動態地獲取全部實現類,並依次實例化、調用其接口方法。
CONSTANTS: c_interface TYPE seoclsname VALUE 'ZIF_XLSX_REPORT'.
TRY. DATA(gt_classes) = cl_sic_configuration=>get_classes_for_interface( c_interface ). CATCH cx_class_not_existent . ENDTRY. LOOP AT gt_classes INTO DATA(gs_class). TRY . CREATE OBJECT go_ref TYPE (gs_class-clsname). CATCH cx_sy_create_object_error. ENDTRY. IF go_ref IS BOUND. go_ref->get_data( CHANGING data = g_data_structure ). ENDIF. ENDLOOP.
- 由於XLSX Workbench中的一個表單在同一時間只能由一個人編輯,對於多sheet頁的表格,無法讓兩個人並行開發表單。但是,因為表單獨立於ABAP 程序,二者只需要通過約定好的內表結構(在示例中是SFLIGHT_T)通信。因此,可以在約定好通信結構的前提下,由一個人進行XLSX Workbench中表單的組件編輯、上下文綁定等工作,另一個(或多個)人進行數據邏輯處理工作。如果在引入了HANA開發人員,還可以把主要邏輯下推至HANA,從而使多人同時在不同層級上開發同一個套表,以提高總體開發速度。
- 將每個sheet頁寫成一個類,所有類繼承同一個接口,在report程序中動態地調用,可以將報表主程序的代碼穩定下來,實現程序的解耦。不同的類之間也是個例的,可以方便地進行單獨的單元測試,而不會在語法檢查時受到其他人的開發內容的干擾。
- 相比於本文開頭提到的INCLUDE的方式,使用面向對象的新開發模式不僅提供了更好的橫向擴展能力(只要增加新的實現類和結構字段即可實現數據處理邏輯和報表內容的擴展),而且也提供了更好的縱向擴展能力,可以通過面向對象的強大特性——繼承——來實現對報表中相似部分進行抽象整合。
注意事項
總結了幾點我們在實際開發中的經驗,以供參考。
AMDP與SELECT-OPTIONS
細心的讀者可能已經注意到上文的示例代碼中並未處理選擇屏幕這一關鍵問題。在Open SQL中我們可以很方便地直接使用range table。而在AMDP中使用它話需要一點點額外的代碼:
可以通過CL_SHDB_SELTAB=>COMBINE_SELTABS( )來將選擇屏幕的輸入條件轉換為AMDP中的SQL Script中的WHERE條件字符串,並使用APPLY_FILTER函數應用這一條件,具體的例子:
(引用自 Handling of SELECT-OPTIONS parameters within AMDP)
異常處理
在本文介紹的開發模式下,HANA視圖、XLSX Workbench表單和ABAP類是可以並行開發的,這意味着開發階段的HANA視圖可能處於不穩定的狀態。ABAP開發者應注意在AMDP方法中顯式地聲明異常、並在調用它時進行處理。不然會很容易遇到程序dump的情況:)
具體的異常可見:AMDP異常
自建結構/表命名
無論是AMDP方法還是XLSX Workbench表單,在實踐中都需要自建結構/表來接收數據。在開發內容分離的情況下,作為通信定義的結構/表類型的命名尤其重要。應當有一套合理的規則來為它們以及其中的字段命名。特別是XLSX Workbench表單的參數結構,在表單復雜的情況下,參數結構同樣會是復雜的深度結構,而且XLSX Workbench的組件自動生成功能會以ABAP結構名為組件命名。如果命名不當的話,將會給后續的開發和溝通帶來相當的負擔。
另外,創建XLSX Workbench上下文時,如選擇自動創建,則生成的組件名和描述會與數據字典中定義的數據名與描述一致。如果定義時能仔細填入這些信息,對后續的工作很有幫助。
模板處理
上傳模板至XLSX Workbench后,建議首先對空模板進行測試輸出,確認無誤后,再進行context和template的綁定等工作。因為有時導入的模板也許會出現兼容問題,在輸出報表時會提示文件錯誤。較早地發現、解決這種問題,可以避免后期一些無謂的工作。
XLSX Workbench設置
在使用XLSX Workbench的過程中,點擊鼠標是一項略顯繁瑣的工作,建議把在配置選項中將確認彈窗關掉,以減輕手指負擔:
大報表的列修改問題
報表中增加列、減少列是常見的需求,在使用XLSX Workbench的時候,如果采取了簡單表的輸出方式,那么插入或刪除新列時,就要把這個新列以右的全部列重新綁定至新位置。
在報表總列數較小的情況下,這很容易做到。但某些報表的列數較多,如我們開發的系統使用情況表,約有167列,需求變更的內容是在第5行新增一列,則意味着要重新綁定162個context value,這是件麻煩的工作。為了避免這種情況的發生,在表單的列數較多時,建議使用動態列或其它動態方式實現對表單內容的填充,以降低變更成本。
參考閱讀:SAP BADI的“多次使用”(multiple use)
本文鏈接:http://www.cnblogs.com/hhelibeb/p/8422711.html
轉載請注明