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 )
 
posted @ 2014-03-17 20:28  封~  阅读(10545)  评论(1编辑  收藏  举报