需求分析:
1、具體需求
本《使用子程序輸出物料表字段屬性》有如下需求:
- 本需求實現的效果,已在《實踐3A3-輸出物料表字段屬性》中中實現,而在其中是對每個字段進行檢查和輸出,代碼比較冗長,可讀性低且容易產生錯誤;
- 本實踐將使用子程序技術,通過模塊化編程-子程序技術,對相似代碼封裝為一個子程序以進行重用,對代碼進行簡化。
2、開發分析
要達成本實踐目標,需考慮地方和思路有如下:
- 如《實踐3A3-輸出物料表字段屬性》,通過DESCRIBE關鍵字,根據不同類型字段,可獲得字段的不同屬性,包括類型(TYPE)、長度(LENGTH)、小數位數(DECIMALS)、輸出長度(OUTPUT-LENGTH)、字段對應數據元素(HELP-ID)/例程(EDIT MASK);
- 需要注意的是,不同類型的字段可獲得的屬性和獲得屬性的方式是存在差異的,如字符型沒有小數位數,如只能通過IN BYTE MODE獲得長度。
- 可以從表中獲得數據后,通過子程序,可以傳入字段后獲得字段的各種屬性,子程序的PAD圖如圖所示。
實踐步驟:
本實踐通過程序編輯器(SE38)即可完成,編寫的代碼將有如下幾部分組成,按開發人員風格不同,其組成部分并非強制一致。
No | 部分 | 說明 |
---|---|---|
1 | 程序聲明 | 聲明本程序執行后是否包含標準標題,數據輸出寬度和每頁的行數量為多少 |
2 | 對象定義 | 定義要在程序執行過程中存儲輸出數據的結構 |
3 | 頁眉輸出 | 通過代碼設置輸出頁眉頁腳 |
4 | 獲取和輸出數據 | 從表中獲得要輸出的數據,并調用子程序將數據按要求輸出 |
5 | 子程序定義 | 通過子程序定義獲得和輸出字段屬性 |
1、程序聲明
程序聲明部分的代碼如下:
REPORT zu0502_mat_stru_data_perform NO STANDARD PAGE HEADING.
因為本程序只輸出一個物料數據的相應信息,所占幅面不大,因此如上代碼,沒指定頁面寬度和頁面高度;在此情況下,會根據當前頁面大小自動確定寬度,同時不會分頁。
2、對象定義
對象定義部分的代碼如下:
*****對象定義
DATA: BEGIN OF mat_stru, "MAT_STRU-結構體名稱
mandt TYPE ztmaterial-mandt, "通過已有表字段定義類型
materialid TYPE ztmaterial-materialid,
materialname TYPE ztmaterial-materialname,
sunit TYPE ztmaterial-bunit,
materialtype TYPE ztmaterial-materialtype,
supplier TYPE ztmaterial-supplier,
sprice TYPE ztmaterial-sprice,
scurrency TYPE ztmaterial-scurrency,
inventory TYPE ztmaterial-inventory,
END OF mat_stru.
PARAMETERS: matnr TYPE ztmaterial-materialid DEFAULT '1017'.
通過如上代碼定義了一個結構mat_stru,此結構也可以通過數據字典進行定義;另外也定義了相應的變量用于數據的輸出;同時定義了一個選擇字段matnr用于選擇界面的輸入,此選擇字段可以在“文本元素”的“選擇文本”中設置程序執行后頁面上的顯示文字。
3、輸出頁眉
輸出頁眉部分的代碼如下:
*&----------------------------------------------------------------------*
*& 輸出頁眉
*&----------------------------------------------------------------------*
TOP-OF-PAGE. "頁眉事件
WRITE:/5(75) sy-uline,
/5 '字段', 20 '字段說明', 35(15) '字段值', 50 '字段類型', 60 '長度' , 70 '小數位數',
/5(75) sy-uline.
頁眉也可通過文本元素設置,或在輸出數據代碼中實現。
4、獲得和輸出數據
獲得和輸出數據部分的代碼如下:
*&----------------------------------------------------------------------*
*& START-OF-SELECTION
*&----------------------------------------------------------------------*
START-OF-SELECTION. "數據處理事件
*****獲得物料信息
SELECT SINGLE "從表ZTMETERIAL中獲得物料信息數據并賦值到結構體
mandt materialid materialname sunit materialtype supplier sprice scurrency inventory
INTO mat_stru
FROM ztmaterial
WHERE materialid = matnr.
*****調用子程序輸出
PERFORM get_describe USING mat_stru-mandt 'MANDT' '集團'.
PERFORM get_describe USING mat_stru-materialid 'MATERIALID' '物料ID'.
PERFORM get_describe USING mat_stru-materialname 'MATERIALNAME' '物料名稱'.
PERFORM get_describe USING mat_stru-sunit 'SUNIT' '銷售計量單位'.
PERFORM get_describe USING mat_stru-materialtype 'MATERIALTYPE' '物料類型'.
PERFORM get_describe USING mat_stru-supplier 'SUPPLIER' '供應商'.
PERFORM get_describe USING mat_stru-sprice 'SPRICE' '價格'.
PERFORM get_describe USING mat_stru-scurrency 'SCURRENCY' '銷售價格單位'.
PERFORM get_describe USING mat_stru-inventory 'INVENTORY' '庫存數量'.
如上程序,首先根據選擇界面輸入的matnr(物料編號)的值,從ztmaterial表中選擇相應的記錄并存儲各字段值到結構mat_stru中。然后,通過PERFORM調用子程序輸出各字段的信息
5、子程序定義
子程序定義部分的代碼如下:
*&---------------------------------------------------------------------*
*& FORM GET_DESCRIBE
*&---------------------------------------------------------------------*
* 獲得字段屬性
*----------------------------------------------------------------------*
* -->fld 字段
* -->fldtxt 字段文本
*----------------------------------------------------------------------*
FORM get_describe USING VALUE(fld) VALUE(fldtxt).
DATA: hlp TYPE string, "含結構字段名稱
struc TYPE dfies-tabname, "結構名稱
fldn TYPE dfies-fieldname, "字段名稱
typ(1) TYPE c, "字段類型
len TYPE i, "字段長度
olen TYPE i, "字段輸出長度
deci TYPE i, "字段小數位數
compo TYPE i. "組合字段包含字段數量
DESCRIBE FIELD fld HELP-ID hlp. "獲得字段名稱
SPLIT hlp AT '-' INTO struc fldn.
DESCRIBE FIELD fld TYPE typ. "獲得字段類型
IF typ <> 'C' AND typ <> 'D' AND typ <> 'N' AND typ <> 'T'.
DESCRIBE FIELD fld LENGTH len IN BYTE MODE. "獲得字段長度
ELSE.
DESCRIBE FIELD fld LENGTH len IN CHARACTER MODE.
ENDIF.
IF typ = 'F' OR typ = 'P'.
DESCRIBE FIELD fld DECIMALS deci. "獲得小數位數
WRITE:/5 fldn, 20 fldtxt, 35(15) fld, 50 typ, 60 len, 70 deci.
ELSEIF typ = 'U' OR typ = 'V'.
DESCRIBE FIELD fld TYPE typ COMPONENTS compo. "獲得字段數量
WRITE:/5 fldn, 20 fldtxt, 35(15) fld, 50 typ, 60 len, 70 compo.
ELSEIF typ <> 'F' AND typ <> 'P' AND typ <> 'U' AND typ <> 'V'.
WRITE:/5 fldn, 20 fldtxt, 35(15) fld, 50 typ, 60 len, 70 ''.
ENDIF.
ENDFORM.
通過如上代碼,定義了一個名為get_describe的子程序,此子程序在“獲得和輸出數據”部分中被調用。此子程序按流程分析進行代碼的實現:首先傳入2個參數:fld、fldtxt,分別是字段和字段說明;然后在代碼部分,先是定義了用來存儲字段屬性值的各個變量,這些變量將會通過DESCRIBE獲得屬性值并予以存儲;隨后根據不同字段類型,獲得各種屬性值并進行輸出。
將如上5部分代碼合成一起,則可以實現本實踐的需求。
本實踐小結:
子程序(Subroutine Procedure)是包含在主程序中單獨作為一個小程序封裝的一段功能代碼;對于程序中多次用到的代碼,則可以抽離出來定義為一個子程序,以能重復應用和降低代碼的復雜性。
1、子程序
1) 子程序的定義
FORM <subr>.
<子程序語句塊>
ENDFORM.
2) 子程序的調用
內部調用:子程序位于相同的程序中
PERFORM <subr>.
外部調用:子程序位于其他程序中
3) 子程序的參數傳遞
可以在子程序中定義傳入的參數類型/值及處理的方式,并在調用時指定內部調用;在參數傳遞時又有不同的方式,分別為:By Reference(引用)、By Value(值)。
另外,如果以表的方式傳遞參數,其定義和調用方式如下:
FORM <subr> TABLES <p_itab> STRUCTURE <p_stru>.
<子程序語句塊>
ENDFORM.
PERFORM <subr> TABLES <itab>.
2、調用其他程序
對于因重復使用代碼或簡化代碼等需要時,除了子程序外,還可以通過SUBMIT和CALL TRANSATION方式直接在一個程序中調用另一個程序。
(實踐5A1 End)