SAP库龄表

&---------------------------------------------------------------------*
*& Report  ZFIR005
*&
*&---------------------------------------------------------------------*
*& Programe ID: ZFIR005
*& Programe Discription: 财务库龄表
*& Change Date: 2015/1/15
*& Change By:  **有希望的草根,QQ:654563691**
*& Version: Ver0.1
*&---------------------------------------------------------------------*

REPORT  ZFIR005 NO STANDARD PAGE HEADING.

TYPE-POOLS: SLIS.
*&---------------------------------------------------------------------*
*&     TYPES DEFINITION
*&---------------------------------------------------------------------*
* 物料数据
TYPES: BEGIN OF TP_MATNR,
        WERKS  TYPE MARD-WERKS,  "工厂
        MATNR  TYPE MARD-MATNR,  "物料号
        LGORT  TYPE MARD-LGORT,  "库存地点
        MAKTX  TYPE MAKT-MAKTX,  "物料描述
        PRCTR  TYPE MARC-PRCTR,  "利润中心
        MATKL  TYPE MARA-MATKL,  "物料组
        XCHPF  TYPE MARA-XCHPF,  "批次管理需求的标识
        MENGE  TYPE BSEG-MENGE,  "数量
        MEINS  TYPE MARA-MEINS,  "数量单位
       END OF TP_MATNR.
* 物料总数量
TYPES: BEGIN OF TP_QTY,
        WERKS  TYPE BSEG-WERKS,  "工厂
        MATNR  TYPE BSEG-MATNR,  "物料号
        MENGE  TYPE BSEG-MENGE,  "数量
        DMBTR  TYPE BSEG-DMBTR,  "按本位币计的金额
       END OF TP_QTY.
* 物料库存数据
TYPES: BEGIN OF TP_DATA,
        WERKS  TYPE MCHB-WERKS, "工厂
        MATNR  TYPE MCHB-MATNR, "物料号
        LGORT  TYPE MCHB-LGORT, "库存地点
        CHARG  TYPE MCHB-CHARG, "批号
        LFGJA  TYPE MCHB-LFGJA, "当前期间的会计年度
        LFMON  TYPE MCHB-LFMON, "当前期间
        SDATE  TYPE SY-DATUM,   "当前日期
        CLABS  TYPE MCHB-CLABS, "非限制使用的估价的库存
        CUMLM  TYPE MCHB-CUMLM, "在运库存
        CINSM  TYPE MCHB-CINSM, "质量检验中的库存
        SOBKZ  TYPE MSKA-SOBKZ, "特殊库存标识
        VBELN  TYPE MSKA-VBELN, "销售和分销凭证号
        POSNR  TYPE MSKA-POSNR, "销售和分销凭证的项目号
        XCHPF  TYPE MARA-XCHPF, "批次管理标志
        MENGE  TYPE MSEG-MENGE, "数量
        LWEDT  TYPE MCH1-LWEDT, "收货日期
       END OF TP_DATA.
* 物料移动数据
TYPES: BEGIN OF TP_MSEG,
        BUKRS  TYPE MSEG-BUKRS,  "公司代码
        MBLNR  TYPE MSEG-MBLNR,  "物料凭证编号
        MJAHR  TYPE MSEG-MJAHR,  "物料凭证年度
        ZEILE  TYPE MSEG-ZEILE,  "物料凭证中的项目
        MATNR  TYPE MSEG-MATNR,  "物料号
        WERKS  TYPE MSEG-WERKS,  "工厂
        LGORT  TYPE MSEG-LGORT,  "库存地点
        BWART  TYPE MSEG-BWART,  "移动类型
        SHKZG  TYPE MSEG-SHKZG,  "借贷标识
        MENGE  TYPE MSEG-MENGE,  "数量
        EXBWR  TYPE MSEG-EXBWR,  "以本地货币计量的过帐金额
        CHARG  TYPE MSEG-CHARG,  "批号
        WAERS  TYPE MSEG-WAERS,  "价格单位
        BUDAT  TYPE MKPF-BUDAT,  "凭证中的过帐日期
        LWEDT  TYPE MCH1-LWEDT,  "最近的收货日期
       END OF TP_MSEG.
* 会计凭证数据
TYPES: BEGIN OF TP_BSEG,
        BUKRS  TYPE BSEG-BUKRS,  "公司代码
        WERKS  TYPE BSEG-WERKS,  "工厂
        BELNR  TYPE BSEG-BELNR,  "会计凭证编号
        GJAHR  TYPE BSEG-GJAHR,  "会计年度
        BUZEI  TYPE BSEG-BUZEI,  "项目号
        SHKZG  TYPE BSEG-SHKZG,  "借方/贷方标识
        DMBTR  TYPE BSEG-DMBTR,  "按本位币计的金额
        MATNR  TYPE BSEG-MATNR,  "物料号
        MENGE  TYPE BSEG-MENGE,  "数量
        MEINS  TYPE BSEG-MEINS,  "数量单位
        BUDAT  TYPE BKPF-BUDAT,  "凭证中的过帐日期
        BLART  TYPE BKPF-BLART,  "凭证类型
        AWTYP  TYPE BKPF-AWTYP,  "参考交易
        AWKEY  TYPE BKPF-AWKEY,  "字段参考关键
       END OF TP_BSEG.
* ALV 输出字段
TYPES: BEGIN OF TP_ALV,
        CHK    TYPE CHAR1,       "CHECBOX
        WERKS  TYPE MARD-WERKS,  "工厂
        LGORT  TYPE MARD-LGORT,  "库存地点
        ZYEAR  TYPE CHAR4,       "运行年份
        ZMONTH TYPE CHAR2,       "运行月份
        MATNR  TYPE MARD-MATNR,  "物料号
        MAKTX  TYPE MAKT-MAKTX,  "物料描述
        MATKL  TYPE MARA-MATKL,  "物料组
        PRCTR  TYPE MARC-PRCTR,  "利润中心
        PRTXT  TYPE CEPCT-MCTXT, "利润中心描述
        XCHPF  TYPE MARA-XCHPF,  "批次管理
        LDATE1 TYPE SY-DATUM,    "最后异动日期
        LDATE2 TYPE SY-DATUM,    "最后销售日期
        PRICE  TYPE MBEW-SALK3,  "单价
        SALK3  TYPE MBEW-SALK3,  "库存金额
        LBKUM1 TYPE MBEW-LBKUM,  "库存数量
        MEINS1 TYPE MARA-MEINS,  "数量单位
        LBKUM2 TYPE MBEW-LBKUM,  "财务库存数量
        MEINS2 TYPE MARA-MEINS,  "财务数量单位
        QTY3M  TYPE MBEW-LBKUM,  "3月以内的库龄数量
        QTY6M  TYPE MBEW-LBKUM,  "4月到6月以内的库龄数量
        QTY9M  TYPE MBEW-LBKUM,  "7月到9月以内的库龄数量
        QTY12M TYPE MBEW-LBKUM,  "10月到12月以内的库龄数量
        QTY18M TYPE MBEW-LBKUM,  "13月到18月以内的库龄数量
        QTY24M TYPE MBEW-LBKUM,  "19月到24月以内的库龄数量
        QTY36M TYPE MBEW-LBKUM,  "25月到36月以内的库龄数量
        QTY60M TYPE MBEW-LBKUM,  "37月到60月以内的库龄数量
        QTY61M TYPE MBEW-LBKUM,  "61月以上的库龄数量
        PRC3M  TYPE MBEW-SALK3,  "3月以内的库龄金额
        PRC6M  TYPE MBEW-SALK3,  "4月到6月以内的库龄金额
        PRC9M  TYPE MBEW-SALK3,  "7月到9月以内的库龄金额
        PRC12M TYPE MBEW-SALK3,  "10月到12月以内的库龄金额
        PRC18M TYPE MBEW-SALK3,  "13月到18月以内的库龄金额
        PRC24M TYPE MBEW-SALK3,  "19月到24月以内的库龄金额
        PRC36M TYPE MBEW-SALK3,  "25月到36月以内的库龄金额
        PRC60M TYPE MBEW-SALK3,  "37月到60月以内的库龄金额
        PRC61M TYPE MBEW-SALK3,  "60月以上的库龄金额
        PERPRC TYPE MBEW-SALK3,  "跌价金额
        WAERS  TYPE MSEG-WAERS,  "价格单位
        PERFLG TYPE CHAR1,       "跌价规则维护标志
       END OF TP_ALV.
*&---------------------------------------------------------------------*
*&     DATA DEFINITION
*&---------------------------------------------------------------------*
DATA: V_GJAHR TYPE BSIS-GJAHR,
      V_MONAT TYPE BKPF-MONAT,
      V_WERKS TYPE T001W-WERKS,
      V_MATNR TYPE MARA-MATNR,
      V_LGORT TYPE MARD-LGORT,
      V_BWKEY TYPE T001W-BWKEY,
      V_QTY   TYPE MBEW-LBKUM,
      V_DMBTR TYPE MBEW-SALK3,
      V_AWKEY TYPE BKPF-AWKEY,
      V_FDATE TYPE SY-DATUM,
      V_TDATE TYPE SY-DATUM,
      V_COUT  TYPE I,
      V_NUM   TYPE NUMC2,
      V_FIELD TYPE CHAR5,
      V_VALUE TYPE FAGLFLEXT-HSLVT.

DATA: S_3M  TYPE RANGE OF SY-DATUM,  "过去3月以内的库龄数量
      S_6M  TYPE RANGE OF SY-DATUM,  "过去4月到6月以内的库龄数量
      S_9M  TYPE RANGE OF SY-DATUM,  "过去7月到9月以内的库龄数量
      S_12M TYPE RANGE OF SY-DATUM,  "过去10月到12月以内的库龄数量
      S_18M TYPE RANGE OF SY-DATUM,  "过去13月到18月以内的库龄数量
      S_24M TYPE RANGE OF SY-DATUM,  "过去19月到24月以内的库龄数量
      S_36M TYPE RANGE OF SY-DATUM,  "过去25月到36月以内的库龄数量
      S_60M TYPE RANGE OF SY-DATUM,  "过去37月到60月以内的库龄数量
      S_61M TYPE SY-DATUM.           "过去61月以上库龄数量

DATA: WK_MATNR    TYPE TP_MATNR,
      IT_MATNR    TYPE STANDARD TABLE OF TP_MATNR,
      WK_MCHB     TYPE TP_DATA,
      IT_MCHB     TYPE STANDARD TABLE OF TP_DATA,
      WK_MARD     TYPE TP_DATA,
      IT_MARD     TYPE STANDARD TABLE OF TP_DATA,
      WK_MSKA     TYPE TP_DATA,
      IT_MSKA     TYPE STANDARD TABLE OF TP_DATA,
      WK_MARC     TYPE TP_DATA,
      IT_MARC     TYPE STANDARD TABLE OF TP_DATA,
      WK_CHARG    TYPE TP_DATA,
      IT_CHARG    TYPE STANDARD TABLE OF TP_DATA,
      WK_DATA     TYPE TP_DATA,
      IT_DATA     TYPE STANDARD TABLE OF TP_DATA,
      WK_ZMMT001  TYPE ZMMT001,
      IT_ZMMT001  TYPE STANDARD TABLE OF ZMMT001,
      WK_ZFIT015  TYPE ZFIT015,
      IT_ZFIT015  TYPE STANDARD TABLE OF ZFIT015,
      WK_ZFIT016  TYPE ZFIT016,
      IT_ZFIT016  TYPE STANDARD TABLE OF ZFIT016,
      WK_ZFIT017  TYPE ZFIT017,
      IT_ZFIT017  TYPE STANDARD TABLE OF ZFIT017,
      WK_OBJ      TYPE FAGLFLEXT,
      WK_FAG1     TYPE FAGLFLEXT,
      IT_FAG1     TYPE STANDARD TABLE OF FAGLFLEXT,
      WK_MCH1     TYPE MCH1,
      IT_MCH1     TYPE STANDARD TABLE OF MCH1,
      WK_CEPCT    TYPE CEPCT,
      IT_CEPCT    TYPE STANDARD TABLE OF CEPCT,
      WK_MSEG     TYPE TP_MSEG,
      IT_MSEG     TYPE STANDARD TABLE OF TP_MSEG,
      IT_MSEG1    TYPE STANDARD TABLE OF TP_MSEG,
      WK_QTY      TYPE TP_QTY,
      IT_QTY      TYPE STANDARD TABLE OF TP_QTY,
      WK_BKPF     TYPE BKPF,
      IT_BKPF     TYPE STANDARD TABLE OF BKPF,
      WK_BSEG     TYPE TP_BSEG,
      IT_BSEG     TYPE STANDARD TABLE OF TP_BSEG,
      IT_AWKEY    TYPE STANDARD TABLE OF TP_MSEG,
      WK_ALV      TYPE TP_ALV,
      IT_ALV      TYPE STANDARD TABLE OF TP_ALV,
      WK_LAYOUT   TYPE SLIS_LAYOUT_ALV,
      IT_FIELDCAT TYPE STANDARD TABLE OF SLIS_FIELDCAT_ALV,
      IT_EVENT    TYPE STANDARD TABLE OF SLIS_ALV_EVENT.


  FIELD-SYMBOLS: <FS_HEAD>  TYPE FAGLFLEXT,
                 <FS_FIELD> TYPE ANY,
                 <FS_MSEG>  TYPE TP_MSEG,
                 <FS_CHARG> TYPE TP_DATA,
                 <FS_MCHB>  TYPE TP_DATA,
                 <FS_MARD>  TYPE TP_DATA,
                 <FS_MSKA>  TYPE TP_DATA,
                 <FS_MARC>  TYPE TP_DATA,
                 <FS_ALV>   TYPE TP_ALV.

*&---------------------------------------------------------------------*
*&     PARAMETERS DEFINITION
*&---------------------------------------------------------------------*
*PARAMETERS: P_MONAT TYPE BKPF-MONAT OBLIGATORY,   "Fiscal Period
*            P_GJAHR TYPE BSIS-GJAHR OBLIGATORY,   "Fiscal Year
PARAMETERS: P_SDATE TYPE SY-DATUM OBLIGATORY,
            P_BUKRS TYPE T001-BUKRS OBLIGATORY.   "Company Code

SELECT-OPTIONS: S_WERKS FOR V_WERKS OBLIGATORY,
                S_MATNR FOR V_MATNR,
                S_LGORT FOR V_LGORT.

*&---------------------------------------------------------------------*
*&     CONSTANTS DEFINITION
*&---------------------------------------------------------------------*
CONSTANTS: C_X          TYPE CHAR1 VALUE 'X',
           C_DAY        TYPE CHAR2 VALUE '01'.

*&---------------------------------------------------------------------*
*&     INITIALIZATION
*&---------------------------------------------------------------------*
INITIALIZATION.
* 初始化数据
  PERFORM INIT_DATA.
* 查询日期设置
  PERFORM SET_DATE.

*&---------------------------------------------------------------------*
*&     AT SELECTION-SCREEN
*&---------------------------------------------------------------------*
AT SELECTION-SCREEN.
* 输入检查
  PERFORM CHECK_INPUT.
*&---------------------------------------------------------------------*
*&     START-OF-SELECTION
*&---------------------------------------------------------------------*
START-OF-SELECTION.
* 得到对象数据
  PERFORM GET_DATA.
* 编辑对象数据
  PERFORM EDIT_DATA.
* 设定 FIELDCAT
  PERFORM SET_FIELDCAT.
* 设定 LAYOUT
  PERFORM SET_LAYOUT.
* 设定 Eventa
  PERFORM SET_ALV_EVENT.
* 输出 ALV
  PERFORM SHOW_ALV.

*&---------------------------------------------------------------------*
*&      Form  INIT_DATA
*&---------------------------------------------------------------------*
*       初始化数据
*----------------------------------------------------------------------*
FORM INIT_DATA .

  CLEAR: V_WERKS,
         V_MATNR,
         V_LGORT,
         V_BWKEY,
         V_QTY,
         WK_MATNR,
         WK_ZMMT001,
         WK_MCH1,
         WK_MCH1,
         WK_MSEG,
         WK_ALV,
         WK_LAYOUT.
  REFRESH: IT_MATNR,
           IT_ZMMT001,
           IT_MCH1,
           IT_CEPCT,
           IT_MSEG,
           IT_ALV,
           IT_FIELDCAT,
           IT_EVENT.

ENDFORM.                    " INIT_DATA
*&---------------------------------------------------------------------*
*&      Form  CHECK_INPUT
*&---------------------------------------------------------------------*
*      输入检查
*----------------------------------------------------------------------*
FORM CHECK_INPUT .

  DATA: L_STR     TYPE CHAR300,
        LT_T001K  TYPE STANDARD TABLE OF T001K,
        LW_T001W  TYPE T001W,
        LT_T001W  TYPE STANDARD TABLE OF T001W.

  REFRESH LT_T001K.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE LT_T001K
    FROM T001K
   WHERE BUKRS = P_BUKRS.

  REFRESH LT_T001W.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE LT_T001W
    FROM T001W
   WHERE WERKS IN S_WERKS.

* 输入判断
  LOOP AT LT_T001W INTO LW_T001W.
    READ TABLE LT_T001K TRANSPORTING NO FIELDS
                        WITH KEY BWKEY = LW_T001W-BWKEY.
    IF SY-SUBRC <> 0.
      CONCATENATE L_STR
                  LW_T001W-WERKS
             INTO L_STR
          SEPARATED BY '/'.
    ENDIF.
  ENDLOOP.
  IF LT_T001W IS INITIAL.
    MESSAGE '工厂不存在,请重新输入!' TYPE 'E'.
    LEAVE TO LIST-PROCESSING.
  ENDIF.
  IF L_STR IS NOT INITIAL.
    L_STR+0(1) = ''.
    CONCATENATE '该公司代码不包含工厂:'
                L_STR
           INTO L_STR.
    MESSAGE E398(00) WITH L_STR.
    LEAVE TO LIST-PROCESSING.
  ENDIF.

ENDFORM.                    " CHECK_INPUT
*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       得到对象数据
*----------------------------------------------------------------------*
FORM GET_DATA .

  DATA: L_MENGE   TYPE MSEG-MENGE, "数量
        LW_MCHB   TYPE TP_DATA,
        LT_MCHB   TYPE STANDARD TABLE OF TP_DATA,
        LW_MSKA   TYPE TP_DATA,
        LT_MSKA   TYPE STANDARD TABLE OF TP_DATA,
        LW_MATNR  TYPE TP_MATNR,
        LT_MATNR  TYPE STANDARD TABLE OF TP_MATNR,
        LW_DATA   TYPE TP_DATA,
        LT_DATA   TYPE STANDARD TABLE OF TP_DATA.

  CLEAR V_FDATE.
  CONCATENATE P_SDATE+0(6)
              '01'
         INTO V_FDATE.
  V_GJAHR = P_SDATE+0(4).
  V_MONAT = P_SDATE+4(2).

*  得到批次管理物料数据
   REFRESH IT_MCHB.
   SELECT MCHB~MATNR   "物料号
          MCHB~WERKS   "工厂
          MCHB~LGORT   "库存地点
          MCHB~CHARG   "批号
          MCHB~LFGJA   "当前期间的会计年度
          MCHB~LFMON   "当前期间
          MCHB~CLABS   "非限制使用的估价的库存
          MCHB~CUMLM   "在运库存
          MCHB~CINSM   "质量检验中的库存
          MARA~XCHPF   "批次管理标志
     INTO CORRESPONDING FIELDS OF TABLE IT_MCHB
     FROM MCHB
     INNER JOIN MARA ON MCHB~MATNR = MARA~MATNR
    WHERE MCHB~MATNR IN S_MATNR
      AND MCHB~WERKS IN S_WERKS
      AND MCHB~LGORT IN S_LGORT
      AND MARA~XCHPF = 'X'.

*  批次物料历史库存
   SELECT MCHBH~MATNR   "物料号
          MCHBH~WERKS   "工厂
          MCHBH~LGORT   "库存地点
          MCHBH~CHARG   "批号
          MCHBH~LFGJA   "当前期间的会计年度
          MCHBH~LFMON   "当前期间
          MCHBH~CLABS   "非限制使用的估价的库存
          MCHBH~CUMLM   "在运库存
          MCHBH~CINSM   "质量检验中的库存
          MARA~XCHPF    "批次管理标志
     APPENDING CORRESPONDING FIELDS OF TABLE IT_MCHB
     FROM MCHBH
     INNER JOIN MARA ON MCHBH~MATNR = MARA~MATNR
    WHERE MCHBH~MATNR IN S_MATNR
      AND MCHBH~WERKS IN S_WERKS
      AND MCHBH~LGORT IN S_LGORT
      AND MARA~XCHPF = 'X'.

*  查询日期绑定
   LOOP AT IT_MCHB ASSIGNING <FS_MCHB>.
     CONCATENATE <FS_MCHB>-LFGJA
                 <FS_MCHB>-LFMON
                 '01'
            INTO <FS_MCHB>-SDATE.
   ENDLOOP.

*   排除库存符合查询期间的对象数据
    DELETE IT_MCHB WHERE SDATE > V_FDATE.

    SORT IT_MCHB BY WERKS ASCENDING
                    MATNR ASCENDING
                    LGORT ASCENDING
                    CHARG ASCENDING
                    SDATE DESCENDING.
*  得到满足查询条件的唯一的批次物料
   DELETE ADJACENT DUPLICATES FROM IT_MCHB COMPARING WERKS
                                                     MATNR
                                                     LGORT
                                                     CHARG.
* 排除库存数量为0的对象数据
  DELETE IT_MCHB WHERE CLABS = 0
                   AND CUMLM = 0
                   AND CINSM = 0.

   APPEND LINES OF IT_MCHB TO IT_DATA.
   APPEND LINES OF IT_MCHB TO IT_CHARG.

*  普通物料管理
   REFRESH IT_MARD.
   SELECT MARD~MATNR   "物料号
          MARD~WERKS   "工厂
          MARD~LGORT   "库存地点
          MARD~LFGJA   "当前期间的会计年度
          MARD~LFMON   "当前期间
          MARD~LABST AS CLABS "非限制使用的估价的库存
          MARD~UMLME AS CUMLM "在运库存
          MARD~INSME AS CINSM "质量检验中的库存
     INTO CORRESPONDING FIELDS OF TABLE IT_MARD
     FROM MARD
     INNER JOIN MARA ON MARD~MATNR = MARA~MATNR
    WHERE MARD~MATNR IN S_MATNR
      AND MARD~WERKS IN S_WERKS
      AND MARD~LGORT IN S_LGORT
      AND MARA~XCHPF <> 'X'.

*  普通物料历史库存
   SELECT MARDH~MATNR   "物料号
          MARDH~WERKS   "工厂
          MARDH~LGORT   "库存地点
          MARDH~LFGJA   "当前期间的会计年度
          MARDH~LFMON   "当前期间
          MARDH~LABST AS CLABS "非限制使用的估价的库存
          MARDH~UMLME AS CUMLM "在运库存
          MARDH~INSME AS CINSM "质量检验中的库存
     APPENDING CORRESPONDING FIELDS OF TABLE IT_MARD
     FROM MARDH
     INNER JOIN MARA ON MARDH~MATNR = MARA~MATNR
    WHERE MARDH~MATNR IN S_MATNR
      AND MARDH~WERKS IN S_WERKS
      AND MARDH~LGORT IN S_LGORT
      AND MARA~XCHPF <> 'X'.

*  查询日期绑定
   LOOP AT IT_MARD ASSIGNING <FS_MARD>.
     CONCATENATE <FS_MARD>-LFGJA
                 <FS_MARD>-LFMON
                 '01'
            INTO <FS_MARD>-SDATE.
   ENDLOOP.

*   排除库存符合查询期间的对象数据
    DELETE IT_MARD WHERE SDATE > V_FDATE.

    SORT IT_MARD BY WERKS ASCENDING
                    MATNR ASCENDING
                    LGORT ASCENDING
                    SDATE DESCENDING.
*  得到满足查询条件的唯一的批次物料
   DELETE ADJACENT DUPLICATES FROM IT_MARD COMPARING WERKS
                                                     MATNR
                                                     LGORT.
* 排除库存数量为0的对象数据
  DELETE IT_MARD WHERE CLABS = 0
                   AND CUMLM = 0
                   AND CINSM = 0.

   APPEND LINES OF IT_MARD TO IT_DATA.

*  特殊物料管理
   REFRESH IT_MSKA.
   SELECT MSKA~MATNR   "物料号
          MSKA~WERKS   "工厂
          MSKA~LGORT   "库存地点
          MSKA~CHARG   "批号
          MSKA~SOBKZ   "特殊库存标识
          MSKA~VBELN   "销售和分销凭证号
          MSKA~POSNR   "销售和分销凭证的项目号
          MSKA~KALAB AS CLABS "非限制使用的估价的库存
          MSKA~KAINS AS CINSM "质量检验中的库存
          MSKA~LFGJA   "当前期间的会计年度
          MSKA~LFMON   "当前期间
     INTO CORRESPONDING FIELDS OF TABLE IT_MSKA
     FROM MSKA
    WHERE MSKA~MATNR IN S_MATNR
      AND MSKA~WERKS IN S_WERKS
      AND MSKA~LGORT IN S_LGORT.
*  特殊物料历史库存
   SELECT MSKAH~MATNR   "物料号
          MSKAH~WERKS   "工厂
          MSKAH~LGORT   "库存地点
          MSKAH~CHARG   "批号
          MSKAH~SOBKZ   "特殊库存标识
          MSKAH~VBELN   "销售和分销凭证号
          MSKAH~POSNR   "销售和分销凭证的项目号
          MSKAH~KALAB AS CLABS "非限制使用的估价的库存
          MSKAH~KAINS AS CINSM "质量检验中的库存
          MSKAH~LFGJA   "当前期间的会计年度
          MSKAH~LFMON   "当前期间
     APPENDING CORRESPONDING FIELDS OF TABLE IT_MSKA
     FROM MSKAH
    WHERE MSKAH~MATNR IN S_MATNR
      AND MSKAH~WERKS IN S_WERKS
      AND MSKAH~LGORT IN S_LGORT.

*  查询日期绑定
   LOOP AT IT_MSKA ASSIGNING <FS_MSKA>.
     CONCATENATE <FS_MSKA>-LFGJA
                 <FS_MSKA>-LFMON
                 '01'
            INTO <FS_MSKA>-SDATE.
   ENDLOOP.

*   排除库存符合查询期间的对象数据
    DELETE IT_MSKA WHERE SDATE > V_FDATE.

    SORT IT_MSKA BY WERKS ASCENDING
                    MATNR ASCENDING
                    LGORT ASCENDING
                    CHARG ASCENDING
                    SDATE DESCENDING.

    REFRESH LT_MSKA.
    APPEND LINES OF IT_MSKA TO LT_MSKA.
*  得到满足查询条件的唯一的批次物料
   DELETE ADJACENT DUPLICATES FROM IT_MSKA COMPARING WERKS
                                                     MATNR
                                                     LGORT
                                                     CHARG.
*  按批次合计销售订单
   LOOP AT IT_MSKA ASSIGNING <FS_MSKA>.
     CLEAR: <FS_MSKA>-CLABS,
            <FS_MSKA>-CINSM,
            <FS_MSKA>-VBELN,
            <FS_MSKA>-POSNR.
     LOOP AT LT_MSKA INTO LW_MSKA
                      WHERE WERKS = <FS_MSKA>-WERKS
                        AND MATNR = <FS_MSKA>-MATNR
                        AND LGORT = <FS_MSKA>-LGORT
                        AND CHARG = <FS_MSKA>-CHARG
                        AND SDATE = <FS_MSKA>-SDATE.
       <FS_MSKA>-CLABS = <FS_MSKA>-CLABS + LW_MSKA-CLABS.
       <FS_MSKA>-CINSM = <FS_MSKA>-CINSM + LW_MSKA-CINSM.
     ENDLOOP.
   ENDLOOP.

* 排除库存数量为0的对象数据
  DELETE IT_MSKA WHERE CLABS = 0
                   AND CUMLM = 0
                   AND CINSM = 0.

   APPEND LINES OF IT_MSKA TO IT_DATA.
   APPEND LINES OF IT_MSKA TO IT_CHARG.

*  在途库存物料管理
   REFRESH IT_MARC.
   SELECT MARC~MATNR   "物料号
          MARC~WERKS   "工厂
          MARC~UMLMC AS CLABS "非限制使用的估价的库存
          MARC~LFGJA   "当前期间的会计年度
          MARC~LFMON   "当前期间
     INTO CORRESPONDING FIELDS OF TABLE IT_MARC
     FROM MARC
    WHERE MARC~MATNR IN S_MATNR
      AND MARC~WERKS IN S_WERKS.

*  特殊物料历史库存
   SELECT MARCH~MATNR   "物料号
          MARCH~WERKS   "工厂
          MARCH~UMLMC AS CLABS "非限制使用的估价的库存
          MARCH~LFGJA   "当前期间的会计年度
          MARCH~LFMON   "当前期间
     APPENDING CORRESPONDING FIELDS OF TABLE IT_MARC
     FROM MARCH
    WHERE MARCH~MATNR IN S_MATNR
      AND MARCH~WERKS IN S_WERKS.


*  查询日期绑定
   LOOP AT IT_MARC ASSIGNING <FS_MARC>.
     <FS_MARC>-LGORT = 'XXXX'.
     CONCATENATE <FS_MARC>-LFGJA
                 <FS_MARC>-LFMON
                 '01'
            INTO <FS_MARC>-SDATE.
   ENDLOOP.

*   排除库存符合查询期间的对象数据
    DELETE IT_MARC WHERE SDATE > V_FDATE.

    SORT IT_MARC BY WERKS ASCENDING
                    MATNR ASCENDING
                    SDATE DESCENDING.

*  得到满足查询条件的唯一的批次物料
   DELETE ADJACENT DUPLICATES FROM IT_MARC COMPARING WERKS
                                                     MATNR.
*  排除库存数量为0的对象数据
   DELETE IT_MARC WHERE CLABS = 0
                    AND CUMLM = 0
                    AND CINSM = 0.

    APPEND LINES OF IT_MARC TO IT_DATA.


*   排除库存数量为0的对象数据
    DELETE IT_DATA WHERE ( CLABS = 0
                       AND CUMLM = 0
                       AND CINSM = 0 )
                   OR SDATE > V_FDATE.
    SORT IT_DATA BY WERKS ASCENDING
                    MATNR ASCENDING
                    LGORT ASCENDING
                    SDATE DESCENDING.
*   得到输出对象
    DELETE ADJACENT DUPLICATES FROM IT_DATA COMPARING WERKS
                                                      MATNR
                                                      LGORT.

  IF IT_DATA IS NOT INITIAL.
*   得到物料属性
    REFRESH LT_MATNR.
    SELECT MARA~MATNR   "物料号
           MARA~MATKL   "物料组
           MAKT~MAKTX   "物料描述
           MARA~XCHPF   "批次管理需求的标识
           MARA~MEINS   "数量单位
           MARC~PRCTR   "利润中心
      INTO CORRESPONDING FIELDS OF TABLE LT_MATNR
      FROM MARA
      INNER JOIN MARC ON MARC~MATNR = MARA~MATNR
      INNER JOIN MAKT ON MAKT~MATNR = MARA~MATNR
                     AND MAKT~SPRAS = SY-LANGU
      FOR ALL ENTRIES IN IT_DATA
     WHERE MARA~MATNR = IT_DATA-MATNR
       AND MARC~WERKS = IT_DATA-WERKS.
  ENDIF.

* 整合对象数据
  REFRESH LT_DATA.
  LOOP AT IT_DATA INTO WK_DATA.
    CLEAR WK_MATNR.
    WK_MATNR-WERKS = WK_DATA-WERKS.
    WK_MATNR-LGORT = WK_DATA-LGORT.
    WK_MATNR-MATNR = WK_DATA-MATNR.
    CLEAR LW_MATNR.
    READ TABLE LT_MATNR INTO LW_MATNR
                    WITH KEY MATNR = WK_DATA-MATNR.
    IF SY-SUBRC = 0.
      WK_MATNR-MAKTX = LW_MATNR-MAKTX.
      WK_MATNR-XCHPF = LW_MATNR-XCHPF.
      WK_MATNR-MEINS = LW_MATNR-MEINS.
      WK_MATNR-PRCTR = LW_MATNR-PRCTR.
      WK_MATNR-MATKL = LW_MATNR-MATKL.
    ENDIF.
*   计算库位总数量
    IF WK_MATNR-XCHPF IS NOT INITIAL.
      LOOP AT IT_MCHB INTO WK_MCHB
                      WHERE WERKS = WK_MATNR-WERKS
                        AND MATNR = WK_MATNR-MATNR
                        AND LGORT = WK_MATNR-LGORT.
*       数量累计:限制使用的估价的库存/在运库存/质量检验中的库存
        CLEAR L_MENGE.
        L_MENGE = WK_MCHB-CLABS + WK_MCHB-CUMLM + WK_MCHB-CINSM.
        WK_MATNR-MENGE = WK_MATNR-MENGE + L_MENGE.
      ENDLOOP.
    ELSE.
*     非批次管理物料设置
      APPEND WK_DATA TO LT_DATA.
      LOOP AT IT_MARD INTO WK_MARD
                      WHERE WERKS = WK_MATNR-WERKS
                        AND MATNR = WK_MATNR-MATNR
                        AND LGORT = WK_MATNR-LGORT.
*       数量累计:限制使用的估价的库存/在运库存/质量检验中的库存
        CLEAR L_MENGE.
        L_MENGE = WK_MARD-CLABS + WK_MARD-CUMLM + WK_MARD-CINSM.
        WK_MATNR-MENGE = WK_MATNR-MENGE + L_MENGE.
      ENDLOOP.
    ENDIF.
    LOOP AT IT_MSKA INTO WK_MSKA
                    WHERE WERKS = WK_MATNR-WERKS
                      AND MATNR = WK_MATNR-MATNR
                      AND LGORT = WK_MATNR-LGORT.
*     数量累计:限制使用的估价的库存/在运库存/质量检验中的库存
      CLEAR L_MENGE.
      L_MENGE = WK_MSKA-CLABS + WK_MSKA-CUMLM + WK_MSKA-CINSM.
      WK_MATNR-MENGE = WK_MATNR-MENGE + L_MENGE.
    ENDLOOP.
*   在途库存设置
    IF WK_MATNR-LGORT = 'XXXX'.
      CLEAR WK_MARC.
      READ TABLE IT_MARC INTO WK_MARC
                         WITH KEY WERKS = WK_MATNR-WERKS
                                  MATNR = WK_MATNR-MATNR.
      IF SY-SUBRC = 0.
        WK_MATNR-MENGE = WK_MARC-CLABS.
      ENDIF.
    ENDIF.
    APPEND WK_MATNR TO IT_MATNR.
  ENDLOOP.

* 非批次管理物料物料移动数据
  IF LT_DATA IS NOT INITIAL.
*   计算库龄和最后物料移动时间
    REFRESH IT_MSEG.
    SELECT MSEG~BUKRS     "公司代码
           MSEG~MBLNR     "物料凭证编号
           MSEG~MJAHR     "物料凭证年度
           MSEG~ZEILE     "物料凭证中的项目
           MSEG~MATNR     "物料号
           MSEG~WERKS     "工厂
           MSEG~LGORT     "库存地点
           MSEG~BWART     "移动类型
           MSEG~SHKZG     "借贷标识
           MSEG~MENGE     "数量
           MSEG~EXBWR     "以本地货币计量的过帐金额
           MSEG~CHARG     "批号
           MSEG~WAERS     "价格单位
           MKPF~BUDAT     "凭证中的过帐日期
      INTO CORRESPONDING FIELDS OF TABLE IT_MSEG
      FROM MKPF
      INNER JOIN MSEG ON MKPF~MBLNR = MSEG~MBLNR
                     AND MKPF~MJAHR = MSEG~MJAHR
      FOR ALL ENTRIES IN LT_DATA
     WHERE MSEG~WERKS = LT_DATA-WERKS
       AND MSEG~MATNR = LT_DATA-MATNR
       AND MSEG~LGORT = LT_DATA-LGORT
       AND MSEG~BUKRS = P_BUKRS
       AND MKPF~BUDAT <= P_SDATE
       AND MSEG~MENGE <> 0
       AND MSEG~BWART IN ('101', '701', '561')
       AND MSEG~XAUTO = ''.

   DELETE IT_MSEG WHERE MATNR IS INITIAL.

   SORT IT_MSEG BY WERKS ASCENDING
                   MATNR ASCENDING
                   LGORT ASCENDING
                   BUDAT DESCENDING.
  ENDIF.

  IF IT_MATNR IS NOT INITIAL.
*   得到批次管理的日期

    IF IT_CHARG IS NOT INITIAL.
      REFRESH IT_MCH1.
      SELECT *
        INTO CORRESPONDING FIELDS OF TABLE IT_MCH1
       FROM MCH1
       FOR ALL ENTRIES IN IT_CHARG
       WHERE MATNR = IT_CHARG-MATNR
         AND CHARG = IT_CHARG-CHARG.

*     按照物料号/最近收货日期排序
      SORT IT_MCH1 BY MATNR ASCENDING
                      CHARG ASCENDING
                      LWEDT DESCENDING.
    ENDIF.
*   批次收货日期管理绑定
    LOOP AT IT_CHARG ASSIGNING <FS_CHARG>.
      CLEAR WK_MCH1.
      READ TABLE IT_MCH1 INTO WK_MCH1
                         WITH KEY MATNR = <FS_CHARG>-MATNR
                                  CHARG = <FS_CHARG>-CHARG
                                  BINARY SEARCH.
      IF SY-SUBRC = 0.
        <FS_CHARG>-LWEDT = WK_MCH1-LWEDT.
      ENDIF.
      <FS_CHARG>-MENGE = <FS_CHARG>-CLABS +
                         <FS_CHARG>-CUMLM +
                         <FS_CHARG>-CINSM.
    ENDLOOP.
*   得到库龄金额
    REFRESH IT_ZFIT015.
    IF P_BUKRS <> '3200'
   AND P_BUKRS <> '3300'.
    SELECT *
      FROM ZFIT015
      INTO CORRESPONDING FIELDS OF TABLE IT_ZFIT015
      FOR ALL ENTRIES IN IT_MATNR
     WHERE BUKRS = P_BUKRS
       AND MATNR = IT_MATNR-MATNR
       AND WERKS = IT_MATNR-WERKS
       AND GJAHR = V_GJAHR
       AND MONAT = V_MONAT.
    ELSE.
      SELECT *
        FROM ZFIT015
        INTO CORRESPONDING FIELDS OF TABLE IT_ZFIT015
        FOR ALL ENTRIES IN IT_MATNR
       WHERE BUKRS = P_BUKRS
         AND MATNR = IT_MATNR-MATNR
         AND GJAHR = V_GJAHR
         AND MONAT = V_MONAT.
      LOOP AT IT_ZFIT015 INTO WK_ZFIT015
                        WHERE WERKS IS INITIAL.
        WK_ZFIT015-WERKS = WK_ZFIT015-BUKRS.
        MODIFY IT_ZFIT015 FROM WK_ZFIT015 TRANSPORTING WERKS.
      ENDLOOP.
    ENDIF.
    SORT IT_ZFIT015 BY WERKS ASCENDING
                       MATNR ASCENDING.
*   得到跌价比率
    REFRESH IT_ZFIT017.
    SELECT *
      FROM ZFIT017
      INTO CORRESPONDING FIELDS OF TABLE IT_ZFIT017
      FOR ALL ENTRIES IN IT_MATNR
     WHERE MATKL = IT_MATNR-MATKL
       AND PRCTR = IT_MATNR-PRCTR.

    SORT IT_ZFIT017 BY MATKL ASCENDING
                       PRCTR ASCENDING.

*   利润中心描述
    REFRESH IT_CEPCT.
    SELECT *
      INTO CORRESPONDING FIELDS OF TABLE IT_CEPCT
      FROM CEPCT
      FOR ALL ENTRIES IN IT_MATNR
     WHERE PRCTR = IT_MATNR-PRCTR
       AND SPRAS = SY-LANGU.
    SORT IT_CEPCT BY PRCTR ASCENDING.
    DELETE ADJACENT DUPLICATES FROM IT_CEPCT COMPARING PRCTR.

* 计算物料财务数量和单位
    REFRESH IT_ZMMT001.
    SELECT *
      INTO CORRESPONDING FIELDS OF TABLE IT_ZMMT001
      FROM ZMMT001
      FOR ALL ENTRIES IN IT_MATNR
     WHERE MATNR = IT_MATNR-MATNR.
    SORT IT_ZMMT001 BY MATNR ASCENDING.
  ENDIF.

* 取得总帐科目数据
  REFRESH IT_FAG1.
  SELECT *
    INTO CORRESPONDING FIELDS OF TABLE IT_FAG1
    FROM FAGLFLEXT
   WHERE RYEAR = V_GJAHR
     AND RACCT = '0014100000'
     AND RBUKRS = P_BUKRS
     AND RBUSA IN S_WERKS
     AND RRCTY = '0'
     AND RLDNR = '0L'.

* 得到发票校验引起的尾差金额
  REFRESH IT_ZFIT016.
  SELECT *
    FROM ZFIT016
    INTO CORRESPONDING FIELDS OF TABLE IT_ZFIT016
   WHERE BUKRS = P_BUKRS
     AND BUDAT <= P_SDATE
     AND GSBER IN S_WERKS.

ENDFORM.                    " GET_DATA
*&---------------------------------------------------------------------*
*&      Form  EDIT_DATA
*&---------------------------------------------------------------------*
*       编辑对象数据
*----------------------------------------------------------------------*
FORM EDIT_DATA .

  DATA: L_QTY    TYPE MBEW-LBKUM,
        L_MENGE  TYPE MSEG-MENGE,
        L_SQTY   TYPE MBEW-LBKUM,
        L_NUM    TYPE MBEW-LBKUM,
        L_DMBTR  TYPE MBEW-SALK3,
        L_SALK3  TYPE MBEW-SALK3,
        L_INDEX  TYPE SY-INDEX,
        LW_MATNR TYPE TP_MATNR,
        L_SUM    TYPE ZFIT015-DMBTR,
        LW_ALV   TYPE TP_ALV.

* 设置期间范围
  PERFORM SET_MONTH.

* 数据整合
  LOOP AT IT_MATNR INTO WK_MATNR.
    L_INDEX = SY-TABIX + 1.

    CLEAR: WK_ALV,L_QTY.
*   物料启用批次管理判断
    IF WK_MATNR-XCHPF IS NOT INITIAL.
*     按照输出行循环批次管理表(物料/库位查找)
      LOOP AT IT_CHARG INTO WK_CHARG
                       WHERE WERKS = WK_MATNR-WERKS
                         AND MATNR = WK_MATNR-MATNR
                         AND LGORT = WK_MATNR-LGORT.

*       计算物料所在库位的数量
        L_QTY = L_QTY + WK_CHARG-MENGE.

*       库龄数量差异调整
        IF L_QTY > WK_MATNR-MENGE.
          WK_CHARG-MENGE = WK_MATNR-MENGE - ( L_QTY - WK_CHARG-MENGE ) .
          L_QTY = WK_MATNR-MENGE.
        ENDIF.

*       过去3月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_3M
         OR WK_CHARG-LWEDT >= P_SDATE.
          WK_ALV-QTY3M = WK_ALV-QTY3M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去4月到6月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_6M.
          WK_ALV-QTY6M = WK_ALV-QTY6M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去7月到9月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_9M.
          WK_ALV-QTY9M = WK_ALV-QTY9M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去10月到12月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_12M.
          WK_ALV-QTY12M = WK_ALV-QTY12M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去13月到18月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_18M.
          WK_ALV-QTY18M = WK_ALV-QTY18M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去19月到24月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_24M.
          WK_ALV-QTY24M = WK_ALV-QTY24M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去25月到36月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_36M.
          WK_ALV-QTY36M = WK_ALV-QTY36M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去37月到60月以内的库龄数量
        IF WK_CHARG-LWEDT IN S_60M.
          WK_ALV-QTY60M = WK_ALV-QTY60M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       过去61月以上的库龄数量
        IF WK_CHARG-LWEDT < S_61M.
          WK_ALV-QTY61M = WK_ALV-QTY61M + WK_CHARG-MENGE.
          CONTINUE.
        ENDIF.
*       库位数量相等判断
        IF L_QTY = WK_MATNR-MENGE.
          EXIT.
        ENDIF.
      ENDLOOP.
    ELSE.
*     按照输出行循环MSEG(物料/库位查找)
      LOOP AT IT_MSEG INTO WK_MSEG
                      WHERE WERKS = WK_MATNR-WERKS
                        AND MATNR = WK_MATNR-MATNR
                        AND LGORT = WK_MATNR-LGORT.

*       移动数量类型判断
        CLEAR L_MENGE.
        L_MENGE = WK_MSEG-MENGE.

*       计算物料所在库位的数量
        L_QTY = L_QTY + L_MENGE.

*       库龄数量差异调整
        IF L_QTY > WK_MATNR-MENGE.
          L_MENGE = WK_MATNR-MENGE - ( L_QTY - L_MENGE ).
          L_QTY = WK_MATNR-MENGE.
        ENDIF.

*       过去3月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_3M.
          WK_ALV-QTY3M = WK_ALV-QTY3M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去4月到6月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_6M.
          WK_ALV-QTY6M = WK_ALV-QTY6M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去7月到9月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_9M.
          WK_ALV-QTY9M = WK_ALV-QTY9M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去10月到12月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_12M.
          WK_ALV-QTY12M = WK_ALV-QTY12M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去13月到18月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_18M.
          WK_ALV-QTY18M = WK_ALV-QTY18M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去19月到24月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_24M.
          WK_ALV-QTY24M = WK_ALV-QTY24M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去25月到36月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_36M.
          WK_ALV-QTY36M = WK_ALV-QTY36M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去37月到60月以内的库龄数量
        IF WK_MSEG-BUDAT IN S_60M.
          WK_ALV-QTY60M = WK_ALV-QTY60M + L_MENGE.
          CONTINUE.
        ENDIF.
*       过去61月以上的库龄数量
        IF WK_MSEG-BUDAT < S_61M.
          WK_ALV-QTY61M = WK_ALV-QTY61M + L_MENGE.
          CONTINUE.
        ENDIF.
*       库位数量相等判断
        IF L_QTY = WK_MATNR-MENGE.
          EXIT.
        ENDIF.
     ENDLOOP.
    ENDIF.
    IF L_QTY < WK_MATNR-MENGE.
      WK_ALV-QTY61M = WK_ALV-QTY61M +
                      WK_MATNR-MENGE - L_QTY.
    ENDIF.
*   计算物料总数量
    L_SQTY = L_SQTY + WK_MATNR-MENGE.
*   库存数量/数量单位
    WK_ALV-LBKUM1 = WK_MATNR-MENGE.
    WK_ALV-MEINS1 = WK_MATNR-MEINS.
    WK_ALV-WAERS = WK_MSEG-WAERS.
    WK_ALV-WERKS = WK_MATNR-WERKS.
    WK_ALV-LGORT = WK_MATNR-LGORT.
    WK_ALV-ZYEAR = V_GJAHR.
    WK_ALV-ZMONTH = V_MONAT.
    WK_ALV-MATNR = WK_MATNR-MATNR.
    WK_ALV-MAKTX = WK_MATNR-MAKTX.
    WK_ALV-MATKL = WK_MATNR-MATKL.
    WK_ALV-XCHPF = WK_MATNR-XCHPF.
    WK_ALV-PRCTR = WK_MATNR-PRCTR.
*   利润中心描述
    CLEAR WK_CEPCT.
    READ TABLE IT_CEPCT INTO WK_CEPCT
                        WITH KEY PRCTR = WK_MATNR-PRCTR
                                 BINARY SEARCH.
    IF SY-SUBRC = 0.
      WK_ALV-PRTXT = WK_CEPCT-MCTXT.
    ENDIF.
*   财务库存数量/数量单位
    CLEAR WK_ZMMT001.
    READ TABLE IT_ZMMT001 INTO WK_ZMMT001
                          BINARY SEARCH
                          WITH KEY MATNR = WK_MATNR-MATNR.
    IF WK_ZMMT001-VALUE1 <> 0.
      WK_ALV-LBKUM2 = WK_ALV-LBKUM1 *
                     WK_ZMMT001-VALUE2 / WK_ZMMT001-VALUE1.
      WK_ALV-MEINS2 = WK_ZMMT001-UNIT.
    ENDIF.

*   同组的最后一行数据
    CLEAR LW_MATNR.
    READ TABLE IT_MATNR INTO LW_MATNR INDEX L_INDEX.
    IF WK_MATNR-MATNR <> LW_MATNR-MATNR.
*     计算库存金额
      CLEAR L_SUM.
      LOOP AT IT_ZFIT015 INTO WK_ZFIT015
                          WHERE WERKS = WK_MATNR-WERKS
                            AND MATNR = WK_MATNR-MATNR.
        L_SUM = L_SUM + WK_ZFIT015-DMBTR.
      ENDLOOP.
*     物料总数量/金额保存
      CLEAR WK_QTY.
      WK_QTY-WERKS = WK_MATNR-WERKS.
      WK_QTY-MATNR = WK_MATNR-MATNR.
      WK_QTY-MENGE = L_SQTY.
      WK_QTY-DMBTR = L_SUM.
      APPEND WK_QTY TO IT_QTY.
      CLEAR L_SQTY.
    ENDIF.
    APPEND WK_ALV TO IT_ALV.
  ENDLOOP.
* 排序
  SORT IT_QTY BY WERKS ASCENDING
                 MATNR ASCENDING.
* 输出列表金额设定
  CLEAR L_INDEX.

  LOOP AT IT_ALV ASSIGNING <FS_ALV>.
    L_INDEX = SY-TABIX + 1.

*   库位数量在物料总数量所占比例
    CLEAR WK_QTY.
    READ TABLE IT_QTY INTO WK_QTY
                      WITH KEY WERKS = <FS_ALV>-WERKS
                               MATNR = <FS_ALV>-MATNR
                               BINARY SEARCH.
    IF WK_QTY-MENGE <> 0.
      <FS_ALV>-PRICE = WK_QTY-DMBTR / WK_QTY-MENGE. "价格

*     库位金额
      <FS_ALV>-SALK3 = <FS_ALV>-LBKUM1 * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      L_SALK3 = L_SALK3 + <FS_ALV>-SALK3.

*     过去历史期间的库龄金额
      <FS_ALV>-PRC3M = <FS_ALV>-QTY3M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC6M = <FS_ALV>-QTY6M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC9M = <FS_ALV>-QTY9M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC12M = <FS_ALV>-QTY12M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC18M = <FS_ALV>-QTY18M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC24M = <FS_ALV>-QTY24M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC36M = <FS_ALV>-QTY36M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC60M = <FS_ALV>-QTY60M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
      <FS_ALV>-PRC61M = <FS_ALV>-QTY61M * ( WK_QTY-DMBTR / WK_QTY-MENGE ).
    ENDIF.

*   差异列累计
    CLEAR L_DMBTR.
    L_DMBTR = <FS_ALV>-PRC3M + <FS_ALV>-PRC6M + <FS_ALV>-PRC9M
            + <FS_ALV>-PRC12M + <FS_ALV>-PRC18M + <FS_ALV>-PRC24M
            + <FS_ALV>-PRC36M + <FS_ALV>-PRC60M + <FS_ALV>-PRC61M.
    IF <FS_ALV>-SALK3 <> L_DMBTR.
      <FS_ALV>-PRC3M = <FS_ALV>-PRC3M + ( <FS_ALV>-SALK3 - L_DMBTR ).
    ENDIF.

*   跌价金额/跌价维护标志
    CLEAR WK_ZFIT017.
    READ TABLE IT_ZFIT017 INTO WK_ZFIT017
                          WITH KEY MATKL = <FS_ALV>-MATKL
                                   PRCTR = <FS_ALV>-PRCTR
                                   BINARY SEARCH.
    IF SY-SUBRC = 0.
      <FS_ALV>-PERPRC = <FS_ALV>-PRC3M * WK_ZFIT017-PER3M / 100 +
                      <FS_ALV>-PRC6M * WK_ZFIT017-PER6M / 100 +
                      <FS_ALV>-PRC9M * WK_ZFIT017-PER9M / 100 +
                      <FS_ALV>-PRC12M * WK_ZFIT017-PER12M / 100 +
                      <FS_ALV>-PRC18M * WK_ZFIT017-PER18M / 100 +
                      <FS_ALV>-PRC24M * WK_ZFIT017-PER24M / 100 +
                      <FS_ALV>-PRC36M * WK_ZFIT017-PER36M / 100 +
                      <FS_ALV>-PRC60M * WK_ZFIT017-PER60M / 100 +
                      <FS_ALV>-PRC61M * WK_ZFIT017-PER61M / 100.
      <FS_ALV>-PERFLG = C_X.
    ENDIF.

*   同组物料的最后一行数据
    CLEAR LW_ALV.
    READ TABLE IT_ALV INTO LW_ALV INDEX L_INDEX.
    IF <FS_ALV>-MATNR <> LW_ALV-MATNR.
*     库位差异金额
      <FS_ALV>-SALK3 = <FS_ALV>-SALK3 + ( WK_QTY-DMBTR - L_SALK3 ).
      <FS_ALV>-PRC3M = <FS_ALV>-PRC3M + ( WK_QTY-DMBTR - L_SALK3 ).
      CLEAR L_SALK3.
    ENDIF.
  ENDLOOP.

* 特殊行:0库存物料金额
  LOOP AT IT_ZFIT015 INTO WK_ZFIT015.
    READ TABLE IT_ALV TRANSPORTING NO FIELDS
                      WITH KEY MATNR = WK_ZFIT015-MATNR.
    IF SY-SUBRC <> 0.
      CLEAR LW_ALV.
      LW_ALV-ZYEAR = V_GJAHR.
      LW_ALV-ZMONTH = V_MONAT.
      LW_ALV-WERKS = WK_ZFIT015-WERKS.
      LW_ALV-MATNR = WK_ZFIT015-MATNR.
      LW_ALV-MAKTX = 'Special line: Qty:0/Amount'.
      LW_ALV-SALK3 = WK_ZFIT015-DMBTR.
      LW_ALV-PRC3M = WK_ZFIT015-DMBTR.
      APPEND LW_ALV TO IT_ALV.
    ENDIF.
  ENDLOOP.

* 特殊行追加: 在制品
  CLEAR WK_OBJ.
  LOOP AT IT_FAG1 INTO WK_FAG1.
    WK_OBJ-HSLVT = WK_OBJ-HSLVT + WK_FAG1-HSLVT.
    WK_OBJ-HSL01 = WK_OBJ-HSL01 + WK_FAG1-HSL01.
    WK_OBJ-HSL02 = WK_OBJ-HSL02 + WK_FAG1-HSL02.
    WK_OBJ-HSL03 = WK_OBJ-HSL03 + WK_FAG1-HSL03.
    WK_OBJ-HSL04 = WK_OBJ-HSL04 + WK_FAG1-HSL04.
    WK_OBJ-HSL05 = WK_OBJ-HSL05 + WK_FAG1-HSL05.
    WK_OBJ-HSL06 = WK_OBJ-HSL06 + WK_FAG1-HSL06.
    WK_OBJ-HSL07 = WK_OBJ-HSL07 + WK_FAG1-HSL07.
    WK_OBJ-HSL08 = WK_OBJ-HSL08 + WK_FAG1-HSL08.
    WK_OBJ-HSL09 = WK_OBJ-HSL09 + WK_FAG1-HSL09.
    WK_OBJ-HSL10 = WK_OBJ-HSL10 + WK_FAG1-HSL10.
    WK_OBJ-HSL11 = WK_OBJ-HSL11 + WK_FAG1-HSL11.
    WK_OBJ-HSL12 = WK_OBJ-HSL12 + WK_FAG1-HSL12.
  ENDLOOP.
* 指针指向对象行
  ASSIGN WK_OBJ TO <FS_HEAD>.

* 默认值
  V_VALUE = WK_OBJ-HSLVT. "余额结转

  V_COUT = V_MONAT.

* 得到指定月的累积金额
  CLEAR V_NUM.
  DO V_COUT TIMES.
*   字段
    V_NUM = V_NUM + 1.
    CONCATENATE 'HSL'
                V_NUM
           INTO V_FIELD.
    ASSIGN COMPONENT V_FIELD OF STRUCTURE <FS_HEAD> TO <FS_FIELD>.
    IF <FS_FIELD> <> 0.
      V_VALUE = V_VALUE + <FS_FIELD>.
    ENDIF.
  ENDDO.
  CLEAR LW_ALV.
  LW_ALV-ZYEAR = V_GJAHR.
  LW_ALV-ZMONTH = V_MONAT.
  LW_ALV-MAKTX = 'Special line: 14100000'.
  LW_ALV-SALK3 = V_VALUE.
  LW_ALV-PRC3M = V_VALUE.
  APPEND LW_ALV TO IT_ALV.

* 特殊行追加: 尾差
  CLEAR L_DMBTR.
  LOOP AT IT_ZFIT016 INTO WK_ZFIT016.
    IF WK_ZFIT016-SHKZG = 'S'.
      L_DMBTR = L_DMBTR + WK_ZFIT016-DMBTR.
    ELSE.
      L_DMBTR = L_DMBTR - WK_ZFIT016-DMBTR.
    ENDIF.
  ENDLOOP.
  CLEAR LW_ALV.
  LW_ALV-ZYEAR = V_GJAHR.
  LW_ALV-ZMONTH = V_MONAT.
  LW_ALV-MAKTX = 'Special line: Tail Difference'.
  LW_ALV-SALK3 = L_DMBTR.
  LW_ALV-PRC3M = L_DMBTR.
  APPEND LW_ALV TO IT_ALV.


ENDFORM.                    " EDIT_DATA
*&---------------------------------------------------------------------*
*&      Form  SET_FIELDCAT
*&---------------------------------------------------------------------*
*       设定 FIELDCAT
*----------------------------------------------------------------------*
FORM SET_FIELDCAT .

  DATA LW_FIEDCAT TYPE SLIS_FIELDCAT_ALV.
  REFRESH IT_FIELDCAT.

* 仓库
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'LGORT'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T01.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 年
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'ZYEAR'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T02.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 月
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'ZMONTH'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T03.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 产品编号
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'MATNR'.
  LW_FIEDCAT-EDIT_MASK = '==MATN1'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T04.

  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 产品描述
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'MAKTX'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T05.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 物料组
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'MATKL'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T40.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 利润中心
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRCTR'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T06.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 利润中心描述
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRTXT'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T43.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 批次管理
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'XCHPF'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T39.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

** 最后异动日期
*  CLEAR LW_FIEDCAT.
*  LW_FIEDCAT-FIELDNAME = 'LDATE1'.
*  LW_FIEDCAT-SELTEXT_L = TEXT-T07.
*  APPEND LW_FIEDCAT TO IT_FIELDCAT.
*
** 最后销售日期
*  CLEAR LW_FIEDCAT.
*  LW_FIEDCAT-FIELDNAME = 'LDATE2'.
*  LW_FIEDCAT-SELTEXT_L = TEXT-T08.
*  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 成本单价
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRICE'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T09.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 价格单位
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'WAERS'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T44.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 实际成本金额
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'SALK3'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T10.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 数量(基本计量单位)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'LBKUM1'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T11.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 基本计量单位
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'MEINS1'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T12.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 数量(财务价量统一单位)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'LBKUM2'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T13.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 财务统一计量单位
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'MEINS2'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T14.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(3月以内)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY3M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T15.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(4-6月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY6M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T16.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(7-9月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY9M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T17.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(10-12月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY12M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T18.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(13-18月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY18M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T19.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(19-24月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY24M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T20.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(25-36月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY36M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T21.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(37-60月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY60M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T22.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄数量(60月以上)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'QTY61M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T23.
  LW_FIEDCAT-EMPHASIZE = 'C500'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.


* 库龄金额(3月以内)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC3M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T24.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(4-6月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC6M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T25.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(7-9月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC9M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T26.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(10-12月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC12M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T27.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(13-18月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC18M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T28.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(19-24月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC24M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T29.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(25-36月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC36M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T30.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(37-60月)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC60M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T31.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 库龄金额(60月以上)
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PRC61M'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T32.
  LW_FIEDCAT-EMPHASIZE = 'C410'.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 跌价金额
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PERPRC'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T41.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

* 跌价维护标志
  CLEAR LW_FIEDCAT.
  LW_FIEDCAT-FIELDNAME = 'PERFLG'.
  LW_FIEDCAT-SELTEXT_L = TEXT-T42.
  APPEND LW_FIEDCAT TO IT_FIELDCAT.

ENDFORM.                    " SET_FIELDCAT
*&---------------------------------------------------------------------*
*&      Form  SET_LAYOUT
*&---------------------------------------------------------------------*
*       设定 LAYOUT
*----------------------------------------------------------------------*
FORM SET_LAYOUT .

  WK_LAYOUT-ZEBRA = C_X.
  WK_LAYOUT-COLWIDTH_OPTIMIZE = C_X.
  WK_LAYOUT-BOX_FIELDNAME = 'CHK'.

ENDFORM.                    " SET_LAYOUT
*&---------------------------------------------------------------------*
*&      Form  SET_ALV_EVENT
*&---------------------------------------------------------------------*
*       设定 Eventa
*----------------------------------------------------------------------*
FORM SET_ALV_EVENT .

  DATA: LW_EVENT TYPE SLIS_ALV_EVENT,
        LW_NAME  TYPE SLIS_FORMNAME VALUE 'TOP_OF_PAGE'.
  REFRESH IT_EVENT.
  CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
   EXPORTING
     I_LIST_TYPE           = 0
   IMPORTING
     ET_EVENTS             = IT_EVENT
   EXCEPTIONS
     LIST_TYPE_WRONG       = 1
     OTHERS                = 2.
  IF SY-SUBRC <> 0.
   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
           WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  CLEAR LW_EVENT.
  READ TABLE IT_EVENT INTO LW_EVENT
                      WITH KEY NAME = LW_NAME.
  IF SY-SUBRC = 0.
    MOVE LW_NAME TO LW_EVENT-FORM.
    MODIFY IT_EVENT FROM LW_EVENT INDEX SY-TABIX..
  ELSE.
    LW_EVENT-FORM = LW_NAME.
    LW_EVENT-NAME = LW_NAME.
    APPEND LW_EVENT TO IT_EVENT.
  ENDIF.

ENDFORM.                    " SET_ALV_EVENT
*&---------------------------------------------------------------------*
*&      Form  SHOW_ALV
*&---------------------------------------------------------------------*
*       输出 ALV
*----------------------------------------------------------------------*
FORM SHOW_ALV .

* Call ALV
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
   EXPORTING
      I_CALLBACK_PROGRAM                = SY-REPID
      IT_EVENTS                         = IT_EVENT
      IS_LAYOUT                         = WK_LAYOUT
      IT_FIELDCAT                       = IT_FIELDCAT
      I_SAVE                            = C_X
    TABLES
      T_OUTTAB                          = IT_ALV
    EXCEPTIONS
      PROGRAM_ERROR                     = 1
      OTHERS                            = 2.
  IF SY-SUBRC <> 0.
   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
           WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.

ENDFORM.                    " SHOW_ALV
*&---------------------------------------------------------------------*
*&      Form  TOP_OF_PAGE1
*&---------------------------------------------------------------------*
*       ALV Header Setting
*----------------------------------------------------------------------*
FORM TOP_OF_PAGE.

  DATA: L_MATNR1 TYPE MARA-MATNR,
        L_MATNR2 TYPE MARA-MATNR,
        LT_HEAD  TYPE SLIS_T_LISTHEADER,
        LW_HEAD  TYPE SLIS_LISTHEADER.

  REFRESH LT_HEAD.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'H'.       "Header
  LW_HEAD-INFO = TEXT-T33. "财务库龄表
  APPEND LW_HEAD TO LT_HEAD.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'S'.       "Selection
  LW_HEAD-KEY = TEXT-T35.  "会计期间:
  CONCATENATE V_GJAHR
              '/'
              V_MONAT
         INTO LW_HEAD-INFO.
  APPEND LW_HEAD TO LT_HEAD.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'S'.       "Selection
  LW_HEAD-KEY = TEXT-T34.  "Company Name:
  LW_HEAD-INFO = P_BUKRS.
  APPEND LW_HEAD TO LT_HEAD.
* 工厂
  IF S_WERKS IS NOT INITIAL.
    CLEAR LW_HEAD.
    LW_HEAD-TYP = 'S'.       "Selection
    LW_HEAD-KEY = TEXT-T36.  "工厂:
*   多个单值查询
    IF S_WERKS-LOW IS NOT INITIAL
   AND S_WERKS-HIGH IS INITIAL.
      LOOP AT S_WERKS.
        CONCATENATE LW_HEAD-INFO
                    S_WERKS-LOW
               INTO LW_HEAD-INFO
               SEPARATED BY '/'.
      ENDLOOP.
      LW_HEAD-INFO+0(1) = ''.
    ENDIF.
*   范围查询
    IF S_WERKS-HIGH IS NOT INITIAL.
      CONCATENATE S_WERKS-LOW
                  '~'
                  S_WERKS-HIGH
             INTO LW_HEAD-INFO.
    ENDIF.
    APPEND LW_HEAD TO LT_HEAD.
  ENDIF.
* 物料编号
  IF S_MATNR IS NOT INITIAL.
    CLEAR LW_HEAD.
    LW_HEAD-TYP = 'S'.       "Selection
    LW_HEAD-KEY = TEXT-T37.  "物料编号:
*   多个单值查询
    IF S_MATNR-LOW IS NOT INITIAL
   AND S_MATNR-HIGH IS INITIAL.
    CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
      EXPORTING
        INPUT         = S_MATNR-LOW
      IMPORTING
        OUTPUT        = LW_HEAD-INFO.
    ENDIF.
*   范围查询
    IF S_MATNR-HIGH IS NOT INITIAL.
      CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
        EXPORTING
          INPUT         = S_MATNR-LOW
        IMPORTING
          OUTPUT        = L_MATNR1.
      CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
        EXPORTING
          INPUT         = S_MATNR-HIGH
        IMPORTING
          OUTPUT        = L_MATNR2.
      CONCATENATE L_MATNR1
                  '~'
                  L_MATNR2
             INTO LW_HEAD-INFO.
    ENDIF.
    APPEND LW_HEAD TO LT_HEAD.
  ENDIF.
* 库存地点
  IF S_LGORT IS NOT INITIAL.
    CLEAR LW_HEAD.
    LW_HEAD-TYP = 'S'.       "Selection
    LW_HEAD-KEY = TEXT-T38.  "库存地点:
*   多个单值查询
    IF S_LGORT-LOW IS NOT INITIAL
   AND S_LGORT-HIGH IS INITIAL.
      LW_HEAD-INFO = S_LGORT-LOW.
    ENDIF.
*   范围查询
    IF S_LGORT-HIGH IS NOT INITIAL.
      CONCATENATE S_LGORT-LOW
                  '~'
                  S_LGORT-HIGH
             INTO LW_HEAD-INFO.
    ENDIF.
    APPEND LW_HEAD TO LT_HEAD.
  ENDIF.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'S'.
  APPEND LW_HEAD TO LT_HEAD.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'S'.
  APPEND LW_HEAD TO LT_HEAD.
  CLEAR LW_HEAD.
  LW_HEAD-TYP = 'S'.
  APPEND LW_HEAD TO LT_HEAD.
  CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
    EXPORTING
      IT_LIST_COMMENTARY       = LT_HEAD.

ENDFORM.                    " TOP_OF_PAGE
*&---------------------------------------------------------------------*
*&      Form  GET_DATE
*&---------------------------------------------------------------------*
*       得到查询日期范围
*----------------------------------------------------------------------*
*      -->I_IDATE  输入日期
*      -->I_MONTH  月份
*      <--C_DATE  查询日期
*----------------------------------------------------------------------*
FORM GET_DATE  USING  I_IDATE TYPE SY-DATUM
                      I_MONTH TYPE T5A4A-DLYMO
               CHANGING C_DATE.

  CLEAR C_DATE.
  CALL FUNCTION 'RP_CALC_DATE_IN_INTERVAL'
    EXPORTING
      DATE            = I_IDATE
      DAYS            = '00'
      MONTHS          = I_MONTH
      SIGNUM          = '-'
      YEARS           = '00'
    IMPORTING
      CALC_DATE       = C_DATE.

ENDFORM.                    " GET_DATE
*&---------------------------------------------------------------------*
*&      Form  SET_MONTH
*&---------------------------------------------------------------------*
*       设置各期间的范围
*----------------------------------------------------------------------*
FORM SET_MONTH .

  DATA: L_DATE1  TYPE SY-DATUM,
        L_DATE2  TYPE SY-DATUM,
        LW_MONTH LIKE LINE OF S_3M.

* 得到查询日期范围(3月以内)
  PERFORM GET_DATE USING P_SDATE
                         '03'
                CHANGING L_DATE1.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE1.
  LW_MONTH-HIGH = P_SDATE.
  APPEND LW_MONTH TO S_3M.

* 得到查询日期范围(4-6月)
  PERFORM GET_DATE USING L_DATE1
                         '03'
                CHANGING L_DATE2.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE2.
  LW_MONTH-HIGH = L_DATE1.
  APPEND LW_MONTH TO S_6M.

* 得到查询日期范围(7-9月)
  PERFORM GET_DATE USING L_DATE2
                         '03'
                CHANGING L_DATE1.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE1.
  LW_MONTH-HIGH = L_DATE2.
  APPEND LW_MONTH TO S_9M.

* 得到查询日期范围(10-12月)
  PERFORM GET_DATE USING L_DATE1
                         '03'
                CHANGING L_DATE2.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE2.
  LW_MONTH-HIGH = L_DATE1.
  APPEND LW_MONTH TO S_12M.

* 得到查询日期范围(13-18月)
  PERFORM GET_DATE USING L_DATE2
                         '06'
                CHANGING L_DATE1.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE1.
  LW_MONTH-HIGH = L_DATE2.
  APPEND LW_MONTH TO S_18M.

* 得到查询日期范围(19-24月)
  PERFORM GET_DATE USING L_DATE1
                         '06'
                CHANGING L_DATE2.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE2.
  LW_MONTH-HIGH = L_DATE1.
  APPEND LW_MONTH TO S_24M.

* 得到查询日期范围(25-36月)
  PERFORM GET_DATE USING L_DATE2
                         '12'
                CHANGING L_DATE1.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE1.
  LW_MONTH-HIGH = L_DATE2.
  APPEND LW_MONTH TO S_36M.

* 得到查询日期范围(37-60月)
  PERFORM GET_DATE USING L_DATE1
                         '24'
                CHANGING L_DATE2.
  CLEAR LW_MONTH.
  LW_MONTH-SIGN = 'I'.
  LW_MONTH-OPTION = 'BT'.
  LW_MONTH-LOW = L_DATE2.
  LW_MONTH-HIGH = L_DATE1.
  APPEND LW_MONTH TO S_60M.

* 得到查询日期范围(61月)
  S_61M = L_DATE2.

ENDFORM.                    " SET_MONTH
*&---------------------------------------------------------------------*
*&      Form  SET_DATE
*&---------------------------------------------------------------------*
*       查询日期设置
*----------------------------------------------------------------------*
FORM SET_DATE .

   CLEAR P_SDATE.
   CALL FUNCTION 'LAST_DAY_OF_MONTHS'
     EXPORTING
       DAY_IN                  = SY-DATUM
     IMPORTING
       LAST_DAY_OF_MONTH       = P_SDATE
     EXCEPTIONS
       DAY_IN_NO_DATE          = 1
       OTHERS                  = 2.
   IF SY-SUBRC <> 0.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
            WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
   ENDIF.

ENDFORM.                    " SET_DATE

本文转载自:https://blog.csdn.net/sinat_28730703/article/details/46357159

猜你喜欢

转载自www.cnblogs.com/BruceKing/p/10729845.html