ZR_FI_009

*===============================基本信息===============================*
* 标题:采购价格与标准价格差异明细表
* 创建日期:2004-12-21       
*===============================定    义===============================*

************************************************************************
* 基本代码
************************************************************************
REPORT ZR_FI_009
NO STANDARD PAGE HEADING
LINE-COUNT 65
LINE-SIZE  174
MESSAGE-ID ZFI1.

************************************************************************
* INCLUDE:包含文件
************************************************************************
INCLUDE OLE2INCL.

************************************************************************
* TABLE: 定义TABLE
************************************************************************
TABLES: T001,  "公司代码
        MARA,  "常规物料数据
        MAKT,  "物料描述
        MBEW,  "物料评估
        EINA,  "采购信息记录 - 一般数据
        EINE,  "采购信息记录 - 采购组织数据
        MKPF,  "抬头:物料凭证
        MSEG,  "凭证段:物料
        T685,  "条件: 类型
        KONH,  "条件( 抬头 )
        KONP,  "条件( 项目 )
        A017,  "物料信息记录 (指定工厂)
        EKKO,  "采购凭证抬头
        EKPO.  "采购凭证项目
************************************************************************
*INTERNAL TABLES
************************************************************************
*定义内表ITABS
*报表最后输出时使用的数据
DATA: BEGIN OF IT_PRINT_001 OCCURS 0.
        DATA FLAG.
        DATA PRODNO LIKE EKPO-MATNR.      "物料号
        DATA MAKTX LIKE MAKT-MAKTX.       "物料名称
        DATA QTY1 LIKE EKPO-MENGE.        "采购数量(X-3)月
        DATA QTY2 LIKE EKPO-MENGE.        "采购数量(X-2)月
        DATA QTY3 LIKE EKPO-MENGE.        "采购数量(X-1)月
        DATA QTY_TOTAL LIKE EKPO-MENGE.   "合计数
        DATA AMOUNT1 LIKE GLT0-TSLVT.     "采购金额(X-3)月
        DATA AMOUNT2 LIKE GLT0-TSLVT.     "采购金额(X-2)月
        DATA AMOUNT3 LIKE GLT0-TSLVT.     "采购金额(X-1)月
        DATA AMOUNT_TOTAL LIKE GLT0-TSLVT."合计金额
        DATA PRICE_AGE TYPE P DECIMALS 4. "加权平均价格
        DATA PRICE_STAND TYPE P DECIMALS 4."标准价格
        DATA PRICE_DIFF TYPE P DECIMALS 4. "差异
        DATA CYL LIKE EKPO-MENGE.          "差异率

        DATA PRICE_DIFF_C LIKE MSEG-MBLNR."差异(字符型)
        DATA CYL_C LIKE MSEG-MBLNR.       "差异率(字符型)

        DATA MENGE LIKE EKPO-MENGE.
        DATA QTY LIKE EKPO-MENGE.         "数量
        DATA PRICE TYPE P DECIMALS 4.     "价格
        DATA PEINH LIKE EKPO-PEINH.       "价格单位
        DATA BPUMZ LIKE EKPO-BPUMZ.       "有关订货价格单位转换为基本单位的分子
        DATA BPUMN LIKE EKPO-BPUMN.       "订单计价单位转换为订单单位的值
        DATA UMREN LIKE EKPO-UMREN.       "订单单位到基本单位转换的分母
        DATA UMREZ LIKE EKPO-UMREZ.       "有关订货价格单位转换为基本单位的分子
        DATA WAERS LIKE EKKO-WAERS.       "货币代码
        DATA WKURS LIKE EKKO-WKURS.       "汇率
        DATA AMOUNT LIKE GLT0-TSLVT.      "金额

        DATA BWART LIKE MSEG-BWART.       "移动类型
        DATA MBLNR LIKE MSEG-MBLNR.       "物料凭证号
        DATA MATNR LIKE MSEG-MATNR.       "物料号
        DATA BUDAT LIKE MKPF-BUDAT.       "物料凭证上的记账日期
        DATA BEDAT LIKE EKKO-BEDAT.       "采购订单上的凭证日期
        DATA BSART LIKE EKKO-BSART.       "采购订单类型
        DATA LIFNR LIKE MSEG-LIFNR.       "供应商帐号
        DATA ANGNR LIKE KONP-KBETR.       "暂估价格
        DATA KNUM1 LIKE A017-KNUMH.       "价格的记录号
        DATA KNUM2 LIKE A017-KNUMH.       "暂估价的记录号
DATA: END OF IT_PRINT_001.

DATA: IT_PRINT_002 LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.
DATA: IT_PRINT_003 LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.
DATA: IT_PRINT_004 LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.

*定义内表ITAB_003
DATA: BEGIN OF ITAB_003 OCCURS 10.
        INCLUDE STRUCTURE MBEWH.
      DATA: MBEWH_DATE LIKE LIKP-ERDAT.
      DATA: BELNR LIKE MLCRP-BELNR.
DATA: END OF ITAB_003.
*定义内表ITAB_103
DATA: BEGIN OF ITAB_103 OCCURS 10.
        INCLUDE STRUCTURE MLCRP.
      DATA: MBEWH_DATE LIKE LIKP-ERDAT.
DATA: END OF ITAB_103.
*定义内表ITAB_203
DATA: BEGIN OF ITAB_203 OCCURS 10.
      DATA: STPRS LIKE MBEW-STPRS.   "标准价格
      DATA: PEINH LIKE MBEW-PEINH.   "价格单位
DATA: END OF ITAB_203.

*定义取采购信息记录上的价格的内表
DATA: BEGIN OF ITAB_PRICE OCCURS 10.
      DATA: KBETR LIKE KONP-KBETR.    "条件定价价格
      DATA: KPEIN LIKE KONP-KPEIN.    "条件定价单位
      DATA: KONWA LIKE KONP-KONWA.    "币别
DATA: END OF ITAB_PRICE.
*取采购信息记录上的价格的汇率
DATA: BEGIN OF ITAB_PRICE_RATE OCCURS 0.
        DATA UKURS LIKE TCURR-UKURS.        "汇率
        DATA GDATU LIKE TCURR-GDATU.        "汇率有效起始日期
DATA: END OF ITAB_PRICE_RATE.

*往数据库增加运行日志
  DATA: BEGIN OF IT_ZREPORTLOG OCCURS  0.
    INCLUDE TYPE ZREPORTLOG.
  DATA: END OF IT_ZREPORTLOG.
************************************************************************
* CONSTANTS : 定义常量
************************************************************************

************************************************************************
* TYPE : 定义数据类型
************************************************************************
TYPE-POOLS: SLIS.

************************************************************************
* DATA : 定义变量
************************************************************************
*单据表格上相关坐标值定义
DATA: A1 TYPE I VALUE 0,
      A2 TYPE I VALUE 0,
      A3 TYPE I VALUE 0,
      A4 TYPE I VALUE 0,
      A5 TYPE I VALUE 0,
      A6 TYPE I VALUE 0,
      A7 TYPE I VALUE 0,
      A8 TYPE I VALUE 0,
      A9 TYPE I VALUE 0.

DATA: B1 TYPE I VALUE 0,
      B2 TYPE I VALUE 0,
      B3 TYPE I VALUE 0,
      B4 TYPE I VALUE 0,
      B5 TYPE I VALUE 0,
      B6 TYPE I VALUE 0,
      B7 TYPE I VALUE 0,
      B8 TYPE I VALUE 0.
DATA: G_DAY(2),
      G_LEN TYPE I,
      G_MOD TYPE I,
      G_DATE_FROM1 LIKE EKKO-AEDAT,    "采购起始日期1
      G_DATE_TO1 LIKE EKKO-AEDAT,      "采购终止日期1
      G_DATE_FROM2 LIKE EKKO-AEDAT,    "采购起始日期2
      G_DATE_TO2 LIKE EKKO-AEDAT,      "采购终止日期2
      G_DATE_FROM3 LIKE EKKO-AEDAT,    "采购起始日期3
      G_DATE_TO3 LIKE EKKO-AEDAT.      "采购终止日期3

DATA: G_RYEAR1(4) TYPE C,
      G_PERID1(2) TYPE C,
      G_RYEAR2(4) TYPE C,
      G_PERID2(2) TYPE C,
      G_RYEAR3(4) TYPE C,
      G_PERID3(2) TYPE C,
      G_RYEAR4(4) TYPE C,
      G_PERID4(2) TYPE C.

DATA: NAME_LAST LIKE USER_ADDR-NAME_LAST,
      NAME_FIRST LIKE USER_ADDR-NAME_FIRST,
      NAME(16).

DATA: L_QTY LIKE EKPO-MENGE,
      L_AMOUNT TYPE P DECIMALS 4,
      G_FROM LIKE EKKO-AEDAT,    "采购起始日期
      G_TO LIKE EKKO-AEDAT.      "采购终止日期

DATA: G_PRICE_CG TYPE P DECIMALS 6.    "采购信息价格
*用于ALV控件双击事件
DATA: G_SELECTED_FIELD_VALUE(80).

*ALV控件构造时需要的参数
DATA: G_ALV_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV,
      G_ALV_FIELDCAT_LINE LIKE LINE OF G_ALV_FIELDCAT,
      G_ALV_EVENT         TYPE SLIS_T_EVENT.

*ALV控件输出的表头
DATA: G_ALV_LISTHEADER TYPE SLIS_T_LISTHEADER.
*指定ALV控件触发TOP_OF_PAGE事件时调用的子程序
DATA: G_ALV_FORMNAME_TOP_OF_PAGE TYPE SLIS_FORMNAME
             VALUE 'F_ALV_EVENT_TOP_OF_PAGE'.
DATA: G_ALV_FORMNAME_END_OF_LIST TYPE SLIS_FORMNAME
             VALUE 'F_ALV_EVENT_END_OF_LIST'.

*指定ALV控件的显示特征
DATA : G_ALV_LAYOUT TYPE SLIS_LAYOUT_ALV.
************************************************************************
* DEFINE: 定义宏
************************************************************************
*普通报表格式的输出宏
DEFINE MACRO1.               "画表格
  WRITE: AT /A1   SY-VLINE.
  WRITE: AT  B1   &1.
  WRITE: AT  A2   SY-VLINE.
  WRITE: AT  B2   &2.
  WRITE: AT  A3   SY-VLINE.
  WRITE: AT  B3   &3.
  WRITE: AT  A4   SY-VLINE.
  WRITE: AT  B4   &4.
  WRITE: AT  A5   SY-VLINE.
  WRITE: AT  B5   &5 RIGHT-JUSTIFIED.
  WRITE: AT  A6   SY-VLINE.
  WRITE: AT  B6   &6 RIGHT-JUSTIFIED.
  WRITE: AT  A7   SY-VLINE.
  WRITE: AT  B7   &7.
  WRITE: AT  A8   SY-VLINE.
  WRITE: AT  B8   &8.
  WRITE: AT  A9   SY-VLINE.
END-OF-DEFINITION.
************************************************************************
*  SELECTION SCREEN : 定义报表筛选条件
************************************************************************
*确定过滤参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_001 WITH FRAME. TITLE BLK_001 .
    PARAMETERS : P_BUKRS LIKE EKKO-BUKRS OBLIGATORY MEMORY ID 009_1. "公司代码
    PARAMETERS : P_RYEAR(4) TYPE C OBLIGATORY DEFAULT SY-DATUM+0(4)."报表年度
    PARAMETERS : P_PERID(2) TYPE C OBLIGATORY DEFAULT SY-DATUM+4(2)."报表期间
    SELECT-OPTIONS P_CYL FOR MSEG-WERKS  DEFAULT ''. "差异率EKPO-UEBTO
    SELECT-OPTIONS P_MATNR FOR MSEG-MATNR MEMORY ID 009_2.          "物料号
SELECTION-SCREEN END OF BLOCK BLK_001.

*采购信息类型
SELECTION-SCREEN BEGIN OF BLOCK BLK_004 WITH FRAME. TITLE BLK_004 .
PARAMETERS: P_ZC RADIOBUTTON GROUP R2 DEFAULT 'X',                  "直接采购
            P_TG RADIOBUTTON GROUP R2.                              "托工采购
SELECTION-SCREEN END OF BLOCK BLK_004.

*选择报表类型
SELECTION-SCREEN BEGIN OF BLOCK BLK_002 WITH FRAME. TITLE BLK_002 .
PARAMETERS: P_REPORT RADIOBUTTON GROUP R1,
            P_ALV RADIOBUTTON GROUP R1 DEFAULT 'X'.
SELECTION-SCREEN END OF BLOCK BLK_002.

*选择文件
*代码“NO-DISPLAY”的作用:隐藏参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_003 WITH FRAME. TITLE BLK_003 .
PARAMETERS: P_FILE LIKE CFFILE-FILENAME NO-DISPLAY  .
SELECTION-SCREEN END OF BLOCK BLK_003.


*===============================事    件===============================*
************************************************************************
* INITIALIZATION.启动程序开始执行
************************************************************************
INITIALIZATION.
  BLK_001 = '检索参数'.
  BLK_002 = '报表类型'.
  BLK_003 = '文件参数'.
  BLK_004 = '采购信息类型'.

  PERFORM. F_INI.
************************************************************************
* AT SELECTION SCREEN:
************************************************************************
AT SELECTION-SCREEN.
  PERFORM. F_CHECK_INPUT.          "检查用户输入
************************************************************************
* START OF SELECTION:
************************************************************************
START-OF-SELECTION.
*往数据库增加运行日志
  IT_ZREPORTLOG-MANDT = SY-MANDT.
  IT_ZREPORTLOG-TCODE = SY-TCODE.
  IT_ZREPORTLOG-DATUM = SY-DATUM.
  IT_ZREPORTLOG-UZEIT = SY-UZEIT.
  IT_ZREPORTLOG-UNAME = SY-UNAME.
  IT_ZREPORTLOG-TITLE = SY-TITLE.
  APPEND IT_ZREPORTLOG.
  INSERT INTO ZREPORTLOG VALUES IT_ZREPORTLOG .

  PERFORM. F_READ_DATA.

  IF P_REPORT = 'X'.
    PERFORM. F_PRINT_REPORT.
  ELSEIF P_ALV = 'X'.
    PERFORM. F_PRINT_ALV.
  ENDIF.
************************************************************************
* END OF SELECTION
************************************************************************
END-OF-SELECTION.

************************************************************************
* TOP OF PAGE
************************************************************************
TOP-OF-PAGE.
  PERFORM. F_HEAD.
************************************************************************
* END OF PAGE
************************************************************************
END-OF-PAGE.
  PERFORM. F_BOTTOM.


*===============================子 例 程===============================*
*&---------------------------------------------------------------------*
*过滤条件有效性检查
*&---------------------------------------------------------------------*
FORM. F_CHECK_INPUT.

  IF SY-SUBRC <> 0.
    MESSAGE E000.
  ENDIF.
ENDFORM.                    " F_CHECK_INPUT
*&---------------------------------------------------------------------*
*从数据库中读取数据,填充报表输出时所用的内表
*不取与托工相关的所有数据
*取采购类型为F,特殊采购类型不为30的记录
*&---------------------------------------------------------------------*
FORM. F_READ_DATA .
DATA: FLAG TYPE I,
      NOWDATE LIKE MKPF-BUDAT.

  PERFORM. CAL_DAY2.

*取前三个月的所有外购物料数据
IF P_ZC = 'X'.
  SELECT DISTINCT A~MATNR AS PRODNO     "物料号
    FROM MSEG AS A INNER JOIN MKPF AS B ON A~MBLNR = B~MBLNR
    INNER JOIN MARC AS C ON A~MATNR = C~MATNR AND A~WERKS = C~WERKS
    INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_001
    WHERE A~BUKRS = P_BUKRS
      AND B~BUDAT >= G_DATE_FROM1
      AND B~BUDAT <= G_DATE_TO3
      AND A~MATNR IN P_MATNR
      AND C~BESKZ = 'F'                       "采购类型
      AND C~SOBSL <> '30'                     "特殊采购类型(不是托工的物料)
      AND ( ( A~BWART = '105' AND A~SOBKZ = '' ) OR
            ( A~BWART = '106' AND A~SOBKZ = '' ) OR

            ( A~BWART = '201' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '202' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '261' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '262' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '411' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '412' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '333' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '334' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z03' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z04' AND A~SOBKZ = 'K' ) OR

*            A~BWART = '161' OR
*            A~BWART = '162' OR
            A~BWART = '101' OR
            A~BWART = '102' ).

*  取有两种采购类型直购物料
      SELECT DISTINCT A~MATNR AS PRODNO     "物料号
    FROM MSEG AS A INNER JOIN MKPF AS B ON A~MBLNR = B~MBLNR
    INNER JOIN MARC AS C ON A~MATNR = C~MATNR AND A~WERKS = C~WERKS
    INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_001
    WHERE A~BUKRS = P_BUKRS
      AND B~BUDAT >= G_DATE_FROM1
      AND B~BUDAT <= G_DATE_TO3
      AND A~MATNR IN P_MATNR
      AND C~BESKZ = 'X'                       "采购类型
      AND ( ( A~BWART = '105' AND A~SOBKZ = '' ) OR
            ( A~BWART = '106' AND A~SOBKZ = '' ) OR

            ( A~BWART = '201' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '202' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '261' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '262' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '411' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '412' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '333' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '334' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z03' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z04' AND A~SOBKZ = 'K' ) ).

ELSEIF P_TG = 'X'.
  SELECT DISTINCT A~MATNR AS PRODNO     "物料号
    FROM MSEG AS A INNER JOIN MKPF AS B ON A~MBLNR = B~MBLNR
    INNER JOIN MARC AS C ON A~MATNR = C~MATNR AND A~WERKS = C~WERKS
    INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_001
    WHERE A~BUKRS = P_BUKRS
      AND B~BUDAT >= G_DATE_FROM1
      AND B~BUDAT <= G_DATE_TO3
      AND A~MATNR IN P_MATNR
      AND C~BESKZ = 'F'                       "采购类型
      AND C~SOBSL = '30'                      "特殊采购类型(是托工的物料)
      AND ( ( A~BWART = '105' AND A~SOBKZ = '' ) OR
            ( A~BWART = '106' AND A~SOBKZ = '' ) OR

            ( A~BWART = '201' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '202' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '261' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '262' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '411' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '412' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '333' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '334' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z03' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z04' AND A~SOBKZ = 'K' ) OR

*            A~BWART = '161' OR
*            A~BWART = '162' OR
            A~BWART = '101' OR
            A~BWART = '102' ).

*取有两种采购类型托工物料
SELECT DISTINCT A~MATNR AS PRODNO     "物料号
    FROM MSEG AS A INNER JOIN MKPF AS B ON A~MBLNR = B~MBLNR
    INNER JOIN MARC AS C ON A~MATNR = C~MATNR AND A~WERKS = C~WERKS
    INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_001
    WHERE A~BUKRS = P_BUKRS
      AND B~BUDAT >= G_DATE_FROM1
      AND B~BUDAT <= G_DATE_TO3
      AND A~MATNR IN P_MATNR
      AND C~BESKZ = 'X'                       "采购类型
      AND C~SOBSL = '30'                      "特殊采购类型(是托工的物料)
      AND ( ( A~BWART = '105' AND A~SOBKZ = '' ) OR
            ( A~BWART = '106' AND A~SOBKZ = '' ) OR

            ( A~BWART = '201' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '202' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '261' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '262' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '411' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '412' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '333' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = '334' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z03' AND A~SOBKZ = 'K' ) OR
            ( A~BWART = 'Z04' AND A~SOBKZ = 'K' ) ).
ENDIF.

*-取物料名称
  LOOP AT IT_PRINT_001.
    SELECT MAKTX
      INTO IT_PRINT_001-MAKTX
      FROM MAKT
      WHERE MATNR = IT_PRINT_001-PRODNO
        AND SPRAS = '1'.
      MODIFY IT_PRINT_001.
    ENDSELECT.
  ENDLOOP.

LOOP AT IT_PRINT_001.
*取前第三个月的数据
  PERFORM. F_DATA_MAKE USING G_DATE_FROM1 G_DATE_TO1 IT_PRINT_001-PRODNO.

  MOVE L_QTY TO IT_PRINT_001-QTY1.
  MOVE L_AMOUNT TO IT_PRINT_001-AMOUNT1.

*取前第二个月的数据
  PERFORM. F_DATA_MAKE USING G_DATE_FROM2 G_DATE_TO2 IT_PRINT_001-PRODNO.

  MOVE L_QTY TO IT_PRINT_001-QTY2.
  MOVE L_AMOUNT TO IT_PRINT_001-AMOUNT2.

*取前第一个月的数据
  PERFORM. F_DATA_MAKE USING G_DATE_FROM3 G_DATE_TO3 IT_PRINT_001-PRODNO.

  MOVE L_QTY TO IT_PRINT_001-QTY3.
  MOVE L_AMOUNT TO IT_PRINT_001-AMOUNT3.

*取物料标准价格
  NOWDATE = G_DATE_TO3 + 1.
  PERFORM. GET_PRICE_BZ USING IT_PRINT_001-PRODNO P_BUKRS NOWDATE
       CHANGING IT_PRINT_001-PRICE_STAND.

  MODIFY IT_PRINT_001 INDEX SY-TABIX.
ENDLOOP.

*汇总
  REFRESH IT_PRINT_003.
  CLEAR IT_PRINT_003.
  LOOP AT IT_PRINT_001.
    "数量合计
    IT_PRINT_001-QTY_TOTAL = IT_PRINT_001-QTY1 + IT_PRINT_001-QTY2
                           + IT_PRINT_001-QTY3.
    "金额合计
    IT_PRINT_001-AMOUNT_TOTAL = IT_PRINT_001-AMOUNT1 + IT_PRINT_001-AMOUNT2
                           + IT_PRINT_001-AMOUNT3.
    "加权平均价
    IF IT_PRINT_001-QTY_TOTAL <> 0.
      IT_PRINT_001-PRICE_AGE = IT_PRINT_001-AMOUNT_TOTAL / IT_PRINT_001-QTY_TOTAL.
    ELSE.
      IT_PRINT_001-PRICE_AGE = 0.
    ENDIF.
    "去负号
    IF IT_PRINT_001-PRICE_AGE < 0.
      IT_PRINT_001-PRICE_AGE = 0 - IT_PRINT_001-PRICE_AGE.
    ENDIF.

    "差异
    IT_PRINT_001-PRICE_DIFF = IT_PRINT_001-PRICE_AGE - IT_PRINT_001-PRICE_STAND.
    IT_PRINT_001-PRICE_DIFF_C = IT_PRINT_001-PRICE_DIFF.
    IF IT_PRINT_001-PRICE_DIFF < 0.
      IT_PRINT_001-PRICE_DIFF_C = 0 - IT_PRINT_001-PRICE_DIFF.
      CONCATENATE '-' IT_PRINT_001-PRICE_DIFF_C INTO IT_PRINT_001-PRICE_DIFF_C.
      CONDENSE IT_PRINT_001-PRICE_DIFF_C.                   "去掉左右空格
    ENDIF.
    "差异率
    IF IT_PRINT_001-PRICE_STAND <> 0.
      IF IT_PRINT_001-PRICE_STAND <> 0.
        IT_PRINT_001-CYL = ( IT_PRINT_001-PRICE_DIFF / IT_PRINT_001-PRICE_STAND ) * 100.
      ELSE.
        IT_PRINT_001-CYL = 0.
      ENDIF.
      IF IT_PRINT_001-CYL < 0.
        IT_PRINT_001-CYL_C = 0 - IT_PRINT_001-CYL.
        CONCATENATE '-' IT_PRINT_001-CYL_C INTO IT_PRINT_001-CYL_C.
        CONDENSE IT_PRINT_001-CYL_C.
        CONCATENATE IT_PRINT_001-CYL_C '%' INTO IT_PRINT_001-CYL_C.
      ELSEIF IT_PRINT_001-CYL > 0.
        IT_PRINT_001-CYL_C = IT_PRINT_001-CYL.
        CONCATENATE IT_PRINT_001-CYL_C '%' INTO IT_PRINT_001-CYL_C.
      ELSE.
        IT_PRINT_001-CYL = 0.
        IT_PRINT_001-CYL_C = 0.
      ENDIF.
    ELSE.
      IT_PRINT_001-CYL = 0.
      IT_PRINT_001-CYL_C = 0.
    ENDIF.
    MODIFY IT_PRINT_001 INDEX SY-TABIX.

*过滤差异率.
    FLAG = 0.
    IF ( IT_PRINT_001-CYL NOT IN P_CYL ) AND ( P_CYL <> 'IEQ' AND P_CYL <> '' ).
      FLAG = 1.
    ELSEIF ( P_CYL = 'IEQ' OR P_CYL = '' ).
      FLAG = 1.
    ENDIF.

    IF FLAG = 1.
      IT_PRINT_003-PRODNO = IT_PRINT_001-PRODNO.
      IT_PRINT_003-MAKTX = IT_PRINT_001-MAKTX.
      IT_PRINT_003-QTY1 = IT_PRINT_001-QTY1.
      IT_PRINT_003-QTY2 = IT_PRINT_001-QTY2.
      IT_PRINT_003-QTY3 = IT_PRINT_001-QTY3.
      IT_PRINT_003-QTY_TOTAL = IT_PRINT_001-QTY_TOTAL.
      IT_PRINT_003-AMOUNT1 = IT_PRINT_001-AMOUNT1.
      IT_PRINT_003-AMOUNT2 = IT_PRINT_001-AMOUNT2.
      IT_PRINT_003-AMOUNT3 = IT_PRINT_001-AMOUNT3.
      IT_PRINT_003-AMOUNT_TOTAL = IT_PRINT_001-AMOUNT_TOTAL.
      IT_PRINT_003-PRICE_AGE = IT_PRINT_001-PRICE_AGE.
      IT_PRINT_003-PRICE_STAND = IT_PRINT_001-PRICE_STAND.
      IT_PRINT_003-PRICE_DIFF = IT_PRINT_001-PRICE_DIFF.
      IT_PRINT_003-CYL = IT_PRINT_001-CYL.

      IT_PRINT_003-PRICE_DIFF_C = IT_PRINT_001-PRICE_DIFF_C.
      IT_PRINT_003-CYL_C = IT_PRINT_001-CYL_C.
      APPEND IT_PRINT_003.
    ENDIF.
  ENDLOOP.

  SORT IT_PRINT_003 BY PRODNO.
ENDFORM.                    " F_READ_DATA
*&---------------------------------------------------------------------*
*     取前三,二,一个月的数据(例如3,4,5月之类的)
*&---------------------------------------------------------------------*
FORM. F_DATA_MAKE USING P_DATE1 P_DATE2 P_PRODNO.
DATA L_ESOKZ LIKE A017-ESOKZ.       "采购信息记录分类

   L_QTY = 0.
   L_AMOUNT = 0.

*--处理非寄售采购订单的入库、标准入库冲销
   REFRESH IT_PRINT_002.
   CLEAR IT_PRINT_002.
IF P_ZC = 'X'.
   SELECT A~MENGE AS QTY                 "收货数量(一定不要用ERFMG,用MENGE可以进行单位转换)
          B~NETPR AS PRICE               "采购订单上净价格
          B~PEINH                        "采购价格单位
          B~BPUMZ                        "有关订货价格单位转换为订货单位的分子
          B~BPUMN                        "订单计价单位转换为订单单位的值
          B~UMREN                        "订单单位到基本单位转换的分母
          B~UMREZ                        "有关订货价格单位转换为基本单位的分子
          C~WAERS                        "币别
          C~WKURS                        "汇率
          C~BEDAT                        "采购订单的凭证日期
          C~LIFNR                        "供应商帐号
          C~BSART                        "采购订单类型
          A~MBLNR                        "物料凭证号
          A~MATNR                        "物料号
          A~BWART                        "移动类型
      FROM MSEG AS A INNER JOIN EKPO AS B               "凭证段:物料&采购凭证项目
           ON A~EBELN = B~EBELN AND A~EBELP = B~EBELP
          INNER JOIN EKKO AS C ON C~EBELN = A~EBELN     "采购凭证抬头
          INNER JOIN MKPF AS D ON D~MBLNR = A~MBLNR     "抬头:物料凭证
          INNER JOIN MARC AS E ON A~MATNR = E~MATNR AND A~WERKS = E~WERKS
     INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_002
     WHERE C~BUKRS = P_BUKRS
       AND D~BUDAT >= P_DATE1
       AND D~BUDAT <= P_DATE2
       AND A~MATNR = P_PRODNO                 "物料号
       AND ( C~BSART = 'IN' OR C~BSART = 'NB' "采购凭证类型
          OR C~BSART = 'NO' OR C~BSART = 'PP'
          OR C~BSART = 'SD')
       AND B~LOEKZ <> 'L'                     "不为删除状态
       AND ( A~BWART = '105' OR               "为采购入库
             A~BWART = '106' )                "标准入库冲销
       AND A~SOBKZ =  ''.                     "特殊库存
ELSEIF P_TG = 'X'.
   SELECT A~MENGE AS QTY                 "收货数量(一定不要用ERFMG,用MENGE可以进行单位转换)
          B~NETPR AS PRICE               "采购订单上净价格
          B~PEINH                        "采购价格单位
          B~BPUMZ                        "有关订货价格单位转换为订货单位的分子
          B~BPUMN                        "订单计价单位转换为订单单位的值
          B~UMREN                        "订单单位到基本单位转换的分母
          B~UMREZ                        "有关订货价格单位转换为基本单位的分子
          C~WAERS                        "币别
          C~WKURS                        "汇率
          C~BEDAT                        "采购订单的凭证日期
          C~LIFNR                        "供应商帐号
          C~BSART                        "采购订单类型
          A~MBLNR                        "物料凭证号
          A~MATNR                        "物料号
          A~BWART                        "移动类型
      FROM MSEG AS A INNER JOIN EKPO AS B               "凭证段:物料&采购凭证项目
           ON A~EBELN = B~EBELN AND A~EBELP = B~EBELP
          INNER JOIN EKKO AS C ON C~EBELN = A~EBELN     "采购凭证抬头
          INNER JOIN MKPF AS D ON D~MBLNR = A~MBLNR     "抬头:物料凭证
          INNER JOIN MARC AS E ON A~MATNR = E~MATNR AND A~WERKS = E~WERKS
     INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_002
     WHERE C~BUKRS = P_BUKRS
       AND D~BUDAT >= P_DATE1
       AND D~BUDAT <= P_DATE2
       AND A~MATNR = P_PRODNO                  "物料号
       AND ( C~BSART = 'TO' OR C~BSART = 'ZRE' "采购凭证类型
          OR C~BSART = 'PP' )
       AND B~LOEKZ <> 'L'                      "不为删除状态
       AND ( A~BWART = '105' OR                "为采购入库
             A~BWART = '106' )                 "标准入库冲销
       AND A~SOBKZ =  ''.                      "特殊库存
ENDIF.

   LOOP AT IT_PRINT_002.
     IF IT_PRINT_002-BWART = '105'.
       L_QTY = L_QTY + IT_PRINT_002-QTY.
       L_AMOUNT = L_AMOUNT + ( IT_PRINT_002-PRICE / IT_PRINT_002-PEINH ) * IT_PRINT_002-QTY
                  * ( IT_PRINT_002-BPUMZ / IT_PRINT_002-BPUMN ) * IT_PRINT_002-WKURS
                  * ( IT_PRINT_002-UMREN / IT_PRINT_002-UMREZ ).
     ELSEIF IT_PRINT_002-BWART = '106'.
       L_QTY = L_QTY - IT_PRINT_002-QTY.
       L_AMOUNT = L_AMOUNT - ( IT_PRINT_002-PRICE / IT_PRINT_002-PEINH ) * IT_PRINT_002-QTY
                  * ( IT_PRINT_002-BPUMZ / IT_PRINT_002-BPUMN ) * IT_PRINT_002-WKURS
                  * ( IT_PRINT_002-UMREN / IT_PRINT_002-UMREZ ).
     ENDIF.
   ENDLOOP.

*---处理标准退货、标准退货冲销、直接收货入库、直接收货入库冲销
    REFRESH IT_PRINT_002.
    CLEAR IT_PRINT_002.
    SELECT A~MENGE AS QTY            "收货数量
           B~NETPR AS PRICE          "采购订单上净价格
           B~PEINH                   "采购价格单位
           B~BPUMZ                   "有关订货价格单位转换为订货单位的分子
           B~BPUMN                   "订单计价单位转换为订单单位的值
           B~UMREN                   "订单单位到基本单位转换的分母
           B~UMREZ                   "有关订货价格单位转换为基本单位的分子
           C~WAERS                   "币别
           C~WKURS                   "汇率
           C~BEDAT                   "采购订单的凭证日期
           C~LIFNR                   "供应商帐号
           C~BSART                   "采购订单类型
           A~MBLNR                   "物料凭证号
           A~MATNR                   "物料号
           A~BWART                   "移动类型
      FROM MSEG AS A INNER JOIN EKPO AS B                "凭证段:物料&采购凭证项目
           ON A~EBELN = B~EBELN AND A~EBELP = B~EBELP
           INNER JOIN EKKO AS C ON C~EBELN = A~EBELN     "采购凭证抬头
           INNER JOIN MKPF AS D ON D~MBLNR = A~MBLNR     "抬头:物料凭证
           INNER JOIN MARC AS E ON A~MATNR = E~MATNR AND A~WERKS = E~WERKS
      INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_002
      WHERE C~BUKRS = P_BUKRS
        AND D~BUDAT >= P_DATE1
        AND D~BUDAT <= P_DATE2
        AND A~MATNR = P_PRODNO                "物料号
*        AND C~BSART = 'RE'                    "采购凭证类型
        AND B~LOEKZ <> 'L'                     "不为删除状态
*        AND A~SOBKZ = ''                      "特殊库存
*        AND ( A~BWART = '161' OR              "标准退货
*              A~BWART = '162' OR              "采购退货冲销
        AND ( A~BWART = '101' OR              "直接收货入库
              A~BWART = '102' ).              "直接收货入库冲销

    LOOP AT IT_PRINT_002.
     IF ( IT_PRINT_002-BWART = '161' ) OR ( IT_PRINT_002-BWART = '102' ).
       L_QTY = L_QTY - IT_PRINT_002-QTY.
       L_AMOUNT = L_AMOUNT - ( IT_PRINT_002-PRICE / IT_PRINT_002-PEINH ) * IT_PRINT_002-QTY
                  * ( IT_PRINT_002-BPUMZ / IT_PRINT_002-BPUMN ) * IT_PRINT_002-WKURS
                  * ( IT_PRINT_002-UMREN / IT_PRINT_002-UMREZ ).
     ELSEIF ( IT_PRINT_002-BWART = '162' ) OR ( IT_PRINT_002-BWART = '101' ).
       L_QTY = L_QTY + IT_PRINT_002-QTY.
       L_AMOUNT = L_AMOUNT + ( IT_PRINT_002-PRICE / IT_PRINT_002-PEINH ) * IT_PRINT_002-QTY
                  * ( IT_PRINT_002-BPUMZ / IT_PRINT_002-BPUMN ) * IT_PRINT_002-WKURS
                  * ( IT_PRINT_002-UMREN / IT_PRINT_002-UMREZ ).
     ENDIF.
   ENDLOOP.

*--处理寄售领料、寄售领料冲销(该处的物料发生出入库时,单位以库存单位为主)
   REFRESH IT_PRINT_002.
   CLEAR IT_PRINT_002.
   SELECT A~MENGE AS QTY            "收货数量
          A~MBLNR
          A~MATNR                   "物料号
          B~BUDAT                   "记账日期
          A~LIFNR                   "供应商帐号
          A~MBLNR                   "物料凭证号
          A~BWART                   "移动类型
     FROM MSEG AS A INNER JOIN MKPF AS B ON B~MBLNR = A~MBLNR     "抬头:物料凭证
     INTO CORRESPONDING FIELDS OF TABLE IT_PRINT_002
     WHERE A~WERKS = P_BUKRS
        AND B~BUDAT >= P_DATE1
        AND B~BUDAT <= P_DATE2
        AND A~MATNR = P_PRODNO                "物料号
        AND A~SOBKZ = 'K'                     "特殊库存标识
        AND ( A~BWART = '201'                 "向成本中心发料
           OR A~BWART = '333'                 "向研发部耗用发料
           OR A~BWART = '261'                 "生产订单领料
           OR A~BWART = '411'                 "转为自有库存
           OR A~BWART = 'Z03'                 "内部订单领料

           OR A~BWART = '202'                 "向成本中心发料冲销
           OR A~BWART = '334'                 "向研发部发料冲销(该功能已取消使用权用)
           OR A~BWART = '262'                 "生产领料冲销
           OR A~BWART = '412'                 "转为自有库存冲销
           OR A~BWART = 'Z04' ).              "内部订单冲销

    LOOP AT IT_PRINT_002.
      L_ESOKZ = '2'.                          "采购信息记录分类=2(寄售)
      PERFORM. F_GET_PRICE USING L_ESOKZ IT_PRINT_002-LIFNR
                                IT_PRINT_002-MATNR IT_PRINT_002-BUDAT
              CHANGING G_PRICE_CG.

      IF ( IT_PRINT_002-BWART = '201' ) OR ( IT_PRINT_002-BWART = '333' ) OR
       ( IT_PRINT_002-BWART = '261' ) OR ( IT_PRINT_002-BWART = '411' ) OR
       ( IT_PRINT_002-BWART = 'Z03' ).
        L_QTY = L_QTY + IT_PRINT_002-QTY.
        L_AMOUNT = L_AMOUNT + IT_PRINT_002-QTY * G_PRICE_CG.
      ELSE.
        L_QTY = L_QTY - IT_PRINT_002-QTY.
        L_AMOUNT = L_AMOUNT - IT_PRINT_002-QTY * G_PRICE_CG.
      ENDIF.
    ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*     获取采购信息记录上的价格及暂估价格(这里取汇率的方法不是很正确,需修改)
*&---------------------------------------------------------------------*
FORM. F_GET_PRICE USING P_ESOKZ P_LIFNR P_MATNR P_BUDAT CHANGING P_PRICE.
DATA: L_KNUM LIKE A017-KNUMH,          "价格的记录号
      L_PRICE1 TYPE P DECIMALS 6,      "价格
      L_PRICE2 TYPE P DECIMALS 6.      "暂估价格

  L_PRICE1 = 0.
  L_PRICE2 = 0.

*-取价格
  L_KNUM = ''.
  SELECT A017~KNUMH
    FROM A017
    INTO L_KNUM
    WHERE A017~KAPPL = 'M'
      AND A017~KSCHL = 'P000'
      AND A017~LIFNR =  P_LIFNR
      AND A017~MATNR = P_MATNR
      AND A017~EKORG = P_BUKRS
      AND A017~WERKS = P_BUKRS
      AND A017~DATBI >= P_BUDAT      "有效期
      AND A017~DATAB <= P_BUDAT      "生效期从
      AND A017~ESOKZ = P_ESOKZ.
  ENDSELECT.

  CLEAR ITAB_PRICE.
  REFRESH ITAB_PRICE.
  SELECT KBETR KPEIN KONWA
    FROM KONP
    INTO CORRESPONDING FIELDS OF TABLE ITAB_PRICE
    WHERE KNUMH = L_KNUM
      AND KOPOS = 1.
  LOOP AT ITAB_PRICE.
    "取外币汇率及其单价
    IF ITAB_PRICE-KONWA <> 'RMB'."取外币汇率及其单价
      SELECT UKURS GDATU
        FROM TCURR
        INTO CORRESPONDING FIELDS OF TABLE ITAB_PRICE_RATE
        WHERE KURST = 'M'                 "汇率类型
          AND FCURR = ITAB_PRICE-KONWA    "从货币
          AND TCURR = 'RMB'               "最终货币
        ORDER BY GDATU ASCENDING.         "按日期升序排列

       LOOP AT ITAB_PRICE_RATE.
         L_PRICE1 = ITAB_PRICE-KBETR * ITAB_PRICE_RATE-UKURS / ITAB_PRICE-KPEIN.
         EXIT.
       ENDLOOP.
    ELSEIF ITAB_PRICE-KONWA = 'RMB'.
      L_PRICE1 = ITAB_PRICE-KBETR / ITAB_PRICE-KPEIN.
    ENDIF.
  ENDLOOP.

  P_PRICE = L_PRICE1.

*-取暂估价格
  IF L_PRICE1 = 0.                "假如取不到价格,就开始取暂估价格

  L_KNUM = ''.
  SELECT A017~KNUMH
    FROM A017
    INTO L_KNUM
    WHERE A017~KAPPL = 'M'
      AND A017~KSCHL = 'P001'
      AND A017~LIFNR =  P_LIFNR
      AND A017~MATNR = P_MATNR
      AND A017~EKORG = P_BUKRS
      AND A017~WERKS = P_BUKRS
      AND A017~DATBI >= P_BUDAT
      AND A017~DATAB <= P_BUDAT
      AND A017~ESOKZ = P_ESOKZ.
  ENDSELECT.

  CLEAR ITAB_PRICE.
  REFRESH ITAB_PRICE.
  CLEAR ITAB_PRICE_RATE.
  REFRESH ITAB_PRICE_RATE.
  SELECT KBETR KPEIN KONWA
    FROM KONP
    INTO CORRESPONDING FIELDS OF TABLE ITAB_PRICE
    WHERE KNUMH = L_KNUM
      AND KOPOS = 1.

  LOOP AT ITAB_PRICE.
    "取外币汇率及其单价
    IF ITAB_PRICE-KONWA <> 'RMB'."取外币汇率及其单价
      SELECT UKURS GDATU
        FROM TCURR
        INTO CORRESPONDING FIELDS OF TABLE ITAB_PRICE_RATE
        WHERE KURST = 'M'                 "汇率类型
          AND FCURR = ITAB_PRICE-KONWA    "从货币
          AND TCURR = 'RMB'               "最终货币
        ORDER BY GDATU ASCENDING. &

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/765243/viewspace-253292/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/765243/viewspace-253292/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值