ABAP STARTING NEW TASK 并行处理

举报
雨绸缪 发表于 2023/08/24 19:07:11 2023/08/24
【摘要】 并行处理在 SAP 中,经常有一些操作是需要上锁的,而这种情况想要同时操作就会出错。比如使用 MM02 的时候需要使用 MMSC 来扩展库存,就会出现如图中的报错:并行处理:当需要处理大量记录并且需要大量时间来产生输出时,可以应用这种并行处理技术来实现运行时间的改进。所以这个并行处理是并行会话/不同会话/多个会话中对功能模块的异步调用。顾名思义,并行处理无非是同时处理那些彼此独立的任务。它...

并行处理

在 SAP 中,经常有一些操作是需要上锁的,而这种情况想要同时操作就会出错。比如使用 MM02 的时候需要使用 MMSC 来扩展库存,就会出现如图中的报错:

image.png

并行处理:当需要处理大量记录并且需要大量时间来产生输出时,可以应用这种并行处理技术来实现运行时间的改进。所以这个并行处理是并行会话/不同会话/多个会话中对功能模块的异步调用。

顾名思义,并行处理无非是同时处理那些彼此独立的任务。它与某些 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_namedest 需要类似字符的数据对象:

  • 添加的 DESTINATION 用于指定 dest 中的单个目标
  • 使用 IN GROUP 指定一组应用程序服务器。RFC 和 RFC 服务器组之间的连接点是关键字 IN GROUP ,支持多个功能模块的并行处理。
  • 一旦远程调用函数在目标系统中启动,调用程序就会使用语句 CALL FUNCTION 继续,而不必等待其处理完成
  • 使用 CALLPERFORMING 指定在远程调用函数终止时接管事件的回调函数。在此进程完成时执行,关键字 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.

实现新建物料的时候自动扩展库位

  1. 在用户出口增强中写入如下代码:
" 更新或者创建工厂视图时自动扩展工厂下所有库位
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.
  1. 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.

最终效果:

跳转事件.gif

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。