转载请标明出处:http://blog.csdn.net/wanglei880526/article/details/8949754

实际项目实施过程中,我们会遇到程序性能优化的问题,这里介绍一种方法:通过RFC接口进行远程函数的异步调用实现程序的并行处理。

同步/异步调用函数语法

同步调用:CALL FUNCTION 'AAA' ;

同步调用的实质:程序进行单线程执行。

异步调用:CALL FUNCTION 'AAA' STARTING NEWTASK <taskname> "任务名称

DESTINATION IN GROUP <RFC Serve Group>

PERFORMING <subroutine>ON END OF TASK。"子程序

异步调用的实质:程序进行多线程执行。

一些关于函数异步调用实现程序并行处理的文章,没有介绍如下问题:

⒈ 为了避免相同程序重复运行产生的后台任务相互冲突,需要保证在相同时间段同一程序只被一个用户占用;

⒉ 异步调用获取的最终结果数据与同步调用获取的结果存在差异;

⒊ 固定RFC Server Group如system = 'parallel_generators'无法保证程序在不同服务器中通用性。

问题1分析:从MD01中运行MRP我们可以知道,系统为了避免相同程序并发执行,导致后台任务冲突, MD01在并行模式下是不允许被两个用户同时执行的。如下图

解决方法:通过在程序中利用锁对象来达到程序相同时间段只被同一用户占用的目的。

问题2分析:在LOOP循环中采用异步调用函数的模式,通过SY-SUBRC = 0来判断任务启动成功,当SY-SUBRC <> 0时,则获取先前启动的进程返回的值,但是这样就遇到一个问题:如第N次循环正好分配给程序的进程被占用完,这样本次无法启动一个任务进程,导致本次的原始数据通过函数无法获取目标,从而最终结果出现数据不完整和数值不断变化的现象。

解决方法:牺牲部分性能保证数据的完整。通过RZ12获取服务器的Max. requests in queue 的值,LOOP循环的时候统计启动的启动的进程数是否 = Max. requests inqueue,如果等于则获取先前启动的进程返回的值,然后再重新启动进程,重复此操作。系统分配给每个程序的最大进程数> Max. requests in queue,但是把启动的进程数限制在Max.requests in queue的水平可以保证获取结果的完整性。如下图所示

问题3分析:一般系统直接指定<RFC Serve Group> =' parallel_generators ',如上图的“服务器组”对应的内容,为了保持一般性通过如下逻辑段获取

CALL 'C_SAPGPARAM'  "#EC CI_CCALL                     ID 'NAME'  FIELD 'rdisp/myname'
    ID 'VALUE' FIELD g_applserver.  "
  SELECT SINGLE classname
    FROM rzllitab
    INTO g_classname   "Server Group Name
    WHERE applserver = g_applserver
    AND grouptype = 'S'.   "S:服务器组,空:登陆组

下面通过例子来说明函数异步调用,这里使用函数

'MD_STOCK_REQUIREMENTS_LIST_API'获取MD04中的物料+工厂 MRP数据明细。首先我们使用同步调用的方法,然后再使用异步调用的方法,比较二者在同等条件下的执行效率。

(假设需求:从物料工厂表MARC中获取一定的行项目,这里设定为18000条,然后通过调用函数获取物料工厂对应的MRP清单,将物料工厂与获取的对应清单整合输出)

同步调用:(完整程序在程序最后)

select matnr werks

    UP TO 18000 ROWS               "数据条目18000
    INTO CORRESPONDING FIELDS OF TABLE it_marc
    FROM marc
    WHERE matnr IN s_matnr
    AND   werks IN s_werks.
 
  LOOP AT it_marc INTO wa_marc.
    CLEAR it_md.
    CALL FUNCTION  'MD_STOCK_REQUIREMENTS_LIST_API'
      EXPORTING
        MATNR                    = wa_marc-matnr
        WERKS                    = wa_marc-werks
      TABLES
        MDEZX                    = it_md
      EXCEPTIONS
        MATERIAL_PLANT_NOT_FOUND = 1
        PLANT_NOT_FOUND          = 2
        OTHERS                   = 3.
 
    LOOP AT it_md INTO wa_md.
      MOVE-CORRESPONDING wa_md TO wa_output.
      wa_output-matnr = wa_marc-matnr.
      wa_output-werks = wa_marc-werks.
      APPEND wa_output TO it_output.
      CLEAR:wa_output,wa_md.
    ENDLOOP.
    CLEAR wa_marc.
  ENDLOOP.

很显然在同步执行情况下,只有一个进程是执行我们调用的函数,其他的进程处于idle状态。

异步调用:

解决问题1:为了达到当前用户可以独占程序,进入选择界面即锁定程序:

AT SELECTION-SCREEN.
  "锁定程序
  CALL FUNCTION 'ENQUEUE_EZZSOPR0032'
    EXPORTING
      mode_trdir     = 'E'         "锁类型
      name           = 'ZSOPR0032' "锁对象名称
      x_name         = ' '
      _scope         = '2'
      _wait          = ' '
      _collect       = ' '
    EXCEPTIONS
      foreign_lock   = 1
      system_failure = 2
      OTHERS         = 3.
  IF sy-subrc <> 0.
    MESSAGE '对象已被锁定,请稍后执行' TYPE 'E'.
  ENDIF.

解决问题1:当程序异步调用函数的操作结束后,即可接触对程序的锁定:

END OF SELECTION.
  "解除程序的锁定
  CALL FUNCTION 'DEQUEUE_EZZSOPR0032'
    EXPORTING
      mode_trdir = 'E'
      name       = 'ZSOPR0032'
      x_name     = ' '
      _scope     = '3'
      _synchron  = ' '
      _collect   = ' '.

解决问题3:获取RFC Serve Group name

*  获取 RFC Serve Group name         Start--*
* 一般系统默认g_classname = 'parallel_generators',但为了通用性按照如下方法获取
  CALL 'C_SAPGPARAM'                                      "#EC CI_CCALL
    ID 'NAME'  FIELD 'rdisp/myname'
    ID 'VALUE' FIELD g_applserver.
 
  SELECT SINGLE classname
    FROM rzllitab
    INTO g_classname   "Server Group Name
    WHERE applserver = g_applserver
    AND grouptype = 'S'.   "S:服务器组,空:登陆组
*  获取 RFC Serve Group name         End--*

解决问题2:通过 最大请求队列的值 来控制启动进程数

SELECT matnr werks

    UP TO 18000 ROWS               "数据条目18000
    INTO CORRESPONDING FIELDS OF TABLE it_marc
    FROM marc
    WHERE matnr IN s_matnr
AND   werks IN s_werks.
 

LOOP AT it_marc INTO wa_marc.

*   生成任务名称 = 'Task' + sy-tabix  Start--*

WRITE sy-tabix TO g_taskname.

CONDENSE g_taskname.

CONCATENATE 'Task' g_taskname INTO g_taskname.

*   生成任务名称 = 'Task' + sy-tabix   End--*

lw_marc-taskname = g_taskname.

lw_marc-matnr = wa_marc-matnr.

lw_marc-werks = wa_marc-werks.

APPEND wa_marc TO lt_marc.

*   异步调用函数    Start--*

CALL FUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API' STARTINGNEW TASK g_taskname

DESTINATION INGROUPg_classname

PERFORMING frm_subroutine_done ONEND OF TASK"子程序

*      只要将函数的EXPORTING参数放在此处,其他参数放到子程序中

EXPORTING

matnr                 = wa_marc-matnr

werks                 = wa_marc-werks

*       系统标准报错信息

EXCEPTIONS

communication_failure = 1  MESSAGE mess

system_failure        = 2 MESSAGE mess

resource_failure      = 3.

IF sy-subrc = 0.

snd_jobs = snd_jobs + 1.

ENDIF.

*   异步调用函数     End--*

open_task_num = open_task_num + 1.   "记录启动的进程数量

IF open_task_num = p_wp.    "p_wp = RZ12中的 Max. requests in queue

*    获取并发进程返回的结果

WAIT UNTIL rcv_jobs >= snd_jobs.

CLEAR:open_task_num,rcv_jobs,snd_jobs.

FREE:lt_marc.

ENDIF.

CLEAR wa_marc.

ENDLOOP.

*&---------------------------------------------------------------------*

*&      Form FRM_SUBROUTINE_DONE

*&---------------------------------------------------------------------*

FORM frm_subroutine_done USING g_taskname.

rcv_jobs = rcv_jobs + 1.  "Receiving data

CLEAR:it_md[].

RECEIVE RESULTS FROMFUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API'

TABLES

mdezx                    = it_md

EXCEPTIONS

material_plant_not_found = 1

plant_not_found          = 2

OTHERS                   = 3.

functioncall1 = done.

SORT lt_marc BY taskname.

LOOP AT it_md INTO wa_md.

READ TABLE lt_marc INTO lw_marc WITH KEY taskname = g_taskname BINARYSEARCH.

MOVE-CORRESPONDING wa_md TO wa_output.

wa_output-matnr = lw_marc-matnr.

wa_output-werks = lw_marc-werks.

APPEND wa_output TO it_output.

CLEAR:wa_output,wa_md,lw_marc.

ENDLOOP.

ENDFORM.                    " FRM_SUBROUTINE_DONE

同步调用运行时间

异步调用运行时间

SE30中截取的两张运行时间图,

同步用时429s = 83sABAP程序使用时间 + 346s数据访问消耗时间;

异步用时75s = 74sABAP 程序使用时间 + <1s的数据库访问消耗时间。

本服务器Max.requests in queue = 5.  运行时间429 / 75 = 5.7,即提升了5倍多的执行效率。

同步调用完整程序:

福大

Description: 同步调用函数获取MRP明细列表DEMO


*&---------------------------------------------------------------------*
*& 程序名称:同步调用函数获取MRP明细列表DEMO
*& 程 序 名:ZDEMO_MXQ_TB
*& 开发日期:2013-05-15
*& 创 建 者:汉得
*& 申 请 者:
*&---------------------------------------------------------------------*
*& 摘要说明
*&--------*
*& 从物料工厂表MARC中获取一定的行项目,然后通过调用函数获取物料工厂对应的
*& MRP清单,将物料工厂与获取的对应清单整合输出
*&---------------------------------------------------------------------*
*& 变更记录
*&    日期          修改者           传输请求号           修改内容及原因
*&---------------  ----------  --------------------  ------------------*
*
*&---------------------------------------------------------------------*REPORT  ZDEMO_MXQ_TB.*----------------------------------------------------------------------*
*       Type-pools                                                     *
*----------------------------------------------------------------------*
TYPE-POOLS: slis.*----------------------------------------------------------------------*
*       Table                                                    *
*----------------------------------------------------------------------*
TABLES:marc.*----------------------------------------------------------------------*
*       Internal Tables and Work Areas
*----------------------------------------------------------------------*DATA:BEGIN OF wa_marc,matnr TYPE marc-matnr, "物料号werks TYPE marc-werks, "工厂END OF wa_marc.DATA:it_marc LIKE TABLE OF wa_marc."函数调用参数
DATA:it_md TYPE STANDARD TABLE OF mdez,wa_md LIKE LINE OF it_md.DATA:BEGIN OF wa_output.INCLUDE STRUCTURE mdez.
DATA:matnr TYPE marc-matnr. "物料号
DATA:werks TYPE marc-werks. "工厂
DATA:END OF wa_output.DATA:it_output LIKE TABLE OF wa_output.*----------------------------------------------------------------------*
*       Variables
*----------------------------------------------------------------------**----------------------------------------------------------------------*
*       ALV层级关系定义
*----------------------------------------------------------------------*
DATA: it_fieldcat TYPE slis_t_fieldcat_alv,wa_layout   TYPE slis_layout_alv.
DATA: wa_fieldcat TYPE slis_fieldcat_alv.
DATA gv_grid TYPE REF TO cl_gui_alv_grid.DATA: git_events    TYPE slis_t_event,        "ALV 事件git_listheader  TYPE slis_t_listheader. "ALV 表头DATA wa_header TYPE slis_listheader.*&---------------------------------------------------------------------*
*&      Define marco
*&---------------------------------------------------------------------*
DEFINE  macro_fill_fcat.clear wa_fieldcat.&1 = &1 + 1.wa_fieldcat-col_pos       = &1.wa_fieldcat-fieldname     = &2.wa_fieldcat-seltext_l     = &3.wa_fieldcat-seltext_m     = &3.wa_fieldcat-seltext_s     = &3.append wa_fieldcat to it_fieldcat.END-OF-DEFINITION.*----------------------------------------------------------------------*
*       SELECTION-SCREEN
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001.
*PARAMETERS:p_wp TYPE c .  "进程数
SELECT-OPTIONS:s_matnr FOR marc-matnr,s_werks FOR marc-werks.SELECTION-SCREEN END OF BLOCK blk1.*initialialization
INITIALIZATION.*at selection screen
AT SELECTION-SCREEN.*start of selection
START-OF-SELECTION.CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'EXPORTINGPERCENTAGE = 10TEXT       = '数据获取中...'.PERFORM frm_get_date.*END OF SELECTION
END-OF-SELECTION.PERFORM frm_init_fieldcat.PERFORM frm_init_layout.PERFORM frm_alv_output.*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_GET_DATE .SELECT matnr werksUP TO 18000 ROWS                                           "最多获取20条数据INTO CORRESPONDING FIELDS OF TABLE it_marcFROM marcWHERE matnr IN s_matnrAND   werks IN s_werks.LOOP AT it_marc INTO wa_marc.CLEAR it_md.CALL FUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API'EXPORTINGMATNR                    = wa_marc-matnrWERKS                    = wa_marc-werksTABLESMDEZX                    = it_mdEXCEPTIONSMATERIAL_PLANT_NOT_FOUND = 1PLANT_NOT_FOUND          = 2OTHERS                   = 3.LOOP AT it_md INTO wa_md.MOVE-CORRESPONDING wa_md TO wa_output.wa_output-matnr = wa_marc-matnr.wa_output-werks = wa_marc-werks.APPEND wa_output TO it_output.CLEAR:wa_output,wa_md.ENDLOOP.CLEAR wa_marc.ENDLOOP.ENDFORM.                    " FRM_GET_DATE*&---------------------------------------------------------------------*
*&      Form  FRM_INIT_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_init_fieldcat.DATA: l_colpos TYPE lvc_s_fcat-col_pos VALUE 0.macro_fill_fcat l_colpos 'MATNR'   '物料号'    .macro_fill_fcat l_colpos 'WERKS'   '工厂'      .macro_fill_fcat l_colpos 'DELKZ'   'MRP元素'   .macro_fill_fcat l_colpos 'MNG01'   '数量'      .macro_fill_fcat l_colpos 'DAT00'   '日期'      .ENDFORM.                    " FRM_INIT_FIELDCAT*&---------------------------------------------------------------------*
*&      Form  FRM_INIT_LAYOUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_init_layout .wa_layout-zebra             = 'X'.wa_layout-f2code            = '&ETA'.   "双击显示详细信息wa_layout-detail_popup      = 'X'.wa_layout-colwidth_optimize = 'X'.
*  wa_layout-box_fieldname     = 'BOX'."将BOX字段作为选择标记列ENDFORM.                    " FRM_INIT_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  FRM_ALV_OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_alv_output .CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'EXPORTINGi_callback_program       = sy-repidis_layout                = wa_layoutit_fieldcat              = it_fieldcati_save                   = 'A'
*      it_events                = git_events[]
*     i_callback_pf_status_set = 'PF_STATUS_SET'
*     i_callback_user_command  = 'USER_COMMAND'TABLESt_outtab                 = it_outputEXCEPTIONSprogram_error            = 1OTHERS                   = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
ENDFORM.                    " FRM_ALV_OUTPUT*Selection texts
*----------------------------------------------------------
* S_MATNR D       .
* S_WERKS D       .

Extracted by Direct Download Enterprise version 1.3.1 - E.G

异步调用完整程序:

Code listing for: ZDEMO_MXQ_YB 
Description: 异步调用函数获取MRP明细列表DEMO


*&---------------------------------------------------------------------*
*& 程序名称:异步调用函数获取MRP明细列表DEMO
*& 程 序 名:ZDEMO_MXQ_YB
*& 开发日期:2013-05-15
*& 创 建 者:汉得
*& 申 请 者:
*&---------------------------------------------------------------------*
*& 摘要说明
*&--------*
*& 从物料工厂表MARC中获取一定的行项目,然后通过调用函数获取物料工厂对应的
*& MRP清单,将物料工厂与获取的对应清单整合输出
*&---------------------------------------------------------------------*
*& 变更记录
*&    日期          修改者           传输请求号           修改内容及原因
*&---------------  ----------  --------------------  ------------------*
*
*&---------------------------------------------------------------------*REPORT  zdemo_mxq_yb.*----------------------------------------------------------------------*
*       Type-pools                                                     *
*----------------------------------------------------------------------*
TYPE-POOLS: slis.*----------------------------------------------------------------------*
*       Table                                                    *
*----------------------------------------------------------------------*
TABLES:marc.*----------------------------------------------------------------------*
*       Internal Tables and Work Areas
*----------------------------------------------------------------------*DATA:BEGIN OF wa_marc,matnr TYPE marc-matnr, "物料号werks TYPE marc-werks, "工厂taskname(10) TYPE c,   "任务名END OF wa_marc.DATA:it_marc LIKE TABLE OF wa_marc.DATA:lt_marc LIKE TABLE OF wa_marc,  "存放临时数据lw_marc LIKE wa_marc."函数调用参数
DATA:it_md TYPE STANDARD TABLE OF mdez,wa_md LIKE LINE OF it_md.DATA:BEGIN OF wa_output.INCLUDE STRUCTURE mdez.
DATA:matnr TYPE marc-matnr. "物料号
DATA:werks TYPE marc-werks. "工厂
DATA:END OF wa_output.DATA:it_output LIKE TABLE OF wa_output.*----------------------------------------------------------------------*
*       Variables
*----------------------------------------------------------------------*
DATA:g_taskname(10) TYPE c,                "task name(同时运行的任务名称必须保持唯一)g_classname TYPE rzlli_apcl,          "Server Group Nameg_applserver TYPE rzllitab-applserver,"RFC Serve Groupexcp_flag(1) TYPE c.     "Number of RESOURCE_FAILUREsDATA:snd_jobs TYPE i,rcv_jobs TYPE i,functioncall1(1) TYPE c.CONSTANTS: done(1) TYPE c VALUE 'X'.*----------------------------------------------------------------------*
*       ALV层级关系定义
*----------------------------------------------------------------------*
DATA: it_fieldcat TYPE slis_t_fieldcat_alv,wa_layout   TYPE slis_layout_alv.
DATA: wa_fieldcat TYPE slis_fieldcat_alv.
DATA gv_grid TYPE REF TO cl_gui_alv_grid.DATA: git_events    TYPE slis_t_event,        "ALV 事件git_listheader  TYPE slis_t_listheader. "ALV 表头DATA wa_header TYPE slis_listheader.*&---------------------------------------------------------------------*
*&      Define marco
*&---------------------------------------------------------------------*
DEFINE  macro_fill_fcat.clear wa_fieldcat.&1 = &1 + 1.wa_fieldcat-col_pos       = &1.wa_fieldcat-fieldname     = &2.wa_fieldcat-seltext_l     = &3.wa_fieldcat-seltext_m     = &3.wa_fieldcat-seltext_s     = &3.append wa_fieldcat to it_fieldcat.END-OF-DEFINITION.*----------------------------------------------------------------------*
*       SELECTION-SCREEN
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK blk1 WITH FRAME TITLE text-001.
*PARAMETERS:p_wp TYPE c .  "进程数
SELECT-OPTIONS:s_matnr FOR marc-matnr,s_werks FOR marc-werks.PARAMETERS:p_wp TYPE c .  "并发进程数(根据RZ12中的最大请求队列数设置)SELECTION-SCREEN END OF BLOCK blk1.*initialialization
INITIALIZATION.p_wp = 5.*at selection screen
AT SELECTION-SCREEN."锁定程序CALL FUNCTION 'ENQUEUE_EZZSOPR0032'EXPORTINGmode_trdir     = 'E'name           = 'ZSOPR0032'x_name         = ' '_scope         = '2'_wait          = ' '_collect       = ' 'EXCEPTIONSforeign_lock   = 1system_failure = 2OTHERS         = 3.IF sy-subrc <> 0.
* Implement suitable error handling hereMESSAGE '对象已被锁定,请稍后执行' TYPE 'E'.ELSE."锁定成功ENDIF.*start of selection
START-OF-SELECTION.CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'EXPORTINGpercentage = 10text       = '数据获取中...'.PERFORM frm_get_date.*END OF SELECTION
END-OF-SELECTION."解除程序的锁定CALL FUNCTION 'DEQUEUE_EZZSOPR0032'EXPORTINGmode_trdir = 'E'name       = 'ZSOPR0032'x_name     = ' '_scope     = '3'_synchron  = ' '_collect   = ' '.PERFORM frm_init_fieldcat.PERFORM frm_init_layout.PERFORM frm_alv_output.*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_get_date .DATA:mess(40) TYPE c.        "并发执行出错信息DATA:open_task_num TYPE i.   "启动任务数量SELECT matnr werksUP TO 18000 ROWS                                        ""数据条目18000INTO CORRESPONDING FIELDS OF TABLE it_marcFROM marcWHERE matnr IN s_matnrAND   werks IN s_werks.*  获取 RFC Serve Group name         Start--*
* 一般系统默认g_classname = 'parallel_generators',但为了通用性按照如下方法获取CALL 'C_SAPGPARAM'                                      "#EC CI_CCALLID 'NAME'  FIELD 'rdisp/myname'ID 'VALUE' FIELD g_applserver.SELECT SINGLE classnameFROM rzllitabINTO g_classname   "Server Group NameWHERE applserver = g_applserverAND grouptype = 'S'.   "S:服务器组,空:登陆组
*  获取 RFC Serve Group name         End--*CLEAR open_task_num.LOOP AT it_marc INTO wa_marc.
*   生成任务名称 = 'Task' + sy-tabix   Start--*WRITE sy-tabix TO g_taskname.CONDENSE g_taskname.CONCATENATE 'Task' g_taskname INTO g_taskname.
*   生成任务名称 = 'Task' + sy-tabix   End--*lw_marc-taskname = g_taskname.lw_marc-matnr = wa_marc-matnr.lw_marc-werks = wa_marc-werks.APPEND wa_marc TO lt_marc.*   异步调用函数    Start--*CALL FUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API' STARTING NEW TASK g_tasknameDESTINATION IN GROUP g_classnamePERFORMING frm_subroutine_done ON END OF TASK "子程序
*      只要将函数的EXPORTING参数放在此处,其他参数放到子程序中EXPORTINGmatnr                 = wa_marc-matnrwerks                 = wa_marc-werks*       系统标准报错信息EXCEPTIONScommunication_failure = 1  MESSAGE messsystem_failure        = 2  MESSAGE messresource_failure      = 3.IF sy-subrc = 0.snd_jobs = snd_jobs + 1.ENDIF.
*   异步调用函数     End--*open_task_num = open_task_num + 1.   "记录启动的进程数量IF open_task_num = p_wp.    "p_wp = RZ12中的 Max. requests in queue*     获取并发进程返回的结果WAIT UNTIL rcv_jobs >= snd_jobs.CLEAR:open_task_num,rcv_jobs,snd_jobs.FREE:lt_marc.ENDIF.CLEAR wa_marc.ENDLOOP.ENDFORM.                    " FRM_GET_DATE*&---------------------------------------------------------------------*
*&      Form  FRM_SUBROUTINE_DONE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_subroutine_done USING g_taskname.rcv_jobs = rcv_jobs + 1.  ""Receiving dataCLEAR:it_md[].RECEIVE RESULTS FROM FUNCTION 'MD_STOCK_REQUIREMENTS_LIST_API'TABLESmdezx                    = it_mdEXCEPTIONSmaterial_plant_not_found = 1plant_not_found          = 2OTHERS                   = 3.functioncall1 = done.SORT lt_marc BY taskname.LOOP AT it_md INTO wa_md.READ TABLE lt_marc INTO lw_marc WITH KEY taskname = g_taskname BINARY SEARCH.MOVE-CORRESPONDING wa_md TO wa_output.wa_output-matnr = lw_marc-matnr.wa_output-werks = lw_marc-werks.APPEND wa_output TO it_output.CLEAR:wa_output,wa_md,lw_marc.ENDLOOP.ENDFORM.                    " FRM_SUBROUTINE_DONE*&---------------------------------------------------------------------*
*&      Form  FRM_INIT_FIELDCAT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_init_fieldcat.DATA: l_colpos TYPE lvc_s_fcat-col_pos VALUE 0.macro_fill_fcat l_colpos 'MATNR'   '物料号'    .macro_fill_fcat l_colpos 'WERKS'   '工厂'      .macro_fill_fcat l_colpos 'DELKZ'   'MRP元素'   .macro_fill_fcat l_colpos 'MNG01'   '数量'      .macro_fill_fcat l_colpos 'DAT00'   '日期'      .ENDFORM.                    " FRM_INIT_FIELDCAT*&---------------------------------------------------------------------*
*&      Form  FRM_INIT_LAYOUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_init_layout .wa_layout-zebra             = 'X'.wa_layout-f2code            = '&ETA'.   "双击显示详细信息wa_layout-detail_popup      = 'X'.wa_layout-colwidth_optimize = 'X'.
*  wa_layout-box_fieldname     = 'BOX'."将BOX字段作为选择标记列ENDFORM.                    " FRM_INIT_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  FRM_ALV_OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM frm_alv_output .CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'EXPORTINGi_callback_program       = sy-repidis_layout                = wa_layoutit_fieldcat              = it_fieldcati_save                   = 'A'
*     it_events                = git_events[]
*     i_callback_pf_status_set = 'PF_STATUS_SET'
*     i_callback_user_command  = 'USER_COMMAND'TABLESt_outtab                 = it_outputEXCEPTIONSprogram_error            = 1OTHERS                   = 2.IF sy-subrc <> 0.MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgnoWITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.ENDIF.
ENDFORM.                    " FRM_ALV_OUTPUT*Selection texts
*----------------------------------------------------------
* P_WP         并发进程数
* S_MATNR D       .
* S_WERKS D       .*Messages
*----------------------------------------------------------
*
* Message class: Hard coded
*   对象已被锁定,请稍后执行

SAP ABAP程序优化-多线程并行处理相关推荐

  1. 赛锐信息:ABAP程序优化的一些总结

    第一部分 程序运行时间的优化 优化的重点之一是运行时间,影响运行时间的因素有很多,首先程序本身的话,从CPU角度讲,指令越少自然运行时间越快,会引发CPU大量操作的基本上主要就是对数据量非常大的内表进 ...

  2. SAP ABAP程序效率优化 Perfomance Tune

    1.使用正确的表.SAP有标准的索引表或者VIEW.参见sap notes 185530/191492/187906   LIPS 使用VGBEL不如先用VBFA表 2.使用正确的索引.好的索引非常好 ...

  3. SAP ABAP性能优化 - 调优工具 SM50 | ST05 | SAT

    更多内容关注公众号:SAP Technical 各位可以关注我的公众号:SAP Technical SAP系统提供了许多性能调优的工具,在本篇博客中,我将介绍下最常用的三种工具也即SM50, ST05 ...

  4. 【04】SAP ABAP性能优化 - 如何选用内表类型(STANDARD, SORTED, HASHED)?

    ABAP提供了三种类型的内表, 即:标准表(Standard Table), 排序表(Sorted Table), 哈希表(Hashed Table).在未声明内表类型时,系统会将类型默认为标准表. ...

  5. 你的ABAP程序给佛祖开过光么?来试试Jerry这个小技巧

    最近Jerry在忙一个项目,技术栈换成了nodejs平台,语言换成了JavaScript,因为赶项目进度,一直没时间更新公众号.感谢大家的支持,关注人数还是慢慢地增长到了3000. 今天我们来聊聊一个 ...

  6. 什么是 SAP ABAP? 类型、ABAP 完整形式和含义

    转载地址:https://www.guru99.com/what-is-abap.html ABAP 是一种由 SAP 创建的高级编程语言,可帮助大型企业定制 SAP ERP. ABAP 可以帮助定制 ...

  7. SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错

    SAP S4HANA 账户组的配置里'Int.Std.Grping'选项没勾选导致ABAP程序报错 BP,试图创建一个新的vendor code, 角色是ZGM001, Grouping是G001, ...

  8. SAP ABAP 因系统维护使ABAP语法不再被支持导致使用很久的程序报错问题之分析

    SAP ABAP 因系统维护使ABAP语法不再被支持导致使用很久的程序报错问题之分析 所在项目客户的一家工厂上线已经超过半年,其业务部门提出一个使用了半年的RF枪程序,突然不能使用了.程序直接Dump ...

  9. 在SAP云平台ABAP编程环境上编写第一段ABAP程序

    距2017年秋季的SAP TechEd大会上一位大佬Björn Goerke,SAP's Chief Technology Officer宣布了SAP Cloud Platform即将支持ABAP至今 ...

最新文章

  1. 滚动条禁止_Axure 教程:不可见滚动条的页面滚动效果
  2. 深度探秘 从 Auto Labeler 挖掘 Tesla 全自动驾驶的工作机制
  3. android如何让service不被杀死-提高进程优先级
  4. .net函数查询_特来电智能分析平台动态查询架构创新实践
  5. Spring Stateless State Security第3部分:JWT +社会认证
  6. java自定义注解学习笔记
  7. Windows Terminal 已上架,快尝鲜
  8. 超分辨率分析(一)--传统方案综述
  9. 3.中小型企业通用自动化运维架构 -- Ansible playbook
  10. 必看 | 机器视觉基础入门
  11. 基于FPGA三大串行通信接口简单概述
  12. html全部颜色代码大全,html代码大全(基础使用代码)(颜色代码完整版)
  13. 计算广告之淘宝oCPC智能出价
  14. pod 排错----Pod 一直处于 Pending 状态
  15. 【图像增强】基于Frangi滤波器实现血管图像增强附matlab代码
  16. Python 程序员需要知道的 30 个技巧
  17. 9.20模拟赛T1[聪明的小偷]
  18. Storm-Kafka: Offset lags for kafka not supported for older versions
  19. 统一社会信用代码正则表达式
  20. 利用反射动态修改 EasyPoi 导出Excel表格标题名称

热门文章

  1. vuls漏洞扫描工具
  2. 关于props的注意事项!
  3. java线程问题小结-----常见面试问题
  4. firefox ie table 布局 兼容性问题
  5. WinForm中给DataGridView添加 自动编号
  6. wkWebView 的一些问题
  7. SQL server 2016 安装步骤
  8. Java并发 正确终止与恢复线程
  9. c#中结构体和类的比较
  10. 富文本编辑器---笑脸表情(一)