ABAP報表程序開發規范
一、 目的
為保證在R/3系統中使用ABAP語言開發報表程序的規范性,特制定本開發規范。在本開發規范的約束下,將源代碼與報表開發人的相關性降到最低;即只要具備基本的ABAP開發技巧,遵循本開發規范,不同的開發人員開發的同樣邏輯的源代碼應該是基本相同的。
二、 適用范圍
本技術規范適用於捷順R/3系統的所有開發人員和除標准對象外的所有ABAP報表程序開發。
三、 職責
ABAP開發小組負責程序的開發、傳輸請求的創建及提交。
BASIS小組負責傳輸請求向PRD系統的傳輸。
四、 開發流程
1、 開發人員接收業務顧問提交的開發需求;如果需要,開發人員應當配合業務顧問進行用戶需求分析;
2、 開發人員根據開發需求在DEV100中進行程序開發;
3、 開發人員將程序傳輸至質量保證系統中進行初步測試,測試完畢后通知業務顧問進入用戶測試階段;
4、 程序在質量保證系統中經用戶測試通過后,開發人員申請將程序傳輸至生產系統,相關主管審批通過后,BASIS人員負責將傳輸請求傳輸至生產系統。
5、 如果程序需要作為后台程序運行,需要在傳輸申請中做出說明,由BASIS人員在生產系統中定義后台作業。
6、 開發和修改程序都需要填寫開發文檔。開發文檔存放於服務器的專用目錄中,每個程序一個文檔,新程序需要新建文檔,修改程序需要修改原來的程序文檔(在原文檔基礎上追加內容,不允許刪除原文檔內容),記錄本次修改的內容和請求號等信息。開發程序申請傳輸生產系統中時,同時提交開發文檔審核,相關主管需要同時檢查程序和文檔的規范性。
五、 命名規則
1、 用戶開發對象的命名規則
1) 用戶開發對象的名稱必須以Z開頭,只能使用字母、數字和下划線。用戶開發對象包括開發類、程序、函數組、函數、透明表、結構等。
2) 開發類一般使用ZREPORT,如有特殊需要,可以創建新的開發類。
3) 報表程序命名規則:Z<XX>_<Y>_<NN>[ADDITIVE]。
其中,XX為模塊名稱,現在常用的有以下幾種: MM——MM模塊,PP——PP模塊,SD——SD模塊,CS——CS模塊,FI——FI模塊,CO——CO模塊,BC――公共模塊,CA――交叉應用;
Y表示程序的類型,目前有四種:R——報表程序,E——批輸入程序,S――SmartForm程序,I——接口程序。
NN為序列號,表示該程序在同一模塊同類型程序中的編號。比如ZSD_R_01,表示SD模塊的一個報表程序。如果業務顧問已經提供需求的編號,則取業務顧問提供的需求編號。
ADDITIVE,程序的附加說明,如項目名稱等,可以靈活使用,不是必須的部分。如果創建與程序相關的Include程序,則Include程序的命名中的ZXX_Y_NN部分與主程序相同,通過ADDITIVE部分區分不同的Include程序,如ZXX_Y_NNTOP,ZXX_Y_NNUI等。
特別說明:
如果需要替換原程序,建議將原程序拷貝為ZXX_Y_NNOLD,而新編寫的程序的命名與被替換程序的命名一致,不要將新程序命名為ZXX_Y_NNN或ZXX_Y_NNNEW。這樣可以避免需要修改需求文檔編號與程序編號的對應關系,也避免在日后維護中由於對應關系沒有更新而導致錯誤的修改已廢除的程序。
4) 數據字典對象的命名規則:Z<XX>_<Y>_<NAME>
其中,XX為模塊名稱,現在常用的有以下幾種:MM——MM模塊,PP——PP模塊,SD——SD模塊,CS——CS模塊,FI——FI模塊,CO——CO模塊,BC――公共模塊,CA――交叉應用;
Y代表對象類型,現在常用的有如下幾種: T――透明表, V――視圖,S――結構類,I――內表類型;
NAME為對象的名稱。盡量給數據字典對象有意義的名稱,不要使用序號;如果定義是配置表及其維護視圖,可以使用3位的序號。
5) 函數組命名方式:Z_<NAME>
其中,NAME表示函數組有意義的名稱,如項目名稱,命名應能表示所包含的函數的用途等。
6) 函數命名方式:Z_<NAME>
函數必須指定所屬的函數組,NAME表示對函數的說明,使用下划線分隔單詞,如Z_ORDER_MODIFY_ABTNR,表示修改訂單的部門(ABTNR)字段。
7) 事務代碼的命名方式:Z<XX><Y><NN>
即對於報表程序取主程序命名,但將下划線去掉。如果業務顧問已經給出事務代碼的命名,則按照業務顧問的命名,只需確保命名以Z開始。
8) SmartForm的命名方式:Z<XX>S<NAME>
其中,XX為模塊名稱,現在常用的有以下幾種:模塊名稱:MM——MM模塊,PP——PP模塊,SD——SD模塊,CS——CS模塊,FI——FI模塊,CO——CO模塊,BC――公共模塊,CA――交叉應用;
NAME為對象的名稱。盡量給SmartForm有意義的名稱,不要使用序號。
2、 SELECT-OPTION的命名方式:SO_<NAME>
其中,NAME賦予變量有意義的名稱,對於類型參照數據字典中表字段的SELECT-OPTION,名稱盡量參照該字段的名稱。
3、 PARAMETER的命名方式:PA_<NAME>
其中,NAME賦予變量有意義的名稱,對於類型參照數據字典中表字段的SELECT-OPTION,名稱盡量參照該字段的名稱。
4、 程序全局變量的命名方式:G<qualification>_<NAME>
其中,全局變量的命名以G開頭,但SELECT-OPTION、PARAMETER及TABLE例外;
qualification主要表示變量的類型,常用的有以下幾種:S――結構,T――內表,X――標志變量(變量值為SPACE或‘X’),C――字符(串),N――數值型字符串,D――日期型,I――整型,P――實數;對於類型參照數據字典中表字段的變量,可以省略此部分;
NAME則賦予變量有意義的名稱,對於類型參照數據字典中表字段的變量,名稱盡量參照該字段的名稱。
5、 子程序接口參數的命名方式:P<qualification>_<NAME>
其中,子程序接口參數的命名以P開頭;
qualification主要表示參數的類型,常用的有以下幾種:S――結構,T――內表,X――標志變量(變量值為SPACE或‘X’),C――字符(串),N――數值型字符串,D――日期型,I――整型,P――實數;對於類型參照數據字典中表字段的參數,可以省略此部分;
NAME則賦予參數有意義的名稱,對於類型參照數據字典中表字段的參數,名稱盡量參照該字段的名稱。
6、 局部變量的命名方式:L<qualification>_<NAME>
其中,子程序中局部變量的命名以L開頭;
qualification主要表示變量的類型,常用的有以下幾種:S――結構,T――內表,X――標志變量(變量值為SPACE或‘X’),C――字符(串),N――數值型字符串,D――日期型,I――整型,P――實數;對於類型參照數據字典中表字段的變量,可以省略此部分;
NAME則賦予變量有意義的名稱,對於類型參照數據字典中表字段的變量,名稱盡量參照該字段的名稱。
六、 程序注釋
程序必須層次清楚,添加詳細注釋。基本原則是在《ABAP報表詳細設計文檔》主程序和子程序邏輯中每一段描述性的信息,都應該添加在源代碼中相應的位置,並且保證標號的順序和層次的一致性。
1、 嚴格按照下列示例填寫程序抬頭注釋信息
*&---------------------------------------------------------------------*
*程序名稱:<程序名稱> *
*程序目的:<程序功能描述> *
*需求編號:<對應的開發需求編號> *
*作 者:<程序的開發用戶名> *
*創建日期:<創建程序的日期> *
*&---------------------------------------------------------------------*
2、 對於子程序,應當在子程序前添加如下注釋:
*&---------------------------------------------------------------------*
*& FORM <子程序名稱>
*&---------------------------------------------------------------------*
* <子程序的功能說明及邏輯的簡述>
*----------------------------------------------------------------------*
* --> <輸入參數名稱> <輸入參數的說明>
* <-- <輸出參數名稱> <輸出參數的說明>
*----------------------------------------------------------------------*
FORM <子程序名稱> [接口定義].
ENDFORM.
3、 對於程序中的全局變量(包括PARAMETER及SELECT-OPTION)及子程序中重要的局部變量應該對其含義、用途做出說明;在聲明內表數據類型或內表變量(包括全局變量及局部變量)時,內表的每個字段必須對其進行注解;參考如下示例
eg.1
****供應商信息內表:用於外部輸出
DATA:BEGIN OF GT_LFA1 OCCURS 0,
LIFNR LIKE LFA1-LIFNR, "供應商編碼
SORTL LIKE LFA1-SORTL, "排序字段
NAME1 LIKE LFA1-NAME1, "名稱 1
KTOKK LIKE LFA1-KTOKK, "供應商帳戶組
DATLT LIKE LFA1-DATLT, "數據通訊線的號碼
END OF GT_LFA1.
eg.2
****復選框, 標志是否前台輸出
PARAMETERS:PA_XUI AS CHECKBOX. "復選框, 標志是否前台輸出
4、 對數據庫查詢、子程序/函數/組件的調用、邏輯運算、邏輯處理等程序處理邏輯要有相應注解;對於用於控制語句與WHERE子句里的判斷值(常量),要有注解或者說明。
eg.1
****選出BOM表頭:指定工廠,指定物料,BOM用途為2或8,替代組為01
SELECT MATNR STLNR WERKS CSLTY
FROM MAST
INTO TABLE ZHEAD
WHERE ( WERKS IN IWERKS OR WERKS IN IWERKS1 )
AND ( MATNR IN IMATNR OR MATNR IN IMATNR1 )
AND ( STLAN = '8' OR STLAN = '2' ) ”類型值為主機或者虛擬BOM
AND STLAL = '01'.
eg.2
****判斷用途選擇,前台或后台輸出
IF SOPT EQ 'X'. "輸出到前台文件
PERFORM EXPORT_DATA_FT. “將數據導出到客戶端文件
ELSE. "輸出到應用服務器文件
PERFORM EXPORT_DATA_BG. “將數據導出到應用服務器文件
ENDIF.
5、 當修改程序時,在程序抬頭注釋后附加程序修改注釋:
*&---------------------------------------------------------------------*
*修 改 人:<修改程序的開發用戶名> *
*修改日期:<修改程序的日期> *
*修改說明:<本次修改的邏輯處理和必要的說明信息> *
*&---------------------------------------------------------------------*
在修改其他開發人員的程序時不要在原代碼行上進行修改,也不要直接刪除原代碼行;應該將要修改的代碼行標注為注釋行,並按如下例子條件注釋,如果:
1) 對原代碼行進行修改,
*----------------------------------------------------------------------*
*BEGIN MODIFY BY <用戶> <修改日期>
*<修改原因>
*<原代碼行>
<新代碼行>
*END MODIFY BY <用戶>
*----------------------------------------------------------------------*
2) 刪除整段原代碼,
*----------------------------------------------------------------------*
*BEGIN DELETE BY <用戶> <修改日期>
*<刪除原因>
*<原代碼行>
*END DELETE BY <用戶>
*----------------------------------------------------------------------*
3) 新增代碼行,
*----------------------------------------------------------------------*
*BEGIN INSERT BY <用戶> <修改日期>
*<新增原因>
<新代碼行>
*END INSERT BY <用戶>
*----------------------------------------------------------------------*
七、 數據庫訪問與內表的使用
1、 沒有相關授權,禁止對SAP系統提供的透明表使用INSERT(插入)、UPDATE(更新)、DELETE(刪除)等可以變更底層數據庫信息的語句;
2、 對一些數據量比較大的透明表查詢,盡可能在查詢條件中使用主鍵和索引,如果有多個主鍵或索引字段,盡可能全部使用,如果不能全部使用,盡可能使用按從左至右的次序使用主鍵或索引字段。
例如:表BKPF的主鍵包含3個字段,BUKRS,GJAHR,BELNR,最好3個主鍵字段共同使用,如果不能全部使用,則至少包含BUKRS;如果使用GJAHR和BELNR,或者使用BELNR,而不指定BUKRS,都會造成效率的下降。
3、 如果訪問的是簇表,必須使用主鍵,如果不能使用,可以先查詢這個簇表的索引表,再根據索引表的記錄訪問該簇表。注意,簇表不能用於多表連接查詢。
例如:需要查詢表BSEG,如果不能使用主鍵,則需要先查詢表BSID和BSAD,然后根據得到的主鍵查詢表BSEG。
4、 對透明表查詢,只選擇需要的字段,禁止使用如下語句:
SELECT * FROM TABLE1.
應該使用以盡量減少需要傳遞的數據量:
SELECT FIELD1 FIELD2 … FROM TABLE1.
5、 如果只讀取透明表的一條記錄,使用SELECT SINGLE。
6、 根據內表的內容查詢透明表,禁止使用下面的語句:
LOOP AT ITAB.
SELECT FROM TABLE1 WHERE FIELD1 = ITAB-FIELD1.
…
ENDLOOP.
應該使用下面的語句:
DESCRIBE TABLE ITAB LINES LINCT.
IF LINCT EQ 0.
STOP.
ENDIF.
SORT ITAB BY FIELD1.
DELETE ADJACENT DUPLICATES FORM ITAB.
SELECT FROM TABLE1
FOR ALL ENTRIES IN ITAB
WHERE FIELD1 = ITAB-FIELD1.
這樣可以減少讀取數據庫的次數,因為FOR ALL ENTRIES會自動遍歷內表,並且將WHERE條件以OR關鍵字連接(系統默認5個OR連接)。使用FOR ALL ENTRIES IN ITAB要注意,ITAB不能為空,否則會造成該WHERE條件無效,同時還需要對ITAB按照字段FIELD1進行排序,並且刪除表中的重復記錄,同樣是為了減少訪問數據庫的次數。
但當可以使用表連接查詢時盡量不要使用FOR ALL ENTRIES,因為FOR ALL ENTRIES往往會形成多條SQL語句,導致數據庫訪問次數的增加。
7、 不要使用透明表的嵌套
SELECT FROM TABLE1.
SELECT FROM TABLE2.
…
ENDSELECT.
ENDSELECT.
8、 建議少使用INNER JOIN或者OUTER JOIN,因為這些語句不會訪問DATA BUFFER,會造成效率的降低。可以創建一個VIEW,實現多個透明表的關聯。INNER JOIN超過三個表,或者是兩個數據量超過10000條記錄的透明表做INNER JOIN且有着關鍵字關聯關系(例如憑證抬頭和憑證行項目),必須定義視圖的方式實現。
9、 查詢透明表時,不要使用ORDER BY,即使是主鍵,也要慎用。因為很容易造成全表搜索。將索引操作應用到內表上。
SELECT FROM TABLE1
WHERE
ORDER BY FEILD1.
10、 檢索內部表時,避免使用下面的語句:
LOOP AT ITAB.
IF ITAB-FIELD1 = VARIANT1.
…
ENDIF.
ENDLOOP.
應該使用下面的語句:
LOOP AT ITAB WHERE FIELD1 = VARIANT1.
…
ENDLOOP.
對於數據量較大的Standard 內表,使用下面的語句可以提高檢索效率:
SORT ITAB BY FIELD1.
LOOP AT ITAB WHERE FIELD1 = VARIANT1 BINARY SEARCH.
…
ENDLOOP.
如果內表僅用於檢索數據,沒有增刪改等操作,而且檢索的字段不會發生變化,可以將內表定義為Hashed內表,其主鍵定義包含檢索時使用的字段。
11、 從透明表讀取數據到內部表時,不要使用下面的語句:
SELECT FROM TABLE1.
ITAB-FIELD1 = TABLE1-FIELD1.
APPEND ITAB.
ENDSELECT.
應該使用下面的語句:
SELECT FROM TABLE1 INTO TABLE ITAB.
12、 原則上不要使用LOOP多層嵌套
LOOP AT ITAB1.
LOOP AT ITAB2.
…
ENDLOOP.
ENDLOOP.
應該使用下面的語句:
LOOP AT ITAB1.
READ TABLE ITAB2 WITH KEY FIELD1 = ITAB1-FIELD1.
IF SY-SUBRC = 0.
…
ENDIF.
ENDLOOP.
13、 完成報表程序的開發后,要通過事務代碼ST05對程序的執行進行SQL跟蹤,檢查程序對數據庫的訪問情況,避免出現兩種情況:單條語句執行超過2000毫秒,或者單條語句反復執行超過10次,這些語句都是需要優化的。單條語句執行時間過長,檢查語句是否使用了索引,要避免全表搜索。單條語句執行次數過多,檢查程序邏輯,是否可以減少訪問數據庫的次數。
14、 在一個LOOP中,工作區在當前循環的最后一次操作后,下次循環開始之前,在循環的最后一句程序語句中,應該用CLEAR清空。對於非循環的情況,一旦這個工作區中的值不再被處理,應該用CLEAR清空。
例:LOOP AT……
……
CLEAR WA.
ENDLOOP.
X = WA.
CLEAR WA.
15、 當程序不再使用內表中的數據時,可以使用REFRESH語句清空內表中的數據;如果內表在程序中不再繼續使用,而且內表中保存了大量的數據,應該使用FREE語句清空內表中數據並釋放分配的內存。
八、 結構化和模塊化
結構化和模塊化遵循如下幾個原則:
a) 如果程序的邏輯部分的編碼量(數據聲明不包括在內)超過100行,必須進行結構化和模塊化(編寫功能相對獨立的子程序和FUNCTION);
b) 對於被其他程序共享的源代碼,要將其包裝在FUNCTION內,提高源代碼的重用性;
c) 程序全局類型定義與變量的聲明及SELECTION-SCREEN的定義,做為單獨的INCLUDE文件,供程序引用。例:INCLUDE ZFI_R_01TOP
d) 如果系統提供了同樣功能的FUNCTION,使用系統提供的FUNCTION。
對於主程序,應按照下面示例進行過程化和結構化。
*&---------------------------------------------------------------------*
*& SELECT-OPTIONS
*&---------------------------------------------------------------------*
SELECT-OPTIONS:
SO_VKORG FOR VBAK-VKORG OBLIGATORY
MEMORY ID VKO,"Sales organization
SO_VTWEG FOR VBAK-VTWEG, "Dis.channel
SO_VKBUR FOR VBAK-VKBUR, "Sales office
SO_KUNNR FOR VBAK-KUNNR, "SOLD-TO
SO_ERDAT FOR VBAK-ERDAT, "Order creation date
SO_AUART FOR VBAK-AUART DEFAULT 'ZTOR' , "Order type
SO_VBELN FOR VBAK-VBELN, "s/o no,
SO_ERNAM FOR VBAK-ERNAM DEFAULT SY-UNAME,
"Name of Person who Created the O
SO_GBSTA FOR VBUP-GBSTA.
*&---------------------------------------------------------------------*
*& INITIALIZATION
*&---------------------------------------------------------------------*
INITIALIZATION.
P_ERDAT-LOW = SY-DATUM.
P_ERDAT-LOW+6(2) = 01.
P_ERDAT-HIGH = SY-DATUM.
APPEND P_ERDAT.
*&---------------------------------------------------------------------*
*& TOP-OF-PAGE
*&---------------------------------------------------------------------*
TOP-OF-PAGE.
PERFORM WRITE_HEADER.
*&---------------------------------------------------------------------*
*& AT LINE-SELECTION
*&---------------------------------------------------------------------*
AT LINE-SELECTION.
GET CURSOR FIELD F VALUE V.
CHECK NOT ( V IS INITIAL ).
PERFORM CALL_TRANSACTION.
PERFORM CHECK_PERIOD.
PERFORM GET_BILLING_DATA.
PERFORM ANALYSIS_DATA.
PERFORM SORT_CHANGING USING OK_CODE_M.
PERFORM PRINT_RTN USING OK_CODE_M.
*&---------------------------------------------------------------------*
* START-OF-SELECTION.
*&---------------------------------------------------------------------*
START-OF-SELECTION.
SET PF-STATUS 'ZOR3'.
PERFORM GET_DATA.
九、ABAP報表詳細設計文檔編寫的原則
要求在詳細設計文檔中體現每一段不可分割的子邏輯,而在編碼階段,直接將這些子邏輯的偽代碼作為注解體現在源代碼中。
4、修改補充:
按版本依次填寫每次修改內容:
1)版本信息記錄:程序修改必填,記錄本次修改對應文件管理中的版本信息;
2)需求描述:程序修改必填,記錄本次修改的業務驅動或系統驅動原因;
3)修改內容描述:程序修改必填,記錄本次修改的邏輯處理和必要的說明信息;