Calling Programs
下面ABAP語句允許你調用一個可執行程序或者事務碼,調用后你可以直接退出主調程序,或者返回到調用被調程序的地方繼續后繼代碼的執行:
可執行Program Transaction
Call (without returning) SUBMIT LEAVE TO TRANSACTION
Call and return SUBMIT AND RETURN CALL TRANSACTION
Calling Executable Programs(SUBMIT)
SUBMIT<rep>|(<field>) [AND RETURN] [<options>].
如果省略AND RETURN選項,主調程序的所有數據與所有級別的List都會從 internal session 中刪除。在被調程序執行完后,會返回到主調程序啟動的地方。
如果帶AND RETURN選項,系統將會保持主調程序的所有數,並在被調程序執行完后返回到主調程序調用處(SUBMIT…AND RETURN語句調用處),然后系統會繼續執行主調程序SUBMIT…AND RETURN后面的語句。
<options>用來將數據傳遞給被調程序,有以下方式:
設置選擇屏幕參數值(SUBMIT...WITH)
當正常執行一個報表程序時,標准的選擇屏幕會顯示,這些屏幕選擇條件可以是程序自己本身的,也可以是綁定的LDB的屏幕字段。當使用SUBMIT調用時,可以通過各種參數選項來給這些屏幕選擇條件填充值:
SUBMIT... [VIA SELECTION-SCREEN]
[USING SELECTION-SET <var>]
[WITH <sel><criterion>]
[WITH FREE SELECTIONS <freesel>]
[WITH SELECTION-TABLE <rspar>].
VIA SELECTION-SCREEN
被調報表程序的選擇屏幕會顯示。如果此選擇打開,並且還使用了其他參數選項來傳輸值時,這些值也會顯示在屏幕中相應的輸入框中,並且用戶可以進一步修改這些值。在默認的情況下,通過SUBMIT調用時是不會顯示可執行程序的選擇屏幕的。
USING SELECTION-SET <var>
使用變式<var>。This option tells the system to start the called program with the variant <var>.
WITH <sel><criterion>
使用此選擇可以對選擇屏幕的某個選擇條件<sel>進行單獨的賦值,並通過<criterion>部分來具體來決定是SELECT-OPTIONS還是PARAMETERS,<criterion>部分可以為以下三種情況:
l <op><f> [SIGN <s>], 用來傳輸屏幕選擇條件的單個值
如果<sel>為SELECT-OPTIONS類型的屏幕選擇條件,則使用<op>去填充選擇內表<sel>的OPTION字段,<f>去填充選擇內表<sel>的LOW字段,<s>去填充選擇內表<sel>的SIGN字段(注:如果屏幕條件取值為某個范圍,則這里<op>不用BT與NB,則使用下面的[NOT] BETWEEN來單獨傳遞)
如果<sel>為PARAMETERS類型的屏幕字段,<op>的值只能是“=”,並將<f>的值賦值給相應屏幕字段<sel>
l [NOT] BETWEEN <f1> AND <f2> [SIGN <s>], 用來傳遞范圍取值
<f1>會傳遞給LOW字段,<f2>會傳遞給HIGH字段,<s>會傳遞給選擇內表<sel>的SIGN字段。如果省略了NOT選項,系統會將OPTION字段設置為BT,如果使用了NOT選項,系統會將OPTION設置為NB。
l IN <seltab>, 通過條件選擇內表(行結構類型與SELECT-OPTION選擇條內表行結構相同)傳遞屏幕參數
該選項會將主調程序中的條件內表<seltab>賦值給被調用程序的條件選擇內表<sel>。<seltab>必須是一個條件內表,可以使用RANGES語句來創建。
WITH FREE SELECTION <freesel>, user dialog for dynamic selections動態選擇的用戶對話
To use this option, both calling and called programs must be connected to a logical
database that supports dynamic selections. In the calling program, use the function
modules FREE_SELECTIONS_INIT and FREE_SELECTIONS_DIALOG. They allow the
user to enter dynamic selections on a selection screen. One export parameter of these
function modules has structure RSDS_TEXPR from the RSDS type group. Transfer the
values of this export parameter by means of the internal table <freesel> of the same
structure to the called report.
要使用此選項,必須將調用報表和被調用報表都連接到支持動態選擇的邏輯數據庫。在調用報表中,使用功能模塊 FREE-SELECTIONS_INIT 和 FREE_SELECTIONS_DIALOG,它們允許用戶在選擇屏幕上輸入動態選擇。這些功能塊的一個輸出參數有 RSDS 類型組中的 RSDS_TEXPR 結構。通過相同結構的內部表<freesel>將此輸出參數的值傳送到被調用報表。
WITH SELECTION-TABLE <rspar>, dynamic transfer of values
<rspar>內表必須是行結構必須是RSPARAMS結構類型的類型,該結構包含以下字段:
SELNAME:SELECT-OPTION 或者 PARAMETER屏幕字段名稱
KIND:如果是SELECT-OPTION時,取值為S,如果PARAMETER時,取值為P。
其他字段與SELECT-OPTION選擇條內表行結構相同。
除了WITH SELECTION-TABLE以外,WITH <sel>選項你可以多次使用。在實際應用中,你可以對某個SELECT-OPTION選擇條件<sel>使用WITH <sel>選項多次,在被調用程序中,系統會將這些行append到selection tables<sel>中,但如果對某個PARAMETER條件使用多次,則會使用最后一次的值。
實例一:參數傳遞
REPORT zjzj_rep2 NO STANDARD PAGE HEADING.
DATA: int TYPE i,
rspar LIKE rsparams OCCURS 10 WITH HEADER LINE.
RANGES seltab FOR int.
WRITE: 'Select a Selection!',
/ '--------------------'.
SKIP.
FORMAT HOTSPOT COLOR 5 INVERSE ON.
WRITE: 'Selection 1',
/ 'Selection 2'.
AT LINE-SELECTION.
CASE sy-lilli."選中的行號
WHEN 4.
seltab-sign = 'I'.
seltab-option = 'BT'.
seltab-low = 1.
seltab-high = 5.
APPEND seltab.
SUBMIT zjzj_rep1 VIA SELECTION-SCREEN
WITH paramet EQ 'Selection 1'
WITH selecto IN seltab
WITH selecto NE 3
AND RETURN.
WHEN 5.
rspar-selname = 'SELECTO'.
rspar-kind = 'S'.
rspar-sign = 'E'.
rspar-option = 'BT'.
rspar-low = 14.
rspar-high = 17.
APPEND rspar.
rspar-selname = 'PARAMET'.
rspar-kind = 'P'.
rspar-low = 'Selection 2'.
APPEND rspar.
rspar-selname = 'SELECTO'.
rspar-kind = 'S'.
rspar-sign = 'I'.
rspar-option = 'GT'.
rspar-low = 10.
APPEND rspar.
SUBMIT zjzj_rep1 VIA SELECTION-SCREEN
WITH SELECTION-TABLE rspar
AND RETURN.
ENDCASE.
REPORT ZJZJ_REP1.
DATA number TYPE i.
PARAMETERS paramet(14).
SELECT-OPTIONS selecto FOR number.
實例二:參數傳遞及返回值接收
REPORT yjzj_call_prog_9_6_2.
TABLES: mard.
DATA: BEGIN OF gx_mard OCCURS 0,
matnr LIKE mard-matnr,
werks LIKE mard-werks,
lgort LIKE mard-lgort,
labst LIKE mard-labst,
insme LIKE mard-insme,
END OF gx_mard,
gt_mard LIKE TABLE OF gx_mard.
CONSTANTS: g_memory(30) VALUE 'JACKYTEST'.
PARAMETERS: p_werks LIKE mard-werks OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR mard-matnr.
PARAMETERS: p_qty AS CHECKBOX.
PARAMETERS: p_type NO-DISPLAY DEFAULT '1'.
START-OF-SELECTION.
DATA: gt_tabsel LIKE rsparams OCCURS 10 WITH HEADER LINE.
IF NOT s_matnr[] IS INITIAL.
LOOP AT s_matnr.
"selection類型參數需要封裝到rsparams類型的內表中才能傳遞
MOVE-CORRESPONDING s_matnr TO gt_tabsel.
"被調用程序中的selection-option參數
gt_tabsel-selname = 'S_MATNR'.
gt_tabsel-kind = 'S'.
APPEND gt_tabsel.
CLEAR gt_tabsel.
ENDLOOP.
ENDIF.
SUBMIT yjzj_call_prog_9_6 WITH p_werks = p_werks
WITH p_qty = p_qty
WITH p_type = 'X'
"傳遞selection類型的參數到被調用程序中
WITH SELECTION-TABLE gt_tabsel
AND RETURN.
"從被調用程序中導入結果
IMPORT gt_mard TO gt_mard FROM MEMORY ID g_memory.
FREE MEMORY ID g_memory.
LOOP AT gt_mard INTO gx_mard.
WRITE:/02 gx_mard-matnr,
gx_mard-werks,
gx_mard-lgort,
gx_mard-labst,
gx_mard-insme.
ENDLOOP.
REPORT yjzj_call_prog_9_6.
TABLES: mard.
DATA: BEGIN OF gx_mard OCCURS 0,
matnr LIKE mard-matnr,
werks LIKE mard-werks,
lgort LIKE mard-lgort,
labst LIKE mard-labst,
insme LIKE mard-insme,
END OF gx_mard,
gt_mard LIKE TABLE OF gx_mard.
CONSTANTS: g_memory(30) VALUE 'JACKYTEST'.
PARAMETERS: p_werks LIKE mard-werks OBLIGATORY.
SELECT-OPTIONS: s_matnr FOR mard-matnr.
PARAMETERS: p_qty AS CHECKBOX.
PARAMETERS: p_type NO-DISPLAY.
START-OF-SELECTION.
SELECT matnr werks lgort labst insme
INTO CORRESPONDING FIELDS OF TABLE gt_mard FROM mard WHERE
matnr IN s_matnr AND
werks EQ p_werks.
DATA: g_tabix TYPE i.
IF p_qty NE space.
LOOP AT gt_mard INTO gx_mard.
g_tabix = sy-tabix.
gx_mard-labst = gx_mard-labst + gx_mard-insme.
IF gx_mard-labst <= 0.
DELETE gt_mard INDEX g_tabix.
CONTINUE.
ENDIF.
ENDLOOP.
ENDIF.
IF p_type NE space.
FREE MEMORY ID g_memory.
"將結果導出到主調用程序
EXPORT gt_mard FROM gt_mard TO MEMORY ID g_memory.
ELSE.
LOOP AT gt_mard INTO gx_mard.
WRITE:/02 gx_mard-matnr,
gx_mard-werks,
gx_mard-lgort,
gx_mard-labst,
gx_mard-insme.
ENDLOOP.
ENDIF.
控制Called Programs中LISTS輸出
當你使用SUBMIT提交一個ABAP program時,你可以控制這個被調程序的輸出列表:修改輸出行列長度格式、輸出到spool file來代替輸出到屏幕、或者是將輸出列表存儲到ABAP memory中。
修改輸出LISTS行列數
SUBMIT... [LINE-SIZE<width>] [LINE-COUNT<length>].
如果被調程序的REPORT語句后面沒有這LINE-SIZE與LINE-COUNT兩個選項,系統將會使用SUBMIT語句后面的這兩個選項來格式化輸出列表。
REPORT zjzj_rep2 NO STANDARD PAGE HEADING.
DATA: NAME(9) VALUE 'ZJZJ_REP1',
WID TYPE I VALUE 80,
LEN TYPE I VALUE 0.
SET PF-STATUS 'SELECT'.
WRITE: 'Select a report and its list format:',
/ '-------------------------------------'.
SKIP.
WRITE: 'Report ', NAME INPUT ON,
/ 'Line size ', WID INPUT ON,
/ 'Page length', LEN INPUT ON.
AT USER-COMMAND.
CASE SY-UCOMM.
WHEN 'SELE'.
READ LINE: 4 FIELD VALUE NAME,
5 FIELD VALUE WID,
6 FIELD VALUE LEN.
SUBMIT (NAME) LINE-SIZE WID LINE-COUNT LEN AND RETURN.
ENDCASE.
將被調程序的輸出列表打印到spool system
SUBMIT... TO SAP-SPOOL<print-parameters>.
可以將被調程序的輸出列表直接輸出到spool system,而不是顯示在屏幕上。
將輸出列表保存到ABAP memory
可以使用EXPORTING LIST TO MEMORY選項將被調程序輸出列表保存到ABAP內存中(而不是直接顯示在屏幕上),供被調程序執行完后,主調程序來使用輸出列表:
SUBMIT... AND RETURN EXPORTING LIST TO MEMORY.
將被調程序的輸出列表存儲到ABAP內存中,可以在被調程序執行完后,主調程序還可以訪問它。EXPORTING LIST TO MEMORY選項需要與AND RETURN選項一起使用。並且不能將EXPORTING LIST TO MEMORY選項與TO SAP-SPOOL選項一起使用。
輸出列表存到內存里時,會以行類型為ABAPLIST的內表形式保存,可以使用下面這幾個Function來訪問ABAP內在中保存的輸出列表(這些函數都是屬於function group SLST):
LIST_FROM_MEMORY:從ABAP Memory中將ListsLoad到row type ABAPLIST的內表中
WRITE_LIST:將行類型為ABAPLIST 的內表中的內容插入到當前輸出列表中.
DISPLAY_LIST:將行類型為ABAPLIST 的內表中的內容顯示在獨立的list screen中
LIST_TO_ASCI:將行類型為ABAPLIST 的內表中的內容轉換ASCII形式
DATA list_tab TYPE TABLE OF abaplist.
SUBMIT report EXPORTING LIST TO MEMORY
AND RETURN.
"從ABAP內存中加載緩存的LIST
CALL FUNCTION 'LIST_FROM_MEMORY'
TABLES
listobject = list_tab
EXCEPTIONS
not_found = 1
OTHERS = 2.
"在當前屏幕中顯示上面加載的LIST
IF sy-subrc = 0.
CALL FUNCTION 'WRITE_LIST'
TABLES
listobject = list_tab.
ENDIF.
使用LEAVE語句退出被調程序
在通常情況下,我們在被調程序的基礎輸出列表(Level為0的List屏幕)按F3就會退出該程序。但是,在返回到主調程序之前,在被調程序里需要執行更多的語句,比如需要使用EXPORT語句將被調程序中的數據存儲到ABAP memory中便於主調程序使用時,像這樣,你可以為Back Function自定義Function Code(不要使用默認的BACK,即要自己重寫默認的BACK Function Code),並且在AT USER-COMMAND事件塊里對相應的Function Code進行處理,當你將數據存儲起來之后,就可以使用LEAVE(因為重寫了默認的BACK Function Code,所以需要使用LEAVE語句來以編程方式退出程序)語句來退出當前被調用的程序了:
REPORT ZJZJ1 NO STANDARD PAGE HEADING.
DATA: ITAB TYPE I OCCURS 10,
NUM TYPE I.
SUBMIT zjzj2 AND RETURN.
IMPORT ITAB FROM MEMORY ID 'HK'.
LOOP AT ITAB INTO NUM.
WRITE / NUM.
ENDLOOP.
TOP-OF-PAGE.
WRITE 'Report 1'.
ULINE.
注:不要將Function定義成默認的BACK了,否則不會被AT USER-COMMAND事件塊捕獲到,會使用默認的回退功能。
REPORT ZJZJ2 NO STANDARD PAGE HEADING.
DATA: NUMBER TYPE I,
ITAB TYPE I OCCURS 10.
SET PF-STATUS 'MYBACK'.
DO 5 TIMES.
NUMBER = SY-INDEX.
APPEND NUMBER TO ITAB.
WRITE / NUMBER.
ENDDO.
TOP-OF-PAGE.
WRITE 'Report 2'.
ULINE.
AT USER-COMMAND.
CASE SY-UCOMM.
WHEN 'MBCK'.
EXPORT ITAB TO MEMORY ID 'HK'."退出前執行一些語句
LEAVE."離開當前被調程序,返回到主調程序
ENDCASE.
CALL TRANSACTION、LEAVE TO TRANSACTION
二種方法調用Tcode:
1、 如果調用后不需要返回到主調程序,則可以使用下面這種方式:
LEAVE TO TRANSACTION <tcod>|(<tcod>)[AND SKIP FIRST SCREEN].
該語句會結束當前主調程序去執行事務碼<tcod>,並且會將主調程序從internal sessions中刪除,而被調用Tcode將會在該external session中新開一個internal session再運行,並且被調程序執行后,並不會回到主調程序調用處繼續往下執行,而是the system returns tothe area menu from which the original program in the call stack was started.
2、 如果調用后還要返回到主調程序,則使用下面這種方式:
CALL TRANSACTION <tcod>|(<tcod>) [AND SKIP FIRST SCREEN] [USING <bdc_tab >].
系統會重新開啟一個internal session,當被調程序結束后,被調Tcode所在的這個internal session會被delete掉,然后返回到主調程序調用處,繼續運行主調程序后面的語句
<bdc_tab>用在BDC調用輸入參數傳遞,具體請參考ABAP Practical Example App.docx文檔
退出程序 Leave Program
LEAVE PROGRAM.
退出整個程序,並刪除所在內部會話、包括加載的程序、實例、數據。
Passing Data Between Programs
請參考以下文檔:
《數據共享與傳遞.docx》
《ABAP BC Programming.docx》的程序間數據共享與傳遞章節