在ABAP程序中,经常出现在Program A中调用Program B的需求,通常来讲,这种需求可以通过Submit或Call transaction的方式实现。
1. Submit
Submit也即直接提交一个程序,语法如下:
SUBMIT {rep|(name)} [selscreen_options]
… … … … … … … … [list_options]
… … … … … … … … [job_options]
… … … … … … … … [AND RETURN].
可以通过AND RETURN关键字控制,执行完被调用的程序后,是否返回主程序。使用SUBMIT时的一个难点在于参数的填充,也即如何填充被调用程序的selection screen,也即参数selscreen_options。
在编程过程中,如果遇到类似的需求,可以用 宏 DEFINE 快速实现,具体可参考下面的模板。
DATA:
lt_spar TYPE STANDARD TABLE OF rsparams,
ls_spar LIKE LINE OF lt_spar.
" fill screen parameters
DEFINE mac_set_parameter.
CLEAR ls_spar.
ls_spar-sign = 'I'.
ls_spar-option = 'EQ'.
ls_spar-selname = &1.
ls_spar-kind = 'P'.
ls_spar-low = &2.
APPEND ls_spar TO lt_spar.
END-OF-DEFINITION.
" fill selection options
DEFINE mac_set_selopt.
CLEAR ls_spar.
ls_spar-sign = 'I'.
ls_spar-option = &4.
ls_spar-selname = &1.
ls_spar-kind = 'S'.
ls_spar-low = &2.
ls_spar-high = &3.
APPEND ls_spar TO lt_spar.
END-OF-DEFINITION.
mac_set_parameter 'P_APPL' 'AIF'.
mac_set_parameter 'P_MAX' ' '.
mac_set_selopt 'S_MDATE' '00000000' '20211231' 'BT'.
SUBMIT /aif/error_handling_trans WITH SELECTION-TABLE lt_spar AND RETURN.
2. CALL Transaction
Call Transaction也即直接调用一个事务代码,其语法如下:
CALL TRANSACTION ta WITH|WITHOUT AUTHORITY-CHECK
… … … … … … … … USING bdc_tab { {[MODE mode] [UPDATE upd]}
… … … … … … … … | [OPTIONS FROM opt] }
… … … … … … … … [MESSAGES INTO itab].
具体的关键字用法,可查看ABAP的帮助文档。在CALL transaction时,其难点在于BDC字段的填充。
注:BDC - Batch Data Input是SAP非常经典一种批量导入技术,可以通过录制屏幕(Tx: SHDB)操作,生成代码。
在编程过程中,如果遇到类似的需求,也可以用 宏 DEFINE 快速实现,具体可参考下面的模板。
下例中,填充BDC包含了两种复杂操作,一种是填充selection-option, 另一种是通过剪切板中的内容来填充selection option,因此调用到了 cl_gui_frontend_services=>clipboard_expor()这个服务。
DATA:
lt_clipdata TYPE STANDARD TABLE OF char120,
lv_rc TYPE i,
ls_bdc TYPE bdcdata,
lt_bdc TYPE STANDARD TABLE OF bdcdata WITH DEFAULT KEY.
FIELD-SYMBOLS:
<ls_msgguid> LIKE LINE OF it_msgguid.
DEFINE bdc_dynpro.
CLEAR ls_bdc.
ls_bdc-program = &1.
ls_bdc-dynpro = &2.
ls_bdc-dynbegin = 'X'.
INSERT ls_bdc INTO TABLE lt_bdc.
END-OF-DEFINITION. "BDC_DYNPRO
DEFINE bdc_field.
CLEAR ls_bdc.
ls_bdc-fnam = &1.
ls_bdc-fval = &2.
INSERT ls_bdc INTO TABLE lt_bdc.
END-OF-DEFINITION. "BDC_DYNPRO
CLEAR es_msg.
CHECK it_msgguid IS NOT INITIAL.
LOOP AT it_msgguid ASSIGNING <ls_msgguid>.
INSERT CONV #( <ls_msgguid>-msgguid ) INTO TABLE lt_clipdata.
ENDLOOP.
IF sy-subrc = 0.
DATA(lv_msgguid) = it_msgguid[ 1 ]-msgguid.
* Put into clipboard
cl_gui_frontend_services=>clipboard_export(
IMPORTING
data = lt_clipdata
* length = " Data length
CHANGING
rc = lv_rc
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
OTHERS = 4
).
IF sy-subrc <> 0.
RETURN.
ENDIF.
ENDIF.
" fill normal screen parameters
bdc_dynpro '/AIF/ERROR_HANDLING_TRANS' '1000'.
bdc_field 'BDC_OKCODE' '=%00291010003785126'.
bdc_field 'P_APPL' 'AIF'.
bdc_field 'P_STS_S' 'X'.
bdc_field 'P_STS_W' 'X'.
" selection-option fill 2 values
bdc_field 'S_IFNAME-LOW' 'TEST_A'.
bdc_dynpro 'BDC_CURSOR' 'S_IFNAME-LOW'.
bdc_dynpro 'SAPLALDB' '3000'.
bdc_field 'BDC_OKCODE' '=ACPT'.
bdc_field 'BDC_CURSOR' 'RSCSEL_255-SLOW_I(02)'.
bdc_field 'RSCSEL_255-SLOW_I(02)' 'TEST_B'.
" fill selection-option from clipboard
bdc_dynpro '/AIF/ERROR_HANDLING_TRANS' '1000'.
bdc_field 'BDC_CURSOR' 'S_GUID32-LOW'.
bdc_field 'BDC_OKCODE' '=%034'.
bdc_dynpro 'SAPLALDB' '3000'.
bdc_field 'BDC_OKCODE' '=CLIP'.
bdc_field 'BDC_CURSOR' 'RSCSEL_255-SLOW_I(01)'.
bdc_dynpro 'SAPLALDB' '3000'.
bdc_field 'BDC_OKCODE' '=ACPT'.
bdc_field 'BDC_CURSOR' 'RSCSEL_255-SLOW_I(01)'.
CALL TRANSACTION '/AIF/ERR' USING lt_bdc
MODE 'E'.
3. 小技巧
- 填充BDC参数时,可以先用Tx: SHDB录制一个预期屏幕操作,然后导出到一个local的程序中,这样在填充BDC参数时,便可以参考系统自动生成的程序。
- 如果遇到,需要在新窗口打开被调用的程序,则可以使用 ABAP4_CALL_TRANSACTION 这个函数,也即对CALL Transaction进行了一个RFC的封装,这样就可以在一个新的进程中打开被调用的transaction。其中田中using_tab参数也即bdc格式的参数。示例如下:
" same as CALL TRANSACTION '/AIF/ERR' USING lt_bdc.
" but open in a new window.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'AIF'
EXPORTING
tcode = '/AIF/ERR'
mode_val = 'E'
update_val = 'L'
TABLES
using_tab = lt_bdc
EXCEPTIONS
call_transaction_denied = 1
tcode_invalid = 2
OTHERS = 3.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
RETURN.
ENDIF.