目录
业务需求:
已经完成任务:
第二部分计算逻辑
批次管理物料
期初期末表更新:
非批次汇总表更新
非批次管理物料
生成非批次物料全局“收货记录表”
起初期末表更新:
“非批次”选项 零件号汇总表:
第三部分 任务拆分:
批次物料期初期末表更新
增加数据定义
增加fieldcat
增加字段内容
非批次物料期初期末表更新
期末库存零件号收货退货期初库存中间表
生成全局“收货记录表”
修改期初期末全局表的非批次物料
全部代码:
学到的技术
运行结果:
接上一篇
基于俄罗斯报表J3RFLVMOBVEDH生成库龄表-CSDN博客
第一部分报表已经完成.
结果:
由于俄罗斯报表输出已经进行汇总,因此第二部分报告计算过程中,不考虑效率问题。
对于有批次管理的物料增加字段: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 |
layout选择之后:
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 组合,用 ( )。 括号前后要有空格。
非批次物料类型:期末数量为零不计算天数。
进行批次管理的物料:
2, 无生产日期,用批次创建日期计算。