通过俄罗斯报表完成库存账龄报告 二

目录

业务需求:

已经完成任务:

第二部分计算逻辑

批次管理物料

期初期末表更新:

非批次汇总表更新

非批次管理物料

生成非批次物料全局“收货记录表”

起初期末表更新:

“非批次”选项 零件号汇总表:

第三部分 任务拆分:

批次物料期初期末表更新

增加数据定义

增加fieldcat

增加字段内容

非批次物料期初期末表更新

期末库存零件号收货退货期初库存中间表 

生成全局“收货记录表”

修改期初期末全局表的非批次物料

全部代码:

学到的技术

运行结果:


业务需求:

接上一篇

基于俄罗斯报表J3RFLVMOBVEDH生成库龄表-CSDN博客

已经完成任务:

第一部分报表已经完成. 

结果:

通过俄罗斯报表完成库存账龄报告 二_第1张图片

第二部分计算逻辑

由于俄罗斯报表输出已经进行汇总,因此第二部分报告计算过程中,不考虑效率问题。

批次管理物料

期初期末表更新:

对于有批次管理的物料增加字段:sap批次时间,生产时间, 过期时间, 天数计算日期 库存天数。

天数计算时间原则采用生产时间,

        如果生产时间为空,采用SAP批次时间,

 库存天数: 期末时间-天数计算时间 (生产时间为空时用SAP批次时间)

非批次汇总表更新

从起初期末表中不考虑批次进行汇总。

数量根据天数和对应的账龄天数进行汇总填入对应账龄区间。

单价 = 期末金额 / 期末数量。

金额 = 数量 * 单价

非批次管理物料

生成非批次物料全局“收货记录表”

非批次管理物料,按照零件号循环生成局部变量表“零件号收货记录表”。 按照下面Excel表逻辑每条记录进行循环 (零件号loop嵌套收货记录表表loop)并写入全局表“非批次物料收货记录表”。

excel表模拟:

零件号收货记录表 零件号循环数据 计算数据 计算数据 计算数据 判断 if false
收货日期 数量 期末日期 期末库存 已收货天数 收货累积数量 账龄表数量 =  数量 期末库存> 收货累积数量 账龄表数量 = 数量-(收货累积数量 - 期末库存) 后续操作
2023-11-16 -20 2023-11-30 100 14 -20 -20 TRUE   写入非批次物料收货记录全局表
2023-11-15 20 2023-11-30 100 15 0 20 TRUE   写入非批次物料收货记录全局表
2023-10-15 19 2023-11-30 100 46 19 19 TRUE   写入非批次物料收货记录全局表
2023-9-15 18 2023-11-30 100 76 37 18 TRUE   写入非批次物料收货记录全局表
2023-8-15 17 2023-11-30 100 107 54 17 TRUE   写入非批次物料收货记录全局表
2023-7-15 16 2023-11-30 100 138 70 16 TRUE   写入非批次物料收货记录全局表
2023-6-15 15 2023-11-30 100 168 85 15 TRUE   写入非批次物料收货记录全局表
2023-5-15 14 2023-11-30 100 199 99 14 TRUE   写入非批次物料收货记录全局表
2023-4-15 13 2023-11-30 100 229 112 13 FALSE 1 写入非批次物料收货记录全局表 退出循环
2023-3-15 12 2023-11-30 100 260 124      
2023-2-15 11 2023-11-30 100 288 135      
2023-1-15 10 2023-11-30 100 319 145      

零件号循环

  从matdoc表读取数据 生成收货记录中间表:零件号,过账日期小于期末时间  移动类型101/102/561。 

  记录表内容:凭证号,零件号,移动类型,数量,增加列“期末日期”,“期末库存”,  “已收货天数”, “已收货累积数量”,“账龄表数量”,“期末库存待消耗数量”

  按照过账日期倒排。

        零件号收货记录表循环:

                期末日期 = 零件号循环-期末日期

                期末库存 = -期末库存

                已收货天数 = 期末日期 - 收货日期。

                已收货累积数量 = 已收货累积数量 + 数量

                账龄表数量 = 数量

                if  期末库存> 收货累积数量  ,     数据写入全局表。

                else if  期末库存= 收货累积数量 , 数据写入全局表, 退出循环。

                else 期末库存< 收货累积数量 ,  账龄表数量 = 数量 - (收货累积数量 - 期末库存) 数据写入全局表,退出循环。

退出零件号循环

非批次物料全局收货表,按照批次物料处理方式,填写相关账龄数量,计算金额。

起初期末表更新:

零件号循环,

取“全局收货表”中最早的收货的时间和库存天数,写入到字段:“天数计算日期” , “库存天数”

“非批次”选项 零件号汇总表:

从起初期末表中读入相关信息。

“全局收货表”循环,

        数量根据天数和对应的账龄天数进行汇总填入对应账龄区间。

        单价 = 期末金额 / 期末数量。

        金额 = 数量 * 单价

第三部分 程序实现:

 参照csdn博客:

PT项目-SAP库存账龄分析报表_sap存货账龄代码-CSDN博客

第三部分 任务拆分:

1,批次物料明细表增加日期字段:sap批次时间,生产时间, 过期时间, 天数计算时间 库存天数

2,非批次物料生成收货计算全局表,包含关键字段,库存天数,数量。

3,组合成账龄表单 (不显示批次)

批次物料期初期末表更新

在gt_qcqm表单上增加字段,(不单独生成表单)

变量名 内表 中文描述 数据元素 查询表单 表单字段 计算逻辑
ERSDA GT_QCQM 创建日期 ERSDA MCH1 ERSDA  
HSDAT GT_QCQM 生产日期 HSDAT MCH1 HSDAT  
VFDAT GT_QCQM 过期日期 VFDAT MCH1 VFDAT  
ZDATE_FOR_CACU GT_QCQM 天数计算日期       首选HSDAT, 其次 ERSDA,
ZDURATION_DAYS GT_QCQM 库存天数       期末日期 - Zdate_for_cacu

增加数据定义

增加fieldcat

通过俄罗斯报表完成库存账龄报告 二_第2张图片

layout选择之后:

通过俄罗斯报表完成库存账龄报告 二_第3张图片

增加字段内容

perform paint_gt_qcqm_batch_material.

FORM paint_gt_qcqm_batch_material .

  LOOP  AT gt_qcqm ASSIGNING FIELD-SYMBOL().
    IF NOT -charg IS INITIAL AND -ersda IS INITIAL  .
      SELECT SINGLE  ersda hsdat vfdat
        FROM mch1
        INTO CORRESPONDING FIELDS OF 
        WHERE matnr = -matnr
        AND charg = -charg   .

      IF NOT -hsdat IS INITIAL.
        -zdate_for_cacu = -hsdat .
      ELSE.
        -zdate_for_cacu = -ersda .
      ENDIF.
      -zduration_days = g_last_datum - -zdate_for_cacu + 1.

      MODIFY gt_qcqm FROM 
      TRANSPORTING ersda hsdat vfdat zdate_for_cacu zduration_days
      WHERE matnr = -matnr AND charg = -charg.
    ENDIF.

    IF -lgobe IS INITIAL.
      SELECT SINGLE lgobe FROM t001l
        INTO -lgobe
        WHERE werks = -werks
        AND lgort = -lgort .

      MODIFY gt_qcqm FROM 
      TRANSPORTING lgobe
       WHERE werks = -werks
        AND lgort = -lgort .
    ENDIF.

  ENDLOOP.
UNASSIGN .
ENDFORM.

非批次物料期初期末表更新

perform paint_gt_qcqm_nonbatchmat.

非批次物料增加 zdate_for_cacu, 和 zduration_days.  

从全局表 “收货记录表” 中获得 zdate_for_cacu 和 zduration_days.

生成期末库存中间表。

FORM get_nonbatchmat_total_endstock .

期末库存总数量中间表  lt_nonbatch_endstock

统计期末库存中间
公司 工厂 零件号 期末数量 期末日期
6000 6000 1040000 100

2023-11-30

         全局期初期末表生成 =>局部表 lt_qcqm_temp

              删除有批次号的行, 删除期末数量为0 的行。

              根据零件号排序。

              temp表 循环,按照零件号累加数量。

TYPES:BEGIN OF ty_nonbatch_endstock ,  "期初期末
          bukrs           TYPE bukrs, "company
          werks           TYPE werks_d,     "plang
          matnr           TYPE matnr   ,   "物料编码.
          meins           TYPE     meins  ,      " 基本基本计量
          zenddate        TYPE budat,  " 从全局变量g_last_datum 获取。
          ztotal_endstock TYPE   j_3rm_endstock , "期末库存数量 stock quantity on period end.
        END OF ty_nonbatch_endstock.
  DATA:ls_nonbatch_endstock TYPE ty_nonbatch_endstock.
  DATA:lt_nonbatch_endstock LIKE TABLE OF ls_nonbatch_endstock.

  DATA(lt_qcqm_temp) = gt_qcqm.

  DELETE lt_qcqm_temp WHERE NOT charg IS INITIAL.
  DELETE lt_qcqm_temp WHERE zqmkcsl EQ 0.
  SORT lt_qcqm_temp BY matnr.

  DATA last_matnr TYPE matnr.
  FREE: last_matnr, ls_nonbatch_endstock, lt_nonbatch_endstock.

  LOOP AT lt_qcqm_temp ASSIGNING FIELD-SYMBOL().
    IF last_matnr IS INITIAL.
      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.
      last_matnr = -matnr.
    ELSEIF last_matnr = -matnr.
      ls_nonbatch_endstock-ztotal_endstock = ls_nonbatch_endstock-ztotal_endstock + -zqmkcsl.
    ELSEIF last_matnr NE -matnr.

      COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.

    ENDIF.
  ENDLOOP.
  COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

期末库存零件号收货退货期初库存中间表 

从matdoc中select 


  DATA(lt_gr_nonbatch) = gt_gr_nonbatch.
  FREE lt_gr_nonbatch.

  SELECT * FROM matdoc
    INTO  CORRESPONDING FIELDS OF TABLE lt_gr_nonbatch
    FOR ALL ENTRIES IN lt_nonbatch_endstock
    WHERE matnr = lt_nonbatch_endstock-matnr
    AND budat <= g_last_datum
    AND ( bwart = 101
    OR     bwart = 102
    OR     bwart = 561 ) .

生成全局“收货记录表”

双重循环。方案如计算逻辑的excel表。FIFO逻辑的最早收货时间,和最长时间写入收货记录表表。

代码:

* 生成 非批次物料收货记录全局表
*零件号循环 lt_nonbatch_endstock
*  lt_gr_nonbatch表中数据写入临时表 lt_grpermat。
*  记录表内容:凭证号,零件号,移动类型,数量,增加列“期末日期”,“期末库存”,  “已收货天数”, “已收货累积数量”,“账龄表数量”,“期末库存待消耗数量”
*  删除零件号与循环不相同的数据。
* lt_grpermat 按照过账日期倒排。
*       lt_grperpmat记录表循环:
*                 zenddat 期末日期
*                 期末库存 = -期末库存
*                已收货天数 = 期末日期 - 收货日期+1 。
*                已收货累积数量 = 已收货累积数量 + 数量
*                 账龄表数量 = 数量
*                if  期末库存> 收货累积数量  ,     数据写入全局表。
*                else if  期末库存= 收货累积数量 , 数据写入全局表, 退出循环。
*                else 期末库存< 收货累积数量 ,  账龄表数量 = 数量 - (收货累积数量 - 期末库存) 数据写入全局表,退出循环。
*退出零件号循环
*  需要写入到qcqm表中的计算日期和duration days 在collect到表中和退出循环前,对之前的相同零件号统一修改。


  LOOP AT  lt_nonbatch_endstock ASSIGNING FIELD-SYMBOL().
    DATA(lt_grpermat) = lt_gr_nonbatch.
    DELETE lt_grpermat WHERE matnr NE -matnr.
    SORT lt_grpermat BY budat DESCENDING.
    LOOP AT  lt_grpermat ASSIGNING FIELD-SYMBOL().
      -zqty_cum = gs_gr_nonbatch-zqty_cum.
      MOVE-CORRESPONDING  TO gs_gr_nonbatch.
      gs_gr_nonbatch-zenddate = g_last_datum.
      gs_gr_nonbatch-ztotal_endstock  = -ztotal_endstock.
      gs_gr_nonbatch-zduration_days = g_last_datum - -budat + 1 .
      gs_gr_nonbatch-zqty_cum = gs_gr_nonbatch-zqty_cum + -stock_qty .
      gs_gr_nonbatch-zqty_consum = -stock_qty .

      IF gs_gr_nonbatch-ztotal_endstock >  gs_gr_nonbatch-zqty_cum.
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
      ELSEIF gs_gr_nonbatch-ztotal_endstock =  gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch from gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration where matnr = -matnr.
        FREE gs_gr_nonbatch.
        EXIT.
      ELSEIF gs_gr_nonbatch-ztotal_endstock < gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zqty_consum = -stock_qty - ( gs_gr_nonbatch-zqty_cum - gs_gr_nonbatch-ztotal_endstock  ).
         gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch from gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration where matnr = -matnr.
        FREE gs_gr_nonbatch.
        EXIT.
      ENDIF.
    ENDLOOP.
  ENDLOOP.

修改期初期末全局表的非批次物料

这个表的源数据来自俄罗斯报表。在计算日期,写入最早消耗收货时间,天数写入最长时间。

这个本来计划在期初期末表中循环的。在实现过程中发现,可以在“生成全局收货记录表”的第一个循环内做完。

对每个循环的物料号,

        填写gs_qcqm 的计算日期<==最早消耗收货时间,天数<==最长时间

        modify gt_qcqm.  where 零件号相同。

        上面代码的free 语句修改位置。

修改后的代码如下: 子例程结构做响应调整。

FORM paint_gt_qcqm_nonbatchmat .

*&*  生成期末库存总数量中间表 lt_nonbatch_endstock
*&
*&*公司 工厂  零件号 期末数量  期末日期
*&*6000 6000  1040000 100 2023-11-30
*&*         全局期初期末表生成 =>局部表 lt_qcqm_temp
*&*&              删除有批次号的行, 删除期末数量为0 的行。
*&*&              根据零件号排序。
*&*&              temp表 循环,按照零件号累加数量。
*&                  collect 对应数据到 lt_nonbatch_endstock 表中。



  TYPES:BEGIN OF ty_nonbatch_endstock ,  "期初期末
          bukrs           TYPE bukrs, "company
          werks           TYPE werks_d,     "plang
          matnr           TYPE matnr   ,   "物料编码.
          meins           TYPE     meins  ,      " 基本基本计量
          zenddate        TYPE budat,  " 从全局变量g_last_datum 获取。
          ztotal_endstock TYPE   j_3rm_endstock , "期末库存数量 stock quantity on period end.
        END OF ty_nonbatch_endstock.
  DATA:ls_nonbatch_endstock TYPE ty_nonbatch_endstock.
  DATA:lt_nonbatch_endstock LIKE TABLE OF ls_nonbatch_endstock.

  DATA(lt_qcqm_temp) = gt_qcqm.

  DELETE lt_qcqm_temp WHERE NOT charg IS INITIAL.
  DELETE lt_qcqm_temp WHERE zqmkcsl EQ 0.
  SORT lt_qcqm_temp BY matnr.

  DATA last_matnr TYPE matnr.
  FREE: last_matnr, ls_nonbatch_endstock, lt_nonbatch_endstock.

  LOOP AT lt_qcqm_temp ASSIGNING FIELD-SYMBOL().
    IF last_matnr IS INITIAL.
      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.
      last_matnr = -matnr.
    ELSEIF last_matnr = -matnr.
      ls_nonbatch_endstock-ztotal_endstock = ls_nonbatch_endstock-ztotal_endstock + -zqmkcsl.
    ELSEIF last_matnr NE -matnr.

      COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.

    ENDIF.
  ENDLOOP.
  COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

*&*  非批次管理物料,按照零件号lt_nonbatch_endstock 的零件号select matdoc表中的收货记录 101 /102  / 561
*&
*&*

  DATA(lt_gr_nonbatch) = gt_gr_nonbatch.
  FREE lt_gr_nonbatch.

  SELECT * FROM matdoc
    INTO  CORRESPONDING FIELDS OF TABLE lt_gr_nonbatch
    FOR ALL ENTRIES IN lt_nonbatch_endstock
    WHERE matnr = lt_nonbatch_endstock-matnr
    AND budat <= g_last_datum
    AND ( bwart = 101
    OR     bwart = 102
    OR     bwart = 561 ) .

* 生成 非批次物料收货记录全局表
*零件号循环 lt_nonbatch_endstock
*  lt_gr_nonbatch表中数据写入临时表 lt_grpermat。
*  记录表内容:凭证号,零件号,移动类型,数量,增加列“期末日期”,“期末库存”,  “已收货天数”, “已收货累积数量”,“账龄表数量”,“期末库存待消耗数量”
*  删除零件号与循环不相同的数据。
* lt_grpermat 按照过账日期倒排。
*       lt_grperpmat记录表循环:
*                 zenddat 期末日期
*                 期末库存 = -期末库存
*                已收货天数 = 期末日期 - 收货日期+1 。
*                已收货累积数量 = 已收货累积数量 + 数量
*                 账龄表数量 = 数量
*                if  期末库存> 收货累积数量  ,     数据写入全局表。
*                else if  期末库存= 收货累积数量 , 数据写入全局表, 退出循环。
*                else 期末库存< 收货累积数量 ,  账龄表数量 = 数量 - (收货累积数量 - 期末库存) 数据写入全局表,退出循环。
*退出零件号循环
*  需要写入到qcqm表中的计算日期和duration days 在collect到表中和退出循环前,对之前的相同零件号统一修改。


  LOOP AT  lt_nonbatch_endstock ASSIGNING FIELD-SYMBOL().
    DATA(lt_grpermat) = lt_gr_nonbatch.
    DELETE lt_grpermat WHERE matnr NE -matnr.
    SORT lt_grpermat BY budat DESCENDING.
    LOOP AT  lt_grpermat ASSIGNING FIELD-SYMBOL().
      -zqty_cum = gs_gr_nonbatch-zqty_cum.
      MOVE-CORRESPONDING  TO gs_gr_nonbatch.
      gs_gr_nonbatch-zenddate = g_last_datum.
      gs_gr_nonbatch-ztotal_endstock  = -ztotal_endstock.
      gs_gr_nonbatch-zduration_days = g_last_datum - -budat + 1 .
      gs_gr_nonbatch-zqty_cum = gs_gr_nonbatch-zqty_cum + -stock_qty .
      gs_gr_nonbatch-zqty_consum = -stock_qty .

      IF gs_gr_nonbatch-ztotal_endstock >  gs_gr_nonbatch-zqty_cum.
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
      ELSEIF gs_gr_nonbatch-ztotal_endstock =  gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch FROM gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration WHERE matnr = -matnr.

        EXIT.
      ELSEIF gs_gr_nonbatch-ztotal_endstock < gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zqty_consum = -stock_qty - ( gs_gr_nonbatch-zqty_cum - gs_gr_nonbatch-ztotal_endstock  ).
        gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch FROM gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration WHERE matnr = -matnr.

        EXIT.
      ENDIF.
    ENDLOOP.

    gs_qcqm-zdate_for_cacu = gs_gr_nonbatch-zearlist_hsdate.
    gs_qcqm-zduration_days = gs_gr_nonbatch-zlongest_duration.
    FREE gs_gr_nonbatch.
    MODIFY gt_qcqm FROM gs_qcqm TRANSPORTING zdate_for_cacu zduration_days WHERE matnr = -matnr.


  ENDLOOP.






ENDFORM.

全部代码:

*&---------------------------------------------------------------------*
*& Report ZMMR005_N
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zmmr005_n.

TABLES:sscrfields, matdoc .

SELECTION-SCREEN: BEGIN OF BLOCK blk1 WITH FRAME TITLE TEXT-001.

  "--->查询屏幕
  SELECT-OPTIONS:
          s_bukrs FOR matdoc-bukrs  DEFAULT 6000,       "公司代码
          s_werks FOR matdoc-werks,      "工厂
          s_lgort FOR matdoc-lgort,     "库存地点
          s_matnr FOR matdoc-matnr  DEFAULT '500000020'.      "物料
  PARAMETERS: p_date TYPE char6 OBLIGATORY DEFAULT 202311 .

  SELECTION-SCREEN BEGIN OF LINE.
    SELECTION-SCREEN COMMENT (31) TEXT-004 FOR FIELD p_d1.
    PARAMETERS p_d1(4) TYPE n DEFAULT '30'.
    PARAMETERS p_d2(4) TYPE n DEFAULT '61'.
    PARAMETERS p_d3(4) TYPE n DEFAULT '91'.
    PARAMETERS p_d4(4) TYPE n DEFAULT '182'.
    PARAMETERS p_d5(4) TYPE n DEFAULT '365'.
    PARAMETERS p_d6(4) TYPE n DEFAULT '547'.
    PARAMETERS p_d7(4) TYPE n DEFAULT '730'.
    PARAMETERS p_d8(4) TYPE n DEFAULT '1825'.
  SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN: END OF BLOCK blk1.

SELECTION-SCREEN: BEGIN OF BLOCK blk2 WITH FRAME TITLE TEXT-002.

  PARAMETERS: r_pc RADIOBUTTON GROUP typ USER-COMMAND sele DEFAULT 'X'.   "按批次查询
  PARAMETERS: r_fpc RADIOBUTTON GROUP typ.                                "不按批次

SELECTION-SCREEN: END OF BLOCK blk2.

DATA: g_beg_datum TYPE sy-datum.
DATA: g_last_datum TYPE sy-datum.

* 定义接受俄罗斯报表相关信息的期初期末表。
TYPES:BEGIN OF ty_qcqm,  "期初期末
        bukrs                          TYPE bukrs, "company
        werks                          TYPE werks_d,     "plang
        lgort                          TYPE lgort_d, "storage location
        lgobe                          TYPE lgobe, "storage location description
        charg                          TYPE charg_d, "SAP batch
        sobkz                          TYPE sobkz, " special stock
        matnr                          TYPE matnr   ,   "物料编码.
        maktx                          TYPE maktx, "物料描述
        zqckcsl                        TYPE j_3rm_begstock,  "stock quantity on period start
        zqckcje                        TYPE j_3rm_begval, "stock value on period star
        zqjshsl                        TYPE j_3rm_recptstock, "期间收货数量total good receipt quantity
        zqjshje                        TYPE j_3rm_recptval, "期间收货金额total good receiptvalue
        zqjfhsl                        TYPE j_3rm_isustock, "期间发货数量 total good issue quantity
        zqjfhje                        TYPE j_3rm_isuval,  "期间发货金额 total good issue value
        zqmkcsl                        TYPE   j_3rm_endstock , "期末库存数量 stock quantity on period end.
        zqmkcje                        TYPE   j_3rm_endval  , "期末库存金额  stock quantity on period end.
        debreval                       TYPE j_3rm_debreval  , "Debit Revaluation.
        credreval                      TYPE  j_3rm_credreval, " credit Reevaluation.
        lifnr                          TYPE     elifn  ,      " 供应商
        kunnr                          TYPE     ekunn  ,      " 客户
        vbeln                          TYPE     mat_kdauf  ,      " 销售订单
        posnr                          TYPE     mat_kdpos  ,      " 销售订单项目
        linkk                          TYPE     j_3rmanylink  ,      " Order/WBS/Vendor/Customer
        bwkey                          TYPE     bwkey  ,      " 估价范围
        pspnr                          TYPE     mat_pspnr  ,      " WBS元素
        bklas                          TYPE     bklas  ,      " 评估类
        saknr                          TYPE     saknr  ,      " 总账科目
        mtart                          TYPE     mtart  ,      " 物料类型
        matkl                          TYPE     matkl  ,      " 物料组
        extwg                          TYPE     extwg  ,      " 外部物料组
        bismt                          TYPE     bismt  ,      " 旧物料号
        ekgrp                          TYPE     ekgrp  ,      " 采购组
        meins                          TYPE     meins  ,      " 基本基本计量
        waers                          TYPE     waers  ,      " 货币
        vprsv                          TYPE     vprsv  ,      " 价格控制
        receipt_from_purchase_stock    TYPE     j_3rm_purchstock  ,      " 采购收货数量
        receipt_from_purchase_value    TYPE     j_3rm_purchval  ,      " 采购收货金额
        issue_to_sales_stock           TYPE     j_3rm_salestock  ,      " 销售发货数量
        issue_to_sales_value           TYPE     j_3rm_saleval  ,      " 销售发货金额
        receipt_from_manufacture_stock TYPE     j_3rm_mrstock  ,      " 生产收货数量
        receipt_from_manufacture_value TYPE     j_3rm_mrval  ,      " 生产收货金额
        issue_to_manufacture_stock     TYPE     j_3rm_misustock  ,      " 生产发货数量
        issue_to_manufacture_value     TYPE     j_3rm_misuval  ,      " 生产发货金额
        receipt_from_transfer_stock    TYPE     j_3rm_xrecstock  ,      " 收货数量_转储
        receipt_from_transfer_value    TYPE     j_3rm_xrecval  ,      " 收货金额_转储
        issue_to_transfer_stock        TYPE     j_3rm_xisustock  ,      " 发货数量_转储
        issue_to_transfer_value        TYPE     j_3rm_xisuval  ,      " 发货金额_转储
        receipt_other_stock            TYPE     j_3rm_orstock  ,      " 收货数量_其他
        receipt_other_value            TYPE     j_3rm_orval  ,      " 收货金额_其他
        issue_other_stock              TYPE     j_3rm_oisustock  ,      " 发货数量_其他
        issue_other_value              TYPE     j_3rm_oisuval  ,      " 发货金额_其他
        issue_to_int_purposes_stock    TYPE     j_3rm_isuintpurstock  ,      " 发货数量_内部用途
        issue_to_int_purposes_value    TYPE     j_3rm_isuintpurval  ,      " 发货金额_内部用途
        vbap_kzbws                     TYPE     bwtar_d  ,      " 评估类型
        prps_kzbws                     TYPE     kzbws  ,     " 评估
        difference_between_values      TYPE       j_3rm_isuintpurval,    " 金额差异
        ersda                          TYPE    ersda   ,    "创建日期MCH1-ERSDA
        hsdat                          TYPE    hsdat   ,    "生产日期MCH1-HSDAT
        vfdat                          TYPE    vfdat   ,    "过期日期MCH1-VFDAT
        zdate_for_cacu                 TYPE    hsdat   ,    "天数计算日期  首选HSDAT, 其次 ERSDA,再其次 ZMMT004-HSDAT
        zduration_days(4)              TYPE  n     ,    "库存天数   计算:  期末日期 - Zdate_for_cacu
      END OF ty_qcqm.
DATA:gs_qcqm TYPE ty_qcqm.
DATA:gt_qcqm LIKE TABLE OF gs_qcqm.
DATA: gt_fieldcat TYPE lvc_t_fcat,
      gs_fieldcat TYPE lvc_s_fcat,
      gs_layout   TYPE lvc_s_layo.
* 定义 非批次物料全局收货表
TYPES:BEGIN OF ty_gr_nonbatch ,  "期初期末
        mblnr                TYPE mblnr , "物料凭证
        mjahr                TYPE mjahr,  "物料凭证年度
        zeile                TYPE mblpo, " 物料凭证项目
        bukrs                TYPE bukrs, "company
        werks                TYPE werks_d,     "plang
        matnr                TYPE matnr   ,   "物料编码.
        bwart                TYPE  bwart,  "移动类型
        budat                TYPE budat, "过账日期
        stock_qty            TYPE nsdm_stock_qty, " matdoc 表中的库存数量 102为负数。
        meins                TYPE     meins  ,      " 基本基本计量
        zenddate             TYPE budat,  " 从全局变量g_last_datum 获取。
        ztotal_endstock      TYPE   j_3rm_endstock , "期末库存数量 stock quantity on period end.
        zduration_days(4)    TYPE  n     ,    "库存天数   计算:  期末日期 - Zdate_for_cacu
        zqty_consum          TYPE  j_3rm_endstock , " 对应收货有多少来消耗期末库存。原则等于stock_qty,最后一条调整。
        zqty_cum             TYPE  j_3rm_endstock , "截止收货日期累积收货数量。
        zearlist_hsdate      TYPE    budat   ,    " 消耗期末库存的最早的一个收货日期,用于paint Gt_qcqm表的计算日期。
        zlongest_duration(4) TYPE n , " 消耗期末库存的最早的一个收货日期的天数,用于paint Gt_qcqm表的zduration_days。
      END OF ty_gr_nonbatch.
DATA:gs_gr_nonbatch TYPE ty_gr_nonbatch.
DATA:gt_gr_nonbatch LIKE TABLE OF gs_gr_nonbatch.

START-OF-SELECTION.

  PERFORM get_beg_end_date.

  PERFORM get_J3RFLVMOBVEDH_data.

  PERFORM paint_gt_qcqm_batch_material.

  PERFORM paint_gt_qcqm_nonbatchmat.


  IF r_pc = 'X'.

    PERFORM get_fieldcat.

    PERFORM display_data.
  ENDIF.

  IF r_fpc = 'X'.


  ENDIF.

*&---------------------------------------------------------------------*
*& Form get_J3RFLVMOBVEDH_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM get_J3RFLVMOBVEDH_data .

*从俄罗斯报表中生成动态表
  DATA:lr_alv_data TYPE REF TO data.
  DATA: rspar TYPE TABLE OF rsparams.
  FIELD-SYMBOLS :   TYPE ANY TABLE.
  cl_salv_bs_runtime_info=>set( EXPORTING display  = abap_false
                                          metadata = abap_false
                                          data     = abap_true ).
  CLEAR lr_alv_data.
  UNASSIGN .
  CLEAR: rspar.
  rspar = VALUE #( ( selname = 'SO_BUDAT'  sign = 'I'    option = 'BT'  low = g_beg_datum    high = g_last_datum )
                   ( selname = 'SO_MATNR' sign = s_matnr-sign option = s_matnr-option  low = s_matnr-low  high = s_matnr-high )
                 ).
  SUBMIT j_3rmobvedh
         WITH so_bukrs-low EQ '6000'
         WITH SELECTION-TABLE rspar
         AND RETURN .
  TRY.
      cl_salv_bs_runtime_info=>get_data_ref( IMPORTING r_data = lr_alv_data ).
      ASSIGN lr_alv_data->* TO .
    CATCH cx_salv_bs_sc_runtime_info.
      MESSAGE 'Unable to retrieve ALV data! Please try other conditions.' TYPE 'E'.
  ENDTRY.
  cl_salv_bs_runtime_info=>clear_all( ).

*  定义宏,减少代码量。
  DEFINE get_gt_qcqm.
    ASSIGN COMPONENT &1 OF STRUCTURE  TO .
       IF sy-subrc EQ 0.
         &2 = .
         UNASSIGN .
       ENDIF.
  END-OF-DEFINITION.

*动态表 中数值存储到全局表gt_qcqm 期初期末表。
  FIELD-SYMBOLS  TYPE any.
  IF  IS ASSIGNED.
    LOOP AT  ASSIGNING FIELD-SYMBOL() .
      get_gt_qcqm 'BUKRS' gs_qcqm-bukrs  .
      get_gt_qcqm 'WERKS' gs_qcqm-werks  .
      get_gt_qcqm 'LGORT' gs_qcqm-lgort  .
      get_gt_qcqm 'LGOBE' gs_qcqm-lgobe  .
      get_gt_qcqm 'CHARG' gs_qcqm-charg  .
      get_gt_qcqm 'SOBKZ' gs_qcqm-sobkz  .
      get_gt_qcqm 'MATNR' gs_qcqm-matnr  .
      get_gt_qcqm 'MAKTX' gs_qcqm-maktx  .
      get_gt_qcqm 'QUANTITY_BEGIN_OF_PERIOD' gs_qcqm-zqckcsl  .
      get_gt_qcqm 'VALUE_BEGIN_OF_PERIOD' gs_qcqm-zqckcje  .
      get_gt_qcqm 'RECEIPT_STOCK' gs_qcqm-zqjshsl  .
      get_gt_qcqm 'RECEIPT_VALUE' gs_qcqm-zqjshje  .
      get_gt_qcqm 'ISSUE_STOCK' gs_qcqm-zqjfhsl  .
      get_gt_qcqm 'ISSUE_VALUE' gs_qcqm-zqjfhje  .
      get_gt_qcqm 'QUANTITY_END_OF_PERIOD' gs_qcqm-zqmkcsl  .
      get_gt_qcqm 'VALUE_END_OF_PERIOD' gs_qcqm-zqmkcje  .
      get_gt_qcqm 'DEBREVAL' gs_qcqm-debreval .
      get_gt_qcqm 'CREDREVAL' gs_qcqm-credreval .
      get_gt_qcqm         'LIFNR' gs_qcqm-lifnr .      " 供应商
      get_gt_qcqm         'KUNNR' gs_qcqm-kunnr .      " 客户
      get_gt_qcqm         'VBELN' gs_qcqm-vbeln .      " 销售订单
      get_gt_qcqm         'POSNR' gs_qcqm-posnr .      " 销售订单项目
      get_gt_qcqm         'LINKK' gs_qcqm-linkk .      " Order/WBS/Vendor/Customer
      get_gt_qcqm         'BWKEY' gs_qcqm-bwkey .      " 估价范围
      get_gt_qcqm         'PSPNR' gs_qcqm-pspnr .      " WBS元素
      get_gt_qcqm         'BKLAS' gs_qcqm-bklas .      " 评估类
      get_gt_qcqm         'SAKNR' gs_qcqm-saknr .      " 总账科目
      get_gt_qcqm         'MTART' gs_qcqm-mtart .      " 物料类型
      get_gt_qcqm         'MATKL' gs_qcqm-matkl .      " 物料组
      get_gt_qcqm         'EXTWG' gs_qcqm-extwg .      " 外部物料组
      get_gt_qcqm         'BISMT' gs_qcqm-bismt .      " 旧物料号
      get_gt_qcqm         'EKGRP' gs_qcqm-ekgrp .      " 采购组
      get_gt_qcqm         'MEINS' gs_qcqm-meins .      " 基本基本计量
      get_gt_qcqm         'WAERS' gs_qcqm-waers .      " 货币
      get_gt_qcqm         'VPRSV' gs_qcqm-vprsv .      " 价格控制
      get_gt_qcqm         'RECEIPT_FROM_PURCHASE_STOCK' gs_qcqm-receipt_from_purchase_stock .      " 采购收货数量
      get_gt_qcqm         'RECEIPT_FROM_PURCHASE_VALUE' gs_qcqm-receipt_from_purchase_value .      " 采购收货金额
      get_gt_qcqm         'ISSUE_TO_SALES_STOCK' gs_qcqm-issue_to_sales_stock .      " 销售发货数量
      get_gt_qcqm         'ISSUE_TO_SALES_VALUE' gs_qcqm-issue_to_sales_value .      " 销售发货金额
      get_gt_qcqm         'RECEIPT_FROM_MANUFACTURE_STOCK' gs_qcqm-receipt_from_manufacture_stock .      " 生产收货数量
      get_gt_qcqm         'RECEIPT_FROM_MANUFACTURE_VALUE' gs_qcqm-receipt_from_manufacture_value .      " 生产收货金额
      get_gt_qcqm         'ISSUE_TO_MANUFACTURE_STOCK' gs_qcqm-issue_to_manufacture_stock .      " 生产发货数量
      get_gt_qcqm         'ISSUE_TO_MANUFACTURE_VALUE' gs_qcqm-issue_to_manufacture_value .      " 生产发货金额
      get_gt_qcqm         'RECEIPT_FROM_TRANSFER_STOCK' gs_qcqm-receipt_from_transfer_stock .      " 收货数量_转储
      get_gt_qcqm         'RECEIPT_FROM_TRANSFER_VALUE' gs_qcqm-receipt_from_transfer_value .      " 收货金额_转储
      get_gt_qcqm         'ISSUE_TO_TRANSFER_STOCK' gs_qcqm-issue_to_transfer_stock .      " 发货数量_转储
      get_gt_qcqm         'ISSUE_TO_TRANSFER_VALUE' gs_qcqm-issue_to_transfer_value .      " 发货金额_转储
      get_gt_qcqm         'RECEIPT_OTHER_STOCK' gs_qcqm-receipt_other_stock .      " 收货数量_其他
      get_gt_qcqm         'RECEIPT_OTHER_VALUE' gs_qcqm-receipt_other_value .      " 收货金额_其他
      get_gt_qcqm         'ISSUE_OTHER_STOCK' gs_qcqm-issue_other_stock .      " 发货数量_其他
      get_gt_qcqm         'ISSUE_OTHER_VALUE' gs_qcqm-issue_other_value .      " 发货金额_其他
      get_gt_qcqm         'ISSUE_TO_INT_PURPOSES_STOCK' gs_qcqm-issue_to_int_purposes_stock .      " 发货数量_内部用途
      get_gt_qcqm         'ISSUE_TO_INT_PURPOSES_VALUE' gs_qcqm-issue_to_int_purposes_value .      " 发货金额_内部用途
      get_gt_qcqm         'VBAP_KZBWS' gs_qcqm-vbap_kzbws .      " 评估类型
      get_gt_qcqm         'PRPS_KZBWS' gs_qcqm-prps_kzbws .      " 评估
      get_gt_qcqm         'DIFFERENCE_BETWEEN_VALUES' gs_qcqm-difference_between_values .      " 价格差异

      gs_qcqm-zqjshje = gs_qcqm-zqjshje - gs_qcqm-debreval .
      gs_qcqm-zqjfhje = gs_qcqm-zqjfhje - gs_qcqm-credreval .
      COLLECT gs_qcqm INTO gt_qcqm.
    ENDLOOP.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form display_data
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM display_data .
  DATA:alv_variant      LIKE disvariant.
  alv_variant-report = sy-repid.
  alv_variant-handle = '1'.    "相当于不同ALV变式的唯一识别
  gs_layout-cwidth_opt = 'X'.
  gs_layout-zebra      = 'X'.
  gs_layout-sel_mode   = 'A'.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program = sy-repid
      is_layout_lvc      = gs_layout
      it_fieldcat_lvc    = gt_fieldcat
      i_save             = 'A'
      is_variant         = alv_variant
    TABLES
      t_outtab           = gt_qcqm.
  IF sy-subrc <> 0.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form get_fieldcat
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM get_fieldcat .
  DEFINE alv_fcat.
    gs_fieldcat-fieldname = &1.
    gs_fieldcat-tabname = 'GT_QCQM' .
    gs_fieldcat-coltext =   gs_fieldcat-scrtext_l =   gs_fieldcat-scrtext_m =  &2.
    gs_fieldcat-rollname = &3.
    gs_fieldcat-no_out = 'X'.
    gs_fieldcat-col_opt   = 'X'.
    gs_FIELDCAT-no_zero =  &4.
    APPEND gs_fieldcat TO gt_fieldcat.
    CLEAR gs_fieldcat.
  END-OF-DEFINITION.

  alv_fcat 'BUKRS'   TEXT-101   'BUKRS'   'X' .
  alv_fcat 'WERKS'   TEXT-102   'WERKS_D'   'X' .
  alv_fcat 'LGORT'   TEXT-103   'LGORT_D'   'X' .
  alv_fcat 'LGOBE'   TEXT-104   'LGOBE'   'X' .
  alv_fcat 'MATNR'   TEXT-105   'MATNR'   'X' .
  alv_fcat 'MAKTX'   TEXT-106   'MAKTX'   'X' .
  alv_fcat 'CHARG'   TEXT-107   'CHARG_D'   'X' .
  alv_fcat 'SOBKZ'   TEXT-108   'SOBKZ'   'X' .
  alv_fcat 'ZQCKCSL'   TEXT-109   'J_3RM_BEGSTOCK'    ''  .
  alv_fcat 'ZQCKCJE'   TEXT-110   'J_3RM_BEGVAL'      ''  .
  alv_fcat 'ZQJSHSL'   TEXT-111   'J_3RM_RECPTSTOCK'  ''  .
  alv_fcat 'ZQJSHJE'   TEXT-112   'J_3RM_RECPTVAL'    ''  .
  alv_fcat 'ZQJFHSL'   TEXT-113   'J_3RM_ISUSTOCK'    ''  .
  alv_fcat 'ZQJFHJE'   TEXT-114   'J_3RM_ISUVAL'      ''  .
  alv_fcat 'ZQMKCSL'   TEXT-115   'J_3RM_ENDSTOCK'    ''  .
  alv_fcat 'ZQMKCJE'   TEXT-116   'J_3RM_ENDVAL'      ''  .
  alv_fcat    'LIFNR'        TEXT-117      'ELIFN'   'X'    .
  alv_fcat    'KUNNR'        TEXT-118  'EKUNN'   'X'    .
  alv_fcat    'VBELN'        TEXT-119  'MAT_KDAUF'   'X'    .
  alv_fcat    'POSNR'        TEXT-120  'MAT_KDPOS'   'X'    .
  alv_fcat    'LINKK'        TEXT-121  'J_3RMANYLINK'   'X'    .
  alv_fcat    'BWKEY'        TEXT-122  'BWKEY'   'X'    .
  alv_fcat    'PSPNR'        TEXT-123  'MAT_PSPNR'   'X'    .
  alv_fcat    'BKLAS'        TEXT-124  'BKLAS'   'X'    .
  alv_fcat    'SAKNR'        TEXT-125  'SAKNR'   'X'    .
  alv_fcat    'MTART'        TEXT-126  'MTART'   'X'    .
  alv_fcat    'MATKL'        TEXT-127  'MATKL'   'X'    .
  alv_fcat    'EXTWG'        TEXT-128  'EXTWG'   'X'    .
  alv_fcat    'BISMT'        TEXT-129  'BISMT'   'X'    .
  alv_fcat    'EKGRP'        TEXT-130  'EKGRP'   'X'    .
  alv_fcat    'MEINS'        TEXT-131  'MEINS'   'X'    .
  alv_fcat    'WAERS'        TEXT-132  'WAERS'   'X'    .
  alv_fcat    'VPRSV'        TEXT-133  'VPRSV'   'X'    .
  alv_fcat    'RECEIPT_FROM_PURCHASE_STOCK'        TEXT-134  'J_3RM_PURCHSTOCK'   ''    .
  alv_fcat    'RECEIPT_FROM_PURCHASE_VALUE'        TEXT-135  'J_3RM_PURCHVAL'   ''    .
  alv_fcat    'ISSUE_TO_SALES_STOCK'        TEXT-136  'J_3RM_SALESTOCK'   ''    .
  alv_fcat    'ISSUE_TO_SALES_VALUE'        TEXT-137  'J_3RM_SALEVAL'   ''    .
  alv_fcat    'RECEIPT_FROM_MANUFACTURE_STOCK'        TEXT-138  'J_3RM_MRSTOCK'   ''    .
  alv_fcat    'RECEIPT_FROM_MANUFACTURE_VALUE'        TEXT-139  'J_3RM_MRVAL'   ''    .
  alv_fcat    'ISSUE_TO_MANUFACTURE_STOCK'        TEXT-140  'J_3RM_MISUSTOCK'   ''    .
  alv_fcat    'ISSUE_TO_MANUFACTURE_VALUE'        TEXT-141  'J_3RM_MISUVAL'   ''    .
  alv_fcat    'RECEIPT_FROM_TRANSFER_STOCK'        TEXT-142  'J_3RM_XRECSTOCK'   ''    .
  alv_fcat    'RECEIPT_FROM_TRANSFER_VALUE'        TEXT-143  'J_3RM_XRECVAL'   ''    .
  alv_fcat    'ISSUE_TO_TRANSFER_STOCK'        TEXT-144  'J_3RM_XISUSTOCK'   ''    .
  alv_fcat    'ISSUE_TO_TRANSFER_VALUE'        TEXT-145  'J_3RM_XISUVAL'   ''    .
  alv_fcat    'RECEIPT_OTHER_STOCK'        TEXT-146  'J_3RM_ORSTOCK'   ''    .
  alv_fcat    'RECEIPT_OTHER_VALUE'        TEXT-147  'J_3RM_ORVAL'   ''    .
  alv_fcat    'ISSUE_OTHER_STOCK'        TEXT-148  'J_3RM_OISUSTOCK'   ''    .
  alv_fcat    'ISSUE_OTHER_VALUE'        TEXT-149  'J_3RM_OISUVAL'   ''    .
  alv_fcat    'ISSUE_TO_INT_PURPOSES_STOCK'        TEXT-150  'J_3RM_ISUINTPURSTOCK'   ''    .
  alv_fcat    'ISSUE_TO_INT_PURPOSES_VALUE'        TEXT-151  'J_3RM_ISUINTPURVAL'   ''    .
  alv_fcat    'VBAP_KZBWS'        TEXT-152  'BWTAR_D'   'X'    .
  alv_fcat    'PRPS_KZBWS'        TEXT-153  'KZBWS'   'X'    .
  alv_fcat   'ERSDA'        TEXT-154      'ERSDA'  'X'.
  alv_fcat   'HSDAT'        TEXT-155 'HSDAT'  'X'.
  alv_fcat   'VFDAT'        TEXT-156 'VFDAT'  'X'.
  alv_fcat   'ZDATE_FOR_CACU' TEXT-157 'HSDAT'  'X'.
  alv_fcat   'ZDURATION_DAYS' TEXT-158 '' 'X' .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form get_beg_end_date
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM get_beg_end_date .
  g_beg_datum = p_date && '01'.
  CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'
    EXPORTING
      i_date = g_beg_datum
    IMPORTING
      e_date = g_last_datum.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form paint_gt_qcqm_batch_material
*&---------------------------------------------------------------------*
*& 对于有批次管理的物料增加字段:sap批次时间,生产时间, 过期时间, 天数计算日期 库存天数。
*&
*&天数计算时间 原则采用生产时间,
*&
*&      如果生产时间为空,采用SAP批次时间,
*&
*&                如果SAP批次时间为初时间,采用zmmt004(期初库存批次表)的时间。
*&
*& 库存天数: 期末时间-天数计算时间 (生产时间为空时用SAP批次时间)
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM paint_gt_qcqm_batch_material .

  LOOP  AT gt_qcqm ASSIGNING FIELD-SYMBOL().
    IF NOT -charg IS INITIAL AND -ersda IS INITIAL  .
      SELECT SINGLE  ersda hsdat vfdat
        FROM mch1
        INTO CORRESPONDING FIELDS OF 
        WHERE matnr = -matnr
        AND charg = -charg   .

      IF NOT -hsdat IS INITIAL.
        -zdate_for_cacu = -hsdat .
      ELSE.
        -zdate_for_cacu = -ersda .
      ENDIF.
      -zduration_days = g_last_datum - -zdate_for_cacu + 1.

      MODIFY gt_qcqm FROM 
      TRANSPORTING ersda hsdat vfdat zdate_for_cacu zduration_days
      WHERE matnr = -matnr AND charg = -charg.
    ENDIF.

    IF -lgobe IS INITIAL.
      SELECT SINGLE lgobe FROM t001l
        INTO -lgobe
        WHERE werks = -werks
        AND lgort = -lgort .

      MODIFY gt_qcqm FROM 
      TRANSPORTING lgobe
       WHERE werks = -werks
        AND lgort = -lgort .
    ENDIF.

  ENDLOOP.
  UNASSIGN .
ENDFORM.
*&---------------------------------------------------------------------*
*& Form paint_gt_qcqm_nonbatchmat
*&---------------------------------------------------------------------*
*& text 对非批次物料填充最早收货日期(计算日期)和zduration_days.
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM paint_gt_qcqm_nonbatchmat .

*&*  生成期末库存总数量中间表 lt_nonbatch_endstock
*&
*&*公司 工厂  零件号 期末数量  期末日期
*&*6000 6000  1040000 100 2023-11-30
*&*         全局期初期末表生成 =>局部表 lt_qcqm_temp
*&*&              删除有批次号的行, 删除期末数量为0 的行。
*&*&              根据零件号排序。
*&*&              temp表 循环,按照零件号累加数量。
*&                  collect 对应数据到 lt_nonbatch_endstock 表中。



  TYPES:BEGIN OF ty_nonbatch_endstock ,  "期初期末
          bukrs           TYPE bukrs, "company
          werks           TYPE werks_d,     "plang
          matnr           TYPE matnr   ,   "物料编码.
          meins           TYPE     meins  ,      " 基本基本计量
          zenddate        TYPE budat,  " 从全局变量g_last_datum 获取。
          ztotal_endstock TYPE   j_3rm_endstock , "期末库存数量 stock quantity on period end.
        END OF ty_nonbatch_endstock.
  DATA:ls_nonbatch_endstock TYPE ty_nonbatch_endstock.
  DATA:lt_nonbatch_endstock LIKE TABLE OF ls_nonbatch_endstock.

  DATA(lt_qcqm_temp) = gt_qcqm.

  DELETE lt_qcqm_temp WHERE NOT charg IS INITIAL.
  DELETE lt_qcqm_temp WHERE zqmkcsl EQ 0.
  SORT lt_qcqm_temp BY matnr.

  DATA last_matnr TYPE matnr.
  FREE: last_matnr, ls_nonbatch_endstock, lt_nonbatch_endstock.

  LOOP AT lt_qcqm_temp ASSIGNING FIELD-SYMBOL().
    IF last_matnr IS INITIAL.
      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.
      last_matnr = -matnr.
    ELSEIF last_matnr = -matnr.
      ls_nonbatch_endstock-ztotal_endstock = ls_nonbatch_endstock-ztotal_endstock + -zqmkcsl.
    ELSEIF last_matnr NE -matnr.

      COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

      ls_nonbatch_endstock-bukrs = -bukrs.
      ls_nonbatch_endstock-werks =  -werks.
      ls_nonbatch_endstock-matnr =  -matnr.
      ls_nonbatch_endstock-meins = -meins.
      ls_nonbatch_endstock-zenddate = g_last_datum .
      ls_nonbatch_endstock-ztotal_endstock = -zqmkcsl.

    ENDIF.
  ENDLOOP.
  COLLECT ls_nonbatch_endstock INTO lt_nonbatch_endstock.

*&*  非批次管理物料,按照零件号lt_nonbatch_endstock 的零件号select matdoc表中的收货记录 101 /102  / 561
*&
*&*

  DATA(lt_gr_nonbatch) = gt_gr_nonbatch.
  FREE lt_gr_nonbatch.

  SELECT * FROM matdoc
    INTO  CORRESPONDING FIELDS OF TABLE lt_gr_nonbatch
    FOR ALL ENTRIES IN lt_nonbatch_endstock
    WHERE matnr = lt_nonbatch_endstock-matnr
    AND budat <= g_last_datum
    AND ( bwart = 101
    OR     bwart = 102
    OR     bwart = 561 ) .

* 生成 非批次物料收货记录全局表
*零件号循环 lt_nonbatch_endstock
*  lt_gr_nonbatch表中数据写入临时表 lt_grpermat。
*  记录表内容:凭证号,零件号,移动类型,数量,增加列“期末日期”,“期末库存”,  “已收货天数”, “已收货累积数量”,“账龄表数量”,“期末库存待消耗数量”
*  删除零件号与循环不相同的数据。
* lt_grpermat 按照过账日期倒排。
*       lt_grperpmat记录表循环:
*                 zenddat 期末日期
*                 期末库存 = -期末库存
*                已收货天数 = 期末日期 - 收货日期+1 。
*                已收货累积数量 = 已收货累积数量 + 数量
*                 账龄表数量 = 数量
*                if  期末库存> 收货累积数量  ,     数据写入全局表。
*                else if  期末库存= 收货累积数量 , 数据写入全局表, 退出循环。
*                else 期末库存< 收货累积数量 ,  账龄表数量 = 数量 - (收货累积数量 - 期末库存) 数据写入全局表,退出循环。
*退出零件号循环
*  需要写入到qcqm表中的计算日期和duration days 在collect到表中和退出循环前,对之前的相同零件号统一修改。


  LOOP AT  lt_nonbatch_endstock ASSIGNING FIELD-SYMBOL().
    DATA(lt_grpermat) = lt_gr_nonbatch.
    DELETE lt_grpermat WHERE matnr NE -matnr.
    SORT lt_grpermat BY budat DESCENDING.
    LOOP AT  lt_grpermat ASSIGNING FIELD-SYMBOL().
      -zqty_cum = gs_gr_nonbatch-zqty_cum.
      MOVE-CORRESPONDING  TO gs_gr_nonbatch.
      gs_gr_nonbatch-zenddate = g_last_datum.
      gs_gr_nonbatch-ztotal_endstock  = -ztotal_endstock.
      gs_gr_nonbatch-zduration_days = g_last_datum - -budat + 1 .
      gs_gr_nonbatch-zqty_cum = gs_gr_nonbatch-zqty_cum + -stock_qty .
      gs_gr_nonbatch-zqty_consum = -stock_qty .

      IF gs_gr_nonbatch-ztotal_endstock >  gs_gr_nonbatch-zqty_cum.
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
      ELSEIF gs_gr_nonbatch-ztotal_endstock =  gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch FROM gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration WHERE matnr = -matnr.

        EXIT.
      ELSEIF gs_gr_nonbatch-ztotal_endstock < gs_gr_nonbatch-zqty_cum.
        gs_gr_nonbatch-zqty_consum = -stock_qty - ( gs_gr_nonbatch-zqty_cum - gs_gr_nonbatch-ztotal_endstock  ).
        gs_gr_nonbatch-zearlist_hsdate = -budat.
        gs_gr_nonbatch-zlongest_duration = gs_gr_nonbatch-zduration_days .
        COLLECT gs_gr_nonbatch INTO gt_gr_nonbatch.
        MODIFY gt_gr_nonbatch FROM gs_gr_nonbatch TRANSPORTING zearlist_hsdate zlongest_duration WHERE matnr = -matnr.

        EXIT.
      ENDIF.
    ENDLOOP.

    gs_qcqm-zdate_for_cacu = gs_gr_nonbatch-zearlist_hsdate.
    gs_qcqm-zduration_days = gs_gr_nonbatch-zlongest_duration.
    FREE gs_gr_nonbatch.
    MODIFY gt_qcqm FROM gs_qcqm TRANSPORTING zdate_for_cacu zduration_days WHERE matnr = -matnr.


  ENDLOOP.






ENDFORM.

学到的技术

select中and / or 组合,用 ( )。 括号前后要有空格。

通过俄罗斯报表完成库存账龄报告 二_第4张图片

运行结果:

通过俄罗斯报表完成库存账龄报告 二_第5张图片

非批次物料类型:期末数量为零不计算天数。

通过俄罗斯报表完成库存账龄报告 二_第6张图片

进行批次管理的物料:

通过俄罗斯报表完成库存账龄报告 二_第7张图片1, 有生产日期,用生产日期计算。

2, 无生产日期,用批次创建日期计算。

你可能感兴趣的:(数据库)