matinal:SAP ABAP 函数异步调用总结(三)

2023-11-18 10:54:09 浏览数 (2)

      在SAP的应用开发中,对于报表的效率是非常重视的。当然优化报表效率的方法有很多,当时当我们遇到需要处理大量数据的报表时会发现用尽所有优化的语句,报表的运行效率还是无法达到用户部门的需求。

     下面,我介绍一种方法,也许会对你有所帮助。ABAP的并行处理(原理类似于java的多线程),它是通过RFC接口进行远程函数的异步调用实现程序的并处理。

     同步/异步调用函数语法:

     同步(sRFC): CALL FUNCTION 'AAA' ;

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

     异步(aRFC):CALL FUNCTION 'AAA' STARTING NEWTASK <taskname> "任务名称

                                             DESTINATION IN GROUP <RFC Serve Group>

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

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

     在使用并行处理的过程中通常会遇到如下的可能会发生的问题:

1、重复运行产生的后台任务相互冲突

2、异步调用获取的最终结果与同步调用结果存在差异

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

     对上述三个问题的解决方法,如下:

1、为了避免后台任务相互冲突,导致输出的数据差异,应确保在相同时间段内同一程序只能被一个用户

     占用。所以在开发的程序中添加所对象可以解决。(程序锁的设置,如附件)

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、如何知道系统设置的并行运行进程数呢,通过RZ12,并双击当前登入组,即可以查看到最大并行进程数,

    如下图:

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

    变量定义-DATA: g_classname   Type rzlli_apcl,   "Server Group Name

                           g_applserver   Type rzllitab-applserver."RFC Serve Group

    取数逻辑-   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:服务器组,空:登陆组

    通过上述的描述,可以通过一个实例来串联一下,实例如附件。

    1、获取服务组

2、异步调用函数

3、处理子例程

4、如果调用的子例程非系统标准,需要在SE37中定义自己需要的处理逻辑子例程

代码语言:javascript复制
*&---------------------------------------------------------------------*
*& Report  ZMATINAL
*&----------------------------------------------------------------------*
*&----------------------------------------------------------------------*
*  Changer           Changed Date         Request  NO.        Dec.
*&----------------------------------------------------------------------*

report  zmatinal message-id zmess.

tables: mara,marc.

types: begin of gs_out,
        werks type marc-werks,"工厂
        dispo type marc-dispo,"MRP控制员
        matnr type marc-matnr,"物料
        maktx type makt-maktx,"物料描述
        meins type mara-meins,"单位
        matkl type mara-matkl,"物料组
        labst type mard-labst,"NO-X非限制库存
        zsupl type mard-labst,"NO-X过期供给
        zreqd type mard-labst,"NO-X过期需求
        ztype type c,         "期间类型
        ztext type c length 20,"期间类型文本
        dat01 type mard-labst, "期间-one
        dat02 type mard-labst, "期间-two
        dat03 type mard-labst, "期间-three
        dat04 type mard-labst, "期间-four
        dat05 type mard-labst, "期间-five
        dat06 type mard-labst, "期间-six
        dat07 type mard-labst, "期间-seven
        dat08 type mard-labst, "期间-eight
        dat09 type mard-labst, "期间-nine
        dat10 type mard-labst, "期间-ten
        dat11 type mard-labst, "期间-evelen
        dat12 type mard-labst, "期间-twelve
       end of gs_out,

       begin of gs_dtl,
        werks type marc-werks,"工厂
        matnr type marc-matnr,"物料
        zdate type sy-datum,  "需求日期
        delb0 type t457t-delb0,"MRP元素
        extra type mdez-extra,"MRP元素数据
        mng01 type mdez-mng01,"收货数量或需求数量
       end of gs_dtl,

       begin of gs_marc,
        matnr type marc-matnr,"物料ID
        werks type marc-werks,"工厂
        dispo type marc-dispo,"MRP控制员
        matkl type mara-matkl,"物料组
        meins type mara-meins,"基本单位
       end of gs_marc,

       begin of gs_mard,
        matnr type mard-matnr,"物料
        werks type mard-werks,"工厂
        lgort type mard-lgort,"库存地点
        labst type mard-labst,"库存数
       end of gs_mard,

       begin of gs_makt,
        matnr type makt-matnr,"物料
        maktx type makt-maktx,"物料描述
       end of gs_makt,

       begin of gs_task,
        matnr type marc-matnr,"物料
        werks type marc-werks,"工厂
        dispo type marc-dispo,"MRP控制员
        matkl type mara-matkl,"物料组
        meins type mara-meins,"单位
        maktx type makt-maktx,"物料描述
        labst type mard-labst,"库存
        taskname type c length 12,
       end of gs_task.

data: gw_task type gs_task,
      gt_task type standard table of gs_task.

data: gw_out    type gs_out,
      gw_dtl    type gs_dtl,
      gw_mard   type gs_mard.

data: gt_out    type standard table of gs_out,
      gt_dtl    type standard table of gs_dtl,"明细alv
      gt_marc   type standard table of gs_marc,
      gt_marc_d type standard table of gs_marc,
      gt_makt   type standard table of gs_makt,
      gt_mard   type standard table of gs_mard,
      gt_mard_s type standard table of gs_mard.
data: gt_noxlog type standard table of znoxlog with header line.

field-symbols:<fs_out>  type gs_out,
              <fs_mard> type gs_mard,
              <fs_marc> type gs_marc,
              <fs_makt> type gs_makt,
              <fs_mrp>  type bapi_mrp_items,
              <fs>,
              <fs1>,
              <fs2>,
              <fs3>.

data: gt_mrp_items type standard table of bapi_mrp_items."MRP_ITEMs数据


data: g_txt type c length 20,
      g_num type n length 2.
data: g_mondy type d,
      g_sundy type d.
data: g_post  type i.
data: g_mark  type c.

*****-------GRID_ALV定义
class lcl_alv definition deferred.
data: g_alv type ref to lcl_alv.
data: gt_fcat  type lvc_t_fcat,
      gw_fcat  type lvc_s_fcat,
      is_layo  type lvc_s_layo,
      is_vart  type disvariant.
data: g_grid1 type ref to cl_gui_alv_grid,
      g_custom_container1 type ref to cl_gui_custom_container,
      g_container1 type scrfname value 'GRID_01'.
data: ok_code type sy-ucomm,
      save_ok type sy-ucomm.

*-----------------------------------------------------------------------*
*DESC:异步取数变量定义
*-----------------------------------------------------------------------*
data: g_taskname(12) type c, "task name(同时运行的任务名称必须保持唯一)
      g_classname    type rzlli_apcl,   "Server Group Name
      g_applserver   type rzllitab-applserver."RFC Serve Group

data: snd_jobs type i,
      rcv_jobs type i,
      functioncall1(1) type c.

constants: done(1) type c value 'X',
           pnum    type i value 5."进程数

*----------------------------------------------------------------------*
*       CLASS LCL_ALV DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_alv definition.
  public section.
    methods:
             create_object,
             fcat_setting,
             layo_setting,
             disp,
             main.

  private section.

endclass.                    "LCL_ALV DEFINITION

*----------------------------------------------------------------------*
*       CLASS LCL_ALV IMPLEMENTATION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
class lcl_alv implementation.
  method create_object.
    if g_custom_container1 is initial.
      "创建容器
      create object g_custom_container1
        exporting
          container_name              = g_container1
        exceptions
          cntl_error                  = 1
          cntl_system_error           = 2
          create_error                = 3
          lifetime_error              = 4
          lifetime_dynpro_dynpro_link = 5
          others                      = 6.
      if sy-subrc ne 0.
        message 'error1' type 'E'.
      endif.

      "创建ALV
      create object g_grid1
        exporting
          i_parent          = g_custom_container1
        exceptions
          error_cntl_create = 1
          error_cntl_init   = 2
          error_cntl_link   = 3
          error_dp_create   = 4
          others            = 5.
      if sy-subrc ne 0.
        message 'error2' type 'E'.
      endif.

    else.
      g_grid1->refresh_table_display( ).
    endif.

  endmethod.                    "CREATE_OBJECT

  method fcat_setting.
    perform frm_set_fcat.

  endmethod.                    "FCAT_SETTING

  method layo_setting.
    is_layo-zebra = 'X'."隔行颜色
    is_layo-sel_mode = 'A'."可选
    is_layo-cwidth_opt = 'X'."输出列显示最优化

    is_vart-report = sy-repid.
  endmethod.                    "LAYO_SETTING

  method disp.
    "输出ALV
    call method g_grid1->set_table_for_first_display
      exporting
        i_structure_name              = 'GS_DTL'
        is_variant                    = is_vart
        i_save                        = 'A'
        i_default                     = 'X'
        is_layout                     = is_layo
      changing
        it_outtab                     = gt_dtl[]
        it_fieldcatalog               = gt_fcat[]
                                                                                                                                                                                                                   "it_sort                       = gt_sort[]
      exceptions
        invalid_parameter_combination = 1
        program_error                 = 2
        too_many_lines                = 3
        others                        = 4.
    if sy-subrc ne 0.
      message 'error3' type 'E'.
    endif.

    call method cl_gui_control=>set_focus
      exporting
        control = g_grid1.
  endmethod.                    "DISP

  method main.
    me->create_object( ).
    me->fcat_setting( ).
    me->layo_setting( ).
    me->disp( ).
  endmethod.                    "MAIN

endclass.                    "LCL_ALV IMPLEMENTATION

*---------------------------------------------------------------------*
* DESC:ALV 变量定义
*---------------------------------------------------------------------*
type-pools: slis.
data: gt_fieldcat    type slis_t_fieldcat_alv with header line,  "定义存放输出字段的内表
      gt_sort        type slis_t_sortinfo_alv,
      gw_layout      type slis_layout_alv, "定义ALV布局设置的工作区
      g_repid        like sy-repid.        "定义系统当前程序名变量
data: gw_stru_disvar type disvariant,        "ALV 显示格式
      gt_events      type slis_t_event.      "ALV 事件

*-----------------------------------------------------------------------*
*DESC:选择屏幕定义
*-----------------------------------------------------------------------*
selection-screen begin of block blk with frame title text-001.
select-options:s_werks for marc-werks obligatory,"工厂
               s_matnr for marc-matnr,"物料
               s_dispo for marc-dispo obligatory,"MRP控制员
               s_matkl for mara-matkl."物料组
select-options:s_lgort for marc-lgpro no-display."NO-X库存
parameters: p_date type mara-ersda default sy-datum obligatory."开始日期
selection-screen end of block blk.

*-----------------------------------------------------------------------*
*INITIALIZATION
*-----------------------------------------------------------------------*
initialization.
  perform frm_init.

*-----------------------------------------------------------------------*
*START-OF-SELECTION
*-----------------------------------------------------------------------*
start-of-selection.
  perform frm_status(zpercent) using 10 '正在读取其他关联数据...'.
  perform frm_get_date."获取计算期间的起始值
  perform frm_get_data."获取基本数据
  if g_mark eq 'X'.
    stop.
  else.
    perform frm_set_lock."设置锁
    perform frm_fill_alv.
    perform frm_set_unlock."解锁
    perform frm_get_event.
    perform frm_init_layout.
    perform frm_sort_build changing gt_sort.
    perform frm_fcat_setting.
    perform frm_output tables gt_out.
  endif.


*&---------------------------------------------------------------------*
*&      Form  frm_init
*&---------------------------------------------------------------------*
*       初始化
*----------------------------------------------------------------------*
form frm_init.
  clear: gt_noxlog,g_mondy,g_sundy.

  "初始化NO-X库存位置
  select *
    into table gt_noxlog
    from znoxlog.

  loop at gt_noxlog.
    s_lgort-low = gt_noxlog-lgort.
    s_lgort-option = 'EQ'.
    s_lgort-sign = 'I'.
    append s_lgort.
  endloop.

endform.                    "frm_init

*&---------------------------------------------------------------------*
*&      Form  frm_get_date
*&---------------------------------------------------------------------*
*       获取日期
*----------------------------------------------------------------------*
form frm_get_date.
  "获取开始日期所在周及时间
  call function 'GET_WEEK_INFO_BASED_ON_DATE'
    exporting
      date   = p_date
    importing
      monday = g_mondy
      sunday = g_sundy.

  g_mondy = p_date.
endform.                    "frm_init

*&---------------------------------------------------------------------*
*&      Form  FRM_get_data
*&---------------------------------------------------------------------*
*       获取基本数据
*----------------------------------------------------------------------*
form frm_get_data.
  "根据输入条件到表MARC及MARA中获取基本数据
  select a~matnr "物料
         a~werks "工厂
         a~dispo "MRP控制员
         b~matkl "物料组
         b~meins "单位
    into table gt_marc
    from marc as a join mara as b on a~matnr = b~matnr
    where a~matnr in s_matnr
      and a~werks in s_werks
      and a~dispo in s_dispo
      and a~lvorm ne 'X'
      and a~mmsta ne '99'
      and b~matkl in s_matkl.

  if gt_marc is not initial.

    "获取物料描述
    gt_marc_d = gt_marc.
    sort: gt_marc_d by matnr.
    delete adjacent duplicates from gt_marc_d comparing matnr.

    select matnr "物料
           maktx "物料描述
      into table gt_makt
      from makt
      for all entries in gt_marc_d
      where matnr = gt_marc_d-matnr
        and spras = '1'.

    "根据内表gt_marc到表MARD中获取库存数
    select matnr "物料
           werks "工厂
           lgort "库存地
           labst "库存
      into table gt_mard
      from mard
      for all entries in gt_marc
      where matnr = gt_marc-matnr
        and werks = gt_marc-werks
        and lgort in s_lgort
        and diskz ne '1'.

    "汇总
    loop at gt_mard assigning <fs_mard>.
      clear:gw_mard.
      move <fs_mard>-matnr to gw_mard-matnr."物料
      move <fs_mard>-werks to gw_mard-werks."工厂
      move <fs_mard>-labst to gw_mard-labst."库存
      collect gw_mard into gt_mard_s.
    endloop.
  else.
    g_mark = 'X'.
    message s006(zppmess) display like 'E'.
  endif.

endform.                    "FRM_get_data

*&---------------------------------------------------------------------*
*&      Form  frm_fill_alv
*&---------------------------------------------------------------------*
*       填充ALV输出
*----------------------------------------------------------------------*
form frm_fill_alv.
  data: l_lgort   type mard-lgort,"库存点变量
        l_count   type i,"列
        l_mondy   type d,"周一
        l_sundy   type d,"周末
        l_num(2)  type n,
        l_txt(20) type c.
  data: l_labst   type mard-labst,"库存
        l_zsupl   type mard-labst,"供给
        l_zreqd   type mard-labst."需求
  data: lt_mrp_01 type standard table of bapi_mrp_items,"计算-NO-X过期供给
        lt_mrp_02 type standard table of bapi_mrp_items,"计算-NO-X过期需求
        lt_mrp_03 type standard table of bapi_mrp_items,"计算-列所对应的NO-X供给
        lt_mrp_04 type standard table of bapi_mrp_items."计算-列所对应的NO-X需求

  sort: gt_makt   by matnr,
        gt_mard_s by matnr werks,
        gt_marc   by matnr werks.

  "临时变量
  data:mess(40) type c,        "并发执行出错信息
       open_task_num type i.   "启动任务数量
  data:l_tabix  type sy-tabix, "索引变量
       l_lines  type i,        "总行数
       l_counts type p.


  "获取 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--*

  clear: open_task_num,l_lines.

  describe table gt_marc lines l_lines.
  l_counts = l_lines.

  loop at gt_marc assigning <fs_marc>.
    clear: gw_out,lt_mrp_01,lt_mrp_02,lt_mrp_03,lt_mrp_04,
           l_labst,l_zsupl,l_zreqd.
    l_tabix = sy-tabix.

    perform frm_percent(zpercent) using sy-tabix l_counts ''.
    move <fs_marc>-matnr to gw_out-matnr."物料
    move <fs_marc>-werks to gw_out-werks."工厂
    move <fs_marc>-dispo to gw_out-dispo."MRP控制员
    move <fs_marc>-matkl to gw_out-matkl."物料组

    "单位转换
    call function 'CONVERSION_EXIT_CUNIT_OUTPUT'
      exporting
        input  = <fs_marc>-meins
      importing
        output = gw_out-meins.

    "获取物料描述
    read table gt_makt assigning <fs_makt> with key matnr = <fs_marc>-matnr binary search.
    if sy-subrc eq 0.
      move <fs_makt>-maktx to gw_out-maktx.
    endif.

    "获取NO-X非限制库存
    read table gt_mard_s assigning <fs_mard> with key matnr = <fs_marc>-matnr binary search.
    if sy-subrc eq 0.
      move <fs_mard>-labst to gw_out-labst.
    endif.

*--优化,异步调用获取数据、
    "生成任务名称 = 'Task'   sy-tabix   Start--*
    move l_tabix to g_taskname.
    condense g_taskname.
    concatenate 'Task' g_taskname into g_taskname.
    "生成任务名称 = 'Task'   sy-tabix   End--*

    clear: gw_task.
    gw_task-matnr = <fs_marc>-matnr.
    gw_task-werks = <fs_marc>-werks.
    gw_task-dispo = <fs_marc>-dispo.
    gw_task-matkl = <fs_marc>-matkl.
    gw_task-meins = gw_out-meins.
    gw_task-maktx = gw_out-maktx.
    gw_task-labst = gw_out-labst.
    gw_task-taskname  = g_taskname.
    append gw_task to gt_task.

*   异步调用函数    Start--*
    call function 'BAPI_MATERIAL_STOCK_REQ_LIST' starting new task g_taskname
        destination in group g_classname
        performing frm_subroutine_done on end of task "子程序
*      只要将函数的EXPORTING参数放在此处,其他参数放到子程序中
        exporting
          material         = <fs_marc>-matnr
          plant            = <fs_marc>-werks
          get_item_details = 'X'
          get_ind_lines    = 'X'
*       系统标准报错信息
        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 = pnum.
*     获取并发进程返回的结果
      wait until rcv_jobs >= snd_jobs.

      clear:open_task_num,rcv_jobs,snd_jobs.
      free:gt_task.
    else.
      if l_tabix = l_lines.
*     获取并发进程返回的结果
        wait until rcv_jobs >= snd_jobs.

        clear:open_task_num,rcv_jobs,snd_jobs.
        free:gt_task.
      endif.
    endif.

  endloop.

endform.                    "frm_fill_alv

*&---------------------------------------------------------------------*
*&      Form  frm_subroutine_done
*&---------------------------------------------------------------------*
*      异步处理子例程
*----------------------------------------------------------------------*
*      -->G_TASKNAME text
*----------------------------------------------------------------------*
form frm_subroutine_done using g_taskname.
  data: l_lgort   type mard-lgort,"库存点变量
        l_auffx   type plaf-auffx,"固定标识
        l_count   type i,"列
        l_mondy   type d,"周一
        l_sundy   type d,"周末
        l_num(2)  type n,
        l_txt(20) type c.
  data: l_labst   type mard-labst,"库存
        l_zsupl   type mard-labst,"供给
        l_zreqd   type mard-labst."需求
  data: l_mark1   type c,
        l_mark2   type c,
        l_mark3   type c,
        l_mark4   type c,
        l_lines   type i.
  data: lt_mrp_01 type standard table of bapi_mrp_items,"计算-NO-X过期供给
        lt_mrp_02 type standard table of bapi_mrp_items,"计算-NO-X过期需求
        lt_mrp_03 type standard table of bapi_mrp_items,"计算-列所对应的NO-X供给
        lt_mrp_04 type standard table of bapi_mrp_items."计算-列所对应的NO-X需求

  rcv_jobs = rcv_jobs   1.  ""Receiving data

  receive results from function 'BAPI_MATERIAL_STOCK_REQ_LIST'
    tables
      mrp_items        = gt_mrp_items.

  read table gt_task into gw_task with key taskname = g_taskname binary search.
  if sy-subrc eq 0.
    clear:l_mark1,l_mark2,l_mark3,l_mark4.

    gw_out-matnr = gw_task-matnr."物料
    gw_out-werks = gw_task-werks."工厂
    gw_out-dispo = gw_task-dispo.
    gw_out-meins = gw_task-meins.
    gw_out-maktx = gw_task-maktx.
    gw_out-labst = gw_task-labst.

    delete gt_mrp_items where ( mrp_element_ind = 'WB' and rec_reqd_qty is initial ).

    if gt_mrp_items is initial and gw_out-labst is initial. "如果MD04为空
      "CONTINUE.
    else.

      lt_mrp_01 = lt_mrp_02 = gt_mrp_items.

      "计算-NO-X过期供给
      delete lt_mrp_01 where ( avail_date is initial ) or ( avail_date ge p_date ).
      delete lt_mrp_01 where plngsegno is not initial or plus_minus ne ' ' or rec_reqd_qty is initial.

      loop at lt_mrp_01 assigning <fs_mrp>.
        if <fs_mrp>-storage_loc in s_lgort.
          if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
            continue.
          else.
            gw_out-zsupl = gw_out-zsupl   <fs_mrp>-rec_reqd_qty.
          endif.
        endif.
      endloop.

      "计算-NO-X过期需求
      delete lt_mrp_02 where ( avail_date is initial ) or ( avail_date ge p_date ).
      delete lt_mrp_02 where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.

      loop at lt_mrp_02 assigning <fs_mrp>.
        clear:l_lgort,l_auffx.

        case <fs_mrp>-order_type.
          when 'BB'."外协采购
            "到表EKPO中获取满足NO-X库存的
            select single lgort
              into l_lgort
              from ekpo
              where ebeln = <fs_mrp>-source_no
                and ebelp = <fs_mrp>-source_item
                and lgort in s_lgort.

            if sy-subrc eq 0.
              gw_out-zreqd = gw_out-zreqd   <fs_mrp>-rec_reqd_qty.
            endif.

          when 'SB'."计划订单-下阶
            "到表PLAF中获取满足NO-X库存的
            select single lgort auffx
              into (l_lgort,l_auffx)
              from plaf
              where plnum = <fs_mrp>-source_no
                and lgort in s_lgort.

            if sy-subrc eq 0.
              if l_auffx eq 'X'."固定
                gw_out-zreqd = gw_out-zreqd   <fs_mrp>-rec_reqd_qty.
              endif.
            endif.

          when 'AR'."生产订单预留
            "到表AFPO中获取满足NO-X库存的
            select single lgort
              into l_lgort
              from afpo
              where aufnr = <fs_mrp>-mrp_no12
                and lgort in s_lgort.

            if sy-subrc eq 0.
              gw_out-zreqd = gw_out-zreqd   <fs_mrp>-rec_reqd_qty.
            endif.

          when others.
        endcase.
      endloop.

      "标识one
      if gw_out-labst is initial and gw_out-zsupl is initial and gw_out-zreqd is initial.
        l_mark1 = 'X'.
      endif.

      "计算-列
      clear:l_count.
      do 3 times.
        l_count = l_count   1.
        case l_count.
          when 1."计算-列所对应的NO-X供给
            clear:g_num.
            l_mondy = g_mondy.
            l_sundy = g_sundy.
            gw_out-ztype = 'A'.
            gw_out-ztext = 'NO-X供给'.
            do 12 times.
              clear:g_txt.
              g_num = g_num   1.
              g_txt = |GW_OUT-DAT{ g_num }|.
              assign (g_txt) to <fs>.

              lt_mrp_03 = gt_mrp_items.
              delete lt_mrp_03 where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
              delete lt_mrp_03 where plngsegno is not initial or plus_minus ne ' ' or rec_reqd_qty is initial.

              loop at lt_mrp_03 assigning <fs_mrp>.
                if <fs_mrp>-storage_loc in s_lgort.
                  if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
                    continue.
                  else.
                    <fs> = <fs>   <fs_mrp>-rec_reqd_qty.
                  endif.
                endif.
              endloop.
              l_mondy = l_sundy   1.
              l_sundy = l_sundy   7.

              "标识two,只要其中一列不为空
              if <fs> is not initial.
                l_mark2 = 'X'.
              endif.
            enddo.
            append gw_out to gt_out.
            clear:gw_out-labst,gw_out-zsupl,gw_out-zreqd.

          when 2."计算-列所对应的NO-X需求
            clear:g_num,gw_out-dat01,gw_out-dat02,gw_out-dat03,gw_out-dat04,gw_out-dat05,gw_out-dat06,
                        gw_out-dat07,gw_out-dat08,gw_out-dat09,gw_out-dat10,gw_out-dat11,gw_out-dat12.
            l_mondy = g_mondy.
            l_sundy = g_sundy.
            gw_out-ztype = 'B'.
            gw_out-ztext = 'NO-X需求'.
            do 12 times.
              clear:g_txt.
              g_num = g_num   1.
              g_txt = |GW_OUT-DAT{ g_num }|.
              assign (g_txt) to <fs>.

              lt_mrp_04 = gt_mrp_items.
              delete lt_mrp_04 where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
              delete lt_mrp_04 where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.

              loop at lt_mrp_04 assigning <fs_mrp>.
                clear:l_lgort,l_auffx.

                case <fs_mrp>-order_type.
                  when 'BB'."外协采购
                    "到表EKPO中获取满足NO-X库存的
                    select single lgort
                      into l_lgort
                      from ekpo
                      where ebeln = <fs_mrp>-source_no
                        and ebelp = <fs_mrp>-source_item
                        and lgort in s_lgort.

                    if sy-subrc eq 0.
                      <fs> = <fs>   <fs_mrp>-rec_reqd_qty.
                    endif.

                  when 'SB'."计划订单-下阶
                    "到表PLAF中获取满足NO-X库存的
                    select single lgort auffx
                      into (l_lgort,l_auffx)
                      from plaf
                      where plnum = <fs_mrp>-source_no
                        and lgort in s_lgort.

                    if sy-subrc eq 0.
                      if l_auffx = 'X'.
                        <fs> = <fs>   <fs_mrp>-rec_reqd_qty.
                      endif.
                    endif.

                  when 'AR'."生产订单预留
                    "到表AFPO中获取满足NO-X库存的
                    select single lgort
                      into l_lgort
                      from afpo
                      where aufnr = <fs_mrp>-mrp_no12
                        and lgort in s_lgort.

                    if sy-subrc eq 0.
                      <fs> = <fs>   <fs_mrp>-rec_reqd_qty.
                    endif.

                  when others.
                endcase.
              endloop.
              l_mondy = l_sundy   1.
              l_sundy = l_sundy   7.

              "标识three,只要其中一列不为空
              if <fs> is not initial.
                l_mark3 = 'X'.
              endif.
            enddo.
            append gw_out to gt_out.

          when 3."计算-NO-X建议供给数量
            clear:g_num,gw_out-dat01,gw_out-dat02,gw_out-dat03,gw_out-dat04,gw_out-dat05,gw_out-dat06,
                        gw_out-dat07,gw_out-dat08,gw_out-dat09,gw_out-dat10,gw_out-dat11,gw_out-dat12.
            gw_out-ztype = 'C'.
            gw_out-ztext = 'NO-X建议供给数量'.

            do 12 times.
              clear:g_txt,l_num,l_txt.
              g_num = g_num   1.
              g_txt = |GW_OUT-DAT{ g_num }|.
              assign (g_txt) to <fs>.

              if g_num = 01."第一列
                l_num = g_num.
                "NO-X供给
                read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
                                                              werks = gw_out-werks
                                                              ztype = 'A'.
                if sy-subrc eq 0.
                  l_txt = |<FS_OUT>-DAT{ l_num }|.
                  assign (l_txt) to <fs1>.
                  l_labst = <fs_out>-labst."库存
                  l_zsupl = <fs_out>-zsupl."供给
                  l_zreqd = <fs_out>-zreqd."需求
                endif.
                "NO-X需求
                read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
                                                              werks = gw_out-werks
                                                              ztype = 'B'.
                if sy-subrc eq 0.
                  l_txt = |<FS_OUT>-DAT{ l_num }|.
                  assign (l_txt) to <fs2>.
                endif.

                "第一列建议供给数量 = 非限制库存   过期供给 - 过期需求   第一列供给 - 第一列的需求
                <fs> = l_labst   l_zsupl - l_zreqd   <fs1> - <fs2>.
              else.
                l_num = g_num - 1.
                "NO-X供给
                read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
                                                              werks = gw_out-werks
                                                              ztype = 'A'.
                if sy-subrc eq 0.
                  l_txt = |<FS_OUT>-DAT{ g_num }|.
                  assign (l_txt) to <fs1>.
                endif.
                "NO-X需求
                read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
                                                              werks = gw_out-werks
                                                              ztype = 'B'.
                if sy-subrc eq 0.
                  l_txt = |<FS_OUT>-DAT{ g_num }|.
                  assign (l_txt) to <fs2>.
                endif.

                "前一列的NO-X建议供给数量
                l_txt = |GW_OUT-DAT{ l_num }|.
                assign (l_txt) to <fs3>.

                "当前NO-X建议供给数量 = 前一列建议供给数   当前列供给 - 当前列需求
                if <fs3> ge 0.
                  <fs> = abs( <fs3> )   <fs1> - <fs2>.
                else.
                  <fs> = <fs1> - <fs2>.
                endif.

                "判断建议数是否大于0,若大于0,清空;否则,取绝对值
                if g_num = 12."最后一次循环,要判断最后两列
                  if <fs> gt 0.
                    clear <fs>.
                  else.
                    <fs> = abs( <fs> ).
                  endif.

                  if <fs3> gt 0.
                    clear <fs3>.
                  else.
                    <fs3> = abs( <fs3> ).
                  endif.
                else."否则只要判断前一列
                  if <fs3> ge 0.
                    clear <fs3>.
                  else.
                    <fs3> = abs( <fs3> ).
                  endif.
                endif.

              endif.

              "标识four,只要其中一列不为空
              if <fs> is not initial.
                l_mark4 = 'X'.
              endif.
            enddo.
            append gw_out to gt_out.
        endcase.
      enddo.

      "删除为空记录
      if l_mark1 = 'X' and l_mark2 is initial and l_mark3 is initial and l_mark4 is initial.
        describe table gt_out lines l_lines.
        delete gt_out index l_lines.
        delete gt_out index l_lines - 1.
        delete gt_out index l_lines - 2.
      endif.
    endif.
  endif.

endform.                    "frm_subroutine_done



*&---------------------------------------------------------------------*
*&      Form  frm_get_detail
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->ALV        text
*      -->MATNR      text
*      -->WERKS      text
*      -->FNAME      text
*----------------------------------------------------------------------*
form frm_get_detail tables alv  structure gw_dtl
                    using matnr type marc-matnr
                          werks type marc-werks
                          fname type slis_fieldname
                          type  type c.

  data: lt_mrp type standard table of bapi_mrp_items."计算-NO-X过期供给
  data: l_lgort type mard-lgort,
        l_auffx type plaf-auffx,
        l_mondy type d,
        l_sundy type d,
        l_times type i.

                                                            "获取MD04
  call function 'BAPI_MATERIAL_STOCK_REQ_LIST'
    exporting
      material         = matnr
      plant            = werks
      get_item_details = 'X'
      get_ind_lines    = 'X'
    tables
      mrp_items        = lt_mrp.

  case fname 0(2).
    when 'ZS'."供给
      delete lt_mrp where ( avail_date is initial ) or ( avail_date ge p_date ).
      delete lt_mrp where plngsegno is not initial or plus_minus ne ' ' or rec_reqd_qty is initial.

      loop at lt_mrp assigning <fs_mrp>.
        clear:gw_dtl.
        if <fs_mrp>-storage_loc in s_lgort.
          if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
            continue.
          else.
            gw_dtl-werks = werks.
            gw_dtl-matnr = matnr.
            gw_dtl-zdate = <fs_mrp>-avail_date."日期
            "MRP元素
            select single delb0
              into gw_dtl-delb0
              from t457t
              where delkz = <fs_mrp>-mrp_element_ind
                and spras = '1'.

            "MRP元素数据
            if <fs_mrp>-peggedrqmt is initial.
              gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
            else.
              gw_dtl-extra = <fs_mrp>-peggedrqmt.
            endif.

            "数量
            gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
            append gw_dtl to alv.
          endif.
        endif.
      endloop.

    when 'ZR'."需求
      delete lt_mrp where ( avail_date is initial ) or ( avail_date ge p_date ).
      delete lt_mrp where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.

      loop at lt_mrp assigning <fs_mrp>.
        clear:gw_dtl,l_lgort,l_auffx.
        case <fs_mrp>-order_type.
          when 'BB'."外协采购
            "到表EKPO中获取满足NO-X库存的
            select single lgort
              into l_lgort
              from ekpo
              where ebeln = <fs_mrp>-source_no
                and ebelp = <fs_mrp>-source_item
                and lgort in s_lgort.

            if sy-subrc eq 0.
              gw_dtl-werks = werks.
              gw_dtl-matnr = matnr.
              gw_dtl-zdate = <fs_mrp>-avail_date."日期
              "MRP元素
              select single delb0
                into gw_dtl-delb0
                from t457t
                where delkz = <fs_mrp>-mrp_element_ind
                  and spras = '1'.

              "MRP元素数据
              if <fs_mrp>-peggedrqmt is initial.
                gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
              else.
                gw_dtl-extra = <fs_mrp>-peggedrqmt.
              endif.

              "数量
              gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
              append gw_dtl to alv.
            endif.

          when 'SB'."计划订单-下阶
            "到表PLAF中获取满足NO-X库存的
            select single lgort auffx
              into (l_lgort,l_auffx)
              from plaf
              where plnum = <fs_mrp>-source_no
                and lgort in s_lgort.

            if sy-subrc eq 0.
              if l_auffx eq 'X'.
                gw_dtl-werks = werks.
                gw_dtl-matnr = matnr.
                gw_dtl-zdate = <fs_mrp>-avail_date."日期
                "MRP元素
                select single delb0
                  into gw_dtl-delb0
                  from t457t
                  where delkz = <fs_mrp>-mrp_element_ind
                    and spras = '1'.

                "MRP元素数据
                if <fs_mrp>-peggedrqmt is initial.
                  gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
                else.
                  gw_dtl-extra = <fs_mrp>-peggedrqmt.
                endif.

                "数量
                gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
                append gw_dtl to alv.
              endif.
            endif.

          when 'AR'."生产订单预留
            "到表AFPO中获取满足NO-X库存的
            select single lgort
              into l_lgort
              from afpo
              where aufnr = <fs_mrp>-mrp_no12
                and lgort in s_lgort.

            if sy-subrc eq 0.
              gw_dtl-werks = werks.
              gw_dtl-matnr = matnr.
              gw_dtl-zdate = <fs_mrp>-avail_date."日期
              "MRP元素
              select single delb0
                into gw_dtl-delb0
                from t457t
                where delkz = <fs_mrp>-mrp_element_ind
                  and spras = '1'.

              "MRP元素数据
              if <fs_mrp>-peggedrqmt is initial.
                gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
              else.
                gw_dtl-extra = <fs_mrp>-peggedrqmt.
              endif.

              "数量
              gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
              append gw_dtl to alv.
            endif.

          when others.
        endcase.
      endloop.

    when 'DA'."期间
      l_sundy = g_sundy.
      l_times = fname 3(2) - 1.
      do l_times times.
        l_mondy = l_sundy   1.
        l_sundy = l_sundy   7.
      enddo.

      if type = 'A'."供给

        delete lt_mrp where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
        delete lt_mrp where plngsegno is not initial or plus_minus ne ' ' or rec_reqd_qty is initial.

        loop at lt_mrp assigning <fs_mrp>.
          clear:gw_dtl.
          if <fs_mrp>-storage_loc in s_lgort.
            if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
              continue.
            else.
              gw_dtl-werks = werks.
              gw_dtl-matnr = matnr.
              gw_dtl-zdate = <fs_mrp>-avail_date."日期
              "MRP元素
              select single delb0
                into gw_dtl-delb0
                from t457t
                where delkz = <fs_mrp>-mrp_element_ind
                  and spras = '1'.

              "MRP元素数据
              if <fs_mrp>-peggedrqmt is initial.
                gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
              else.
                gw_dtl-extra = <fs_mrp>-peggedrqmt.
              endif.

              "数量
              gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
              append gw_dtl to alv.
            endif.
          endif.
        endloop.
      elseif type = 'B'."需求
        delete lt_mrp where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
        delete lt_mrp where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.

        loop at lt_mrp assigning <fs_mrp>.
          clear:gw_dtl,l_lgort,l_auffx.
          case <fs_mrp>-order_type.
            when 'BB'."外协采购
              "到表EKPO中获取满足NO-X库存的
              select single lgort
                into l_lgort
                from ekpo
                where ebeln = <fs_mrp>-source_no
                  and ebelp = <fs_mrp>-source_item
                  and lgort in s_lgort.

              if sy-subrc eq 0.
                gw_dtl-werks = werks.
                gw_dtl-matnr = matnr.
                gw_dtl-zdate = <fs_mrp>-avail_date."日期
                "MRP元素
                select single delb0
                  into gw_dtl-delb0
                  from t457t
                  where delkz = <fs_mrp>-mrp_element_ind
                    and spras = '1'.

                "MRP元素数据
                if <fs_mrp>-peggedrqmt is initial.
                  gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
                else.
                  gw_dtl-extra = <fs_mrp>-peggedrqmt.
                endif.

                "数量
                gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
                append gw_dtl to alv.
              endif.

            when 'SB'."计划订单-下阶
              "到表PLAF中获取满足NO-X库存的
              select single lgort auffx
                into (l_lgort,l_auffx)
                from plaf
                where plnum = <fs_mrp>-source_no
                  and lgort in s_lgort.

              if sy-subrc eq 0.
                if l_auffx eq 'X'.
                  gw_dtl-werks = werks.
                  gw_dtl-matnr = matnr.
                  gw_dtl-zdate = <fs_mrp>-avail_date."日期
                  "MRP元素
                  select single delb0
                    into gw_dtl-delb0
                    from t457t
                    where delkz = <fs_mrp>-mrp_element_ind
                      and spras = '1'.

                  "MRP元素数据
                  if <fs_mrp>-peggedrqmt is initial.
                    gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
                  else.
                    gw_dtl-extra = <fs_mrp>-peggedrqmt.
                  endif.

                  "数量
                  gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
                  append gw_dtl to alv.
                endif.
              endif.

            when 'AR'."生产订单预留
              "到表AFPO中获取满足NO-X库存的
              select single lgort
                into l_lgort
                from afpo
                where aufnr = <fs_mrp>-mrp_no12
                  and lgort in s_lgort.

              if sy-subrc eq 0.
                gw_dtl-werks = werks.
                gw_dtl-matnr = matnr.
                gw_dtl-zdate = <fs_mrp>-avail_date."日期
                "MRP元素
                select single delb0
                  into gw_dtl-delb0
                  from t457t
                  where delkz = <fs_mrp>-mrp_element_ind
                    and spras = '1'.

                "MRP元素数据
                if <fs_mrp>-peggedrqmt is initial.
                  gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
                else.
                  gw_dtl-extra = <fs_mrp>-peggedrqmt.
                endif.

                "数量
                gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
                append gw_dtl to alv.
              endif.

            when others.
          endcase.
        endloop.
      endif.

    when others.

  endcase.

endform.                    "frm_get_detail

*&---------------------------------------------------------------------*
*&      Form  frm_get_text
*&---------------------------------------------------------------------*
*       获取提示文本
*----------------------------------------------------------------------*
*      -->PERCENT    text
*      -->TEXT       text
*----------------------------------------------------------------------*
form frm_get_text using percent type i
                        text    type string.

  call function 'SAPGUI_PROGRESS_INDICATOR'
    exporting
      percentage = percent
      text       = text.

endform.                    "frm_get_text

*&---------------------------------------------------------------------*
*&      Form  frm_get_event
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
form frm_get_event .
  data l_events type slis_alv_event."slis_alv_event是一个包含name和form字段的结构,均为字符型

  call function 'REUSE_ALV_EVENTS_GET'
    exporting
      i_list_type     = 0
    importing
      et_events       = gt_events
    exceptions
      list_type_wrong = 1
      others          = 2.
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
           with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.

endform.                    "frm_get_event

*&---------------------------------------------------------------------*
*&      Form  frm_sort_build
*&---------------------------------------------------------------------*
*       输出排序设置
*----------------------------------------------------------------------*
*      -->LT_SORT    text
*----------------------------------------------------------------------*
form frm_sort_build changing lt_sort type slis_t_sortinfo_alv.
  data: ls_sort type slis_sortinfo_alv.
  refresh lt_sort.

  clear ls_sort.
  ls_sort-spos = 1.
  ls_sort-fieldname = 'WERKS'.
  ls_sort-up   = 'X'.
  append ls_sort to lt_sort.

  clear ls_sort.
  ls_sort-spos = 2.
  ls_sort-fieldname = 'DISPO'.
  ls_sort-up   = 'X'.
  append ls_sort to lt_sort.

  clear ls_sort.
  ls_sort-spos = 3.
  ls_sort-fieldname = 'MATNR'.
  ls_sort-up   = 'X'.
  append ls_sort to lt_sort.

  clear ls_sort.
  ls_sort-spos = 4.
  ls_sort-fieldname = 'MEINS'.
  ls_sort-up   = 'X'.
  append ls_sort to lt_sort.

  clear ls_sort.
  ls_sort-spos = 5.
  ls_sort-fieldname = 'MAKTX'.
  ls_sort-up   = 'X'.
  append ls_sort to lt_sort.

endform.                    "frm_sort_build

*&---------------------------------------------------------------------*
*&      Form  frm_init_layout
*&---------------------------------------------------------------------*
*       布局设置
*----------------------------------------------------------------------*
form frm_init_layout.
  gw_layout-zebra  = 'X'."间隔行颜色变换
  gw_layout-detail_popup = 'X'.
  gw_layout-colwidth_optimize = 'X'."自动调整列宽

endform.                    " FRM_INIT_LAYOUT

*&---------------------------------------------------------------------*
*&      Form  frm_fcat_setting
*&---------------------------------------------------------------------*
*       设置输出字段
*----------------------------------------------------------------------*
form frm_fcat_setting.
  data: l_num type n length 2,
        l_txt type c length 20,"字段
        l_dis type c length 20,"描述
        l_mondy type d,
        l_sundy type d.
  refresh gt_fieldcat.

  perform frm_init_fieldcat using 'WERKS' '工厂'           'X' 'X' ' ' ' ' ' '.
  perform frm_init_fieldcat using 'DISPO' 'MRP控制员'      'X' 'X' ' ' ' ' ' '.
  perform frm_init_fieldcat using 'MATNR' '物料号'         'X' 'X' ' ' 'X' ' '.
  perform frm_init_fieldcat using 'MEINS' '单位'           'X' 'X' ' ' ' ' ' '.
  perform frm_init_fieldcat using 'MAKTX' '物料描述'       'X' 'X' ' ' ' ' ' '.
  perform frm_init_fieldcat using 'LABST' 'NO-X非限制库存' 'X' 'X' ' ' 'X' ' '.
  perform frm_init_fieldcat using 'ZSUPL' 'NO-X过期供给'   'X' 'X' 'X' 'X' ' '.
  perform frm_init_fieldcat using 'ZREQD' 'NO-X过期需求'   'X' 'X' 'X' 'X' ' '.
  perform frm_init_fieldcat using 'ZTEXT' '期间'           'X' 'X' ' ' ' ' ' '.
  "动态输出期间字段
  clear:l_num,l_txt,l_dis.
  l_mondy = g_mondy.
  l_sundy = g_sundy.
  do 12 times.
    l_num = l_num   1.
    l_txt = |DAT{ l_num }|.
    l_dis = |{ l_mondy }-{ l_sundy }|.
    perform frm_init_fieldcat using l_txt l_dis ' ' ' ' 'X' 'X' ' '.
    l_mondy = l_sundy   1.
    l_sundy = l_sundy   7.
  enddo.

endform.                    "frm_fcat_setting

*&---------------------------------------------------------------------*
*&      Form  frm_init_fieldcat
*&---------------------------------------------------------------------*
*      初始化输出字段
*----------------------------------------------------------------------*
*      -->VALU01     text
*      -->VALU02     text
*      -->VALU03     text
*      -->VALU04     text
*      -->VALU05     text
*      -->VALU06     text
*      -->VALU07     text
*----------------------------------------------------------------------*
form frm_init_fieldcat using valu01
                             valu02
                             valu03
                             valu04
                             valu05
                             valu06
                             valu07.

  clear:gt_fieldcat.
  gt_fieldcat-fieldname  = valu01."字段名
  gt_fieldcat-seltext_m  = valu02."字段描述
  gt_fieldcat-key        = valu03."主键
  gt_fieldcat-fix_column = valu04."固定列
  gt_fieldcat-hotspot    = valu05."热点
  gt_fieldcat-no_zero    = valu06."隐藏前导零
  gt_fieldcat-no_sign    = valu07."符号
  append gt_fieldcat.

endform.                    "frm_set_fcat


*&---------------------------------------------------------------------*
*&      Form  frm_output
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->TAB        text
*----------------------------------------------------------------------*
form frm_output tables tab.
*ALV输出
  g_repid = sy-repid.

  call function 'REUSE_ALV_GRID_DISPLAY'
    exporting
      i_callback_program      = g_repid
      is_layout               = gw_layout
      it_fieldcat             = gt_fieldcat[]
      i_save                  = 'X'
      is_variant              = gw_stru_disvar"变量信息
      it_events               = gt_events[]
      it_sort                 = gt_sort[]
      i_callback_user_command = 'FRM_USER_COMMAND'
    tables
      t_outtab                = tab
    exceptions
      program_error           = 1
      others                  = 2.
  if sy-subrc <> 0.
    message id sy-msgid type sy-msgty number sy-msgno
            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
  endif.
endform.                    "frm_output

*&---------------------------------------------------------------------*
*&      Form  FRM_USER_COMMAND
*&---------------------------------------------------------------------*
*       事件处理
*----------------------------------------------------------------------*
*      -->R_UCOMM      text
*      -->RS_SELFIELD  text
*----------------------------------------------------------------------*
form frm_user_command using r_ucomm like sy-ucomm
                            rs_selfield type slis_selfield.

  clear:gt_dtl.
  case r_ucomm.
    when '&IC1'.
      read table gt_out assigning <fs_out> index rs_selfield-tabindex.
      if rs_selfield-fieldname = 'ZSUPL' or rs_selfield-fieldname = 'ZREQD'."供给/需求
        perform frm_get_detail tables gt_dtl
                               using <fs_out>-matnr
                                     <fs_out>-werks
                                     rs_selfield-fieldname
                                     <fs_out>-ztype.

        if gt_dtl is not initial.
          call screen 0100 starting at 30 5.
        endif.
      else.
        if rs_selfield-fieldname 0(3) = 'DAT'.
          perform frm_get_detail tables gt_dtl
                                 using <fs_out>-matnr
                                       <fs_out>-werks
                                       rs_selfield-fieldname
                                       <fs_out>-ztype.

          if gt_dtl is not initial.
            call screen 0100 starting at 30 5.
          endif.
        endif.
      endif.

    when others.
  endcase.
endform.                    "FRM_USER_COMMAND

*&---------------------------------------------------------------------*
*&      Form  frm_set_fcat
*&---------------------------------------------------------------------*
*       输出字段设置
*----------------------------------------------------------------------*
form frm_set_fcat.
  if gt_fcat is initial.
    clear: gw_fcat.
    gw_fcat-col_pos    = 1.
    gw_fcat-fieldname  = 'WERKS'.
    gw_fcat-tabname    = 'MARC'.
    gw_fcat-scrtext_m  = '工厂'.
    append gw_fcat to gt_fcat.

    clear: gw_fcat.
    gw_fcat-col_pos    = 2.
    gw_fcat-fieldname  = 'MATNR'.
    gw_fcat-tabname    = 'MARC'.
    gw_fcat-scrtext_m  = '物料'.
    gw_fcat-no_zero    = 'X'.
    append gw_fcat to gt_fcat.

    clear: gw_fcat.
    gw_fcat-col_pos    = 3.
    gw_fcat-fieldname  = 'ZDATE'.
    gw_fcat-scrtext_m  = '日期'.
    append gw_fcat to gt_fcat.

    clear: gw_fcat.
    gw_fcat-col_pos    = 4.
    gw_fcat-fieldname  = 'DELB0'.
    gw_fcat-tabname    = 'T457T'.
    gw_fcat-scrtext_m  = 'MRP元素'.
    append gw_fcat to gt_fcat.

    clear: gw_fcat.
    gw_fcat-col_pos    = 5.
    gw_fcat-fieldname  = 'EXTRA'.
    gw_fcat-tabname    = 'MDEZ'.
    gw_fcat-scrtext_m  = 'MRP元素数据'.
    gw_fcat-fix_column = 'X'.
    append gw_fcat to gt_fcat.

    clear: gw_fcat.
    gw_fcat-col_pos    = 6.
    gw_fcat-fieldname  = 'MNG01'.
    gw_fcat-tabname    = 'MDEZ'.
    gw_fcat-scrtext_m  = '收货数量或需求数量'.
    gw_fcat-fix_column = 'X'.
    gw_fcat-do_sum     = 'X'.
    append gw_fcat to gt_fcat.
  endif.
endform.                    "frm_set_fcat

*&---------------------------------------------------------------------*
*&      Form  frm_set_lock
*&---------------------------------------------------------------------*
*       上锁
*----------------------------------------------------------------------*
form frm_set_lock.
  "锁定程序
  call function 'ENQUEUE_EZZSOPR0032'
    exporting
      mode_trdir     = 'E'
      name           = 'ZPPR0056'
      x_name         = ' '
      _scope         = '2'
      _wait          = ' '
      _collect       = ' '
    exceptions
      foreign_lock   = 1
      system_failure = 2
      others         = 3.

  if sy-subrc <> 0.
* Implement suitable error handling here
    message '对象已被锁定,请稍后执行' type 'S' display like 'E'.
    stop.
  else.
    "锁定成功
  endif.
endform.                    "frm_set_lock

*&---------------------------------------------------------------------*
*&      Form  frm_set_unlock
*&---------------------------------------------------------------------*
*       解锁
*----------------------------------------------------------------------*
form frm_set_unlock.
  "解除程序的锁定
  call function 'DEQUEUE_EZZSOPR0032'
    exporting
      mode_trdir = 'E'
      name       = 'ZPPR0056'
      x_name     = ' '
      _scope     = '3'
      _synchron  = ' '
      _collect   = ' '.
endform.                    "frm_set_unlock

*&---------------------------------------------------------------------*
*&      Module  STATUS_0100  OUTPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
module status_0100 output.
  set pf-status 'ZSTA1'.
*  SET TITLEBAR 'xxx'.
  create object g_alv.
  g_alv->main( ).
endmodule.                 " STATUS_0100  OUTPUT

*&---------------------------------------------------------------------*
*&      Module  EXIT  INPUT
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
module exit input.
  leave to screen 0.

endmodule.                 " EXIT  INPUT

0 人点赞