ABAP STARTING NEW TASK 并行处理
【摘要】 并行处理在 SAP 中,经常有一些操作是需要上锁的,而这种情况想要同时操作就会出错。比如使用 MM02 的时候需要使用 MMSC 来扩展库存,就会出现如图中的报错:并行处理:当需要处理大量记录并且需要大量时间来产生输出时,可以应用这种并行处理技术来实现运行时间的改进。所以这个并行处理是并行会话/不同会话/多个会话中对功能模块的异步调用。顾名思义,并行处理无非是同时处理那些彼此独立的任务。它...
并行处理
在 SAP 中,经常有一些操作是需要上锁的,而这种情况想要同时操作就会出错。比如使用 MM02
的时候需要使用 MMSC
来扩展库存,就会出现如图中的报错:
并行处理:当需要处理大量记录并且需要大量时间来产生输出时,可以应用这种并行处理技术来实现运行时间的改进。所以这个并行处理是并行会话/不同会话/多个会话中对功能模块的异步调用。
顾名思义,并行处理无非是同时处理那些彼此独立的任务。它与某些 OOP 语言(C#,C++,Java)中的线程类似。实际上,并行处理是使用 RFC 服务器组执行异步 RFC( asynchronous RFC,缩写 aRFC )。
RFC 服务器组是一个 SAP 概念,它允许配置标识符并关联多个应用程序服务器以及可用资源的百分比。
语法结构
CALL FUNCTION func_name STARTING NEW TASK task
[DESTINATION {dest|{IN GROUP {group|DEFAULT}}}]
[{CALLING meth}|{PERFORMING subr} ON END OF TASK]
parameter_list.
使用 RFC 接口在 func 中指定的启用远程的功能模块的异步调用 (aRFC)。func_name
和 dest
需要类似字符的数据对象:
- 添加的
DESTINATION
用于指定 dest 中的单个目标 - 使用
IN GROUP
指定一组应用程序服务器。RFC 和 RFC 服务器组之间的连接点是关键字 IN GROUP ,支持多个功能模块的并行处理。 - 一旦远程调用函数在目标系统中启动,调用程序就会使用语句
CALL FUNCTION
继续,而不必等待其处理完成 - 使用
CALL
和PERFORMING
指定在远程调用函数终止时接管事件的回调函数。在此进程完成时执行,关键字PERFORMING subr
在任务结束时或调用方法在任务结束时。
要等待 aRFC 调用被执行,请使用 WAIT UNTILL
命令。 如果条件满足,程序将继续执行,如果不满足,则进程将等待下一个 aRFC 执行完毕,直到条件满足或所有 aRFC 调用都执行完毕。
如果服务器上没有可用资源, aRFC 发生 RESOURCE_FAILURE 系统异常
示例:
*&---------------------------------------------------------------------*
*& Report zparallel_processing
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zparallel_processing.
TYPES:
BEGIN OF gts_task,
task TYPE c LENGTH 5,
foo TYPE c LENGTH 5,
bar TYPE c LENGTH 5,
subrc TYPE c LENGTH 5,
message TYPE text80,
END OF gts_task.
DATA gv_tasks TYPE i.
DATA gt_tasks TYPE TABLE OF gts_task.
FIELD-SYMBOLS <gs_tasks> TYPE gts_task.
START-OF-SELECTION.
PERFORM main.
FORM main.
CLEAR gv_tasks.
PERFORM call_rfc USING 1 ''.
PERFORM call_rfc USING 1 'NONE'.
PERFORM call_rfc USING 0 'NONE'.
PERFORM call_rfc USING 1 'UNKNOWN'.
PERFORM call_rfc USING -1 'NONE'.
WAIT UNTIL gv_tasks EQ 0.
WRITE: / `Task `, `Foo `, `Bar `, `Subrc`, `Message`.
LOOP AT gt_tasks ASSIGNING <gs_tasks>.
WRITE: / <gs_tasks>-task,
<gs_tasks>-foo,
<gs_tasks>-bar,
<gs_tasks>-subrc,
<gs_tasks>-message.
ENDLOOP.
WRITE / '所有任务已完成.'.
ENDFORM.
FORM call_rfc USING iv_foo TYPE i
iv_rfc TYPE rfcdest.
DATA lv_msg TYPE c LENGTH 80.
APPEND INITIAL LINE TO gt_tasks ASSIGNING <gs_tasks>.
<gs_tasks>-task = lines( gt_tasks ).
<gs_tasks>-foo = iv_foo.
CALL FUNCTION 'Z_TEST_RFC' DESTINATION iv_rfc
STARTING NEW TASK <gs_tasks>-task
PERFORMING callback ON END OF TASK
EXPORTING
iv_foo = iv_foo
EXCEPTIONS
communication_failure = 1 MESSAGE lv_msg
system_failure = 2 MESSAGE lv_msg.
IF sy-subrc EQ 0.
lv_msg = '任务开始'.
ENDIF.
<gs_tasks>-subrc = sy-subrc.
<gs_tasks>-message = lv_msg.
ADD 1 TO gv_tasks.
ENDFORM.
FORM callback USING p_task TYPE clike.
DATA lv_bar TYPE i.
DATA lv_msg TYPE c LENGTH 80.
READ TABLE gt_tasks ASSIGNING <gs_tasks>
WITH KEY task = p_task.
CHECK sy-subrc EQ 0.
RECEIVE RESULTS FROM FUNCTION 'Z_TEST_RFC'
IMPORTING
ev_bar = lv_bar
EXCEPTIONS
system_failure = 1 MESSAGE lv_msg
wrong_input = 2.
CASE sy-subrc.
WHEN 0.
lv_msg = '任务成功完成.'.
WHEN 2.
lv_msg = '输入错误异常.'.
ENDCASE.
<gs_tasks>-subrc = sy-subrc.
<gs_tasks>-message = lv_msg.
<gs_tasks>-bar = lv_bar.
SUBTRACT 1 FROM gv_tasks.
ENDFORM.
实现新建物料的时候自动扩展库位
- 在用户出口增强中写入如下代码:
" 更新或者创建工厂视图时自动扩展工厂下所有库位
IF sy-tcode = 'MM01' AND sy-ucomm = 'BU' OR sy-ucomm = 'YES' .
IF wmard-werks IS NOT INITIAL AND wmard-lgort IS NOT INITIAL.
DATA: gs_t001l TYPE t001l.
DATA: gt_t001l LIKE TABLE OF gs_t001l,
returnmsg TYPE bapiret2_tt. "返回参数
REFRESH gt_t001l.
SELECT werks lgort FROM t001l INTO CORRESPONDING FIELDS OF TABLE gt_t001l
WHERE werks = wmard-werks AND lgort <> wmard-lgort.
IF sy-subrc = 0. " 当前选择的工厂和库位存在
CALL FUNCTION 'ZRFC_PARELLEL_MMSC' STARTING NEW TASK 'TASK1'
EXPORTING
i_matnr = wmara-matnr
i_werks = wmard-werks
i_lgort = wmard-lgort
TABLES
returnmessages = returnmsg[]. "返回参数
ENDIF.
ENDIF.
ENDIF.
- 在
SE37
中创建如下函数模块,并设置为Remote-Enabled Module
,源代码如下:
FUNCTION zrfc_parellel_mmsc .
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(I_MATNR) TYPE MATNR
*" VALUE(I_WERKS) TYPE WERKS_D
*" VALUE(I_LGORT) TYPE LGORT_D OPTIONAL
*" VALUE(I_DELAY) TYPE FLAG DEFAULT 'X'
*" TABLES
*" RETURNMESSAGES STRUCTURE BAPI_MATRETURN2 OPTIONAL
*"----------------------------------------------------------------------
DATA: headdata TYPE bapimathead, "带有控制信息的表头段
storagelocationdata TYPE bapi_mard,
storagelocationdatax TYPE bapi_mardx,
ls_returnmes TYPE bapi_matreturn2.
DATA: gt_out TYPE TABLE OF ty_out,
gs_out TYPE ty_out.
CLEAR gt_out.
SELECT werks lgort INTO CORRESPONDING FIELDS OF TABLE gt_out
FROM t001l
WHERE werks = i_werks
AND lgort <> i_lgort.
LOOP AT gt_out INTO gs_out.
SELECT SINGLE lgort INTO @DATA(lv_lgort) FROM mard
WHERE matnr = @i_matnr
AND werks = @gs_out-werks AND lgort = @gs_out-lgort.
IF sy-subrc <> 0.
IF i_delay = 'X'.
WAIT UP TO 8 SECONDS. " 延迟
ENDIF.
CLEAR headdata .
headdata-material_long = i_matnr. "物料
headdata-storage_view = 'X'. "存储视图
CLEAR storagelocationdata.
storagelocationdata-plant = gs_out-werks.
storagelocationdata-stge_loc = gs_out-lgort.
CLEAR storagelocationdatax.
storagelocationdatax-plant = gs_out-werks.
storagelocationdatax-stge_loc = gs_out-lgort.
CALL FUNCTION 'BAPI_MATERIAL_SAVEDATA' " STARTING NEW TASK gv_task
* PERFORMING return_msg ON END OF TASK
EXPORTING
headdata = headdata
storagelocationdata = storagelocationdata
storagelocationdatax = storagelocationdatax
* IMPORTING
* RETURN = RETURN
TABLES
returnmessages = returnmessages[].
CLEAR ls_returnmes.
READ TABLE returnmessages[] INTO ls_returnmes WITH KEY type = 'E' .
IF sy-subrc EQ 0.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ENDIF.
ENDIF.
ENDLOOP.
ENDFUNCTION.
使用 STARTING NEW TASK 来打开新的 Win 窗口
*&---------------------------------------------------------------------*
*& Report Z_OPEN_NEW_WINDOW
*&---------------------------------------------------------------------*
*& This is the main ABAP report calling the SAP Transaction VA03 in a new session or in a new window
*&---------------------------------------------------------------------*
REPORT z_open_new_window.
DATA :
wa_spa TYPE rfc_spagpa,
itab_spa TYPE TABLE OF rfc_spagpa.
wa_spa-parid = 'AUN'.
wa_spa-parval = '1100004898'.
APPEND wa_spa TO itab_spa.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'VA03'
DESTINATION 'NONE'
EXPORTING
tcode = 'VA03'
skip_screen = 'X'
TABLES
spagpa_tab = itab_spa
EXCEPTIONS
communication_failure = 1
system_failure = 2.
IF sy-subrc <> 0.
" ERROR
ENDIF.
最终效果:
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)