SAP庫存賬齡分析報表(轉)


功能概述 
1.1. 業務背景 
本程序是對物料按工廠、庫存地點、物料號、銷售訂單號進行查詢當前的庫存及庫齡的報表。 
1.2. 功能描述 
本程序能夠查詢出每個物料的數量、金額數據及庫齡的明細數據。 
1.2. 使用范圍 
所有有庫存的事業部都需要查看庫存及庫齡情況。 
1.3. 權限設定 
所有有查看庫存權限的人員都需要有這個權限。 
需要增加權限對象:M_MSEG_LGO、M_MSEG_WMB、M_MSEG_WWA。 
1.4. 處理類型 
前台手動執行。 
1.5. 數據量及使用頻率 
本程序為庫存相關,用戶需要查詢時可以進行查詢。
功能詳述 
2.1. 程序標題及其屬性 
程序標題:“庫存異常表(庫齡報表)” 
2.2. 屏幕設計 
2.2.1. 屏幕流 
2.2.2. 輸入屏幕 
 
結果如下: 

顯示出結果后,可以用Excel導出。
報表各字段取值邏輯
本程序分為兩種情況,一種是普通庫存,一種是對應銷售訂單的庫存,需要把兩種情況分別處理,然后加在一起顯示,普通庫存取數邏輯如下: 
描述 參考字段 
工廠 MARD-WERKS 
工廠描述 T001W-NAME1 
庫存地點 MARD-LGORT 
庫存地點描述 T001L-LGOBE 
物料號 MARD-MATNR 
物料描述 MAKT-MAKTL 
庫存類型 普通庫存 
銷售訂單號 MSKA-VBELN   
銷售訂單行項目MSKA-POSNR 
當前庫存數量 MARD-LABST(MSKA-KALAB) 
當前庫存金額 當前庫存數量 * (MBEW-SALK3 / MBEW-LBKUM),最終結果保留小數點后兩位 
庫存1-30天數量 1、以每個工廠、庫存地點、物料號為條件取 MSEG-MENGE MKPF-BUDAT from ( MSEG inner join MKPF by MSEG-MBLNR = MKPF-MBLNR and MSEG-MJAHR = MKPF-MJAHR) where MSEG-WERKS = MARD-WERKS and MSEG-LGORT = MARD-LGORT and MSEG-MATNR = MARD-MATNR and MSEG-SHKZG = ‘S’ and MSEG-SOBKZ NE ‘E’ ,取物料憑證數據時排除移動類型321和322。 
2、對上面的結果集以MKPF-BUDAT為基礎倒排,當入庫數據中存在20131231的數據時,到庫齡報表期初數據表(ZMM_MSEG)把歷史數據取出,把“當前庫存數量”分配到這個結果中,20131231的數據不分配,直接跳到以前的歷史數據,直到分配完為止,如果歷史數據不足按20131231的數據計算。 
3、對以上結果以當前日期為基准,在1-30天內數據累加后放在這個字段中。 
庫存1-30天數量 1、以每個工廠、庫存地點、物料號為條件取 MSEG-MENGE MKPF-BUDAT from ( MSEG inner join MKPF by MSEG-MBLNR = MKPF-MBLNR and MSEG-MJAHR = MKPF-MJAHR) where MSEG-WERKS = MARD-WERKS and MSEG-LGORT = MARD-LGORT and MSEG-MATNR = MARD-MATNR and MSEG-SHKZG = ‘S’ and MSEG-SOBKZ NE ‘E’ ,取物料憑證數據時排除移動類型321和322。 
2、對上面的結果集以MKPF-BUDAT為基礎倒排,當入庫數據中存在20131231的數據時,到庫齡報表期初數據表(ZMM_MSEG)把歷史數據取出,把“當前庫存數量”分配到這個結果中,20131231的數據不分配,直接跳到以前的歷史數據,直到分配完為止,如果歷史數據不足按20131231的數據計算。 
3、對以上結果以當前日期為基准,在1-30天內數據累加后放在這個字段中。 
庫存91-180天數量 第1、2步操作前面已經做過,只需要第3步操作,把結果在91-180天內的數據累加放在這個字段中。 
庫存91-180天金額 庫存91-180天數量 * (MBEW-SALK3 / MBEW-LBKUM),最終結果保留小數點后兩位。 
后面天數的數量和金額以此類推

邏輯描述
本程序如果普通庫存選中則抽取MARD表的數據為基礎取出MARD-LABST不為零的數據然后進行后續處理,如果對應銷售訂單的庫存選中則抽取MSKA表的數據為基礎取出MSKA-KALAB不為零的數據然后進行后續處理,如果兩個都選中則兩個表各自抽取出數據后加到一起顯示,默認是全部選中。取到基礎數據后再以此為基礎取MSEG、MKPF表中的所有入庫信息然后按時間倒序排列,當入庫數據中存在20131231的數據時,到庫齡報表期初數據表(ZMM_MSEG)把歷史數據取出,把“當前庫存數量”分配到這個結果中,20131231的數據不分配,直接跳到以前的歷史數據,直到分配完為止,如果歷史數據不足按20131231的數據計算,然后以這個序列的數量以當前日期為基准,分配到各自的庫存時間范圍內。具體的邏輯請參考以上取值邏輯。 
考慮沖銷的情況: 
1、對於初始化入庫(20131231)采用從物料憑證表取入出庫雙向數據,經過累計后計算出一條數據,然后去找歷史數據。

2、對於其他數據采用從物料憑證表取單向入庫數據,然后到物料憑證表查詢是否存在入庫數據的沖銷憑證數據,如果存在沖銷憑證數據,則把這條入庫數據刪除。

表名:ZMM_MSEG 
描述:庫齡報表期初數據 
字段:字段描述 
客戶端 
物料編號 
工廠 
庫存地點 
銷售憑證 
銷售憑證項目 
憑證中的過帳日期 
數量 
基本計量單位 
字段名稱 
MANDT 
MATNR 
WERKS 
LGORT 
VBELN 
POSNR 
BUDAT 
MENGE 
MEINS 
示例代碼如下

*-----------------------------------------------------------------------*
* 程序名稱:ZMMEXEC0140
* 程序標題:庫存異常表(庫齡報表)
* 程序類型:功能報表

* 創建日期:2014-01-16
* 模塊    :
* 請求號  :
* 功能描述:
* 相關文檔:
*----------------------------------------------------------------------*
* 修改記錄:
* 作者          日期       請求號      修改原因描述
*-----------  --------  -----------------------------------------------*
*
*----------------------------------------------------------------------*
REPORT zmmexec0140
  NO STANDARD PAGE HEADING
  MESSAGE-ID zcomm.

*----------------------------------------------------------------------*
*        INCLUDE                                                       *
*----------------------------------------------------------------------*
INCLUDE zslis.

*----------------------------------------------------------------------*
* 聲明數據表;
*----------------------------------------------------------------------*
TABLES: mkpf, mseg, mard, mska,t001w.

*----------------------------------------------------------------------*
* 定義結構;
*----------------------------------------------------------------------*
TYPES: gtf_price TYPE p LENGTH 15 DECIMALS 9,
       gtf_dmbtr TYPE vtcur12,
       gtf_menge TYPE p LENGTH 15 DECIMALS 3.

TYPES: BEGIN OF gts_alv_data,
         matnr TYPE mard-matnr,
         werks TYPE mard-werks,
         lgort TYPE mard-lgort,
         maktx TYPE makt-maktx,  " 物料描述
         name1 TYPE t001w-name1, " 工廠描述
         lgobe TYPE t001l-lgobe, " 庫存地點描述
         ztype TYPE char10,
         vbeln TYPE mska-vbeln,
         posnr TYPE mska-posnr,
         meins TYPE mara-meins,
         msehl TYPE msehl,
         waers TYPE t001-waers,
         price TYPE gtf_price,
         menge TYPE gtf_menge,
         dmbtr TYPE gtf_dmbtr,
         meng1 TYPE gtf_menge,
         dmbt1 TYPE gtf_dmbtr,
         meng2 TYPE gtf_menge,
         dmbt2 TYPE gtf_dmbtr,
         meng3 TYPE gtf_menge,
         dmbt3 TYPE gtf_dmbtr,
         meng4 TYPE gtf_menge,
         dmbt4 TYPE gtf_dmbtr,
         meng5 TYPE gtf_menge,
         dmbt5 TYPE gtf_dmbtr,
         meng6 TYPE gtf_menge,
         dmbt6 TYPE gtf_dmbtr,
         meng7 TYPE gtf_menge,
         dmbt7 TYPE gtf_dmbtr,
         meng8 TYPE gtf_menge,
         dmbt8 TYPE gtf_dmbtr,
         meng9 TYPE gtf_menge,
         dmbt9 TYPE gtf_dmbtr,
*         meng10 TYPE gtf_menge, "20160615 add
*         dmbt10 TYPE gtf_dmbtr, "20160615 add
         meng99 TYPE gtf_menge,
         dmbt99 TYPE gtf_dmbtr,
         kunnr TYPE kna1-kunnr,
         kunnrt TYPE kna1-name1,
         aufnr TYPE aufk-aufnr,
         aufnrt TYPE aufk-ktext,
         bstkd TYPE vbkd-bstkd,
       END OF gts_alv_data.
TYPES: BEGIN OF gts_alv_base,
         grp      TYPE i,  " 用於分組
         id       TYPE i,
         tag      TYPE i,
         sel      TYPE char1,
         light    TYPE c,
         rowcolor TYPE char4,
         msg      TYPE text255,
       END OF gts_alv_base.
TYPES: BEGIN OF gts_alv.
INCLUDE   TYPE gts_alv_data.
INCLUDE   TYPE gts_alv_base.
TYPES: END OF gts_alv.

TYPES: BEGIN OF gts_t001,
         bwkey TYPE t001k-bwkey,
         bukrs TYPE t001-bukrs,
         waers TYPE t001-waers,
       END OF gts_t001.

*----------------------------------------------------------------------*
* 定義內表;
*----------------------------------------------------------------------*
DATA: gds_alv     TYPE gts_alv,
      gdt_alv     TYPE TABLE OF gts_alv.
DATA: gdt_t001l   TYPE zfit_lgort2 WITH HEADER LINE,
      gdt_t001    TYPE TABLE OF gts_t001 WITH HEADER LINE.

*----------------------------------------------------------------------*
* 定義范圍變量;
*----------------------------------------------------------------------*
RANGES: gdr_werks FOR ekpo-werks.

*----------------------------------------------------------------------*
* 定義變量;
*----------------------------------------------------------------------*
DATA: gdf_mandt TYPE mandt,
      gdf_budat TYPE sydatum,
      gdf_datum TYPE sydatum,
      gdf_lfgja TYPE mard-lfgja,
      gdf_lfmon TYPE mard-lfmon.

DATA d1 TYPE p.
DATA d2 TYPE p.
DATA d3 TYPE p.
DATA d4 TYPE p.
DATA d5 TYPE p.
DATA d6 TYPE p.
DATA d7 TYPE p.
DATA d8 TYPE p.

*----------------------------------------------------------------------*
* 定義常量.
*----------------------------------------------------------------------*
*CONSTANTS: gdc_idate TYPE sydatum VALUE '20131231'. " 初始庫存倒入日期
*DATA: gdc_idate TYPE sydatum VALUE '20131231'. " 初始庫存倒入日期 "add by lumingdao 20160101
DATA: gdc_idate TYPE sydatum VALUE '20151231'. " 初始庫存倒入日期

*----------------------------------------------------------------------*
*        SELECTION-SCREEN  檢索條件                                    *
*----------------------------------------------------------------------*
SELECTION-SCREEN BEGIN OF BLOCK choi1 WITH FRAME TITLE text-003.
PARAMETERS: p_r1 TYPE char1 RADIOBUTTON GROUP grp1 DEFAULT 'X' USER-COMMAND zks.
PARAMETERS: p_r2 TYPE char1 RADIOBUTTON GROUP grp1.
PARAMETERS: p_budat TYPE sydatum MODIF ID his.
SELECTION-SCREEN END OF BLOCK choi1.

SELECTION-SCREEN BEGIN OF BLOCK selt WITH FRAME TITLE text-001.
PARAMETERS: p_bukrs TYPE t001-bukrs OBLIGATORY DEFAULT '8200'.
SELECT-OPTIONS: so_werks FOR t001w-werks.
SELECT-OPTIONS: so_lgort FOR mard-lgort.
SELECT-OPTIONS: so_matnr FOR mard-matnr.
SELECT-OPTIONS: so_vbeln FOR mska-vbeln.
SELECT-OPTIONS: so_posnr FOR mska-posnr.
************************20160616 add***********************************
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 '90'.
PARAMETERS p_d3(4) TYPE n DEFAULT '180'.
PARAMETERS p_d4(4) TYPE n DEFAULT '365'.
PARAMETERS p_d5(4) TYPE n DEFAULT '730'.
PARAMETERS p_d6(4) TYPE n DEFAULT '1095'.
PARAMETERS p_d7(4) TYPE n DEFAULT '1460'.
PARAMETERS p_d8(4) TYPE n DEFAULT '1825'.
SELECTION-SCREEN END OF LINE.
**********************************************************************
SELECTION-SCREEN END OF BLOCK selt.

SELECTION-SCREEN BEGIN OF BLOCK choi WITH FRAME TITLE text-002.
PARAMETERS: p_c1 TYPE char1 AS CHECKBOX DEFAULT 'X'.
PARAMETERS: p_c2 TYPE char1 AS CHECKBOX DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK choi.

*$*$----------------------------------------------------------------$*$*
*$*$                          Main Program                          $*$*
*$*$----------------------------------------------------------------$*$*
*--------- 初始化 ----------
INITIALIZATION.
  p_budat = sy-datum - 1.

*&------------------------------------------------------------
*&     At selection-screen.
*&------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT.
  LOOP AT SCREEN.
    CASE 'X'.
      WHEN p_r1.
        IF screen-group1 = 'HIS'.
          screen-active = 0.
          MODIFY SCREEN.
        ENDIF.
      WHEN p_r2.
        IF screen-group1 = 'HIS'.
          screen-active = 1.
          MODIFY SCREEN.
        ENDIF.
      WHEN OTHERS.
    ENDCASE.
  ENDLOOP.

*&------------------------------------------------------------
*&     At selection-screen.
*&------------------------------------------------------------
AT SELECTION-SCREEN.
* 修改上線日期 “added 20140710
*  PERFORM get_init_date USING sy-mandt '' CHANGING gdc_idate.
* 檢查參數輸入的合法性 / 檢查輸入權限
  PERFORM frm_check_parameter.

AT SELECTION-SCREEN ON BLOCK selt.
  PERFORM check_date. "20160616 add

*&------------------------------------------------------------
*&     LOAD-OF-PROGRAM.
*&------------------------------------------------------------
LOAD-OF-PROGRAM.
*--------- START-OF-SELECTION ----------
START-OF-SELECTION.

  "根據公司代碼==》獲取期初導入日期
  PERFORM frm_get_init_data CHANGING gdc_idate.

* 從數據表去數據並整理
  PERFORM get_data.

END-OF-SELECTION.

  IF gdt_alv[] IS INITIAL.
*   沒有找到相關的數據!
    MESSAGE s001 DISPLAY LIKE 'E'.
  ELSE.
*   顯示alv界面
    PERFORM frm_display_lvc.
  ENDIF.

  CLEAR:   gdt_alv, gdt_t001l, gdr_werks, gdt_t001.
  REFRESH: gdt_alv, gdt_t001l, gdr_werks, gdt_t001.

  INCLUDE zinitial_data. "added 20140710

************************************************************************
*                         END OF MAIN PROGRAM
************************************************************************



*&---------------------------------------------------------------------*
*&      Form  FRM_CHECK_PARAMETER
*&---------------------------------------------------------------------*
*       檢查參數輸入的合法性 / 檢查輸入的條件
*----------------------------------------------------------------------*
FORM frm_check_parameter.

  "add by luming dao 20151231
  DATA: lt_itab LIKE TABLE OF zmm_bukrs WITH HEADER LINE.
  REFRESH lt_itab.
  IF p_bukrs <> '8100' AND p_bukrs <> '8200' .
    STOP.
  ENDIF.
  SELECT *
         INTO CORRESPONDING FIELDS OF TABLE lt_itab
         FROM zmm_bukrs
         WHERE bukrs EQ p_bukrs
           AND lgort IN so_lgort
           AND werks IN so_werks
         .
  IF lt_itab[] IS INITIAL.
    SET CURSOR FIELD 'P_BUKRS'.
    MESSAGE e000 WITH '沒有你要查詢的數據!'.
    RETURN.
  ENDIF.

  IF sy-ucomm = 'ZKS'.
    RETURN.
  ENDIF.

  IF p_c1 <> 'X' AND p_c2 <> 'X'.
    SET CURSOR FIELD 'P_C1'.
    MESSAGE e000 WITH '請至少選擇一種庫存類型'.
    RETURN.
  ENDIF.
  "added by XXX 20160722 begin
  IF  p_bukrs = '8100'.
    gdc_idate = '20131231'.
  ENDIF.
  "added by yangk 20160722 end
  IF p_r2 = 'X'.
    IF p_budat < gdc_idate.
      SET CURSOR FIELD 'P_BUDAT'.
      MESSAGE e000 WITH '歷史庫齡日期不能小於' gdc_idate.
    ENDIF.
    IF p_budat >= sy-datum.
      SET CURSOR FIELD 'P_BUDAT'.
      MESSAGE e000 WITH '歷史庫齡日期不能大於等於當天'.
    ENDIF.
    CALL FUNCTION 'RP_LAST_DAY_OF_MONTHS'
      EXPORTING
        day_in            = p_budat
      IMPORTING
        last_day_of_month = gdf_budat
      EXCEPTIONS
        day_in_no_date    = 1
        OTHERS            = 2.
    IF sy-subrc <> 0.
      SET CURSOR FIELD 'P_BUDAT'.
      MESSAGE e000 WITH '歷史庫齡日期格式不正確'.
    ENDIF.
    gdf_lfgja = gdf_budat+0(4).
    gdf_lfmon = gdf_budat+4(2).
    gdf_datum = p_budat.
  ELSE.
    gdf_datum = sy-datum.
  ENDIF.

** 工廠的權限檢查  AUTHORITY-CHECK OBJECT 'M_BEST_WRK'
*  CALL FUNCTION 'ZFI_GET_WERKS'
*    EXPORTING
*      ir_werks   = so_werks[]
*    IMPORTING
*      er_werks   = gdr_werks[]
*    EXCEPTIONS
*      not_found  = 1
*      not_enough = 2
*      OTHERS     = 3.
*  IF sy-subrc <> 0.
*    SET CURSOR FIELD 'SO_WERKS-LOW'.
*    MESSAGE e004 WITH '操作工廠的權限不足!'.
*  ENDIF.
* 工廠的權限檢查  AUTHORITY-CHECK OBJECT 'M_MSEG_WMB'
  CALL FUNCTION 'ZFI_GET_WERK2'
    EXPORTING
      ir_werks   = so_werks[]
*     ir_werks   = gdr_werks[]
    IMPORTING
      er_werks   = gdr_werks[]
    EXCEPTIONS
      not_found  = 1
      not_enough = 2
      OTHERS     = 3.
  IF sy-subrc <> 0.
    SET CURSOR FIELD 'SO_WERKS-LOW'.
    MESSAGE e004 WITH '操作工廠的權限不足!'.
  ENDIF.
* 工廠的權限檢查  AUTHORITY-CHECK OBJECT 'M_MSEG_WMA'
  CALL FUNCTION 'ZFI_GET_WERK3'
    EXPORTING
      ir_werks   = gdr_werks[]
    IMPORTING
      er_werks   = gdr_werks[]
    EXCEPTIONS
      not_found  = 1
      not_enough = 2
      OTHERS     = 3.
  IF sy-subrc <> 0.
    SET CURSOR FIELD 'SO_WERKS-LOW'.
    MESSAGE e004 WITH '操作工廠的權限不足!'.
  ENDIF.

* 庫存地點的權限檢查  AUTHORITY-CHECK OBJECT 'M_MSEG_LGO'
  CALL FUNCTION 'ZFI_GET_LGORT'
    EXPORTING
      ir_werks   = gdr_werks[]
      ir_lgort   = so_lgort[]
    TABLES
      et_lgort   = gdt_t001l[]
    EXCEPTIONS
      not_found  = 1
      not_enough = 2
      OTHERS     = 3.
  IF sy-subrc <> 0.
    SET CURSOR FIELD 'SO_LGORT-LOW'.
    MESSAGE e004 WITH '操作庫存地點的權限不足!'.
  ENDIF.

* 公司幣種信息
  CLEAR: gdt_t001, gdt_t001[].
  SELECT t001k~bwkey
         t001~bukrs
         t001~waers
    INTO TABLE gdt_t001
    FROM t001k INNER JOIN t001 ON t001~bukrs = t001k~bukrs.
  SORT gdt_t001 BY bwkey bukrs.

ENDFORM.                    " FRM_CHECK_PARAMETER

*&---------------------------------------------------------------------*
*&      Form  GET_DATA
*&---------------------------------------------------------------------*
*       邏輯處理
*----------------------------------------------------------------------*
FORM get_data.

  CLEAR:   gdt_alv.
  REFRESH: gdt_alv.

  IF p_c1 = 'X'. " 普通庫存
    PERFORM frm_get_data.
  ENDIF.
  IF p_c2 = 'X'. " 銷售訂單庫存
    PERFORM frm_get_data2.
  ENDIF.

  SORT gdt_alv BY werks lgort matnr ztype vbeln posnr.

ENDFORM.                    " GET_DATA

*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATA
*&---------------------------------------------------------------------*
*       主邏輯
*----------------------------------------------------------------------*
FORM frm_get_data .
  DATA: BEGIN OF ldt_mard OCCURS 10,
         matnr TYPE mard-matnr,
         werks TYPE mard-werks,
         lgort TYPE mard-lgort,
         lfgja TYPE mard-lfgja,
         lfmon TYPE mard-lfmon,
         labst TYPE mard-labst,
         insme TYPE mard-insme,  " 質檢庫存
         speme TYPE mard-speme,  " 凍結庫存
         maktx TYPE makt-maktx,  " 物料描述
         name1 TYPE t001w-name1, " 工廠描述
         lgobe TYPE t001l-lgobe, " 庫存地點描述
         meins TYPE mara-meins,
        END OF ldt_mard,
        BEGIN OF ldt_mbew OCCURS 10,
         matnr TYPE mbew-matnr, " 物料編號
         bwkey TYPE mbew-bwkey, " 評估范圍
         bwtar TYPE mbew-bwtar, " 評估類型
         lfgja TYPE mbew-lfgja,
         lfmon TYPE mbew-lfmon,
         lbkum TYPE mbew-lbkum, " 總計已估計庫存
         salk3 TYPE mbew-salk3, " 估價的總庫存價值
         vprsv TYPE mbew-vprsv, " 價格控制指示符
         verpr TYPE mbew-verpr, " 移動平均價格/周期單價
         stprs TYPE mbew-stprs, " 標准價格
         peinh TYPE mbew-peinh, " 價格單位
        END OF ldt_mbew,
        BEGIN OF ldt_mseg OCCURS 10,
         mblnr TYPE mkpf-mblnr,
         mjahr TYPE mkpf-mjahr,
         budat TYPE mkpf-budat,
         zeile TYPE mseg-zeile,
         matnr TYPE mseg-matnr,
         werks TYPE mseg-werks,
         lgort TYPE mseg-lgort,
         shkzg TYPE mseg-shkzg,
         menge TYPE mseg-menge,
         meins TYPE mseg-meins,
        END OF ldt_mseg,
        ldt_msegi LIKE TABLE OF ldt_mseg WITH HEADER LINE,
        BEGIN OF ldt_mseg2 OCCURS 10,
         matnr TYPE mseg-matnr,
         werks TYPE mseg-werks,
         lgort TYPE mseg-lgort,
         meng1 TYPE gtf_menge,
         meng2 TYPE gtf_menge,
         meng3 TYPE gtf_menge,
         meng4 TYPE gtf_menge,
         meng5 TYPE gtf_menge,
         meng6 TYPE gtf_menge,
         meng7 TYPE gtf_menge,
         meng8 TYPE gtf_menge,
         meng9 TYPE gtf_menge,
*         meng10 TYPE gtf_menge, "20160615 add
*         meins type mseg-meins,
        END OF ldt_mseg2,
        BEGIN OF ldt_mbst OCCURS 10,
         mblnr TYPE mseg-mblnr,
         mjahr TYPE mseg-mjahr,
         zeile TYPE mseg-zeile,
         sjahr TYPE mseg-sjahr, " 物料憑證年度
         smbln TYPE mseg-smbln, " 物料憑證編號
         smblp TYPE mseg-smblp, " 物料憑證中的項目
        END OF ldt_mbst,
*        ldt_zmseg TYPE TABLE OF zmm_mseg WITH HEADER LINE, "add by lumingdao 20160108
        ldt_zmseg TYPE TABLE OF zmm_mseg_new WITH HEADER LINE.

  DATA: ldf_price TYPE gtf_price,
        ldf_index TYPE i,
        ldf_count TYPE i,
        ldf_vprsv TYPE mbew-vprsv,
        ldf_menge TYPE gtf_menge,
        ldf_dmbtr TYPE gtf_dmbtr,
        ldf_days  TYPE i,
        ldf_meng1 TYPE mseg-menge,
        ldf_meng2 TYPE mseg-menge.

  CLEAR:   ldt_mard, ldt_mbew, ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_mbst, ldt_msegi.
  REFRESH: ldt_mard, ldt_mbew, ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_mbst, ldt_msegi.

  SELECT mard~matnr
         mard~werks
         mard~lgort
         mard~lfgja
         mard~lfmon
         mard~labst  " 非限制庫存
         mard~insme  " 質檢庫存
         mard~speme  " 凍結庫存
         makt~maktx  " 物料描述
         t001w~name1 " 工廠描述
         t001l~lgobe " 庫存地點描述
         mara~meins
    INTO TABLE ldt_mard
    FROM mard LEFT OUTER JOIN makt ON makt~matnr = mard~matnr
                                  AND makt~spras = '1'
              LEFT OUTER JOIN t001w ON t001w~werks = mard~werks
              LEFT OUTER JOIN t001l ON t001l~werks = mard~werks
                                   AND t001l~lgort = mard~lgort
              LEFT OUTER JOIN mara ON mara~matnr = mard~matnr
   WHERE mard~matnr IN so_matnr
     AND mard~werks IN gdr_werks.
*     AND mard~lgort IN so_lgort.
  IF p_r2 = 'X'.
    SELECT mardh~matnr
           mardh~werks
           mardh~lgort
           mardh~lfgja
           mardh~lfmon
           mardh~labst  " 非限制庫存
           mardh~insme  " 質檢庫存
           mardh~speme  " 凍結庫存
           makt~maktx  " 物料描述
           t001w~name1 " 工廠描述
           t001l~lgobe " 庫存地點描述
           mara~meins
      APPENDING TABLE ldt_mard
      FROM mardh LEFT OUTER JOIN makt ON makt~matnr = mardh~matnr
                                     AND makt~spras = '1'
                 LEFT OUTER JOIN t001w ON t001w~werks = mardh~werks
                 LEFT OUTER JOIN t001l ON t001l~werks = mardh~werks
                                      AND t001l~lgort = mardh~lgort
                 LEFT OUTER JOIN mara ON mara~matnr = mardh~matnr
*     WHERE mardh~matnr IN so_matnr
*       AND mardh~werks IN gdr_werks.
**       AND mardh~lgort IN so_lgort.
*    DELETE ldt_mard WHERE lfgja > gdf_lfgja.
*    DELETE ldt_mard WHERE lfgja = gdf_lfgja AND lfmon > gdf_lfmon.
*    SORT ldt_mard BY matnr werks lgort lfgja DESCENDING lfmon DESCENDING.
*    LOOP AT ldt_mard.
*      ldf_index = sy-tabix.
*      AT NEW lgort.
*        ldf_count = 0.
*      ENDAT.
*      ADD 1 TO ldf_count.
*      IF ldf_count > 1.
*        ldt_mard-lfgja = '1900'.
*        ldt_mard-lfmon = '01'.
*        MODIFY ldt_mard INDEX ldf_index.
*      ENDIF.
*    ENDLOOP.
*    DELETE ldt_mard WHERE lfgja = '1900' AND lfmon = '01'.
      WHERE mardh~matnr IN so_matnr
        AND mardh~werks IN gdr_werks
        AND ( lfgja > gdf_lfgja OR lfgja = gdf_lfgja AND lfmon >= gdf_lfmon ).
    SORT ldt_mard BY matnr werks lgort lfgja ASCENDING lfmon ASCENDING.
    LOOP AT ldt_mard.
      ldf_index = sy-tabix.
      AT NEW lgort.
        ldf_count = 0.
      ENDAT.
      ADD 1 TO ldf_count.
      IF ldf_count > 1.
        ldt_mard-lfgja = '9999'.
        ldt_mard-lfmon = '12'.
        MODIFY ldt_mard INDEX ldf_index.
      ENDIF.
    ENDLOOP.
    DELETE ldt_mard WHERE lfgja = '9999' AND lfmon = '12'.


*   查詢日期不是月底的時候,需要倒推數量
    IF p_budat < gdf_budat.
      IF ldt_mard[] IS NOT INITIAL.
        SELECT mkpf~mblnr
               mkpf~mjahr
               mkpf~budat
               mseg~zeile
               mseg~matnr
               mseg~werks
               mseg~lgort
               mseg~shkzg
               mseg~menge
               mseg~meins
          INTO TABLE ldt_mseg
          FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                                   AND mkpf~mjahr = mseg~mjahr
         WHERE mseg~matnr IN so_matnr
           AND mseg~werks IN gdr_werks
*           AND mseg~lgort IN so_lgort
           AND mseg~sobkz <> 'E'
           AND mkpf~budat > p_budat
           AND mkpf~budat <= gdf_budat.
        LOOP AT ldt_mseg.
          READ TABLE ldt_mard WITH KEY matnr = ldt_mseg-matnr
                                       werks = ldt_mseg-werks
                                       lgort = ldt_mseg-lgort BINARY SEARCH.
          IF sy-subrc = 0.
            ldf_index = sy-tabix.
            IF ldt_mseg-shkzg = 'S'.
              ldt_mard-labst = ldt_mard-labst - ldt_mseg-menge.
            ELSE.
              ldt_mard-labst = ldt_mard-labst + ldt_mseg-menge.
            ENDIF.
            MODIFY ldt_mard INDEX ldf_index.
          ENDIF.
        ENDLOOP.
        CLEAR: ldt_mseg, ldt_mseg[].
      ENDIF.
    ENDIF.
  ENDIF.
  IF ldt_mard[] IS INITIAL.
    RETURN.
  ENDIF.
  SORT ldt_mard BY matnr werks lgort.

* 在設定中, 工廠werks與評估范圍bwkey 是完全一致的,省掉轉換的麻煩
  SELECT matnr " 物料編號
         bwkey " 評估范圍
         bwtar " 評估類型
         lfgja
         lfmon
         lbkum " 總計已估計庫存
         salk3 " 估價的總庫存價值
         vprsv " 價格控制指示符
         verpr " 移動平均價格/周期單價
         stprs " 標准價格
         peinh " 價格單位
    INTO TABLE ldt_mbew
    FROM mbew
   WHERE matnr IN so_matnr
     AND bwkey IN gdr_werks
     AND bwtar = ''.
  IF p_r2 = 'X'.
    SELECT matnr " 物料編號
           bwkey " 評估范圍
           bwtar " 評估類型
           lfgja
           lfmon
           lbkum " 總計已估計庫存
           salk3 " 估價的總庫存價值
           vprsv " 價格控制指示符
           verpr " 移動平均價格/周期單價
           stprs " 標准價格
           peinh " 價格單位
      APPENDING TABLE ldt_mbew
      FROM mbewh
     WHERE matnr IN so_matnr
       AND bwkey IN gdr_werks
       AND bwtar = ''
       AND ( lfgja > gdf_lfgja OR lfgja = gdf_lfgja AND lfmon >= gdf_lfmon ).
    SORT ldt_mbew BY matnr bwkey bwtar lfgja ASCENDING lfmon ASCENDING.
    LOOP AT ldt_mbew.
      ldf_index = sy-tabix.
      AT NEW bwtar.
        ldf_count = 0.
      ENDAT.
      ADD 1 TO ldf_count.
      IF ldf_count > 1.
        ldt_mbew-lfgja = '9999'.
        ldt_mbew-lfmon = '12'.
        MODIFY ldt_mbew INDEX ldf_index.
      ENDIF.
    ENDLOOP.
    DELETE ldt_mbew WHERE lfgja = '9999' AND lfmon = '12'.
  ENDIF.
  SORT ldt_mbew BY matnr bwkey bwtar.

* 整理數據
  LOOP AT ldt_mard.
    AT NEW werks.
      CLEAR: ldf_menge, ldf_dmbtr.
*     讀取單位價格
      READ TABLE ldt_mbew WITH KEY matnr = ldt_mard-matnr
                                   bwkey = ldt_mard-werks BINARY SEARCH.
      IF sy-subrc = 0.
        IF ldt_mbew-vprsv = 'S'.
          ldf_vprsv = 'S'.
          IF ldt_mbew-peinh = 0 OR ldt_mbew-peinh = 1.
            ldf_price = ldt_mbew-stprs.
          ELSE.
            ldf_price = ldt_mbew-stprs / ldt_mbew-peinh.
          ENDIF.
        ELSE.
          ldf_vprsv = 'V'.
          ldf_menge = ldt_mbew-lbkum.
          ldf_dmbtr = ldt_mbew-salk3.
          IF ldt_mbew-peinh = 0 OR ldt_mbew-peinh = 1.
            IF ldt_mbew-lbkum = 0.
              ldf_price = ldt_mbew-verpr.
            ELSE.
              ldf_price = ldt_mbew-salk3 / ldt_mbew-lbkum.
            ENDIF.
          ELSE.
            IF ldt_mbew-lbkum = 0.
              ldf_price = ldt_mbew-verpr / ldt_mbew-peinh.
            ELSE.
              ldf_price = ldt_mbew-salk3 / ldt_mbew-lbkum / ldt_mbew-peinh.
            ENDIF.
          ENDIF.
        ENDIF.
      ELSE.
        ldf_vprsv = 'S'.
        ldf_price = 0.
*        IF ldt_mbew-lbkum = 0.
*          ldf_price = 0.
*        ELSE.
*          ldf_price = ldt_mbew-salk3 / ldt_mbew-lbkum.
*        ENDIF.
      ENDIF.
    ENDAT.
**   按照庫存地點權限進行過濾
*    READ TABLE gdt_t001l WITH KEY werks = ldt_mard-werks
*                                  lgort = ldt_mard-lgort BINARY SEARCH.
*    IF sy-subrc <> 0.
*      CONTINUE.
*    ENDIF.

*   整理常規數據
    CLEAR gds_alv.
    gds_alv-matnr  = ldt_mard-matnr.
    gds_alv-maktx  = ldt_mard-maktx.
    gds_alv-werks  = ldt_mard-werks.
    gds_alv-name1  = ldt_mard-name1.
    gds_alv-lgort  = ldt_mard-lgort.
    gds_alv-lgobe  = ldt_mard-lgobe.
    gds_alv-ztype  = '普通庫存'.
    gds_alv-meins  = ldt_mard-meins.
    CALL FUNCTION 'ZTOOL_GET_MSEHL'
      EXPORTING
        meins = gds_alv-meins
      IMPORTING
        msehl = gds_alv-msehl.
    READ TABLE gdt_t001 WITH KEY bwkey = gds_alv-werks BINARY SEARCH.
    IF sy-subrc = 0.
      gds_alv-waers = gdt_t001-waers.
    ENDIF.
*    gds_alv-price  = ldf_price.
    gds_alv-menge  = ldt_mard-labst + ldt_mard-insme + ldt_mard-speme.
    gds_alv-dmbtr  = gds_alv-menge * ldf_price.
    ldf_menge = ldf_menge - gds_alv-menge.
    ldf_dmbtr = ldf_dmbtr - gds_alv-dmbtr.
    APPEND gds_alv TO gdt_alv.
    AT END OF werks.
      IF ldf_vprsv = 'V'.
        IF ldf_menge = 0 AND ldf_dmbtr <> 0.
*         存在尾差的情況下,將尾差寫到最后一行
          DESCRIBE TABLE gdt_alv LINES ldf_count.
          READ TABLE gdt_alv INTO gds_alv INDEX ldf_count.
          gds_alv-dmbtr = gds_alv-dmbtr + ldf_dmbtr.
          MODIFY gdt_alv FROM gds_alv INDEX ldf_count TRANSPORTING dmbtr.
        ENDIF.
      ENDIF.
    ENDAT.
  ENDLOOP.
* 去掉庫存為零的項目
  DELETE gdt_alv WHERE menge = 0.
  IF so_lgort[] IS NOT INITIAL.
    DELETE gdt_alv WHERE lgort NOT IN so_lgort[].
  ENDIF.
* 按照庫存地點權限進行過濾
  IF gdt_t001l[] IS NOT INITIAL.
    LOOP AT gdt_alv INTO gds_alv.
      ldf_index = sy-tabix. "added by yangk 20150831  原因:ldf_index參數未指定,導致數據有問題,權限小的用戶會down
      READ TABLE gdt_t001l WITH KEY werks = gds_alv-werks
                                    lgort = gds_alv-lgort BINARY SEARCH.
      IF sy-subrc <> 0.
        gds_alv-menge = 0.
        MODIFY gdt_alv FROM gds_alv INDEX ldf_index TRANSPORTING menge.
      ENDIF.
    ENDLOOP.
    CLEAR ldf_index."added by yangk 20150831
  ENDIF.
  DELETE gdt_alv WHERE menge = 0.

  CLEAR:   ldt_mard, ldt_mbew.
  REFRESH: ldt_mard, ldt_mbew.

* 獲取庫齡
* 期初庫齡
  SELECT *
    INTO TABLE ldt_zmseg
*    FROM zmm_mseg "add by XXX 20160108
    FROM zmm_mseg_new "add by XXX 20160108
     FOR ALL ENTRIES IN gdt_alv
   WHERE matnr = gdt_alv-matnr
     AND werks = gdt_alv-werks
     AND lgort = gdt_alv-lgort
     AND ( vbeln = '' OR vbeln = '0000000000' )
     AND budat <= gdc_idate .
  SORT ldt_zmseg BY matnr werks lgort budat DESCENDING.
* 對2013-12-31的庫存數量
* 按照入庫的日期,進行逐一匹配比對... 2013-12-31是期初導入,特殊邏輯處理
  SELECT mkpf~mblnr
         mkpf~mjahr
         mkpf~budat
         mseg~zeile
         mseg~matnr
         mseg~werks
         mseg~lgort
         mseg~shkzg
         mseg~menge
         mseg~meins
    INTO TABLE ldt_msegi
    FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                             AND mkpf~mjahr = mseg~mjahr
     FOR ALL ENTRIES IN gdt_alv
   WHERE mseg~matnr = gdt_alv-matnr
     AND mseg~werks = gdt_alv-werks
     AND mseg~lgort = gdt_alv-lgort
     AND mseg~bwart <> '321'
     AND mseg~bwart <> '322'
     AND mseg~sobkz <> 'E'
*     AND mseg~shkzg = 'H'
     AND mkpf~budat = gdc_idate .
  SORT ldt_msegi BY matnr werks lgort.
  LOOP AT ldt_msegi.
    CLEAR ldt_mseg.
    ldt_mseg-matnr = ldt_msegi-matnr.
    ldt_mseg-werks = ldt_msegi-werks.
    ldt_mseg-lgort = ldt_msegi-lgort.
    IF ldt_msegi-shkzg = 'S'.
      ldt_mseg-menge = ldt_msegi-menge.
    ELSE.
      ldt_mseg-menge = 0 - ldt_msegi-menge.
    ENDIF.
    ldt_mseg-meins = ldt_msegi-meins.
    ldt_mseg-budat = gdc_idate.
    COLLECT ldt_mseg.
  ENDLOOP.
* 按照入庫的日期,進行逐一匹配比對... 2013-12-31是期初導入,特殊邏輯處理
  SELECT mkpf~mblnr
         mkpf~mjahr
         mkpf~budat
         mseg~zeile
         mseg~matnr
         mseg~werks
         mseg~lgort
         mseg~shkzg
         mseg~menge
         mseg~meins
    APPENDING TABLE ldt_mseg
    FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                             AND mkpf~mjahr = mseg~mjahr
     FOR ALL ENTRIES IN gdt_alv
   WHERE mseg~matnr = gdt_alv-matnr
     AND mseg~werks = gdt_alv-werks
     AND mseg~lgort = gdt_alv-lgort
     AND mseg~bwart <> '321'
     AND mseg~bwart <> '322'
     AND mseg~sobkz <> 'E'
     AND mseg~shkzg = 'S'
     AND mkpf~budat <> gdc_idate.
  IF p_r2 = 'X'.
    DELETE ldt_mseg WHERE budat > gdf_budat.
  ENDIF.
* 獲取所有的沖銷憑證 - 2013-12-31是期初導入,特殊邏輯處理,沖銷從2014年開始判斷
  IF p_r2 = 'X'.
    SELECT mseg~mblnr
           mseg~mjahr
           mseg~zeile
           mseg~sjahr " 物料憑證年度
           mseg~smbln " 物料憑證編號
           mseg~smblp " 物料憑證中的項目
      INTO TABLE ldt_mbst
      FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                               AND mkpf~mjahr = mseg~mjahr
     WHERE mseg~smbln <> ''
       AND mseg~mjahr >= '2014'
       AND mseg~bwart <> '321'
       AND mseg~bwart <> '322'
       AND mkpf~budat <= gdf_budat.
  ELSE.
    SELECT mblnr
           mjahr
           zeile
           sjahr " 物料憑證年度
           smbln " 物料憑證編號
           smblp " 物料憑證中的項目
      INTO TABLE ldt_mbst
      FROM mseg
     WHERE smbln <> ''
       AND mjahr >= '2014'
       AND bwart <> '321'
       AND bwart <> '322'.
  ENDIF.
  SORT ldt_mbst BY sjahr smbln smblp.
* 將沖銷憑證剔出 - 沖銷的情況總是比較少的,所以優先處理
  SORT ldt_mseg BY mjahr mblnr zeile.
  LOOP AT ldt_mbst.
    READ TABLE ldt_mseg WITH KEY mjahr = ldt_mbst-sjahr
                                 mblnr = ldt_mbst-smbln
                                 zeile = ldt_mbst-smblp BINARY SEARCH.
    IF sy-subrc = 0.
*     刪除 被沖銷憑證
      DELETE ldt_mseg INDEX sy-tabix.
*     刪除 沖銷憑證
      DELETE ldt_mseg WHERE mjahr = ldt_mbst-mjahr
                        AND mblnr = ldt_mbst-mblnr
                        AND zeile = ldt_mbst-zeile.
    ENDIF.
  ENDLOOP.
* 處理庫存
  SORT ldt_mseg BY matnr werks lgort budat DESCENDING.
  LOOP AT ldt_mseg.
    CLEAR ldt_mseg2.
    ldt_mseg2-matnr = ldt_mseg-matnr.
    ldt_mseg2-werks = ldt_mseg-werks.
    ldt_mseg2-lgort = ldt_mseg-lgort.
*   物料憑證中menge數量單位就是物料數據中的基本單位,所以不用做單位換算邏輯
*    ldt_mseg2-meins = ldt_mseg-meins.
    IF ldt_mseg-budat = gdc_idate . " 期初數據處理
      ldf_meng1 = ldt_mseg-menge.
      LOOP AT ldt_zmseg WHERE matnr = ldt_mseg-matnr
                          AND werks = ldt_mseg-werks
                          AND lgort = ldt_mseg-lgort
                          AND menge > 0.
        ldf_index = sy-tabix.
        ldf_days = gdf_datum - ldt_zmseg-budat.
        IF ldt_zmseg-menge >= ldf_meng1.
          ldf_meng2 = ldf_meng1.
        ELSE.
          ldf_meng2 = ldt_zmseg-menge.
        ENDIF.

*        IF ldf_days <= 30.
*          ldt_mseg2-meng1 = ldf_meng2.
*        ELSEIF ldf_days <= 90.
*          ldt_mseg2-meng2 = ldf_meng2.
*        ELSEIF ldf_days <= 180.
*          ldt_mseg2-meng3 = ldf_meng2.
**        ELSEIF ldf_days <= 270. "20160615 add
**          ldt_mseg2-meng10 = ldf_meng2.
*        ELSEIF ldf_days <= 365.
*          ldt_mseg2-meng4 = ldf_meng2.
*        ELSEIF ldf_days <= 730.  " 兩年內
*          ldt_mseg2-meng5 = ldf_meng2.
*        ELSEIF ldf_days <= 1095. " 三年內
*          ldt_mseg2-meng6 = ldf_meng2.
*        ELSEIF ldf_days <= 1460. " 四年內
*          ldt_mseg2-meng7 = ldf_meng2.
*        ELSEIF ldf_days <= 1825. " 五年內
*          ldt_mseg2-meng8 = ldf_meng2.
*        ELSE.
*          ldt_mseg2-meng9 = ldf_meng2.
*        ENDIF.
**************************20160616 change*****************************
        IF ldf_days <= d1.
          ldt_mseg2-meng1 = ldf_meng2.
        ELSEIF ldf_days <= d2.
          ldt_mseg2-meng2 = ldf_meng2.
        ELSEIF ldf_days <= d3.
          ldt_mseg2-meng3 = ldf_meng2.
        ELSEIF ldf_days <=  d4.
          ldt_mseg2-meng4 = ldf_meng2.
        ELSEIF ldf_days <=  d5.  " 兩年內
          ldt_mseg2-meng5 = ldf_meng2.
        ELSEIF ldf_days <=  d6. " 三年內
          ldt_mseg2-meng6 = ldf_meng2.
        ELSEIF ldf_days <=  d7. " 四年內
          ldt_mseg2-meng7 = ldf_meng2.
        ELSEIF ldf_days <=  d8. " 五年內
          ldt_mseg2-meng8 = ldf_meng2.
        ELSE.
          ldt_mseg2-meng9 = ldf_meng2.
        ENDIF.
**********************************************************************
        COLLECT ldt_mseg2.
        CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
               ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
        ldt_zmseg-menge = ldt_zmseg-menge - ldf_meng2.
        MODIFY ldt_zmseg INDEX ldf_index.
        ldf_meng1 = ldf_meng1 - ldf_meng2.
        IF ldf_meng1 <= 0.
          EXIT.
        ENDIF.
      ENDLOOP.
      IF ldf_meng1 > 0..
        ldf_days = gdf_datum - ldt_mseg-budat.
*        IF ldf_days <= 30.
*          ldt_mseg2-meng1 = ldf_meng1.
*        ELSEIF ldf_days <= 90.
*          ldt_mseg2-meng2 = ldf_meng1.
*        ELSEIF ldf_days <= 180.
*          ldt_mseg2-meng3 = ldf_meng1.
*        ELSEIF ldf_days <= 365.
*          ldt_mseg2-meng4 = ldf_meng1.
*        ELSEIF ldf_days <= 730.
*          ldt_mseg2-meng5 = ldf_meng1.
*        ELSEIF ldf_days <= 1095. " 三年內
*          ldt_mseg2-meng6 = ldf_meng1.
*        ELSEIF ldf_days <= 1460. " 四年內
*          ldt_mseg2-meng7 = ldf_meng1.
*        ELSEIF ldf_days <= 1825. " 五年內
*          ldt_mseg2-meng8 = ldf_meng1.
*        ELSE.
*          ldt_mseg2-meng9 = ldf_meng1.
*        ENDIF.
**************************20160616 change*****************************
        IF ldf_days <= d1.
          ldt_mseg2-meng1 = ldf_meng1.
        ELSEIF ldf_days <= d2.
          ldt_mseg2-meng2 = ldf_meng1.
        ELSEIF ldf_days <= d3.
          ldt_mseg2-meng3 = ldf_meng1.
        ELSEIF ldf_days <=  d4.
          ldt_mseg2-meng4 = ldf_meng1.
        ELSEIF ldf_days <=  d5.  " 兩年內
          ldt_mseg2-meng5 = ldf_meng1.
        ELSEIF ldf_days <=  d6. " 三年內
          ldt_mseg2-meng6 = ldf_meng1.
        ELSEIF ldf_days <=  d7. " 四年內
          ldt_mseg2-meng7 = ldf_meng1.
        ELSEIF ldf_days <=  d8. " 五年內
          ldt_mseg2-meng8 = ldf_meng1.
        ELSE.
          ldt_mseg2-meng9 = ldf_meng1.
        ENDIF.
**********************************************************************
        COLLECT ldt_mseg2.
        CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
               ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
      ENDIF.
    ELSE.
      ldf_days = gdf_datum - ldt_mseg-budat.
*      IF ldf_days <= 30.
*        ldt_mseg2-meng1 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 90.
*        ldt_mseg2-meng2 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 180.
*        ldt_mseg2-meng3 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 365.
*        ldt_mseg2-meng4 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 730.
*        ldt_mseg2-meng5 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1095. " 三年內
*        ldt_mseg2-meng6 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1460. " 四年內
*        ldt_mseg2-meng7 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1825. " 五年內
*        ldt_mseg2-meng8 = ldt_mseg-menge.
*      ELSE.
*        ldt_mseg2-meng9 = ldt_mseg-menge.
*      ENDIF.
**************************20160616 change*****************************
      IF ldf_days <= d1.
        ldt_mseg2-meng1 = ldt_mseg-menge.
      ELSEIF ldf_days <= d2.
        ldt_mseg2-meng2 = ldt_mseg-menge.
      ELSEIF ldf_days <= d3.
        ldt_mseg2-meng3 = ldt_mseg-menge.
      ELSEIF ldf_days <=  d4.
        ldt_mseg2-meng4 = ldt_mseg-menge.
      ELSEIF ldf_days <=  d5.  " 兩年內
        ldt_mseg2-meng5 = ldt_mseg-menge.
      ELSEIF ldf_days <=  d6. " 三年內
        ldt_mseg2-meng6 = ldt_mseg-menge.
      ELSEIF ldf_days <=  d7. " 四年內
        ldt_mseg2-meng7 = ldt_mseg-menge.
      ELSEIF ldf_days <=  d8. " 五年內
        ldt_mseg2-meng8 = ldt_mseg-menge.
      ELSE.
        ldt_mseg2-meng9 = ldt_mseg-menge.
      ENDIF.
**********************************************************************
      COLLECT ldt_mseg2.
      CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
             ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
    ENDIF.
*    ldf_days = gdf_datum - ldt_mseg-budat.
*    IF ldf_days <= 30.
*      ldt_mseg2-meng1 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 90.
*      ldt_mseg2-meng2 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 180.
*      ldt_mseg2-meng3 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 365.
*      ldt_mseg2-meng4 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 730.
*      ldt_mseg2-meng5 = ldt_mseg-menge.
*    ELSE.
*      ldt_mseg2-meng6 = ldt_mseg-menge.
*    ENDIF.
*    COLLECT ldt_mseg2.
  ENDLOOP.
  SORT ldt_mseg2 BY matnr werks lgort.

* 計算庫齡
  SORT gdt_alv BY matnr werks lgort vbeln posnr.
  LOOP AT gdt_alv INTO gds_alv.
    ldf_index = sy-tabix.
    IF gds_alv-menge = 0.
      gds_alv-price = 0.
    ELSE.
      gds_alv-price = gds_alv-dmbtr / gds_alv-menge.
    ENDIF.
    ldf_menge = gds_alv-menge.
    ldf_dmbtr = gds_alv-dmbtr.
    READ TABLE ldt_mseg2 WITH KEY matnr = gds_alv-matnr
                                  werks = gds_alv-werks
                                  lgort = gds_alv-lgort BINARY SEARCH.
    IF sy-subrc = 0.
      DO 1 TIMES.
        IF ldf_menge < ldt_mseg2-meng1.
          gds_alv-meng1 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng1 = ldt_mseg2-meng1.
        ldf_menge = ldf_menge - ldt_mseg2-meng1.

        IF ldf_menge < ldt_mseg2-meng2.
          gds_alv-meng2 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng2 = ldt_mseg2-meng2.
        ldf_menge = ldf_menge - ldt_mseg2-meng2.

        IF ldf_menge < ldt_mseg2-meng3.
          gds_alv-meng3 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng3 = ldt_mseg2-meng3.
        ldf_menge = ldf_menge - ldt_mseg2-meng3.

****************************20160615 add******************************
*        IF ldf_menge < ldt_mseg2-meng10.
*          gds_alv-meng10 = ldf_menge.
*          ldf_menge = 0.
*          EXIT.
*        ENDIF.
*        gds_alv-meng10 = ldt_mseg2-meng10.
*        ldf_menge = ldf_menge - ldt_mseg2-meng10.
**********************************************************************

        IF ldf_menge < ldt_mseg2-meng4.
          gds_alv-meng4 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng4 = ldt_mseg2-meng4.
        ldf_menge = ldf_menge - ldt_mseg2-meng4.

        IF ldf_menge < ldt_mseg2-meng5.
          gds_alv-meng5 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng5 = ldt_mseg2-meng5.
        ldf_menge = ldf_menge - ldt_mseg2-meng5.

        IF ldf_menge < ldt_mseg2-meng6.
          gds_alv-meng6 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng6 = ldt_mseg2-meng6.
        ldf_menge = ldf_menge - ldt_mseg2-meng6.

        IF ldf_menge < ldt_mseg2-meng7.
          gds_alv-meng7 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng7 = ldt_mseg2-meng7.
        ldf_menge = ldf_menge - ldt_mseg2-meng7.

        IF ldf_menge < ldt_mseg2-meng8.
          gds_alv-meng8 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng8 = ldt_mseg2-meng8.
        ldf_menge = ldf_menge - ldt_mseg2-meng8.

        IF ldf_menge < ldt_mseg2-meng9.
          gds_alv-meng9 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng9 = ldt_mseg2-meng9.
        ldf_menge = ldf_menge - ldt_mseg2-meng9.
      ENDDO.
    ENDIF.
*   初始庫存導入
    IF ldf_menge > 0.
      gds_alv-meng99 = ldf_menge.
      ldf_days = gdf_datum - gdc_idate.
*      IF ldf_days <= 30.
*        ADD 1 TO gds_alv-meng1.
*      ELSEIF ldf_days <= 90.
*        ADD 1 TO gds_alv-meng2.
*      ELSEIF ldf_days <= 180.
*        ADD 1 TO gds_alv-meng3.
**      ELSEIF ldf_days <= 270. "20160615 add
**        ADD 1 TO gds_alv-meng10.
*      ELSEIF ldf_days <= 365.
*        ADD 1 TO gds_alv-meng4.
*      ELSEIF ldf_days <= 730.
*        ADD 1 TO gds_alv-meng5.
*      ELSEIF ldf_days <= 1095. " 三年內
*        ADD 1 TO gds_alv-meng6.
*      ELSEIF ldf_days <= 1460. " 四年內
*        ADD 1 TO gds_alv-meng7.
*      ELSEIF ldf_days <= 1825. " 五年內
*        ADD 1 TO gds_alv-meng8.
*      ELSE.
*        ADD 1 TO gds_alv-meng9.
*      ENDIF.
*************************20160616 change******************************
      IF ldf_days <= d1.
        ADD 1 TO gds_alv-meng1.
      ELSEIF ldf_days <= d2.
        ADD 1 TO gds_alv-meng2.
      ELSEIF ldf_days <= d3.
        ADD 1 TO gds_alv-meng3.
      ELSEIF ldf_days <= d4.
        ADD 1 TO gds_alv-meng4.
      ELSEIF ldf_days <= d5.
        ADD 1 TO gds_alv-meng5.
      ELSEIF ldf_days <= d6. " 三年內
        ADD 1 TO gds_alv-meng6.
      ELSEIF ldf_days <= d7. " 四年內
        ADD 1 TO gds_alv-meng7.
      ELSEIF ldf_days <= d8. " 五年內
        ADD 1 TO gds_alv-meng8.
      ELSE.
        ADD 1 TO gds_alv-meng9.
      ENDIF.
**********************************************************************
    ENDIF.
*   計算金額
    gds_alv-dmbt1 = gds_alv-meng1 * gds_alv-price.
    gds_alv-dmbt2 = gds_alv-meng2 * gds_alv-price.
    gds_alv-dmbt3 = gds_alv-meng3 * gds_alv-price.
*    gds_alv-dmbt10 = gds_alv-meng10 * gds_alv-price. "20160615 add
    gds_alv-dmbt4 = gds_alv-meng4 * gds_alv-price.
    gds_alv-dmbt5 = gds_alv-meng5 * gds_alv-price.
    gds_alv-dmbt6 = gds_alv-meng6 * gds_alv-price.
    gds_alv-dmbt7 = gds_alv-meng7 * gds_alv-price.
    gds_alv-dmbt8 = gds_alv-meng8 * gds_alv-price.
    gds_alv-dmbt9 = gds_alv-meng9 * gds_alv-price.
*   處理尾差
    ldf_dmbtr = ldf_dmbtr
              - gds_alv-dmbt1
              - gds_alv-dmbt2
              - gds_alv-dmbt3
*              - gds_alv-dmbt10 "20160615 add
              - gds_alv-dmbt4
              - gds_alv-dmbt5
              - gds_alv-dmbt6
              - gds_alv-dmbt7
              - gds_alv-dmbt8
              - gds_alv-dmbt9.
    IF ldf_dmbtr <> 0.
*      gds_alv-dmbt99 = ldf_dmbtr.
      IF gds_alv-meng1 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt1.
      ELSEIF gds_alv-meng2 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt2.
      ELSEIF gds_alv-meng3 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt3.
*      ELSEIF gds_alv-meng10 <> 0. "20160615 add
*        ADD ldf_dmbtr TO gds_alv-dmbt10.
      ELSEIF gds_alv-meng4 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt4.
      ELSEIF gds_alv-meng5 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt5.
      ELSEIF gds_alv-meng6 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt6.
      ELSEIF gds_alv-meng7 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt7.
      ELSEIF gds_alv-meng8 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt8.
      ELSEIF gds_alv-meng9 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt9.
      ELSE.
        gds_alv-dmbtr = gds_alv-dmbtr - ldf_dmbtr.
      ENDIF.
    ENDIF.
    MODIFY gdt_alv FROM gds_alv INDEX ldf_index.
  ENDLOOP.

  CLEAR:   ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_mbst, ldt_msegi.
  REFRESH: ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_mbst, ldt_msegi.

ENDFORM.                    " FRM_GET_DATA

*&---------------------------------------------------------------------*
*&      Form  FRM_GET_DATA2
*&---------------------------------------------------------------------*
*       主邏輯
*----------------------------------------------------------------------*
FORM frm_get_data2.
  DATA: BEGIN OF ldt_mska OCCURS 10,
         matnr TYPE mska-matnr,
         werks TYPE mska-werks,
         lgort TYPE mska-lgort,
         charg TYPE mska-charg,
         sobkz TYPE mska-sobkz,
         vbeln TYPE mska-vbeln,
         posnr TYPE mska-posnr,
         lfgja TYPE mska-lfgja,
         lfmon TYPE mska-lfmon,
         kalab TYPE mska-kalab,  " 非限制庫存
         kains TYPE mska-kains,  " 質量檢驗中的庫存
         kaspe TYPE mska-kaspe,  " 凍結的庫存
         maktx TYPE makt-maktx,  " 物料描述
         name1 TYPE t001w-name1, " 工廠描述
         lgobe TYPE t001l-lgobe, " 庫存地點描述
         meins TYPE mara-meins,
        END OF ldt_mska,
        BEGIN OF ldt_mska2 OCCURS 10,
         matnr TYPE mska-matnr,
         werks TYPE mska-werks,
         vbeln TYPE mska-vbeln,
         posnr TYPE mska-posnr,
         lgort TYPE mska-lgort,
         lfgja TYPE mska-lfgja,
         lfmon TYPE mska-lfmon,
         kalab TYPE mska-kalab,  " 非限制庫存
         kains TYPE mska-kains,  " 質量檢驗中的庫存
         kaspe TYPE mska-kaspe,  " 凍結的庫存
         maktx TYPE makt-maktx,  " 物料描述
         name1 TYPE t001w-name1, " 工廠描述
         lgobe TYPE t001l-lgobe, " 庫存地點描述
         meins TYPE mara-meins,
        END OF ldt_mska2,
        BEGIN OF ldt_ebew OCCURS 10,
         matnr TYPE ebew-matnr, " 物料編號
         bwkey TYPE ebew-bwkey, " 評估范圍
         bwtar TYPE ebew-bwtar, " 評估類型
         sobkz TYPE ebew-sobkz,
         vbeln TYPE ebew-vbeln,
         posnr TYPE ebew-posnr,
         lfgja TYPE ebew-lfgja,
         lfmon TYPE ebew-lfmon,
         lbkum TYPE ebew-lbkum, " 總計已估計庫存
         salk3 TYPE ebew-salk3, " 估價的總庫存價值
         vprsv TYPE ebew-vprsv, " 價格控制指示符
         verpr TYPE ebew-verpr, " 移動平均價格/周期單價
         stprs TYPE ebew-stprs, " 標准價格
         peinh TYPE ebew-peinh, " 價格單位
        END OF ldt_ebew,
        BEGIN OF ldt_mseg OCCURS 10,
         mblnr TYPE mkpf-mblnr,
         mjahr TYPE mkpf-mjahr,
         budat TYPE mkpf-budat,
         zeile TYPE mseg-zeile,
         matnr TYPE mseg-matnr,
         werks TYPE mseg-werks,
         lgort TYPE mseg-lgort,
         shkzg TYPE mseg-shkzg,
         kdauf TYPE mseg-kdauf,
         kdpos TYPE mseg-kdpos,
         menge TYPE mseg-menge,
         meins TYPE mseg-meins,
         mat_kdauf TYPE mseg-mat_kdauf,
         mat_kdpos TYPE mseg-mat_kdpos,
        END OF ldt_mseg,
        ldt_msegi LIKE TABLE OF ldt_mseg WITH HEADER LINE,
        BEGIN OF ldt_mseg2 OCCURS 10,
         matnr TYPE mseg-matnr,
         werks TYPE mseg-werks,
         lgort TYPE mseg-lgort,
         kdauf TYPE mseg-kdauf,
         kdpos TYPE mseg-kdpos,
         meng1 TYPE gtf_menge,
         meng2 TYPE gtf_menge,
         meng3 TYPE gtf_menge,
         meng4 TYPE gtf_menge,
         meng5 TYPE gtf_menge,
         meng6 TYPE gtf_menge,
         meng7 TYPE gtf_menge,
         meng8 TYPE gtf_menge,
         meng9 TYPE gtf_menge,
*         meng10 TYPE gtf_menge, "20160615 add
*         meins type mseg-meins,
        END OF ldt_mseg2,
        BEGIN OF ldt_mbst OCCURS 10,
         mblnr TYPE mseg-mblnr,
         mjahr TYPE mseg-mjahr,
         zeile TYPE mseg-zeile,
         sjahr TYPE mseg-sjahr, " 物料憑證年度
         smbln TYPE mseg-smbln, " 物料憑證編號
         smblp TYPE mseg-smblp, " 物料憑證中的項目
        END OF ldt_mbst,
        BEGIN OF ldt_vbak OCCURS 10,
          vbeln TYPE vbak-vbeln,
          kunnr TYPE vbak-kunnr,
        END OF ldt_vbak,
        BEGIN OF ldt_vbap OCCURS 10,
          vbeln TYPE vbap-vbeln,
          posnr TYPE vbap-posnr,
          aufnr TYPE vbap-aufnr,
        END OF ldt_vbap,
        BEGIN OF ldt_aufk OCCURS 10,
          aufnr TYPE aufk-aufnr,
          ktext TYPE aufk-ktext,
        END OF ldt_aufk,
*        ldt_zmseg TYPE TABLE OF zmm_mseg WITH HEADER LINE,  "add by lumingdao 20160108
        ldt_zmseg TYPE TABLE OF zmm_mseg_new WITH HEADER LINE."add by lumingdao 20160108

  DATA: ldf_price TYPE gtf_price,
        ldf_index TYPE i,
        ldf_count TYPE i,
        ldf_kdauf TYPE mseg-kdauf,
        ldf_kdpos TYPE mseg-kdpos,
        ldf_vprsv TYPE ebew-vprsv,
        ldf_menge TYPE gtf_menge,
        ldf_meng1 TYPE mseg-menge,
        ldf_meng2 TYPE mseg-menge,
        ldf_dmbtr TYPE gtf_dmbtr,
        ldf_days  TYPE i.
  DATA: ldt_alv TYPE TABLE OF gts_alv WITH HEADER LINE.

  CLEAR:   ldt_mska, ldt_mska2, ldt_ebew, ldt_mseg, ldt_mseg2, ldt_zmseg,
           ldt_alv, ldt_msegi, ldt_mbst, ldt_vbak, ldt_vbap, ldt_aufk.
  REFRESH: ldt_mska, ldt_mska2, ldt_ebew, ldt_mseg, ldt_mseg2, ldt_zmseg,
           ldt_alv, ldt_msegi, ldt_mbst, ldt_vbak, ldt_vbap, ldt_aufk.

  SELECT mska~matnr
         mska~werks
         mska~lgort
         mska~charg
         mska~sobkz
         mska~vbeln
         mska~posnr
         mska~lfgja
         mska~lfmon
         mska~kalab
         mska~kains  " 質檢庫存
         mska~kaspe  " 凍結庫存
         makt~maktx  " 物料描述
         t001w~name1 " 工廠描述
         t001l~lgobe " 庫存地點描述
         mara~meins
    INTO TABLE ldt_mska
    FROM mska LEFT OUTER JOIN makt ON makt~matnr = mska~matnr
                                  AND makt~spras = '1'
              LEFT OUTER JOIN t001w ON t001w~werks = mska~werks
              LEFT OUTER JOIN t001l ON t001l~werks = mska~werks
                                   AND t001l~lgort = mska~lgort
              LEFT OUTER JOIN mara ON mara~matnr = mska~matnr
   WHERE mska~matnr IN so_matnr
     AND mska~werks IN gdr_werks
*     AND mska~lgort IN so_lgort
     AND mska~vbeln IN so_vbeln
     AND mska~posnr IN so_posnr.
  IF p_r2 = 'X'.
    SELECT mskah~matnr
           mskah~werks
           mskah~lgort
           mskah~charg
           mskah~sobkz
           mskah~vbeln
           mskah~posnr
           mskah~lfgja
           mskah~lfmon
           mskah~kalab
           mskah~kains  " 質檢庫存
           mskah~kaspe  " 凍結庫存
           makt~maktx  " 物料描述
           t001w~name1 " 工廠描述
           t001l~lgobe " 庫存地點描述
           mara~meins
      APPENDING TABLE ldt_mska
      FROM mskah LEFT OUTER JOIN makt ON makt~matnr = mskah~matnr
                                     AND makt~spras = '1'
                 LEFT OUTER JOIN t001w ON t001w~werks = mskah~werks
                 LEFT OUTER JOIN t001l ON t001l~werks = mskah~werks
                                      AND t001l~lgort = mskah~lgort
                 LEFT OUTER JOIN mara ON mara~matnr = mskah~matnr
*     WHERE mskah~matnr IN so_matnr
*       AND mskah~werks IN gdr_werks
**       AND mskah~lgort IN so_lgort
*       AND mskah~vbeln IN so_vbeln
*       AND mskah~posnr IN so_posnr.
*    DELETE ldt_mska WHERE lfgja > gdf_lfgja.
*    DELETE ldt_mska WHERE lfgja = gdf_lfgja AND lfmon > gdf_lfmon.
*    SORT ldt_mska BY matnr werks lgort charg sobkz vbeln posnr lfgja DESCENDING lfmon DESCENDING.
*    LOOP AT ldt_mska.
*      ldf_index = sy-tabix.
*      AT NEW posnr.
*        ldf_count = 0.
*      ENDAT.
*      ADD 1 TO ldf_count.
*      IF ldf_count > 1.
*        ldt_mska-lfgja = '1900'.
*        ldt_mska-lfmon = '01'.
*        MODIFY ldt_mska INDEX ldf_index.
*      ENDIF.
*    ENDLOOP.
*    DELETE ldt_mska WHERE lfgja = '1900' AND lfmon = '01'.
     WHERE mskah~matnr IN so_matnr
       AND mskah~werks IN gdr_werks
*       AND mskah~lgort IN so_lgort
       AND mskah~vbeln IN so_vbeln
       AND mskah~posnr IN so_posnr
       AND ( lfgja > gdf_lfgja OR lfgja = gdf_lfgja AND lfmon >= gdf_lfmon ).
    SORT ldt_mska BY matnr werks lgort charg sobkz vbeln posnr lfgja ASCENDING lfmon ASCENDING.
    LOOP AT ldt_mska.
      ldf_index = sy-tabix.
      AT NEW posnr.
        ldf_count = 0.
      ENDAT.
      ADD 1 TO ldf_count.
      IF ldf_count > 1.
        ldt_mska-lfgja = '9999'.
        ldt_mska-lfmon = '12'.
        MODIFY ldt_mska INDEX ldf_index.
      ENDIF.
    ENDLOOP.
    DELETE ldt_mska WHERE lfgja = '9999' AND lfmon = '12'.

*   查詢日期不是月底的時候,需要倒推數量
    IF p_budat < gdf_budat.
      IF ldt_mska[] IS NOT INITIAL.
        SELECT mkpf~mblnr
               mkpf~mjahr
               mkpf~budat
               mseg~zeile
               mseg~matnr
               mseg~werks
               mseg~lgort
               mseg~shkzg
               mseg~kdauf
               mseg~kdpos
               mseg~menge
               mseg~meins
               mseg~mat_kdauf
               mseg~mat_kdpos
          INTO TABLE ldt_mseg
          FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                                   AND mkpf~mjahr = mseg~mjahr
         WHERE mseg~matnr IN so_matnr
           AND mseg~werks IN gdr_werks
*           AND mseg~lgort IN so_lgort
           AND mseg~sobkz = 'E'
           AND ( ( mseg~kdauf IN so_vbeln AND mseg~kdpos IN so_posnr )
              OR ( mseg~mat_kdauf IN so_vbeln AND mseg~mat_kdpos IN so_posnr ) )
           AND mkpf~budat > p_budat
           AND mkpf~budat <= gdf_budat.
        SORT ldt_mska BY matnr werks lgort vbeln posnr charg sobkz.
        LOOP AT ldt_mseg.
          IF ldt_mseg-kdauf IS INITIAL.
            ldf_kdauf = ldt_mseg-mat_kdauf.
            ldf_kdpos = ldt_mseg-mat_kdpos.
          ELSE.
            ldf_kdauf = ldt_mseg-kdauf.
            ldf_kdpos = ldt_mseg-kdpos.
          ENDIF.
          READ TABLE ldt_mska WITH KEY matnr = ldt_mseg-matnr
                                       werks = ldt_mseg-werks
                                       lgort = ldt_mseg-lgort
                                       vbeln = ldf_kdauf
                                       posnr = ldf_kdpos BINARY SEARCH.
          IF sy-subrc = 0.
            ldf_index = sy-tabix.
            IF ldt_mseg-shkzg = 'S'.
              ldt_mska-kalab = ldt_mska-kalab - ldt_mseg-menge.
            ELSE.
              ldt_mska-kalab = ldt_mska-kalab + ldt_mseg-menge.
            ENDIF.
            MODIFY ldt_mska INDEX ldf_index.
          ENDIF.
        ENDLOOP.
        CLEAR: ldt_mseg, ldt_mseg[].
      ENDIF.
    ENDIF.
  ENDIF.
  IF ldt_mska[] IS INITIAL.
    RETURN.
  ENDIF.
  LOOP AT ldt_mska.
    MOVE-CORRESPONDING ldt_mska TO ldt_mska2.
    COLLECT ldt_mska2.
  ENDLOOP.

* 在設定中, 工廠werks與評估范圍bwkey 是完全一致的,省掉轉換的麻煩
  SELECT matnr " 物料編號
         bwkey " 評估范圍
         bwtar " 評估類型
         sobkz
         vbeln
         posnr
         lfgja
         lfmon
         lbkum " 總計已估計庫存
         salk3 " 估價的總庫存價值
         vprsv " 價格控制指示符
         verpr " 移動平均價格/周期單價
         stprs " 標准價格
         peinh " 價格單位
    INTO TABLE ldt_ebew
    FROM ebew
   WHERE matnr IN so_matnr
     AND bwkey IN gdr_werks
     AND bwtar = ''
     AND sobkz = 'E'
     AND vbeln IN so_vbeln
     AND posnr IN so_posnr.
  IF p_r2 = 'X'.
    SELECT matnr " 物料編號
           bwkey " 評估范圍
           bwtar " 評估類型
           sobkz
           vbeln
           posnr
           lfgja
           lfmon
           lbkum " 總計已估計庫存
           salk3 " 估價的總庫存價值
           vprsv " 價格控制指示符
           verpr " 移動平均價格/周期單價
           stprs " 標准價格
           peinh " 價格單位
      APPENDING TABLE ldt_ebew
      FROM ebewh
*     WHERE matnr IN so_matnr
*       AND bwkey IN gdr_werks
*       AND bwtar = ''
*       AND sobkz = 'E'
*       AND vbeln IN so_vbeln
*       AND posnr IN so_posnr.
*    DELETE ldt_ebew WHERE lfgja > gdf_lfgja.
*    DELETE ldt_ebew WHERE lfgja = gdf_lfgja AND lfmon > gdf_lfmon.
*    SORT ldt_ebew BY matnr bwkey bwtar sobkz vbeln posnr lfgja DESCENDING lfmon DESCENDING.
*    LOOP AT ldt_ebew.
*      ldf_index = sy-tabix.
*      AT NEW posnr.
*        ldf_count = 0.
*      ENDAT.
*      ADD 1 TO ldf_count.
*      IF ldf_count > 1.
*        ldt_ebew-lfgja = '1900'.
*        ldt_ebew-lfmon = '01'.
*        MODIFY ldt_ebew INDEX ldf_index.
*      ENDIF.
*    ENDLOOP.
*    DELETE ldt_ebew WHERE lfgja = '1900' AND lfmon = '01'.
     WHERE matnr IN so_matnr
       AND bwkey IN gdr_werks
       AND bwtar = ''
       AND sobkz = 'E'
       AND vbeln IN so_vbeln
       AND posnr IN so_posnr
       AND ( lfgja > gdf_lfgja OR lfgja = gdf_lfgja AND lfmon >= gdf_lfmon ).
    SORT ldt_ebew BY matnr bwkey bwtar sobkz vbeln posnr lfgja ASCENDING lfmon ASCENDING.
    LOOP AT ldt_ebew.
      ldf_index = sy-tabix.
      AT NEW posnr.
        ldf_count = 0.
      ENDAT.
      ADD 1 TO ldf_count.
      IF ldf_count > 1.
        ldt_ebew-lfgja = '9999'.
        ldt_ebew-lfmon = '12'.
        MODIFY ldt_ebew INDEX ldf_index.
      ENDIF.
    ENDLOOP.
    DELETE ldt_ebew WHERE lfgja = '9999' AND lfmon = '12'.

  ENDIF.
  SORT ldt_ebew BY matnr bwkey sobkz vbeln posnr.

* 整理數據
  SORT ldt_mska2 BY matnr werks vbeln posnr lgort.
  LOOP AT ldt_mska2.
    AT NEW posnr.
      CLEAR: ldf_menge, ldf_dmbtr.
*     讀取單位價格
      READ TABLE ldt_ebew WITH KEY matnr = ldt_mska2-matnr
                                   bwkey = ldt_mska2-werks
*                                   sobkz = ldt_mska-sobkz
                                   vbeln = ldt_mska2-vbeln
                                   posnr = ldt_mska2-posnr BINARY SEARCH.
      IF sy-subrc = 0.
        IF ldt_ebew-vprsv = 'S'.
          ldf_vprsv = 'S'.
          IF ldt_ebew-peinh = 0 OR ldt_ebew-peinh = 1.
            ldf_price = ldt_ebew-stprs.
          ELSE.
            ldf_price = ldt_ebew-stprs / ldt_ebew-peinh.
          ENDIF.
        ELSE.
          ldf_vprsv = 'V'.
          ldf_menge = ldt_ebew-lbkum.
          ldf_dmbtr = ldt_ebew-salk3.
          IF ldt_ebew-peinh = 0 OR ldt_ebew-peinh = 1.
            IF ldt_ebew-lbkum = 0.
              ldf_price = ldt_ebew-verpr.
            ELSE.
              ldf_price = ldt_ebew-salk3 / ldt_ebew-lbkum.
            ENDIF.
          ELSE.
            IF ldt_ebew-lbkum = 0.
              ldf_price = ldt_ebew-verpr / ldt_ebew-peinh.
            ELSE.
              ldf_price = ldt_ebew-salk3 / ldt_ebew-lbkum / ldt_ebew-peinh.
            ENDIF.
          ENDIF.
        ENDIF.
      ELSE.
        ldf_vprsv = ''.
        ldf_price = 0.
      ENDIF.
    ENDAT.
**   按照庫存地點權限進行過濾
*    READ TABLE gdt_t001l WITH KEY werks = ldt_mska-werks
*                                  lgort = ldt_mska-lgort BINARY SEARCH.
*    IF sy-subrc <> 0.
*      CONTINUE.
*    ENDIF.

*   整理常規數據
    CLEAR gds_alv.
    gds_alv-matnr  = ldt_mska2-matnr.
    gds_alv-maktx  = ldt_mska2-maktx.
    gds_alv-werks  = ldt_mska2-werks.
    gds_alv-name1  = ldt_mska2-name1.
    gds_alv-lgort  = ldt_mska2-lgort.
    gds_alv-lgobe  = ldt_mska2-lgobe.
    gds_alv-ztype  = '銷售訂單庫存'.
    gds_alv-vbeln  = ldt_mska2-vbeln.
    gds_alv-posnr  = ldt_mska2-posnr.
    gds_alv-meins  = ldt_mska2-meins.

    SELECT SINGLE bstkd FROM vbkd
      INTO gds_alv-bstkd
      WHERE vbeln = gds_alv-vbeln
        AND posnr = ''.

    CALL FUNCTION 'ZTOOL_GET_MSEHL'
      EXPORTING
        meins = gds_alv-meins
      IMPORTING
        msehl = gds_alv-msehl.
    READ TABLE gdt_t001 WITH KEY bwkey = gds_alv-werks BINARY SEARCH.
    IF sy-subrc = 0.
      gds_alv-waers = gdt_t001-waers.
    ENDIF.
    gds_alv-price  = ldf_price.
    gds_alv-menge  = ldt_mska2-kalab + ldt_mska2-kains + ldt_mska2-kaspe.
    gds_alv-dmbtr  = gds_alv-menge * ldf_price.
    ldf_dmbtr = ldf_dmbtr - gds_alv-dmbtr.
    ldf_menge = ldf_menge - gds_alv-menge.
    APPEND gds_alv TO ldt_alv.
    AT END OF posnr.
      IF ldf_vprsv = 'V'.
        IF ldf_menge = 0 AND ldf_dmbtr <> 0.
*         存在尾差的情況下,調整尾差
          DESCRIBE TABLE ldt_alv LINES ldf_count.
          READ TABLE ldt_alv INTO gds_alv INDEX ldf_count.
          gds_alv-dmbtr = gds_alv-dmbtr + ldf_dmbtr.
          MODIFY ldt_alv FROM gds_alv INDEX ldf_count.
        ENDIF.
      ENDIF.
    ENDAT.
  ENDLOOP.
* 去掉庫存為零的項目
  DELETE ldt_alv WHERE menge = 0.
  IF so_lgort[] IS NOT INITIAL.
    DELETE ldt_alv WHERE lgort NOT IN so_lgort.
  ENDIF.
* 按照庫存地點權限進行過濾
  IF gdt_t001l[] IS NOT INITIAL.
    LOOP AT ldt_alv INTO gds_alv.
      ldf_index = sy-tabix. "added by yangk 20150831  原因:ldf_index參數未指定,導致數據有問題,權限小的用戶會down
      READ TABLE gdt_t001l WITH KEY werks = gds_alv-werks
                                    lgort = gds_alv-lgort BINARY SEARCH.
      IF sy-subrc <> 0.
        gds_alv-menge = 0.
        MODIFY ldt_alv FROM gds_alv INDEX ldf_index TRANSPORTING menge.
      ENDIF.
      CLEAR ldf_index.
    ENDLOOP.
  ENDIF.
  DELETE ldt_alv WHERE menge = 0.

  CLEAR:   ldt_mska, ldt_mska2, ldt_ebew.
  REFRESH: ldt_mska, ldt_mska2, ldt_ebew.

* 獲取庫齡
* 期初庫齡
  SELECT *
    INTO TABLE ldt_zmseg
*    FROM zmm_mseg "add by lumingdao 20160108
    FROM zmm_mseg_new "add by lumingdao 20160108
     FOR ALL ENTRIES IN ldt_alv
   WHERE matnr = ldt_alv-matnr
     AND werks = ldt_alv-werks
     AND lgort = ldt_alv-lgort
     AND ( vbeln <> '' AND vbeln <> '0000000000' )
     AND budat <= gdc_idate.
  SORT ldt_zmseg BY matnr werks lgort vbeln posnr budat DESCENDING.
* 對2013-12-31的庫存數量
* 按照入庫的日期,進行逐一匹配比對... 2013-12-31是期初導入,特殊邏輯處理
  SELECT mkpf~mblnr
         mkpf~mjahr
         mkpf~budat
         mseg~zeile
         mseg~matnr
         mseg~werks
         mseg~lgort
         mseg~shkzg
         mseg~kdauf
         mseg~kdpos
         mseg~menge
         mseg~meins
         mseg~mat_kdauf
         mseg~mat_kdpos
    INTO TABLE ldt_msegi
    FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                             AND mkpf~mjahr = mseg~mjahr
     FOR ALL ENTRIES IN ldt_alv
   WHERE mseg~matnr = ldt_alv-matnr
     AND mseg~werks = ldt_alv-werks
     AND mseg~lgort = ldt_alv-lgort
     AND mseg~bwart <> '321'
     AND mseg~bwart <> '322'
     AND mseg~sobkz = 'E'
     AND ( ( mseg~kdauf = ldt_alv-vbeln
       AND mseg~kdpos = ldt_alv-posnr )
       OR ( mseg~mat_kdauf = ldt_alv-vbeln
       AND mseg~mat_kdpos = ldt_alv-posnr ) )
     AND  mkpf~budat = gdc_idate.
  SORT ldt_msegi BY matnr werks lgort.
  LOOP AT ldt_msegi.
    CLEAR ldt_mseg.
    ldt_mseg-matnr = ldt_msegi-matnr.
    ldt_mseg-werks = ldt_msegi-werks.
    ldt_mseg-lgort = ldt_msegi-lgort.
    ldt_mseg-mat_kdauf = ldt_msegi-mat_kdauf.
    ldt_mseg-mat_kdpos = ldt_msegi-mat_kdpos.
    ldt_mseg-kdauf = ldt_msegi-kdauf.
    ldt_mseg-kdpos = ldt_msegi-kdpos.
    IF ldt_msegi-shkzg = 'S'.
      ldt_mseg-menge = ldt_msegi-menge.
    ELSE.
      ldt_mseg-menge = 0 - ldt_msegi-menge.
    ENDIF.
    ldt_mseg-meins = ldt_msegi-meins.
    ldt_mseg-budat = gdc_idate.
    COLLECT ldt_mseg.
  ENDLOOP.
* 按照入庫的日期,進行逐一匹配比對...
  SELECT mkpf~mblnr
         mkpf~mjahr
         mkpf~budat
         mseg~zeile
         mseg~matnr
         mseg~werks
         mseg~lgort
         mseg~shkzg
         mseg~kdauf
         mseg~kdpos
         mseg~menge
         mseg~meins
         mseg~mat_kdauf
         mseg~mat_kdpos
    APPENDING TABLE ldt_mseg
    FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                             AND mkpf~mjahr = mseg~mjahr
     FOR ALL ENTRIES IN ldt_alv
   WHERE mseg~matnr = ldt_alv-matnr
     AND mseg~werks = ldt_alv-werks
     AND mseg~lgort = ldt_alv-lgort
     AND mseg~bwart <> '321'
     AND mseg~bwart <> '322'
     AND mseg~sobkz = 'E'
     AND ( ( mseg~kdauf = ldt_alv-vbeln
       AND mseg~kdpos = ldt_alv-posnr )
       OR ( mseg~mat_kdauf = ldt_alv-vbeln
       AND mseg~mat_kdpos = ldt_alv-posnr ) )
     AND mseg~shkzg = 'S'
     AND mkpf~budat <> gdc_idate .
  IF p_r2 = 'X'.
    DELETE ldt_mseg WHERE budat > gdf_budat.
  ENDIF.
* 獲取所有的沖銷憑證 - 2013-12-31是期初導入,特殊邏輯處理,沖銷從2014年開始判斷
  IF p_r2 = 'X'.
    SELECT mseg~mblnr
           mseg~mjahr
           mseg~zeile
           mseg~sjahr " 物料憑證年度
           mseg~smbln " 物料憑證編號
           mseg~smblp " 物料憑證中的項目
      INTO TABLE ldt_mbst
      FROM mseg INNER JOIN mkpf ON mkpf~mblnr = mseg~mblnr
                               AND mkpf~mjahr = mseg~mjahr
     WHERE mseg~smbln <> ''
       AND mseg~mjahr >= '2014'
       AND mseg~bwart <> '321'
       AND mseg~bwart <> '322'
       AND mkpf~budat <= gdf_budat.
  ELSE.
    SELECT mblnr
           mjahr
           zeile
           sjahr " 物料憑證年度
           smbln " 物料憑證編號
           smblp " 物料憑證中的項目
      INTO TABLE ldt_mbst
      FROM mseg
     WHERE smbln <> ''
       AND mjahr >= '2014'
       AND mseg~bwart <> '321'
       AND mseg~bwart <> '322'.
  ENDIF.
  SORT ldt_mbst BY sjahr smbln smblp.
* 將沖銷憑證剔出 - 沖銷的情況總是比較少的,所以優先處理
  SORT ldt_mseg BY mjahr mblnr zeile.
  LOOP AT ldt_mbst.
    READ TABLE ldt_mseg WITH KEY mjahr = ldt_mbst-sjahr
                                 mblnr = ldt_mbst-smbln
                                 zeile = ldt_mbst-smblp BINARY SEARCH.
    IF sy-subrc = 0.
*     刪除 被沖銷憑證
      DELETE ldt_mseg INDEX sy-tabix.
*     刪除 沖銷憑證
      DELETE ldt_mseg WHERE mjahr = ldt_mbst-mjahr
                        AND mblnr = ldt_mbst-mblnr
                        AND zeile = ldt_mbst-zeile.
    ENDIF.
  ENDLOOP.
* 處理庫存
  SORT ldt_mseg BY matnr werks lgort kdauf kdpos budat DESCENDING.
  LOOP AT ldt_mseg.
    CLEAR ldt_mseg2.
    ldt_mseg2-matnr = ldt_mseg-matnr.
    ldt_mseg2-werks = ldt_mseg-werks.
    ldt_mseg2-lgort = ldt_mseg-lgort.
    "修改 20150112  hou
    IF  ldt_mseg2-werks <> '8130'.
      IF ldt_mseg-kdauf IS INITIAL.
        ldt_mseg2-kdauf = ldt_mseg-mat_kdauf.
        ldt_mseg2-kdpos = ldt_mseg-mat_kdpos.
      ELSE.
        ldt_mseg2-kdauf = ldt_mseg-kdauf.
        ldt_mseg2-kdpos = ldt_mseg-kdpos.
      ENDIF.
    ELSE.
      IF ldt_mseg-mat_kdauf IS  NOT INITIAL.
        ldt_mseg2-kdauf = ldt_mseg-mat_kdauf.
        ldt_mseg2-kdpos = ldt_mseg-mat_kdpos.
      ELSE.
        ldt_mseg2-kdauf = ldt_mseg-kdauf.
        ldt_mseg2-kdpos = ldt_mseg-kdpos.
      ENDIF.
    ENDIF.
*   物料憑證中menge數量單位就是物料數據中的基本單位,所以不用做單位換算邏輯
*    ldt_mseg2-meins = ldt_mseg-meins.
    IF ldt_mseg-budat = gdc_idate. " 期初數據處理
      ldf_meng1 = ldt_mseg-menge.
      LOOP AT ldt_zmseg WHERE matnr = ldt_mseg-matnr
                          AND werks = ldt_mseg-werks
                          AND lgort = ldt_mseg-lgort
                          AND vbeln = ldt_mseg2-kdauf
                          AND posnr = ldt_mseg2-kdpos
                          AND menge > 0.
        ldf_index = sy-tabix.
        ldf_days = gdf_datum - ldt_zmseg-budat.
        IF ldt_zmseg-menge >= ldf_meng1.
          ldf_meng2 = ldf_meng1.
        ELSE.
          ldf_meng2 = ldt_zmseg-menge.
        ENDIF.
*        IF ldf_days <= 30.
*          ldt_mseg2-meng1 = ldf_meng2.
*        ELSEIF ldf_days <= 90.
*          ldt_mseg2-meng2 = ldf_meng2.
*        ELSEIF ldf_days <= 180.
*          ldt_mseg2-meng3 = ldf_meng2.
**        ELSEIF ldf_days <= 270. "20160615 add
**          ldt_mseg2-meng10 = ldf_meng2.
*        ELSEIF ldf_days <= 365.
*          ldt_mseg2-meng4 = ldf_meng2.
*        ELSEIF ldf_days <= 730.
*          ldt_mseg2-meng5 = ldf_meng2.
*        ELSEIF ldf_days <= 1095. " 三年內
*          ldt_mseg2-meng6 = ldf_meng2.
*        ELSEIF ldf_days <= 1460. " 四年內
*          ldt_mseg2-meng7 = ldf_meng2.
*        ELSEIF ldf_days <= 1825. " 五年內
*          ldt_mseg2-meng8 = ldf_meng2.
*        ELSE.
*          ldt_mseg2-meng9 = ldf_meng2.
*        ENDIF.
***************************20160616 change****************************
        IF ldf_days <= d1.
          ldt_mseg2-meng1 = ldf_meng2.
        ELSEIF ldf_days <= d2.
          ldt_mseg2-meng2 = ldf_meng2.
        ELSEIF ldf_days <= d3.
          ldt_mseg2-meng3 = ldf_meng2.
        ELSEIF ldf_days <= d4.
          ldt_mseg2-meng4 = ldf_meng2.
        ELSEIF ldf_days <= d5.
          ldt_mseg2-meng5 = ldf_meng2.
        ELSEIF ldf_days <= d6. " 三年內
          ldt_mseg2-meng6 = ldf_meng2.
        ELSEIF ldf_days <= d7. " 四年內
          ldt_mseg2-meng7 = ldf_meng2.
        ELSEIF ldf_days <= d8. " 五年內
          ldt_mseg2-meng8 = ldf_meng2.
        ELSE.
          ldt_mseg2-meng9 = ldf_meng2.
        ENDIF.
**********************************************************************
        COLLECT ldt_mseg2.
        CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
               ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
        ldt_zmseg-menge = ldt_zmseg-menge - ldf_meng2.
        MODIFY ldt_zmseg INDEX ldf_index.
        ldf_meng1 = ldf_meng1 - ldf_meng2.
        IF ldf_meng1 <= 0.
          EXIT.
        ENDIF.
      ENDLOOP.
      IF ldf_meng1 > 0..
        ldf_days = gdf_datum - ldt_mseg-budat.
*        IF ldf_days <= 30.
*          ldt_mseg2-meng1 = ldf_meng1.
*        ELSEIF ldf_days <= 90.
*          ldt_mseg2-meng2 = ldf_meng1.
*        ELSEIF ldf_days <= 180.
*          ldt_mseg2-meng3 = ldf_meng1.
**        ELSEIF ldf_days <= 270. "20160615 add
**          ldt_mseg2-meng10 = ldf_meng1.
*        ELSEIF ldf_days <= 365.
*          ldt_mseg2-meng4 = ldf_meng1.
*        ELSEIF ldf_days <= 730.
*          ldt_mseg2-meng5 = ldf_meng1.
*        ELSEIF ldf_days <= 1095. " 三年內
*          ldt_mseg2-meng6 = ldf_meng1.
*        ELSEIF ldf_days <= 1460. " 四年內
*          ldt_mseg2-meng7 = ldf_meng1.
*        ELSEIF ldf_days <= 1825. " 五年內
*          ldt_mseg2-meng8 = ldf_meng1.
*        ELSE.
*          ldt_mseg2-meng9 = ldf_meng1.
*        ENDIF.
*************************20160616 change******************************
        IF ldf_days <= d1.
          ldt_mseg2-meng1 = ldf_meng1.
        ELSEIF ldf_days <= d2.
          ldt_mseg2-meng2 = ldf_meng1.
        ELSEIF ldf_days <= d3.
          ldt_mseg2-meng3 = ldf_meng1.
        ELSEIF ldf_days <= d4.
          ldt_mseg2-meng4 = ldf_meng1.
        ELSEIF ldf_days <= d5.
          ldt_mseg2-meng5 = ldf_meng1.
        ELSEIF ldf_days <= d6. " 三年內
          ldt_mseg2-meng6 = ldf_meng1.
        ELSEIF ldf_days <= d7. " 四年內
          ldt_mseg2-meng7 = ldf_meng1.
        ELSEIF ldf_days <= d8. " 五年內
          ldt_mseg2-meng8 = ldf_meng1.
        ELSE.
          ldt_mseg2-meng9 = ldf_meng1.
        ENDIF.
**********************************************************************
        COLLECT ldt_mseg2.
        CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
               ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
      ENDIF.
    ELSE.
      ldf_days = gdf_datum - ldt_mseg-budat.
*      IF ldf_days <= 30.
*        ldt_mseg2-meng1 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 90.
*        ldt_mseg2-meng2 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 180.
*        ldt_mseg2-meng3 = ldt_mseg-menge.
**      ELSEIF ldf_days <= 270. "20160615 add
**        ldt_mseg2-meng10 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 365.
*        ldt_mseg2-meng4 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 730.
*        ldt_mseg2-meng5 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1095. " 三年內
*        ldt_mseg2-meng6 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1460. " 四年內
*        ldt_mseg2-meng7 = ldt_mseg-menge.
*      ELSEIF ldf_days <= 1825. " 五年內
*        ldt_mseg2-meng8 = ldt_mseg-menge.
*      ELSE.
*        ldt_mseg2-meng9 = ldt_mseg-menge.
*      ENDIF.
*************************20160616 change******************************
      IF ldf_days <= d1.
        ldt_mseg2-meng1 = ldt_mseg-menge.
      ELSEIF ldf_days <= d2.
        ldt_mseg2-meng2 = ldt_mseg-menge.
      ELSEIF ldf_days <= d3.
        ldt_mseg2-meng3 = ldt_mseg-menge.
      ELSEIF ldf_days <= d4.
        ldt_mseg2-meng4 = ldt_mseg-menge.
      ELSEIF ldf_days <= d5.
        ldt_mseg2-meng5 = ldt_mseg-menge.
      ELSEIF ldf_days <= d6. " 三年內
        ldt_mseg2-meng6 = ldt_mseg-menge.
      ELSEIF ldf_days <= d7. " 四年內
        ldt_mseg2-meng7 = ldt_mseg-menge.
      ELSEIF ldf_days <= d8. " 五年內
        ldt_mseg2-meng8 = ldt_mseg-menge.
      ELSE.
        ldt_mseg2-meng9 = ldt_mseg-menge.
      ENDIF.
**********************************************************************
      COLLECT ldt_mseg2.
      CLEAR: ldt_mseg2-meng1, ldt_mseg2-meng2, ldt_mseg2-meng3, ldt_mseg2-meng4, ldt_mseg2-meng5,
             ldt_mseg2-meng6, ldt_mseg2-meng7, ldt_mseg2-meng8, ldt_mseg2-meng9.
    ENDIF.
*    ldf_days = gdf_datum - ldt_mseg-budat.
*    IF ldf_days <= 30.
*      ldt_mseg2-meng1 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 90.
*      ldt_mseg2-meng2 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 180.
*      ldt_mseg2-meng3 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 365.
*      ldt_mseg2-meng4 = ldt_mseg-menge.
*    ELSEIF ldf_days <= 730.
*      ldt_mseg2-meng5 = ldt_mseg-menge.
*    ELSE.
*      ldt_mseg2-meng6 = ldt_mseg-menge.
*    ENDIF.
*    COLLECT ldt_mseg2.
  ENDLOOP.
  SORT ldt_mseg2 BY matnr werks lgort kdauf kdpos.

* 銷售訂單
  IF ldt_alv[] IS NOT INITIAL.
    SELECT vbeln kunnr
      INTO TABLE ldt_vbak
      FROM vbak
       FOR ALL ENTRIES IN ldt_alv
     WHERE vbeln = ldt_alv-vbeln.
    SORT ldt_vbak BY vbeln.
    SELECT vbeln posnr aufnr
      INTO TABLE ldt_vbap
      FROM vbap
       FOR ALL ENTRIES IN ldt_alv
     WHERE vbeln = ldt_alv-vbeln
       AND posnr = ldt_alv-posnr.
    SORT ldt_vbap BY vbeln posnr.
    IF ldt_vbap[] IS NOT INITIAL.
      SELECT aufnr ktext
        INTO TABLE ldt_aufk
        FROM aufk
         FOR ALL ENTRIES IN ldt_vbap
       WHERE aufnr = ldt_vbap-aufnr
         AND autyp = '01'.
      SORT ldt_aufk BY aufnr.
    ENDIF.
  ENDIF.

* 計算庫齡
  SORT ldt_alv BY matnr werks lgort vbeln posnr.
  LOOP AT ldt_alv INTO gds_alv.
    ldf_index = sy-tabix.
    READ TABLE ldt_vbak WITH KEY vbeln = gds_alv-vbeln BINARY SEARCH.
    IF sy-subrc = 0.
      gds_alv-kunnr = ldt_vbak-kunnr.
      CALL FUNCTION 'ZTOOL_GET_KNAME'
        EXPORTING
          kunnr = gds_alv-kunnr
        IMPORTING
          name1 = gds_alv-kunnrt.
    ENDIF.
    READ TABLE ldt_vbap WITH KEY vbeln = gds_alv-vbeln
                                 posnr = gds_alv-posnr BINARY SEARCH.
    IF sy-subrc = 0.
      gds_alv-aufnr = ldt_vbap-aufnr.
      READ TABLE ldt_aufk WITH KEY aufnr = gds_alv-aufnr BINARY SEARCH.
      IF sy-subrc = 0.
        gds_alv-aufnrt = ldt_aufk-ktext.
      ENDIF.
    ENDIF.
    ldf_menge = gds_alv-menge.
    ldf_dmbtr = gds_alv-dmbtr.
    READ TABLE ldt_mseg2 WITH KEY matnr = gds_alv-matnr
                                  werks = gds_alv-werks
                                  lgort = gds_alv-lgort
                                  kdauf = gds_alv-vbeln
                                  kdpos = gds_alv-posnr BINARY SEARCH.
    IF sy-subrc = 0.
      DO 1 TIMES.
        IF ldf_menge < ldt_mseg2-meng1.
          gds_alv-meng1 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng1 = ldt_mseg2-meng1.
        ldf_menge = ldf_menge - ldt_mseg2-meng1.

        IF ldf_menge < ldt_mseg2-meng2.
          gds_alv-meng2 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng2 = ldt_mseg2-meng2.
        ldf_menge = ldf_menge - ldt_mseg2-meng2.

        IF ldf_menge < ldt_mseg2-meng3.
          gds_alv-meng3 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng3 = ldt_mseg2-meng3.
        ldf_menge = ldf_menge - ldt_mseg2-meng3.

****************************20160615 add******************************
*        IF ldf_menge < ldt_mseg2-meng10.
*          gds_alv-meng10 = ldf_menge.
*          ldf_menge = 0.
*          EXIT.
*        ENDIF.
*        gds_alv-meng10 = ldt_mseg2-meng10.
*        ldf_menge = ldf_menge - ldt_mseg2-meng10.
**********************************************************************

        IF ldf_menge < ldt_mseg2-meng4.
          gds_alv-meng4 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng4 = ldt_mseg2-meng4.
        ldf_menge = ldf_menge - ldt_mseg2-meng4.

        IF ldf_menge < ldt_mseg2-meng5.
          gds_alv-meng5 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng5 = ldt_mseg2-meng5.
        ldf_menge = ldf_menge - ldt_mseg2-meng5.

        IF ldf_menge < ldt_mseg2-meng6.
          gds_alv-meng6 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng6 = ldt_mseg2-meng6.
        ldf_menge = ldf_menge - ldt_mseg2-meng6.

        IF ldf_menge < ldt_mseg2-meng7.
          gds_alv-meng7 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng7 = ldt_mseg2-meng7.
        ldf_menge = ldf_menge - ldt_mseg2-meng7.

        IF ldf_menge < ldt_mseg2-meng8.
          gds_alv-meng8 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng8 = ldt_mseg2-meng8.
        ldf_menge = ldf_menge - ldt_mseg2-meng8.

        IF ldf_menge < ldt_mseg2-meng9.
          gds_alv-meng9 = ldf_menge.
          ldf_menge = 0.
          EXIT.
        ENDIF.
        gds_alv-meng9 = ldt_mseg2-meng9.
        ldf_menge = ldf_menge - ldt_mseg2-meng9.
      ENDDO.
    ENDIF.
*   初始庫存導入
    IF ldf_menge > 0.
      gds_alv-meng99 = ldf_menge.
      ldf_days = gdf_datum - gdc_idate.
*      IF ldf_days <= 30.
*        ADD ldf_menge TO gds_alv-meng1.
*      ELSEIF ldf_days <= 90.
*        ADD ldf_menge TO gds_alv-meng2.
*      ELSEIF ldf_days <= 180.
*        ADD ldf_menge TO gds_alv-meng3.
**      ELSEIF ldf_days <= 270. "20160615 add
**        ADD ldf_menge TO gds_alv-meng10.
*      ELSEIF ldf_days <= 365.
*        ADD ldf_menge TO gds_alv-meng4.
*      ELSEIF ldf_days <= 730.
*        ADD ldf_menge TO gds_alv-meng5.
*      ELSEIF ldf_days <= 1095. " 三年內
*        ADD ldf_menge TO gds_alv-meng6.
*      ELSEIF ldf_days <= 1460. " 四年內
*        ADD ldf_menge TO gds_alv-meng7.
*      ELSEIF ldf_days <= 1825. " 五年內
*        ADD ldf_menge TO gds_alv-meng8.
*      ELSE.
*        ADD ldf_menge TO gds_alv-meng9.
*      ENDIF.
************************20160616 change*******************************
      IF ldf_days <= d1.
        ADD ldf_menge TO gds_alv-meng1.
      ELSEIF ldf_days <= d2.
        ADD ldf_menge TO gds_alv-meng2.
      ELSEIF ldf_days <= d3.
        ADD ldf_menge TO gds_alv-meng3.
      ELSEIF ldf_days <= d4.
        ADD ldf_menge TO gds_alv-meng4.
      ELSEIF ldf_days <= d5.
        ADD ldf_menge TO gds_alv-meng5.
      ELSEIF ldf_days <= d6. " 三年內
        ADD ldf_menge TO gds_alv-meng6.
      ELSEIF ldf_days <= d7. " 四年內
        ADD ldf_menge TO gds_alv-meng7.
      ELSEIF ldf_days <= d8. " 五年內
        ADD ldf_menge TO gds_alv-meng8.
      ELSE.
        ADD ldf_menge TO gds_alv-meng9.
      ENDIF.
**********************************************************************
    ENDIF.
*   計算金額
    gds_alv-dmbt1 = gds_alv-meng1 * gds_alv-price.
    gds_alv-dmbt2 = gds_alv-meng2 * gds_alv-price.
    gds_alv-dmbt3 = gds_alv-meng3 * gds_alv-price.
*    gds_alv-dmbt10 = gds_alv-meng10 * gds_alv-price. "20160615 add
    gds_alv-dmbt4 = gds_alv-meng4 * gds_alv-price.
    gds_alv-dmbt5 = gds_alv-meng5 * gds_alv-price.
    gds_alv-dmbt6 = gds_alv-meng6 * gds_alv-price.
    gds_alv-dmbt7 = gds_alv-meng7 * gds_alv-price.
    gds_alv-dmbt8 = gds_alv-meng8 * gds_alv-price.
    gds_alv-dmbt9 = gds_alv-meng9 * gds_alv-price.
*   處理尾差
    ldf_dmbtr = ldf_dmbtr
              - gds_alv-dmbt1
              - gds_alv-dmbt2
              - gds_alv-dmbt3
*              - gds_alv-dmbt10 "20160615 add
              - gds_alv-dmbt4
              - gds_alv-dmbt5
              - gds_alv-dmbt6
              - gds_alv-dmbt7
              - gds_alv-dmbt8
              - gds_alv-dmbt9.
    IF ldf_dmbtr <> 0.
*      gds_alv-dmbt9 = ldf_dmbtr.
      IF gds_alv-meng1 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt1.
      ELSEIF gds_alv-meng2 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt2.
      ELSEIF gds_alv-meng3 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt3.
*      ELSEIF gds_alv-meng10 <> 0. "20160615 add
*        ADD ldf_dmbtr TO gds_alv-dmbt10.
      ELSEIF gds_alv-meng4 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt4.
      ELSEIF gds_alv-meng5 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt5.
      ELSEIF gds_alv-meng6 <> 0.
        ADD ldf_dmbtr TO gds_alv-dmbt6.
*      ELSEIF ldf_days <= 1095. " 三年內
*        ADD ldf_dmbtr TO gds_alv-dmbt7.
*      ELSEIF ldf_days <= 1460. " 四年內
*        ADD ldf_dmbtr TO gds_alv-dmbt8.
*      ELSEIF ldf_days <= 1825. " 五年內
*        ADD ldf_dmbtr TO gds_alv-dmbt9.
***********************20160616 change********************************
      ELSEIF ldf_days <= d6. " 三年內
        ADD ldf_dmbtr TO gds_alv-dmbt7.
      ELSEIF ldf_days <= d7. " 四年內
        ADD ldf_dmbtr TO gds_alv-dmbt8.
      ELSEIF ldf_days <= d8. " 五年內
        ADD ldf_dmbtr TO gds_alv-dmbt9.
**********************************************************************
      ELSE.
        gds_alv-dmbtr = gds_alv-dmbtr - ldf_dmbtr.
      ENDIF.
    ENDIF.
    MODIFY ldt_alv FROM gds_alv INDEX ldf_index.
  ENDLOOP.

  APPEND LINES OF ldt_alv TO gdt_alv.

  CLEAR:   ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_alv, ldt_msegi, ldt_mbst,
           ldt_vbak, ldt_vbap, ldt_aufk.
  REFRESH: ldt_mseg, ldt_mseg2, ldt_zmseg, ldt_alv, ldt_msegi, ldt_mbst,
           ldt_vbak, ldt_vbap, ldt_aufk.

ENDFORM.                    " FRM_GET_DATA2

*&---------------------------------------------------------------------*
*&      Form  FRM_DISPLAY_ALV
*&---------------------------------------------------------------------*
*       顯示alv界面
*----------------------------------------------------------------------*
FORM frm_display_lvc.

* 設定報表輸出樣式。
  PERFORM set_layout_lvc.
* 設定報表列標題格式
  PERFORM set_fieldcat_lvc.
* 輸出ALV報表
  PERFORM alv_grid_display_lvc.

ENDFORM.                    " FRM_DISPLAY_ALV

*&---------------------------------------------------------------------*
*&      Form  SET_LAYOUT_LVC
*&---------------------------------------------------------------------*
*       設定報表輸出樣式。
*----------------------------------------------------------------------*
FORM set_layout_lvc.
  CLEAR: gds_alv_layout_lvc.
* 設置Grid的字段列寬度自動適應
  gds_alv_layout_lvc-cwidth_opt = 'X'.
* 設置Grid的行顏色變換顯示
  gds_alv_layout_lvc-zebra  = 'X'.
* 置彈出窗口的標題欄
  gds_alv_layout_lvc-detailtitl = '詳細內容'.
* 設置Grid的多行選擇列,其中BOX必須為內表的一列,為一個字符長度
  gds_alv_layout_lvc-box_fname = 'SEL'.
** 行顏色字段設置
*  gds_alv_layout_lvc-info_fname = 'ROWCOLOR'.
* 信號燈設置
*  IF r3 = 'X'.
*    gds_alv_layout_lvc-excp_fname = 'LIGHT'.
**   gds_alv_layout_lvc-excp_led = 'X'.
*  ENDIF.
ENDFORM.                    " SET_LAYOUT_LVC

*&---------------------------------------------------------------------*
*&      Form  SET_FIELDCAT_LVC
*&---------------------------------------------------------------------*
*       設定報表列標題格式
*----------------------------------------------------------------------*
FORM set_fieldcat_lvc.
  DATA dat TYPE p.
  DATA text TYPE scrtext_l.

  DATA l_d1(4) TYPE c.
  DATA l_d2(4) TYPE c.
  DATA l_d3(4) TYPE c.
  DATA l_d4(4) TYPE c.
  DATA l_d5(4) TYPE c.
  DATA l_d6(4) TYPE c.
  DATA l_d7(4) TYPE c.
  DATA l_d8(4) TYPE c.
  DATA l_dat(4) TYPE c.

* ------ initial valuation
  CLEAR   gdt_alv_fieldcat_lvc.
  REFRESH gdt_alv_fieldcat_lvc.

  gdf_alv_col_pos = 0.
  DEFINE fieldcat_macro.
    gdf_alv_col_pos = gdf_alv_col_pos + 1.
    gds_alv_fieldcat_lvc-tabname   = 'GDT_ALV'.
    gds_alv_fieldcat_lvc-fieldname = '&1'.
    gds_alv_fieldcat_lvc-scrtext_l = &2.
    gds_alv_fieldcat_lvc-key       = &3.
    gds_alv_fieldcat_lvc-emphasize = &4.
    gds_alv_fieldcat_lvc-no_out    = &5.
    gds_alv_fieldcat_lvc-convexit  = &6.
*   gds_alv_fieldcat_lvc-edit      = &6.
*   gds_alv_fieldcat_lvc-hotspot   = &6.
*   GdS_ALV_FIELDCAT_LVC-DECIMALS  = &6.
*   gds_alv_fieldcat_lvc-checkbox  = &6.
    gds_alv_fieldcat_lvc-outputlen = &7.
    gds_alv_fieldcat_lvc-no_zero   = &8.
    gds_alv_fieldcat_lvc-just      = &9.
    gds_alv_fieldcat_lvc-col_pos   = gdf_alv_col_pos.
    append gds_alv_fieldcat_lvc to gdt_alv_fieldcat_lvc.
    clear gds_alv_fieldcat_lvc.
  END-OF-DEFINITION.

* 列標題設定
  fieldcat_macro werks '工廠' 'X' '' '' '' '' '' ''.
  fieldcat_macro name1 '工廠描述' '' '' '' '' '' '' ''.
  fieldcat_macro lgort '庫存地點' 'X' '' '' '' '' '' ''.
  fieldcat_macro lgobe '庫存地點描述' '' '' '' '' '' '' ''.
  fieldcat_macro matnr '物料號' 'X' '' '' 'MATN1' '' '' ''.
  fieldcat_macro maktx '物料描述' '' '' '' '' '' '' ''.
  fieldcat_macro ztype '庫存類型' '' 'X' '' '' '' '' ''.
  IF p_c2 = 'X'. " 銷售訂單庫存
    fieldcat_macro bstkd 'IMIS合同號' '' 'X' '' '' '' '' ''.
    fieldcat_macro vbeln '銷售訂單號' 'X' '' '' 'ALPHA' '' '' ''.
    fieldcat_macro posnr '銷售訂單行項目' 'X' '' '' '' '' 'X' ''.
    fieldcat_macro kunnr '客戶編碼' '' '' '' 'ALPHA' '' '' ''.
    fieldcat_macro kunnrt '客戶描述' '' '' '' '' '' '' ''.
    fieldcat_macro aufnr '內部訂單' '' '' '' 'ALPHA' '' '' ''.
    fieldcat_macro aufnrt '項目描述' '' '' '' '' '' '' ''.
  ENDIF.
  fieldcat_macro menge '當前庫存數量' '' 'C700' '' '' '' 'X' ''.
  fieldcat_macro meins '單位' '' '' 'X' 'CUNIT' '' '' ''.
  fieldcat_macro msehl '單位描述' '' '' '' '' '' '' ''.
  fieldcat_macro dmbtr '當前庫存金額' '' 'C300' '' '' '' 'X' ''.
  fieldcat_macro waers '幣種' '' '' '' '' '' '' ''.
*  fieldcat_macro meng99 '期初庫存' '' 'C500' '' '' '' 'X' ''.
*  fieldcat_macro dmbt99 '尾差金額' '' 'C500' '' '' '' 'X' ''.
*  fieldcat_macro meng1 '庫存1-30天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt1 '庫存1-30天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng2 '庫存31-90天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt2 '庫存31-90天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng3 '庫存91-180天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt3 '庫存91-180天金額' '' 'C300' '' '' '' 'X' ''.
**************************20160615 add*********************************
**  fieldcat_macro meng10 '庫存181-270天數量' '' 'C700' '' '' '' 'X' ''.
**  fieldcat_macro dmbt10 '庫存181-270天金額' '' 'C300' '' '' '' 'X' ''.
**  fieldcat_macro meng4 '庫存271-365天數量' '' 'C700' '' '' '' 'X' ''.
**  fieldcat_macro dmbt4 '庫存271-365天金額' '' 'C300' '' '' '' 'X' ''.
***********************************************************************
*  fieldcat_macro meng4 '庫存181-365天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt4 '庫存181-365天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng5 '庫存366-730天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt5 '庫存366-730天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng6 '庫存731-1095天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt6 '庫存731-1095天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng7 '庫存1095-1460天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt7 '庫存1095-1460天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng8 '庫存1460-1825天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt8 '庫存1460-1825天金額' '' 'C300' '' '' '' 'X' ''.
*  fieldcat_macro meng9 '庫存大於1825天數量' '' 'C700' '' '' '' 'X' ''.
*  fieldcat_macro dmbt9 '庫存大於1825天金額' '' 'C300' '' '' '' 'X' ''.
******************************20160616 change*************************

*  PERFORM form_change CHANGING d1.
  l_d1 = d1.
  CONCATENATE '庫存1-' l_d1 '天數量' INTO text.
  fieldcat_macro meng1 text '' 'C700' '' '' '' 'X' ''.
  CONCATENATE '庫存1-' l_d1 '天金額' INTO text.
  fieldcat_macro dmbt1 text '' 'C300' '' '' '' 'X' ''.
  PERFORM dat_change USING d1 CHANGING dat.

*  PERFORM form_change CHANGING d2.
  IF dat LT d2.
    l_d2 = d2.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d2 '天數量' INTO text.
    fieldcat_macro meng2 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d2 '天金額' INTO text.
    fieldcat_macro dmbt2 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d2 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d3.
  IF dat LT d3.
    l_d3 = d3.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d3 '天數量' INTO text.
    fieldcat_macro meng3 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d3 '天金額' INTO text.
    fieldcat_macro dmbt3 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d3 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d4.
  IF dat LT d4.
    l_d4 = d4.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d4 '天數量' INTO text.
    fieldcat_macro meng4 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d4 '天金額' INTO text.
    fieldcat_macro dmbt4 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d4 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d5.
  IF dat LT d5.
    l_d5 = d5.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d5 '天數量' INTO text.
    fieldcat_macro meng5 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d5 '天金額' INTO text.
    fieldcat_macro dmbt5 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d5 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d6.
  IF dat LT d6.
    l_d6 = d6.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d6 '天數量' INTO text.
    fieldcat_macro meng6 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d6 '天金額' INTO text.
    fieldcat_macro dmbt6 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d6 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d7.
  IF dat LT d7.
    l_d7 = d7.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d7 '天數量' INTO text.
    fieldcat_macro meng7 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d7 '天金額' INTO text.
    fieldcat_macro dmbt7 text '' 'C300' '' '' '' 'X' ''.
    PERFORM dat_change USING d7 CHANGING dat.
  ENDIF.

*  PERFORM form_change CHANGING d8.
  IF dat LT d8.
    l_d8 = d8.
    l_dat = dat.
    CONCATENATE '庫存' l_dat '-' l_d8 '天數量' INTO text.
    fieldcat_macro meng8 text '' 'C700' '' '' '' 'X' ''.
    CONCATENATE '庫存' l_dat '-' l_d8 '天金額' INTO text.
    fieldcat_macro dmbt8 text '' 'C300' '' '' '' 'X' ''.
  ENDIF.

  IF l_d8 IS INITIAL.
    l_d8 = d8.
  ENDIF.
  CONCATENATE '庫存大於' l_d8 '天數量' INTO text.
  fieldcat_macro meng9 text '' 'C700' '' '' '' 'X' ''.
  CONCATENATE '庫存大於' l_d8 '天金額' INTO text.
  fieldcat_macro dmbt9 text '' 'C300' '' '' '' 'X' ''.
**********************************************************************

* 其他項目補充
  CALL FUNCTION 'ZTOOL_BUILD_FIELDCAT'
    EXPORTING
      im_fieldcat = gdt_alv_fieldcat_lvc
    IMPORTING
      fieldcat    = gdt_alv_fieldcat_lvc
    TABLES
      itab        = gdt_alv.

ENDFORM.                    " SET_FIELDCAT_LVC

*&---------------------------------------------------------------------*
*&      Form  ALV_GRID_DISPLAY_LVC
*&---------------------------------------------------------------------*
*       輸出ALV報表
*----------------------------------------------------------------------*
FORM alv_grid_display_lvc.
  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'
    EXPORTING
      i_callback_program       = sy-repid
      i_callback_pf_status_set = 'SET_PF_STATUS_LVC'
      i_callback_user_command  = 'USER_COMMAND_LVC'
      is_layout_lvc            = gds_alv_layout_lvc  "設定報表輸出樣式。
      it_fieldcat_lvc          = gdt_alv_fieldcat_lvc[]
*     it_sort_lvc              = gdt_alv_sortinfo_lvc
      i_default                = 'X'
      i_save                   = 'A'  "設定是否可以保存報表布局
*     i_html_height_top        = 12
*     i_html_height_end        = 8
    TABLES
      t_outtab                 = gdt_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.                    " ALV_GRID_DISPLAY_LVC

*&---------------------------------------------------------------------*
*&      Form  PF_STATUS_SET_LVC
*&---------------------------------------------------------------------*
*       定義用戶自定義的屏幕菜單。
*----------------------------------------------------------------------*
FORM set_pf_status_lvc USING im_extab TYPE slis_t_extab.
  DATA: l_count TYPE i.
  DATA: ldt_fcode TYPE TABLE OF sy-ucomm.

  CLEAR:   ldt_fcode.
  REFRESH: ldt_fcode.

  DESCRIBE TABLE gdt_alv[] LINES l_count.
  SET TITLEBAR  'TITLE' WITH l_count.

*  APPEND '&SUM' TO ldt_fcode.   " 小計
*  APPEND '&ABC' TO ldt_fcode.   " ABC分析
*  APPEND '&GRAPH' TO ldt_fcode. " 圖形分析
  APPEND 'SAVE' TO ldt_fcode.   " 保存
  SET PF-STATUS 'STANDARD' EXCLUDING ldt_fcode.
ENDFORM.                    "SET_PF_STATUS_LVC


*&---------------------------------------------------------------------*
*&      Form  USER_COMMAND_LVC
*&---------------------------------------------------------------------*
*       響應菜單項及相應事件。
*----------------------------------------------------------------------*
FORM user_command_lvc USING im_ucomm   TYPE sy-ucomm
                            im_filecat TYPE slis_selfield.
  DATA: lv_tag  TYPE i.

  CASE im_ucomm .
*   返回/退出
    WHEN  'BACK' OR  'EXIT'.
      LEAVE TO SCREEN 0.
    WHEN 'CANCEL'.
      LEAVE PROGRAM.

*   刷新
    WHEN 'REFR'.
*     從數據表取數據並整理
      PERFORM get_data.
      IF gdt_alv[] IS INITIAL.
        MESSAGE i001.  " 沒有找到相關的數據!
        LEAVE TO SCREEN 0.
      ELSE.
        im_filecat-refresh = 'X'.
      ENDIF.

*   雙擊
    WHEN '&IC1' .
      READ TABLE gdt_alv INTO gds_alv INDEX im_filecat-tabindex.
      IF sy-subrc = 0.
        PERFORM frm_alv_dbclick USING gds_alv im_filecat CHANGING lv_tag.
        IF lv_tag <> 0.
        ENDIF.
      ENDIF .

    WHEN OTHERS.
  ENDCASE.
ENDFORM.                    "user_command_lvc
*&---------------------------------------------------------------------*
*&      Form  FRM_GET_INIT_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM frm_get_init_data  CHANGING c_date.

  DATA:lt_itab LIKE TABLE OF zmm_bukrs WITH HEADER LINE,
       BEGIN OF lt_bukrs OCCURS 0,
         werks TYPE lgort-werks,
       END OF lt_bukrs,
       BEGIN OF lt_lgort OCCURS 0,
         lgort TYPE mseg-lgort,
       END OF lt_lgort.

  IF sy-mandt EQ '810'.
    c_date = '20131231'.
  ELSEIF sy-mandt EQ '820' OR sy-mandt EQ '600' OR sy-mandt = '401'.
    IF p_bukrs EQ '8100'.
      c_date = '20140630'.
    ELSEIF p_bukrs EQ '8200'.
      c_date = '20151231'.
    ENDIF.
  ENDIF.

  IF so_werks[] IS INITIAL AND so_lgort[] IS INITIAL.
    "獲取庫齡報表:公司代碼工廠庫存地點
    SELECT *
           INTO CORRESPONDING FIELDS OF TABLE lt_itab
           FROM zmm_bukrs
           WHERE bukrs EQ p_bukrs
           .

    LOOP AT lt_itab.
      lt_bukrs-werks = lt_itab-werks.
      lt_lgort-lgort = lt_itab-lgort.
      APPEND: lt_bukrs,
              lt_lgort.
      CLEAR:lt_bukrs,
            lt_lgort.
    ENDLOOP.
    SORT lt_bukrs.
    SORT lt_lgort.

    DELETE ADJACENT DUPLICATES FROM lt_bukrs.
    DELETE ADJACENT DUPLICATES FROM lt_lgort.

    "將庫齡報表:公司代碼工廠庫存地點 寫入到選擇屏幕中的變量中
    LOOP AT lt_bukrs.
      PERFORM frm_add_werks_data  USING so_werks[] lt_bukrs-werks  '' 'EQ'.
    ENDLOOP.

    LOOP AT lt_lgort.
      PERFORM frm_add_lgort_data  USING so_lgort[] lt_lgort-lgort  '' 'EQ'.
    ENDLOOP.


  ENDIF.

*  BREAK-POINT.

ENDFORM.                    " FRM_GET_INIT_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_ADD_WERKS_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM frm_add_werks_data  USING    r_range LIKE so_werks[]
                                  u_low
                                  u_high
                                  u_option
                                   .
  DATA: lw_range LIKE LINE OF so_werks.
  lw_range-sign   = 'I'."  I -> include  E -> exclude (包含、排除)
  lw_range-option = u_option." EQ, BT, NE,CP....
  lw_range-low    = u_low.
  lw_range-high   = u_high.
  APPEND lw_range TO r_range.

ENDFORM.                    " FRM_ADD_WERKS_DATA
*&---------------------------------------------------------------------*
*&      Form  FRM_ADD_LGORT_DATA
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM frm_add_lgort_data  USING   r_range LIKE so_lgort[]
                                  u_low
                                  u_high
                                  u_option
                                   .

  DATA: lw_range LIKE LINE OF so_lgort.
  lw_range-sign   = 'I'."  I -> include  E -> exclude (包含、排除)
  lw_range-option = u_option." EQ, BT, NE,CP....
  lw_range-low    = u_low.
  lw_range-high   = u_high.
  APPEND lw_range TO r_range.

ENDFORM.                    " FRM_ADD_LGORT_DATA
*&---------------------------------------------------------------------*
*&      Form  CHECK_DATE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM check_date .
  FIELD-SYMBOLS: <date1>,
                 <date2>.
  DATA name(4) TYPE c.
  DATA l_num TYPE n.

  DO 7 TIMES.
    l_num = l_num + 1.
    CONCATENATE 'P_D' l_num INTO name.
    ASSIGN (name) TO <date1>.
    l_num = l_num + 1.
    CONCATENATE 'P_D' l_num INTO name.
    ASSIGN (name) TO <date2>.
    IF <date2> IS INITIAL.
      <date2> = <date1>.
    ENDIF.
    IF <date2> LT <date1>.
      MESSAGE e000 WITH '請輸入正確日期順序'.
    ENDIF.
    l_num = l_num - 1.
  ENDDO.

  d1 = p_d1.
  d2 = p_d2.
  d3 = p_d3.
  d4 = p_d4.
  d5 = p_d5.
  d6 = p_d6.
  d7 = p_d7.
  d8 = p_d8.
ENDFORM.                    " CHECK_DATE
*&---------------------------------------------------------------------*
*&      Form  DAT_CHANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      -->P_D1  text
*      <--P_DAT  text
*----------------------------------------------------------------------*
FORM dat_change  USING    date
                 CHANGING dat.
  CLEAR dat.
  dat = date + 1.
*  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
*    EXPORTING
*      input  = dat
*    IMPORTING
*      output = dat.
ENDFORM.                    " DAT_CHANGE
*&---------------------------------------------------------------------*
*&      Form  FORM_CHANGE
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_D1  text
*----------------------------------------------------------------------*
FORM form_change  CHANGING date.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
    EXPORTING
      input  = date
    IMPORTING
      output = date.
ENDFORM.                    " FORM_CHANGE

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM