• ABAP中的‘多线程’


          在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中定义自己需要的处理逻辑子例程
     
       1 *&---------------------------------------------------------------------*
       2 *& Report  ZPPR0056
       3 *&----------------------------------------------------------------------*
       4 *&  Program  Name :  ZPPR0056
       5 *&  Author's  Name : QLB
       6 *&  Written   Date : 2014.01.08
       7 *&  Request  Number: DEVK940516
       8 *&  Program Description: 共用料区分建议报表--并行处理
       9 *&----------------------------------------------------------------------*
      10 *  Changer           Changed Date         Request  NO.        Dec.
      11 *&----------------------------------------------------------------------*
      12 
      13 report  zppr0056 message-id zppmess.
      14 
      15 tables: mara,marc.
      16 
      17 types: begin of gs_out,
      18         werks type marc-werks,"工厂
      19         dispo type marc-dispo,"MRP控制员
      20         matnr type marc-matnr,"物料
      21         maktx type makt-maktx,"物料描述
      22         meins type mara-meins,"单位
      23         matkl type mara-matkl,"物料组
      24         labst type mard-labst,"NO-X非限制库存
      25         zsupl type mard-labst,"NO-X过期供给
      26         zreqd type mard-labst,"NO-X过期需求
      27         ztype type c,         "期间类型
      28         ztext type c length 20,"期间类型文本
      29         dat01 type mard-labst, "期间-one
      30         dat02 type mard-labst, "期间-two
      31         dat03 type mard-labst, "期间-three
      32         dat04 type mard-labst, "期间-four
      33         dat05 type mard-labst, "期间-five
      34         dat06 type mard-labst, "期间-six
      35         dat07 type mard-labst, "期间-seven
      36         dat08 type mard-labst, "期间-eight
      37         dat09 type mard-labst, "期间-nine
      38         dat10 type mard-labst, "期间-ten
      39         dat11 type mard-labst, "期间-evelen
      40         dat12 type mard-labst, "期间-twelve
      41        end of gs_out,
      42 
      43        begin of gs_dtl,
      44         werks type marc-werks,"工厂
      45         matnr type marc-matnr,"物料
      46         zdate type sy-datum,  "需求日期
      47         delb0 type t457t-delb0,"MRP元素
      48         extra type mdez-extra,"MRP元素数据
      49         mng01 type mdez-mng01,"收货数量或需求数量
      50        end of gs_dtl,
      51 
      52        begin of gs_marc,
      53         matnr type marc-matnr,"物料ID
      54         werks type marc-werks,"工厂
      55         dispo type marc-dispo,"MRP控制员
      56         matkl type mara-matkl,"物料组
      57         meins type mara-meins,"基本单位
      58        end of gs_marc,
      59 
      60        begin of gs_mard,
      61         matnr type mard-matnr,"物料
      62         werks type mard-werks,"工厂
      63         lgort type mard-lgort,"库存地点
      64         labst type mard-labst,"库存数
      65        end of gs_mard,
      66 
      67        begin of gs_makt,
      68         matnr type makt-matnr,"物料
      69         maktx type makt-maktx,"物料描述
      70        end of gs_makt,
      71 
      72        begin of gs_task,
      73         matnr type marc-matnr,"物料
      74         werks type marc-werks,"工厂
      75         dispo type marc-dispo,"MRP控制员
      76         matkl type mara-matkl,"物料组
      77         meins type mara-meins,"单位
      78         maktx type makt-maktx,"物料描述
      79         labst type mard-labst,"库存
      80         taskname type c length 12,
      81        end of gs_task.
      82 
      83 data: gw_task type gs_task,
      84       gt_task type standard table of gs_task.
      85 
      86 data: gw_out    type gs_out,
      87       gw_dtl    type gs_dtl,
      88       gw_mard   type gs_mard.
      89 
      90 data: gt_out    type standard table of gs_out,
      91       gt_dtl    type standard table of gs_dtl,"明细alv
      92       gt_marc   type standard table of gs_marc,
      93       gt_marc_d type standard table of gs_marc,
      94       gt_makt   type standard table of gs_makt,
      95       gt_mard   type standard table of gs_mard,
      96       gt_mard_s type standard table of gs_mard.
      97 data: gt_noxlog type standard table of znoxlog with header line.
      98 
      99 field-symbols:<fs_out>  type gs_out,
     100               <fs_mard> type gs_mard,
     101               <fs_marc> type gs_marc,
     102               <fs_makt> type gs_makt,
     103               <fs_mrp>  type bapi_mrp_items,
     104               <fs>,
     105               <fs1>,
     106               <fs2>,
     107               <fs3>.
     108 
     109 data: gt_mrp_items type standard table of bapi_mrp_items."MRP_ITEMs数据
     110 
     111 
     112 data: g_txt type c length 20,
     113       g_num type n length 2.
     114 data: g_mondy type d,
     115       g_sundy type d.
     116 data: g_post  type i.
     117 data: g_mark  type c.
     118 
     119 *****-------GRID_ALV定义
     120 class lcl_alv definition deferred.
     121 data: g_alv type ref to lcl_alv.
     122 data: gt_fcat  type lvc_t_fcat,
     123       gw_fcat  type lvc_s_fcat,
     124       is_layo  type lvc_s_layo,
     125       is_vart  type disvariant.
     126 data: g_grid1 type ref to cl_gui_alv_grid,
     127       g_custom_container1 type ref to cl_gui_custom_container,
     128       g_container1 type scrfname value 'GRID_01'.
     129 data: ok_code type sy-ucomm,
     130       save_ok type sy-ucomm.
     131 
     132 *-----------------------------------------------------------------------*
     133 *DESC:异步取数变量定义
     134 *-----------------------------------------------------------------------*
     135 data: g_taskname(12) type c, "task name(同时运行的任务名称必须保持唯一)
     136       g_classname    type rzlli_apcl,   "Server Group Name
     137       g_applserver   type rzllitab-applserver."RFC Serve Group
     138 
     139 data: snd_jobs type i,
     140       rcv_jobs type i,
     141       functioncall1(1) type c.
     142 
     143 constants: done(1) type c value 'X',
     144            pnum    type i value 5."进程数
     145 
     146 *----------------------------------------------------------------------*
     147 *       CLASS LCL_ALV DEFINITION
     148 *----------------------------------------------------------------------*
     149 *
     150 *----------------------------------------------------------------------*
     151 class lcl_alv definition.
     152   public section.
     153     methods:
     154              create_object,
     155              fcat_setting,
     156              layo_setting,
     157              disp,
     158              main.
     159 
     160   private section.
     161 
     162 endclass.                    "LCL_ALV DEFINITION
     163 
     164 *----------------------------------------------------------------------*
     165 *       CLASS LCL_ALV IMPLEMENTATION
     166 *----------------------------------------------------------------------*
     167 *
     168 *----------------------------------------------------------------------*
     169 class lcl_alv implementation.
     170   method create_object.
     171     if g_custom_container1 is initial.
     172       "创建容器
     173       create object g_custom_container1
     174         exporting
     175           container_name              = g_container1
     176         exceptions
     177           cntl_error                  = 1
     178           cntl_system_error           = 2
     179           create_error                = 3
     180           lifetime_error              = 4
     181           lifetime_dynpro_dynpro_link = 5
     182           others                      = 6.
     183       if sy-subrc ne 0.
     184         message 'error1' type 'E'.
     185       endif.
     186 
     187       "创建ALV
     188       create object g_grid1
     189         exporting
     190           i_parent          = g_custom_container1
     191         exceptions
     192           error_cntl_create = 1
     193           error_cntl_init   = 2
     194           error_cntl_link   = 3
     195           error_dp_create   = 4
     196           others            = 5.
     197       if sy-subrc ne 0.
     198         message 'error2' type 'E'.
     199       endif.
     200 
     201     else.
     202       g_grid1->refresh_table_display( ).
     203     endif.
     204 
     205   endmethod.                    "CREATE_OBJECT
     206 
     207   method fcat_setting.
     208     perform frm_set_fcat.
     209 
     210   endmethod.                    "FCAT_SETTING
     211 
     212   method layo_setting.
     213     is_layo-zebra = 'X'."隔行颜色
     214     is_layo-sel_mode = 'A'."可选
     215     is_layo-cwidth_opt = 'X'."输出列显示最优化
     216 
     217     is_vart-report = sy-repid.
     218   endmethod.                    "LAYO_SETTING
     219 
     220   method disp.
     221     "输出ALV
     222     call method g_grid1->set_table_for_first_display
     223       exporting
     224         i_structure_name              = 'GS_DTL'
     225         is_variant                    = is_vart
     226         i_save                        = 'A'
     227         i_default                     = 'X'
     228         is_layout                     = is_layo
     229       changing
     230         it_outtab                     = gt_dtl[]
     231         it_fieldcatalog               = gt_fcat[]
     232                                                                                                                                                                                                                    "it_sort                       = gt_sort[]
     233       exceptions
     234         invalid_parameter_combination = 1
     235         program_error                 = 2
     236         too_many_lines                = 3
     237         others                        = 4.
     238     if sy-subrc ne 0.
     239       message 'error3' type 'E'.
     240     endif.
     241 
     242     call method cl_gui_control=>set_focus
     243       exporting
     244         control = g_grid1.
     245   endmethod.                    "DISP
     246 
     247   method main.
     248     me->create_object( ).
     249     me->fcat_setting( ).
     250     me->layo_setting( ).
     251     me->disp( ).
     252   endmethod.                    "MAIN
     253 
     254 endclass.                    "LCL_ALV IMPLEMENTATION
     255 
     256 *---------------------------------------------------------------------*
     257 * DESC:ALV 变量定义
     258 *---------------------------------------------------------------------*
     259 type-pools: slis.
     260 data: gt_fieldcat    type slis_t_fieldcat_alv with header line,  "定义存放输出字段的内表
     261       gt_sort        type slis_t_sortinfo_alv,
     262       gw_layout      type slis_layout_alv, "定义ALV布局设置的工作区
     263       g_repid        like sy-repid.        "定义系统当前程序名变量
     264 data: gw_stru_disvar type disvariant,        "ALV 显示格式
     265       gt_events      type slis_t_event.      "ALV 事件
     266 
     267 *-----------------------------------------------------------------------*
     268 *DESC:选择屏幕定义
     269 *-----------------------------------------------------------------------*
     270 selection-screen begin of block blk with frame title text-001.
     271 select-options:s_werks for marc-werks obligatory,"工厂
     272                s_matnr for marc-matnr,"物料
     273                s_dispo for marc-dispo obligatory,"MRP控制员
     274                s_matkl for mara-matkl."物料组
     275 select-options:s_lgort for marc-lgpro no-display."NO-X库存
     276 parameters: p_date type mara-ersda default sy-datum obligatory."开始日期
     277 selection-screen end of block blk.
     278 
     279 *-----------------------------------------------------------------------*
     280 *INITIALIZATION
     281 *-----------------------------------------------------------------------*
     282 initialization.
     283   perform frm_init.
     284 
     285 *-----------------------------------------------------------------------*
     286 *START-OF-SELECTION
     287 *-----------------------------------------------------------------------*
     288 start-of-selection.
     289   perform frm_status(zpercent) using 10 '正在读取其他关联数据...'.
     290   perform frm_get_date."获取计算期间的起始值
     291   perform frm_get_data."获取基本数据
     292   if g_mark eq 'X'.
     293     stop.
     294   else.
     295     perform frm_set_lock."设置锁
     296     perform frm_fill_alv.
     297     perform frm_set_unlock."解锁
     298     perform frm_get_event.
     299     perform frm_init_layout.
     300     perform frm_sort_build changing gt_sort.
     301     perform frm_fcat_setting.
     302     perform frm_output tables gt_out.
     303   endif.
     304 
     305 
     306 *&---------------------------------------------------------------------*
     307 *&      Form  frm_init
     308 *&---------------------------------------------------------------------*
     309 *       初始化
     310 *----------------------------------------------------------------------*
     311 form frm_init.
     312   clear: gt_noxlog,g_mondy,g_sundy.
     313 
     314   "初始化NO-X库存位置
     315   select *
     316     into table gt_noxlog
     317     from znoxlog.
     318 
     319   loop at gt_noxlog.
     320     s_lgort-low = gt_noxlog-lgort.
     321     s_lgort-option = 'EQ'.
     322     s_lgort-sign = 'I'.
     323     append s_lgort.
     324   endloop.
     325 
     326 endform.                    "frm_init
     327 
     328 *&---------------------------------------------------------------------*
     329 *&      Form  frm_get_date
     330 *&---------------------------------------------------------------------*
     331 *       获取日期
     332 *----------------------------------------------------------------------*
     333 form frm_get_date.
     334   "获取开始日期所在周及时间
     335   call function 'GET_WEEK_INFO_BASED_ON_DATE'
     336     exporting
     337       date   = p_date
     338     importing
     339       monday = g_mondy
     340       sunday = g_sundy.
     341 
     342   g_mondy = p_date.
     343 endform.                    "frm_init
     344 
     345 *&---------------------------------------------------------------------*
     346 *&      Form  FRM_get_data
     347 *&---------------------------------------------------------------------*
     348 *       获取基本数据
     349 *----------------------------------------------------------------------*
     350 form frm_get_data.
     351   "根据输入条件到表MARC及MARA中获取基本数据
     352   select a~matnr "物料
     353          a~werks "工厂
     354          a~dispo "MRP控制员
     355          b~matkl "物料组
     356          b~meins "单位
     357     into table gt_marc
     358     from marc as a join mara as b on a~matnr = b~matnr
     359     where a~matnr in s_matnr
     360       and a~werks in s_werks
     361       and a~dispo in s_dispo
     362       and a~lvorm ne 'X'
     363       and a~mmsta ne '99'
     364       and b~matkl in s_matkl.
     365 
     366   if gt_marc is not initial.
     367 
     368     "获取物料描述
     369     gt_marc_d = gt_marc.
     370     sort: gt_marc_d by matnr.
     371     delete adjacent duplicates from gt_marc_d comparing matnr.
     372 
     373     select matnr "物料
     374            maktx "物料描述
     375       into table gt_makt
     376       from makt
     377       for all entries in gt_marc_d
     378       where matnr = gt_marc_d-matnr
     379         and spras = '1'.
     380 
     381     "根据内表gt_marc到表MARD中获取库存数
     382     select matnr "物料
     383            werks "工厂
     384            lgort "库存地
     385            labst "库存
     386       into table gt_mard
     387       from mard
     388       for all entries in gt_marc
     389       where matnr = gt_marc-matnr
     390         and werks = gt_marc-werks
     391         and lgort in s_lgort
     392         and diskz ne '1'.
     393 
     394     "汇总
     395     loop at gt_mard assigning <fs_mard>.
     396       clear:gw_mard.
     397       move <fs_mard>-matnr to gw_mard-matnr."物料
     398       move <fs_mard>-werks to gw_mard-werks."工厂
     399       move <fs_mard>-labst to gw_mard-labst."库存
     400       collect gw_mard into gt_mard_s.
     401     endloop.
     402   else.
     403     g_mark = 'X'.
     404     message s006(zppmess) display like 'E'.
     405   endif.
     406 
     407 endform.                    "FRM_get_data
     408 
     409 *&---------------------------------------------------------------------*
     410 *&      Form  frm_fill_alv
     411 *&---------------------------------------------------------------------*
     412 *       填充ALV输出
     413 *----------------------------------------------------------------------*
     414 form frm_fill_alv.
     415   data: l_lgort   type mard-lgort,"库存点变量
     416         l_count   type i,"
     417         l_mondy   type d,"周一
     418         l_sundy   type d,"周末
     419         l_num(2)  type n,
     420         l_txt(20) type c.
     421   data: l_labst   type mard-labst,"库存
     422         l_zsupl   type mard-labst,"供给
     423         l_zreqd   type mard-labst."需求
     424   data: lt_mrp_01 type standard table of bapi_mrp_items,"计算-NO-X过期供给
     425         lt_mrp_02 type standard table of bapi_mrp_items,"计算-NO-X过期需求
     426         lt_mrp_03 type standard table of bapi_mrp_items,"计算-列所对应的NO-X供给
     427         lt_mrp_04 type standard table of bapi_mrp_items."计算-列所对应的NO-X需求
     428 
     429   sort: gt_makt   by matnr,
     430         gt_mard_s by matnr werks,
     431         gt_marc   by matnr werks.
     432 
     433   "临时变量
     434   data:mess(40) type c,        "并发执行出错信息
     435        open_task_num type i.   "启动任务数量
     436   data:l_tabix  type sy-tabix, "索引变量
     437        l_lines  type i,        "总行数
     438        l_counts type p.
     439 
     440 
     441   "获取 RFC Serve Group name         Start--*
     442   "一般系统默认g_classname = 'parallel_generators',但为了通用性按照如下方法获取
     443   call 'C_SAPGPARAM'                                      "#EC CI_CCALL
     444     id 'NAME'  field 'rdisp/myname'
     445     id 'VALUE' field g_applserver.
     446 
     447   select single classname
     448      from rzllitab
     449      into g_classname   "Server Group Name
     450     where applserver = g_applserver
     451       and grouptype = 'S'.   "S:服务器组,空:登陆组
     452   "获取 RFC Serve Group name         End--*
     453 
     454   clear: open_task_num,l_lines.
     455 
     456   describe table gt_marc lines l_lines.
     457   l_counts = l_lines.
     458 
     459   loop at gt_marc assigning <fs_marc>.
     460     clear: gw_out,lt_mrp_01,lt_mrp_02,lt_mrp_03,lt_mrp_04,
     461            l_labst,l_zsupl,l_zreqd.
     462     l_tabix = sy-tabix.
     463 
     464     perform frm_percent(zpercent) using sy-tabix l_counts ''.
     465     move <fs_marc>-matnr to gw_out-matnr."物料
     466     move <fs_marc>-werks to gw_out-werks."工厂
     467     move <fs_marc>-dispo to gw_out-dispo."MRP控制员
     468     move <fs_marc>-matkl to gw_out-matkl."物料组
     469 
     470     "单位转换
     471     call function 'CONVERSION_EXIT_CUNIT_OUTPUT'
     472       exporting
     473         input  = <fs_marc>-meins
     474       importing
     475         output = gw_out-meins.
     476 
     477     "获取物料描述
     478     read table gt_makt assigning <fs_makt> with key matnr = <fs_marc>-matnr binary search.
     479     if sy-subrc eq 0.
     480       move <fs_makt>-maktx to gw_out-maktx.
     481     endif.
     482 
     483     "获取NO-X非限制库存
     484     read table gt_mard_s assigning <fs_mard> with key matnr = <fs_marc>-matnr binary search.
     485     if sy-subrc eq 0.
     486       move <fs_mard>-labst to gw_out-labst.
     487     endif.
     488 
     489 *--优化,异步调用获取数据、
     490     "生成任务名称 = 'Task' + sy-tabix   Start--*
     491     move l_tabix to g_taskname.
     492     condense g_taskname.
     493     concatenate 'Task' g_taskname into g_taskname.
     494     "生成任务名称 = 'Task' + sy-tabix   End--*
     495 
     496     clear: gw_task.
     497     gw_task-matnr = <fs_marc>-matnr.
     498     gw_task-werks = <fs_marc>-werks.
     499     gw_task-dispo = <fs_marc>-dispo.
     500     gw_task-matkl = <fs_marc>-matkl.
     501     gw_task-meins = gw_out-meins.
     502     gw_task-maktx = gw_out-maktx.
     503     gw_task-labst = gw_out-labst.
     504     gw_task-taskname  = g_taskname.
     505     append gw_task to gt_task.
     506 
     507 *   异步调用函数    Start--*
     508     call function 'BAPI_MATERIAL_STOCK_REQ_LIST' starting new task g_taskname
     509         destination in group g_classname
     510         performing frm_subroutine_done on end of task "子程序
     511 *      只要将函数的EXPORTING参数放在此处,其他参数放到子程序中
     512         exporting
     513           material         = <fs_marc>-matnr
     514           plant            = <fs_marc>-werks
     515           get_item_details = 'X'
     516           get_ind_lines    = 'X'
     517 *       系统标准报错信息
     518         exceptions
     519           communication_failure = 1  message mess
     520           system_failure        = 2  message mess
     521           resource_failure      = 3.
     522 
     523     if sy-subrc = 0.
     524       snd_jobs = snd_jobs + 1.
     525     endif.
     526 *   异步调用函数     End--*
     527 
     528     open_task_num = open_task_num + 1.   "记录启动的进程数量
     529 
     530     if open_task_num = pnum.
     531 *     获取并发进程返回的结果
     532       wait until rcv_jobs >= snd_jobs.
     533 
     534       clear:open_task_num,rcv_jobs,snd_jobs.
     535       free:gt_task.
     536     else.
     537       if l_tabix = l_lines.
     538 *     获取并发进程返回的结果
     539         wait until rcv_jobs >= snd_jobs.
     540 
     541         clear:open_task_num,rcv_jobs,snd_jobs.
     542         free:gt_task.
     543       endif.
     544     endif.
     545 
     546   endloop.
     547 
     548 endform.                    "frm_fill_alv
     549 
     550 *&---------------------------------------------------------------------*
     551 *&      Form  frm_subroutine_done
     552 *&---------------------------------------------------------------------*
     553 *      异步处理子例程
     554 *----------------------------------------------------------------------*
     555 *      -->G_TASKNAME text
     556 *----------------------------------------------------------------------*
     557 form frm_subroutine_done using g_taskname.
     558   data: l_lgort   type mard-lgort,"库存点变量
     559         l_auffx   type plaf-auffx,"固定标识
     560         l_count   type i,"
     561         l_mondy   type d,"周一
     562         l_sundy   type d,"周末
     563         l_num(2)  type n,
     564         l_txt(20) type c.
     565   data: l_labst   type mard-labst,"库存
     566         l_zsupl   type mard-labst,"供给
     567         l_zreqd   type mard-labst."需求
     568   data: l_mark1   type c,
     569         l_mark2   type c,
     570         l_mark3   type c,
     571         l_mark4   type c,
     572         l_lines   type i.
     573   data: lt_mrp_01 type standard table of bapi_mrp_items,"计算-NO-X过期供给
     574         lt_mrp_02 type standard table of bapi_mrp_items,"计算-NO-X过期需求
     575         lt_mrp_03 type standard table of bapi_mrp_items,"计算-列所对应的NO-X供给
     576         lt_mrp_04 type standard table of bapi_mrp_items."计算-列所对应的NO-X需求
     577 
     578   rcv_jobs = rcv_jobs + 1.  ""Receiving data
     579 
     580   receive results from function 'BAPI_MATERIAL_STOCK_REQ_LIST'
     581     tables
     582       mrp_items        = gt_mrp_items.
     583 
     584   read table gt_task into gw_task with key taskname = g_taskname binary search.
     585   if sy-subrc eq 0.
     586     clear:l_mark1,l_mark2,l_mark3,l_mark4.
     587 
     588     gw_out-matnr = gw_task-matnr."物料
     589     gw_out-werks = gw_task-werks."工厂
     590     gw_out-dispo = gw_task-dispo.
     591     gw_out-meins = gw_task-meins.
     592     gw_out-maktx = gw_task-maktx.
     593     gw_out-labst = gw_task-labst.
     594 
     595     delete gt_mrp_items where ( mrp_element_ind = 'WB' and rec_reqd_qty is initial ).
     596 
     597     if gt_mrp_items is initial and gw_out-labst is initial. "如果MD04为空
     598       "CONTINUE.
     599     else.
     600 
     601       lt_mrp_01 = lt_mrp_02 = gt_mrp_items.
     602 
     603       "计算-NO-X过期供给
     604       delete lt_mrp_01 where ( avail_date is initial ) or ( avail_date ge p_date ).
     605       delete lt_mrp_01 where plngsegno is not initial or plus_minus ne '+' or rec_reqd_qty is initial.
     606 
     607       loop at lt_mrp_01 assigning <fs_mrp>.
     608         if <fs_mrp>-storage_loc in s_lgort.
     609           if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
     610             continue.
     611           else.
     612             gw_out-zsupl = gw_out-zsupl + <fs_mrp>-rec_reqd_qty.
     613           endif.
     614         endif.
     615       endloop.
     616 
     617       "计算-NO-X过期需求
     618       delete lt_mrp_02 where ( avail_date is initial ) or ( avail_date ge p_date ).
     619       delete lt_mrp_02 where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.
     620 
     621       loop at lt_mrp_02 assigning <fs_mrp>.
     622         clear:l_lgort,l_auffx.
     623 
     624         case <fs_mrp>-order_type.
     625           when 'BB'."外协采购
     626             "到表EKPO中获取满足NO-X库存的
     627             select single lgort
     628               into l_lgort
     629               from ekpo
     630               where ebeln = <fs_mrp>-source_no
     631                 and ebelp = <fs_mrp>-source_item
     632                 and lgort in s_lgort.
     633 
     634             if sy-subrc eq 0.
     635               gw_out-zreqd = gw_out-zreqd + <fs_mrp>-rec_reqd_qty.
     636             endif.
     637 
     638           when 'SB'."计划订单-下阶
     639             "到表PLAF中获取满足NO-X库存的
     640             select single lgort auffx
     641               into (l_lgort,l_auffx)
     642               from plaf
     643               where plnum = <fs_mrp>-source_no
     644                 and lgort in s_lgort.
     645 
     646             if sy-subrc eq 0.
     647               if l_auffx eq 'X'."固定
     648                 gw_out-zreqd = gw_out-zreqd + <fs_mrp>-rec_reqd_qty.
     649               endif.
     650             endif.
     651 
     652           when 'AR'."生产订单预留
     653             "到表AFPO中获取满足NO-X库存的
     654             select single lgort
     655               into l_lgort
     656               from afpo
     657               where aufnr = <fs_mrp>-mrp_no12
     658                 and lgort in s_lgort.
     659 
     660             if sy-subrc eq 0.
     661               gw_out-zreqd = gw_out-zreqd + <fs_mrp>-rec_reqd_qty.
     662             endif.
     663 
     664           when others.
     665         endcase.
     666       endloop.
     667 
     668       "标识one
     669       if gw_out-labst is initial and gw_out-zsupl is initial and gw_out-zreqd is initial.
     670         l_mark1 = 'X'.
     671       endif.
     672 
     673       "计算-列
     674       clear:l_count.
     675       do 3 times.
     676         l_count = l_count + 1.
     677         case l_count.
     678           when 1."计算-列所对应的NO-X供给
     679             clear:g_num.
     680             l_mondy = g_mondy.
     681             l_sundy = g_sundy.
     682             gw_out-ztype = 'A'.
     683             gw_out-ztext = 'NO-X供给'.
     684             do 12 times.
     685               clear:g_txt.
     686               g_num = g_num + 1.
     687               g_txt = |GW_OUT-DAT{ g_num }|.
     688               assign (g_txt) to <fs>.
     689 
     690               lt_mrp_03 = gt_mrp_items.
     691               delete lt_mrp_03 where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
     692               delete lt_mrp_03 where plngsegno is not initial or plus_minus ne '+' or rec_reqd_qty is initial.
     693 
     694               loop at lt_mrp_03 assigning <fs_mrp>.
     695                 if <fs_mrp>-storage_loc in s_lgort.
     696                   if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
     697                     continue.
     698                   else.
     699                     <fs> = <fs> + <fs_mrp>-rec_reqd_qty.
     700                   endif.
     701                 endif.
     702               endloop.
     703               l_mondy = l_sundy + 1.
     704               l_sundy = l_sundy + 7.
     705 
     706               "标识two,只要其中一列不为空
     707               if <fs> is not initial.
     708                 l_mark2 = 'X'.
     709               endif.
     710             enddo.
     711             append gw_out to gt_out.
     712             clear:gw_out-labst,gw_out-zsupl,gw_out-zreqd.
     713 
     714           when 2."计算-列所对应的NO-X需求
     715             clear:g_num,gw_out-dat01,gw_out-dat02,gw_out-dat03,gw_out-dat04,gw_out-dat05,gw_out-dat06,
     716                         gw_out-dat07,gw_out-dat08,gw_out-dat09,gw_out-dat10,gw_out-dat11,gw_out-dat12.
     717             l_mondy = g_mondy.
     718             l_sundy = g_sundy.
     719             gw_out-ztype = 'B'.
     720             gw_out-ztext = 'NO-X需求'.
     721             do 12 times.
     722               clear:g_txt.
     723               g_num = g_num + 1.
     724               g_txt = |GW_OUT-DAT{ g_num }|.
     725               assign (g_txt) to <fs>.
     726 
     727               lt_mrp_04 = gt_mrp_items.
     728               delete lt_mrp_04 where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
     729               delete lt_mrp_04 where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.
     730 
     731               loop at lt_mrp_04 assigning <fs_mrp>.
     732                 clear:l_lgort,l_auffx.
     733 
     734                 case <fs_mrp>-order_type.
     735                   when 'BB'."外协采购
     736                     "到表EKPO中获取满足NO-X库存的
     737                     select single lgort
     738                       into l_lgort
     739                       from ekpo
     740                       where ebeln = <fs_mrp>-source_no
     741                         and ebelp = <fs_mrp>-source_item
     742                         and lgort in s_lgort.
     743 
     744                     if sy-subrc eq 0.
     745                       <fs> = <fs> + <fs_mrp>-rec_reqd_qty.
     746                     endif.
     747 
     748                   when 'SB'."计划订单-下阶
     749                     "到表PLAF中获取满足NO-X库存的
     750                     select single lgort auffx
     751                       into (l_lgort,l_auffx)
     752                       from plaf
     753                       where plnum = <fs_mrp>-source_no
     754                         and lgort in s_lgort.
     755 
     756                     if sy-subrc eq 0.
     757                       if l_auffx = 'X'.
     758                         <fs> = <fs> + <fs_mrp>-rec_reqd_qty.
     759                       endif.
     760                     endif.
     761 
     762                   when 'AR'."生产订单预留
     763                     "到表AFPO中获取满足NO-X库存的
     764                     select single lgort
     765                       into l_lgort
     766                       from afpo
     767                       where aufnr = <fs_mrp>-mrp_no12
     768                         and lgort in s_lgort.
     769 
     770                     if sy-subrc eq 0.
     771                       <fs> = <fs> + <fs_mrp>-rec_reqd_qty.
     772                     endif.
     773 
     774                   when others.
     775                 endcase.
     776               endloop.
     777               l_mondy = l_sundy + 1.
     778               l_sundy = l_sundy + 7.
     779 
     780               "标识three,只要其中一列不为空
     781               if <fs> is not initial.
     782                 l_mark3 = 'X'.
     783               endif.
     784             enddo.
     785             append gw_out to gt_out.
     786 
     787           when 3."计算-NO-X建议供给数量
     788             clear:g_num,gw_out-dat01,gw_out-dat02,gw_out-dat03,gw_out-dat04,gw_out-dat05,gw_out-dat06,
     789                         gw_out-dat07,gw_out-dat08,gw_out-dat09,gw_out-dat10,gw_out-dat11,gw_out-dat12.
     790             gw_out-ztype = 'C'.
     791             gw_out-ztext = 'NO-X建议供给数量'.
     792 
     793             do 12 times.
     794               clear:g_txt,l_num,l_txt.
     795               g_num = g_num + 1.
     796               g_txt = |GW_OUT-DAT{ g_num }|.
     797               assign (g_txt) to <fs>.
     798 
     799               if g_num = 01."第一列
     800                 l_num = g_num.
     801                 "NO-X供给
     802                 read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
     803                                                               werks = gw_out-werks
     804                                                               ztype = 'A'.
     805                 if sy-subrc eq 0.
     806                   l_txt = |<FS_OUT>-DAT{ l_num }|.
     807                   assign (l_txt) to <fs1>.
     808                   l_labst = <fs_out>-labst."库存
     809                   l_zsupl = <fs_out>-zsupl."供给
     810                   l_zreqd = <fs_out>-zreqd."需求
     811                 endif.
     812                 "NO-X需求
     813                 read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
     814                                                               werks = gw_out-werks
     815                                                               ztype = 'B'.
     816                 if sy-subrc eq 0.
     817                   l_txt = |<FS_OUT>-DAT{ l_num }|.
     818                   assign (l_txt) to <fs2>.
     819                 endif.
     820 
     821                 "第一列建议供给数量 = 非限制库存 + 过期供给 - 过期需求 + 第一列供给 - 第一列的需求
     822                 <fs> = l_labst + l_zsupl - l_zreqd + <fs1> - <fs2>.
     823               else.
     824                 l_num = g_num - 1.
     825                 "NO-X供给
     826                 read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
     827                                                               werks = gw_out-werks
     828                                                               ztype = 'A'.
     829                 if sy-subrc eq 0.
     830                   l_txt = |<FS_OUT>-DAT{ g_num }|.
     831                   assign (l_txt) to <fs1>.
     832                 endif.
     833                 "NO-X需求
     834                 read table gt_out assigning <fs_out> with key matnr = gw_out-matnr
     835                                                               werks = gw_out-werks
     836                                                               ztype = 'B'.
     837                 if sy-subrc eq 0.
     838                   l_txt = |<FS_OUT>-DAT{ g_num }|.
     839                   assign (l_txt) to <fs2>.
     840                 endif.
     841 
     842                 "前一列的NO-X建议供给数量
     843                 l_txt = |GW_OUT-DAT{ l_num }|.
     844                 assign (l_txt) to <fs3>.
     845 
     846                 "当前NO-X建议供给数量 = 前一列建议供给数 + 当前列供给 - 当前列需求
     847                 if <fs3> ge 0.
     848                   <fs> = abs( <fs3> ) + <fs1> - <fs2>.
     849                 else.
     850                   <fs> = <fs1> - <fs2>.
     851                 endif.
     852 
     853                 "判断建议数是否大于0,若大于0,清空;否则,取绝对值
     854                 if g_num = 12."最后一次循环,要判断最后两列
     855                   if <fs> gt 0.
     856                     clear <fs>.
     857                   else.
     858                     <fs> = abs( <fs> ).
     859                   endif.
     860 
     861                   if <fs3> gt 0.
     862                     clear <fs3>.
     863                   else.
     864                     <fs3> = abs( <fs3> ).
     865                   endif.
     866                 else."否则只要判断前一列
     867                   if <fs3> ge 0.
     868                     clear <fs3>.
     869                   else.
     870                     <fs3> = abs( <fs3> ).
     871                   endif.
     872                 endif.
     873 
     874               endif.
     875 
     876               "标识four,只要其中一列不为空
     877               if <fs> is not initial.
     878                 l_mark4 = 'X'.
     879               endif.
     880             enddo.
     881             append gw_out to gt_out.
     882         endcase.
     883       enddo.
     884 
     885       "删除为空记录
     886       if l_mark1 = 'X' and l_mark2 is initial and l_mark3 is initial and l_mark4 is initial.
     887         describe table gt_out lines l_lines.
     888         delete gt_out index l_lines.
     889         delete gt_out index l_lines - 1.
     890         delete gt_out index l_lines - 2.
     891       endif.
     892     endif.
     893   endif.
     894 
     895 endform.                    "frm_subroutine_done
     896 
     897 
     898 
     899 *&---------------------------------------------------------------------*
     900 *&      Form  frm_get_detail
     901 *&---------------------------------------------------------------------*
     902 *       text
     903 *----------------------------------------------------------------------*
     904 *      -->ALV        text
     905 *      -->MATNR      text
     906 *      -->WERKS      text
     907 *      -->FNAME      text
     908 *----------------------------------------------------------------------*
     909 form frm_get_detail tables alv  structure gw_dtl
     910                     using matnr type marc-matnr
     911                           werks type marc-werks
     912                           fname type slis_fieldname
     913                           type  type c.
     914 
     915   data: lt_mrp type standard table of bapi_mrp_items."计算-NO-X过期供给
     916   data: l_lgort type mard-lgort,
     917         l_auffx type plaf-auffx,
     918         l_mondy type d,
     919         l_sundy type d,
     920         l_times type i.
     921 
     922                                                             "获取MD04
     923   call function 'BAPI_MATERIAL_STOCK_REQ_LIST'
     924     exporting
     925       material         = matnr
     926       plant            = werks
     927       get_item_details = 'X'
     928       get_ind_lines    = 'X'
     929     tables
     930       mrp_items        = lt_mrp.
     931 
     932   case fname+0(2).
     933     when 'ZS'."供给
     934       delete lt_mrp where ( avail_date is initial ) or ( avail_date ge p_date ).
     935       delete lt_mrp where plngsegno is not initial or plus_minus ne '+' or rec_reqd_qty is initial.
     936 
     937       loop at lt_mrp assigning <fs_mrp>.
     938         clear:gw_dtl.
     939         if <fs_mrp>-storage_loc in s_lgort.
     940           if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
     941             continue.
     942           else.
     943             gw_dtl-werks = werks.
     944             gw_dtl-matnr = matnr.
     945             gw_dtl-zdate = <fs_mrp>-avail_date."日期
     946             "MRP元素
     947             select single delb0
     948               into gw_dtl-delb0
     949               from t457t
     950               where delkz = <fs_mrp>-mrp_element_ind
     951                 and spras = '1'.
     952 
     953             "MRP元素数据
     954             if <fs_mrp>-peggedrqmt is initial.
     955               gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
     956             else.
     957               gw_dtl-extra = <fs_mrp>-peggedrqmt.
     958             endif.
     959 
     960             "数量
     961             gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
     962             append gw_dtl to alv.
     963           endif.
     964         endif.
     965       endloop.
     966 
     967     when 'ZR'."需求
     968       delete lt_mrp where ( avail_date is initial ) or ( avail_date ge p_date ).
     969       delete lt_mrp where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.
     970 
     971       loop at lt_mrp assigning <fs_mrp>.
     972         clear:gw_dtl,l_lgort,l_auffx.
     973         case <fs_mrp>-order_type.
     974           when 'BB'."外协采购
     975             "到表EKPO中获取满足NO-X库存的
     976             select single lgort
     977               into l_lgort
     978               from ekpo
     979               where ebeln = <fs_mrp>-source_no
     980                 and ebelp = <fs_mrp>-source_item
     981                 and lgort in s_lgort.
     982 
     983             if sy-subrc eq 0.
     984               gw_dtl-werks = werks.
     985               gw_dtl-matnr = matnr.
     986               gw_dtl-zdate = <fs_mrp>-avail_date."日期
     987               "MRP元素
     988               select single delb0
     989                 into gw_dtl-delb0
     990                 from t457t
     991                 where delkz = <fs_mrp>-mrp_element_ind
     992                   and spras = '1'.
     993 
     994               "MRP元素数据
     995               if <fs_mrp>-peggedrqmt is initial.
     996                 gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
     997               else.
     998                 gw_dtl-extra = <fs_mrp>-peggedrqmt.
     999               endif.
    1000 
    1001               "数量
    1002               gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1003               append gw_dtl to alv.
    1004             endif.
    1005 
    1006           when 'SB'."计划订单-下阶
    1007             "到表PLAF中获取满足NO-X库存的
    1008             select single lgort auffx
    1009               into (l_lgort,l_auffx)
    1010               from plaf
    1011               where plnum = <fs_mrp>-source_no
    1012                 and lgort in s_lgort.
    1013 
    1014             if sy-subrc eq 0.
    1015               if l_auffx eq 'X'.
    1016                 gw_dtl-werks = werks.
    1017                 gw_dtl-matnr = matnr.
    1018                 gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1019                 "MRP元素
    1020                 select single delb0
    1021                   into gw_dtl-delb0
    1022                   from t457t
    1023                   where delkz = <fs_mrp>-mrp_element_ind
    1024                     and spras = '1'.
    1025 
    1026                 "MRP元素数据
    1027                 if <fs_mrp>-peggedrqmt is initial.
    1028                   gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1029                 else.
    1030                   gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1031                 endif.
    1032 
    1033                 "数量
    1034                 gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1035                 append gw_dtl to alv.
    1036               endif.
    1037             endif.
    1038 
    1039           when 'AR'."生产订单预留
    1040             "到表AFPO中获取满足NO-X库存的
    1041             select single lgort
    1042               into l_lgort
    1043               from afpo
    1044               where aufnr = <fs_mrp>-mrp_no12
    1045                 and lgort in s_lgort.
    1046 
    1047             if sy-subrc eq 0.
    1048               gw_dtl-werks = werks.
    1049               gw_dtl-matnr = matnr.
    1050               gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1051               "MRP元素
    1052               select single delb0
    1053                 into gw_dtl-delb0
    1054                 from t457t
    1055                 where delkz = <fs_mrp>-mrp_element_ind
    1056                   and spras = '1'.
    1057 
    1058               "MRP元素数据
    1059               if <fs_mrp>-peggedrqmt is initial.
    1060                 gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1061               else.
    1062                 gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1063               endif.
    1064 
    1065               "数量
    1066               gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1067               append gw_dtl to alv.
    1068             endif.
    1069 
    1070           when others.
    1071         endcase.
    1072       endloop.
    1073 
    1074     when 'DA'."期间
    1075       l_sundy = g_sundy.
    1076       l_times = fname+3(2) - 1.
    1077       do l_times times.
    1078         l_mondy = l_sundy + 1.
    1079         l_sundy = l_sundy + 7.
    1080       enddo.
    1081 
    1082       if type = 'A'."供给
    1083 
    1084         delete lt_mrp where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
    1085         delete lt_mrp where plngsegno is not initial or plus_minus ne '+' or rec_reqd_qty is initial.
    1086 
    1087         loop at lt_mrp assigning <fs_mrp>.
    1088           clear:gw_dtl.
    1089           if <fs_mrp>-storage_loc in s_lgort.
    1090             if <fs_mrp>-mrp_element_ind = 'PA' and <fs_mrp>-firmed ne 'X'.
    1091               continue.
    1092             else.
    1093               gw_dtl-werks = werks.
    1094               gw_dtl-matnr = matnr.
    1095               gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1096               "MRP元素
    1097               select single delb0
    1098                 into gw_dtl-delb0
    1099                 from t457t
    1100                 where delkz = <fs_mrp>-mrp_element_ind
    1101                   and spras = '1'.
    1102 
    1103               "MRP元素数据
    1104               if <fs_mrp>-peggedrqmt is initial.
    1105                 gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1106               else.
    1107                 gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1108               endif.
    1109 
    1110               "数量
    1111               gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1112               append gw_dtl to alv.
    1113             endif.
    1114           endif.
    1115         endloop.
    1116       elseif type = 'B'."需求
    1117         delete lt_mrp where ( avail_date gt l_sundy ) or ( avail_date lt l_mondy ).
    1118         delete lt_mrp where plngsegno is not initial or plus_minus ne '-' or rec_reqd_qty is initial.
    1119 
    1120         loop at lt_mrp assigning <fs_mrp>.
    1121           clear:gw_dtl,l_lgort,l_auffx.
    1122           case <fs_mrp>-order_type.
    1123             when 'BB'."外协采购
    1124               "到表EKPO中获取满足NO-X库存的
    1125               select single lgort
    1126                 into l_lgort
    1127                 from ekpo
    1128                 where ebeln = <fs_mrp>-source_no
    1129                   and ebelp = <fs_mrp>-source_item
    1130                   and lgort in s_lgort.
    1131 
    1132               if sy-subrc eq 0.
    1133                 gw_dtl-werks = werks.
    1134                 gw_dtl-matnr = matnr.
    1135                 gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1136                 "MRP元素
    1137                 select single delb0
    1138                   into gw_dtl-delb0
    1139                   from t457t
    1140                   where delkz = <fs_mrp>-mrp_element_ind
    1141                     and spras = '1'.
    1142 
    1143                 "MRP元素数据
    1144                 if <fs_mrp>-peggedrqmt is initial.
    1145                   gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1146                 else.
    1147                   gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1148                 endif.
    1149 
    1150                 "数量
    1151                 gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1152                 append gw_dtl to alv.
    1153               endif.
    1154 
    1155             when 'SB'."计划订单-下阶
    1156               "到表PLAF中获取满足NO-X库存的
    1157               select single lgort auffx
    1158                 into (l_lgort,l_auffx)
    1159                 from plaf
    1160                 where plnum = <fs_mrp>-source_no
    1161                   and lgort in s_lgort.
    1162 
    1163               if sy-subrc eq 0.
    1164                 if l_auffx eq 'X'.
    1165                   gw_dtl-werks = werks.
    1166                   gw_dtl-matnr = matnr.
    1167                   gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1168                   "MRP元素
    1169                   select single delb0
    1170                     into gw_dtl-delb0
    1171                     from t457t
    1172                     where delkz = <fs_mrp>-mrp_element_ind
    1173                       and spras = '1'.
    1174 
    1175                   "MRP元素数据
    1176                   if <fs_mrp>-peggedrqmt is initial.
    1177                     gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1178                   else.
    1179                     gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1180                   endif.
    1181 
    1182                   "数量
    1183                   gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1184                   append gw_dtl to alv.
    1185                 endif.
    1186               endif.
    1187 
    1188             when 'AR'."生产订单预留
    1189               "到表AFPO中获取满足NO-X库存的
    1190               select single lgort
    1191                 into l_lgort
    1192                 from afpo
    1193                 where aufnr = <fs_mrp>-mrp_no12
    1194                   and lgort in s_lgort.
    1195 
    1196               if sy-subrc eq 0.
    1197                 gw_dtl-werks = werks.
    1198                 gw_dtl-matnr = matnr.
    1199                 gw_dtl-zdate = <fs_mrp>-avail_date."日期
    1200                 "MRP元素
    1201                 select single delb0
    1202                   into gw_dtl-delb0
    1203                   from t457t
    1204                   where delkz = <fs_mrp>-mrp_element_ind
    1205                     and spras = '1'.
    1206 
    1207                 "MRP元素数据
    1208                 if <fs_mrp>-peggedrqmt is initial.
    1209                   gw_dtl-extra = |{ <fs_mrp>-mrp_no }/{ <fs_mrp>-mrp_pos }|.
    1210                 else.
    1211                   gw_dtl-extra = <fs_mrp>-peggedrqmt.
    1212                 endif.
    1213 
    1214                 "数量
    1215                 gw_dtl-mng01 = <fs_mrp>-rec_reqd_qty.
    1216                 append gw_dtl to alv.
    1217               endif.
    1218 
    1219             when others.
    1220           endcase.
    1221         endloop.
    1222       endif.
    1223 
    1224     when others.
    1225 
    1226   endcase.
    1227 
    1228 endform.                    "frm_get_detail
    1229 
    1230 *&---------------------------------------------------------------------*
    1231 *&      Form  frm_get_text
    1232 *&---------------------------------------------------------------------*
    1233 *       获取提示文本
    1234 *----------------------------------------------------------------------*
    1235 *      -->PERCENT    text
    1236 *      -->TEXT       text
    1237 *----------------------------------------------------------------------*
    1238 form frm_get_text using percent type i
    1239                         text    type string.
    1240 
    1241   call function 'SAPGUI_PROGRESS_INDICATOR'
    1242     exporting
    1243       percentage = percent
    1244       text       = text.
    1245 
    1246 endform.                    "frm_get_text
    1247 
    1248 *&---------------------------------------------------------------------*
    1249 *&      Form  frm_get_event
    1250 *&---------------------------------------------------------------------*
    1251 *       text
    1252 *----------------------------------------------------------------------*
    1253 form frm_get_event .
    1254   data l_events type slis_alv_event."slis_alv_event是一个包含name和form字段的结构,均为字符型
    1255 
    1256   call function 'REUSE_ALV_EVENTS_GET'
    1257     exporting
    1258       i_list_type     = 0
    1259     importing
    1260       et_events       = gt_events
    1261     exceptions
    1262       list_type_wrong = 1
    1263       others          = 2.
    1264   if sy-subrc <> 0.
    1265     message id sy-msgid type sy-msgty number sy-msgno
    1266            with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    1267   endif.
    1268 
    1269 endform.                    "frm_get_event
    1270 
    1271 *&---------------------------------------------------------------------*
    1272 *&      Form  frm_sort_build
    1273 *&---------------------------------------------------------------------*
    1274 *       输出排序设置
    1275 *----------------------------------------------------------------------*
    1276 *      -->LT_SORT    text
    1277 *----------------------------------------------------------------------*
    1278 form frm_sort_build changing lt_sort type slis_t_sortinfo_alv.
    1279   data: ls_sort type slis_sortinfo_alv.
    1280   refresh lt_sort.
    1281 
    1282   clear ls_sort.
    1283   ls_sort-spos = 1.
    1284   ls_sort-fieldname = 'WERKS'.
    1285   ls_sort-up   = 'X'.
    1286   append ls_sort to lt_sort.
    1287 
    1288   clear ls_sort.
    1289   ls_sort-spos = 2.
    1290   ls_sort-fieldname = 'DISPO'.
    1291   ls_sort-up   = 'X'.
    1292   append ls_sort to lt_sort.
    1293 
    1294   clear ls_sort.
    1295   ls_sort-spos = 3.
    1296   ls_sort-fieldname = 'MATNR'.
    1297   ls_sort-up   = 'X'.
    1298   append ls_sort to lt_sort.
    1299 
    1300   clear ls_sort.
    1301   ls_sort-spos = 4.
    1302   ls_sort-fieldname = 'MEINS'.
    1303   ls_sort-up   = 'X'.
    1304   append ls_sort to lt_sort.
    1305 
    1306   clear ls_sort.
    1307   ls_sort-spos = 5.
    1308   ls_sort-fieldname = 'MAKTX'.
    1309   ls_sort-up   = 'X'.
    1310   append ls_sort to lt_sort.
    1311 
    1312 endform.                    "frm_sort_build
    1313 
    1314 *&---------------------------------------------------------------------*
    1315 *&      Form  frm_init_layout
    1316 *&---------------------------------------------------------------------*
    1317 *       布局设置
    1318 *----------------------------------------------------------------------*
    1319 form frm_init_layout.
    1320   gw_layout-zebra  = 'X'."间隔行颜色变换
    1321   gw_layout-detail_popup = 'X'.
    1322   gw_layout-colwidth_optimize = 'X'."自动调整列宽
    1323 
    1324 endform.                    " FRM_INIT_LAYOUT
    1325 
    1326 *&---------------------------------------------------------------------*
    1327 *&      Form  frm_fcat_setting
    1328 *&---------------------------------------------------------------------*
    1329 *       设置输出字段
    1330 *----------------------------------------------------------------------*
    1331 form frm_fcat_setting.
    1332   data: l_num type n length 2,
    1333         l_txt type c length 20,"字段
    1334         l_dis type c length 20,"描述
    1335         l_mondy type d,
    1336         l_sundy type d.
    1337   refresh gt_fieldcat.
    1338 
    1339   perform frm_init_fieldcat using 'WERKS' '工厂'           'X' 'X' ' ' ' ' ' '.
    1340   perform frm_init_fieldcat using 'DISPO' 'MRP控制员'      'X' 'X' ' ' ' ' ' '.
    1341   perform frm_init_fieldcat using 'MATNR' '物料号'         'X' 'X' ' ' 'X' ' '.
    1342   perform frm_init_fieldcat using 'MEINS' '单位'           'X' 'X' ' ' ' ' ' '.
    1343   perform frm_init_fieldcat using 'MAKTX' '物料描述'       'X' 'X' ' ' ' ' ' '.
    1344   perform frm_init_fieldcat using 'LABST' 'NO-X非限制库存' 'X' 'X' ' ' 'X' ' '.
    1345   perform frm_init_fieldcat using 'ZSUPL' 'NO-X过期供给'   'X' 'X' 'X' 'X' ' '.
    1346   perform frm_init_fieldcat using 'ZREQD' 'NO-X过期需求'   'X' 'X' 'X' 'X' ' '.
    1347   perform frm_init_fieldcat using 'ZTEXT' '期间'           'X' 'X' ' ' ' ' ' '.
    1348   "动态输出期间字段
    1349   clear:l_num,l_txt,l_dis.
    1350   l_mondy = g_mondy.
    1351   l_sundy = g_sundy.
    1352   do 12 times.
    1353     l_num = l_num + 1.
    1354     l_txt = |DAT{ l_num }|.
    1355     l_dis = |{ l_mondy }-{ l_sundy }|.
    1356     perform frm_init_fieldcat using l_txt l_dis ' ' ' ' 'X' 'X' ' '.
    1357     l_mondy = l_sundy + 1.
    1358     l_sundy = l_sundy + 7.
    1359   enddo.
    1360 
    1361 endform.                    "frm_fcat_setting
    1362 
    1363 *&---------------------------------------------------------------------*
    1364 *&      Form  frm_init_fieldcat
    1365 *&---------------------------------------------------------------------*
    1366 *      初始化输出字段
    1367 *----------------------------------------------------------------------*
    1368 *      -->VALU01     text
    1369 *      -->VALU02     text
    1370 *      -->VALU03     text
    1371 *      -->VALU04     text
    1372 *      -->VALU05     text
    1373 *      -->VALU06     text
    1374 *      -->VALU07     text
    1375 *----------------------------------------------------------------------*
    1376 form frm_init_fieldcat using valu01
    1377                              valu02
    1378                              valu03
    1379                              valu04
    1380                              valu05
    1381                              valu06
    1382                              valu07.
    1383 
    1384   clear:gt_fieldcat.
    1385   gt_fieldcat-fieldname  = valu01."字段名
    1386   gt_fieldcat-seltext_m  = valu02."字段描述
    1387   gt_fieldcat-key        = valu03."主键
    1388   gt_fieldcat-fix_column = valu04."固定列
    1389   gt_fieldcat-hotspot    = valu05."热点
    1390   gt_fieldcat-no_zero    = valu06."隐藏前导零
    1391   gt_fieldcat-no_sign    = valu07."符号
    1392   append gt_fieldcat.
    1393 
    1394 endform.                    "frm_set_fcat
    1395 
    1396 
    1397 *&---------------------------------------------------------------------*
    1398 *&      Form  frm_output
    1399 *&---------------------------------------------------------------------*
    1400 *       text
    1401 *----------------------------------------------------------------------*
    1402 *      -->TAB        text
    1403 *----------------------------------------------------------------------*
    1404 form frm_output tables tab.
    1405 *ALV输出
    1406   g_repid = sy-repid.
    1407 
    1408   call function 'REUSE_ALV_GRID_DISPLAY'
    1409     exporting
    1410       i_callback_program      = g_repid
    1411       is_layout               = gw_layout
    1412       it_fieldcat             = gt_fieldcat[]
    1413       i_save                  = 'X'
    1414       is_variant              = gw_stru_disvar"变量信息
    1415       it_events               = gt_events[]
    1416       it_sort                 = gt_sort[]
    1417       i_callback_user_command = 'FRM_USER_COMMAND'
    1418     tables
    1419       t_outtab                = tab
    1420     exceptions
    1421       program_error           = 1
    1422       others                  = 2.
    1423   if sy-subrc <> 0.
    1424     message id sy-msgid type sy-msgty number sy-msgno
    1425             with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    1426   endif.
    1427 endform.                    "frm_output
    1428 
    1429 *&---------------------------------------------------------------------*
    1430 *&      Form  FRM_USER_COMMAND
    1431 *&---------------------------------------------------------------------*
    1432 *       事件处理
    1433 *----------------------------------------------------------------------*
    1434 *      -->R_UCOMM      text
    1435 *      -->RS_SELFIELD  text
    1436 *----------------------------------------------------------------------*
    1437 form frm_user_command using r_ucomm like sy-ucomm
    1438                             rs_selfield type slis_selfield.
    1439 
    1440   clear:gt_dtl.
    1441   case r_ucomm.
    1442     when '&IC1'.
    1443       read table gt_out assigning <fs_out> index rs_selfield-tabindex.
    1444       if rs_selfield-fieldname = 'ZSUPL' or rs_selfield-fieldname = 'ZREQD'."供给/需求
    1445         perform frm_get_detail tables gt_dtl
    1446                                using <fs_out>-matnr
    1447                                      <fs_out>-werks
    1448                                      rs_selfield-fieldname
    1449                                      <fs_out>-ztype.
    1450 
    1451         if gt_dtl is not initial.
    1452           call screen 0100 starting at 30 5.
    1453         endif.
    1454       else.
    1455         if rs_selfield-fieldname+0(3) = 'DAT'.
    1456           perform frm_get_detail tables gt_dtl
    1457                                  using <fs_out>-matnr
    1458                                        <fs_out>-werks
    1459                                        rs_selfield-fieldname
    1460                                        <fs_out>-ztype.
    1461 
    1462           if gt_dtl is not initial.
    1463             call screen 0100 starting at 30 5.
    1464           endif.
    1465         endif.
    1466       endif.
    1467 
    1468     when others.
    1469   endcase.
    1470 endform.                    "FRM_USER_COMMAND
    1471 
    1472 *&---------------------------------------------------------------------*
    1473 *&      Form  frm_set_fcat
    1474 *&---------------------------------------------------------------------*
    1475 *       输出字段设置
    1476 *----------------------------------------------------------------------*
    1477 form frm_set_fcat.
    1478   if gt_fcat is initial.
    1479     clear: gw_fcat.
    1480     gw_fcat-col_pos    = 1.
    1481     gw_fcat-fieldname  = 'WERKS'.
    1482     gw_fcat-tabname    = 'MARC'.
    1483     gw_fcat-scrtext_m  = '工厂'.
    1484     append gw_fcat to gt_fcat.
    1485 
    1486     clear: gw_fcat.
    1487     gw_fcat-col_pos    = 2.
    1488     gw_fcat-fieldname  = 'MATNR'.
    1489     gw_fcat-tabname    = 'MARC'.
    1490     gw_fcat-scrtext_m  = '物料'.
    1491     gw_fcat-no_zero    = 'X'.
    1492     append gw_fcat to gt_fcat.
    1493 
    1494     clear: gw_fcat.
    1495     gw_fcat-col_pos    = 3.
    1496     gw_fcat-fieldname  = 'ZDATE'.
    1497     gw_fcat-scrtext_m  = '日期'.
    1498     append gw_fcat to gt_fcat.
    1499 
    1500     clear: gw_fcat.
    1501     gw_fcat-col_pos    = 4.
    1502     gw_fcat-fieldname  = 'DELB0'.
    1503     gw_fcat-tabname    = 'T457T'.
    1504     gw_fcat-scrtext_m  = 'MRP元素'.
    1505     append gw_fcat to gt_fcat.
    1506 
    1507     clear: gw_fcat.
    1508     gw_fcat-col_pos    = 5.
    1509     gw_fcat-fieldname  = 'EXTRA'.
    1510     gw_fcat-tabname    = 'MDEZ'.
    1511     gw_fcat-scrtext_m  = 'MRP元素数据'.
    1512     gw_fcat-fix_column = 'X'.
    1513     append gw_fcat to gt_fcat.
    1514 
    1515     clear: gw_fcat.
    1516     gw_fcat-col_pos    = 6.
    1517     gw_fcat-fieldname  = 'MNG01'.
    1518     gw_fcat-tabname    = 'MDEZ'.
    1519     gw_fcat-scrtext_m  = '收货数量或需求数量'.
    1520     gw_fcat-fix_column = 'X'.
    1521     gw_fcat-do_sum     = 'X'.
    1522     append gw_fcat to gt_fcat.
    1523   endif.
    1524 endform.                    "frm_set_fcat
    1525 
    1526 *&---------------------------------------------------------------------*
    1527 *&      Form  frm_set_lock
    1528 *&---------------------------------------------------------------------*
    1529 *       上锁
    1530 *----------------------------------------------------------------------*
    1531 form frm_set_lock.
    1532   "锁定程序
    1533   call function 'ENQUEUE_EZZSOPR0032'
    1534     exporting
    1535       mode_trdir     = 'E'
    1536       name           = 'ZPPR0056'
    1537       x_name         = ' '
    1538       _scope         = '2'
    1539       _wait          = ' '
    1540       _collect       = ' '
    1541     exceptions
    1542       foreign_lock   = 1
    1543       system_failure = 2
    1544       others         = 3.
    1545 
    1546   if sy-subrc <> 0.
    1547 * Implement suitable error handling here
    1548     message '对象已被锁定,请稍后执行' type 'S' display like 'E'.
    1549     stop.
    1550   else.
    1551     "锁定成功
    1552   endif.
    1553 endform.                    "frm_set_lock
    1554 
    1555 *&---------------------------------------------------------------------*
    1556 *&      Form  frm_set_unlock
    1557 *&---------------------------------------------------------------------*
    1558 *       解锁
    1559 *----------------------------------------------------------------------*
    1560 form frm_set_unlock.
    1561   "解除程序的锁定
    1562   call function 'DEQUEUE_EZZSOPR0032'
    1563     exporting
    1564       mode_trdir = 'E'
    1565       name       = 'ZPPR0056'
    1566       x_name     = ' '
    1567       _scope     = '3'
    1568       _synchron  = ' '
    1569       _collect   = ' '.
    1570 endform.                    "frm_set_unlock
    1571 
    1572 *&---------------------------------------------------------------------*
    1573 *&      Module  STATUS_0100  OUTPUT
    1574 *&---------------------------------------------------------------------*
    1575 *       text
    1576 *----------------------------------------------------------------------*
    1577 module status_0100 output.
    1578   set pf-status 'ZSTA1'.
    1579 *  SET TITLEBAR 'xxx'.
    1580   create object g_alv.
    1581   g_alv->main( ).
    1582 endmodule.                 " STATUS_0100  OUTPUT
    1583 
    1584 *&---------------------------------------------------------------------*
    1585 *&      Module  EXIT  INPUT
    1586 *&---------------------------------------------------------------------*
    1587 *       text
    1588 *----------------------------------------------------------------------*
    1589 module exit input.
    1590   leave to screen 0.
    1591 
    1592 endmodule.                 " EXIT  INPUT
    View Code
     (备注:参考来源 http://blog.csdn.net/zhongguomao/article/details/8963815 )
     
  • 相关阅读:
    典型漏洞归纳之上传漏洞
    典型漏洞归纳之解析漏洞
    Python学习目录
    MySQL数据库优化的八种方式
    深度剖析Flask上下文管理机制
    算法十大排序(含动图)
    设计模式代码实例
    设计模式
    数据结构
    算法基础
  • 原文地址:https://www.cnblogs.com/qlb8268/p/3606061.html
Copyright © 2020-2023  润新知