ZR_FI_021

*===============================基本信息===============================*
* 标题:装配型公司标准成本表
* 创建日期:2005-09-22       
*===============================定    义===============================*

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

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

************************************************************************
* TABLE: 定义TABLE
************************************************************************
TABLES: MBEW,  "物料评估
        MARA,  "常规物料数据
        MARC,  "
        KEKO,  "产品成本核算 - 表头数据
        CKIS,  "项目单位成本核算/产品成本核算分项列举
        MAST,  "BOM链接物料
        STPO,  "BOM项目
        STKO,  "BOM表头
        A005,
        KONH,
        KONP,
        T001,  "公司代码
        MAKT,  "物料描述
        T023T,  "物料组描述
        CRHD.  "工作中心表头
************************************************************************
*INTERNAL TABLES
************************************************************************
*定义输出的内表IT_PRINT_001
DATA: BEGIN OF IT_PRINT_001 OCCURS 0.
        DATA FLAG.
        DATA NO TYPE I.                      "序号
        DATA WERKS LIKE KEKO-WERKS.          "公司代码
        DATA KALNR LIKE KEKO-KALNR.          "成本估算号(产品成本核算)
        DATA KADKY LIKE KEKO-KADKY.          "成本核算日期
        DATA MATNR LIKE MBEW-MATNR.          "成品料号
        DATA MAKTX LIKE MAKT-MAKTX.          "物料名称
        DATA MATKL LIKE T023T-MATKL.         "物料组
        DATA WGBEZ LIKE T023T-WGBEZ.         "物料组的描述

        DATA CLASS LIKE CKIS-TYPPS.          "记录类别
        DATA ITEM_NAME_ALL LIKE MAKT-MAKTX.  "父项目名称(材料大类)
        DATA ITEM_NAME_ALL2 LIKE MAKT-MAKTX. "父项目名称(具体类别)
        DATA ITEM_CODE LIKE MBEW-MATNR.      "子项目代码(用于存放物料号、信息记录)
        DATA ITEM_NAME LIKE MAKT-MAKTX.      "子项目名称
        DATA PMEHT LIKE CKIS-PMEHT.          "计量单位
        DATA MENGE TYPE P DECIMALS 4.        "数量
        DATA AMOUNT TYPE P DECIMALS 2.       "标准成本金额
        DATA TOTAL TYPE P DECIMALS 2.        "标准成本小计
        DATA TOTAL_C(15).                    "
        DATA RATE TYPE P DECIMALS 4.         "占比
        DATA RATE_C(15).                     "
        DATA AMOUNT2 TYPE P DECIMALS 2.      "行业成本

        DATA WERTN TYPE P DECIMALS 4.        "价格
        DATA PEINH TYPE P DECIMALS 4.        "单位价格
        DATA LSTAR LIKE CKIS-LSTAR.          "活动类型
        DATA INFNR LIKE CKIS-INFNR.          "信息记录
        DATA KSTAR LIKE CKIS-KSTAR.          "成本要素
        DATA KOSTL LIKE CKIS-KOSTL.          "成本中心
        DATA ARBPL LIKE CRHD-ARBPL.          "工作中心
        DATA ARBID LIKE CKIS-ARBID.          "对象 ID
DATA: END OF IT_PRINT_001.

DATA: ITAB_TEMP LIKE IT_PRINT_001 OCCURS 10 WITH HEADER LINE.

*定义内部使用的内表ITABS
DATA: BEGIN OF ITABS OCCURS 0.
        DATA FLAG.
        DATA WERKS LIKE KEKO-WERKS.          "公司代码
        DATA KALNR LIKE KEKO-KALNR.          "成本估算号(产品成本核算)
        DATA KADKY LIKE KEKO-KADKY.          "成本核算日期
        DATA MATNR LIKE MBEW-MATNR.          "成品料号

        DATA NO TYPE I.                      "序号
        DATA FEHLKZ LIKE CKIS-FEHLKZ.        "错误状态
        DATA ISEND TYPE I.                   "是否是最未层
        DATA TIERNO TYPE I.                  "BOM层次
        DATA TYPPS LIKE CKIS-TYPPS.          "记录类别
        DATA RECO_CODE LIKE MBEW-MATNR.      "记录代码(用于存放物料号、信息记录)
        DATA RECO_NAME LIKE MAKT-MAKTX.      "记录名称
        DATA TOTAL TYPE P DECIMALS 4.        "总计值
        DATA FWAER_KPF LIKE CKIS-FWAER_KPF.  "货币
        DATA MENGE TYPE P DECIMALS 4.        "数量
        DATA PMEHT LIKE CKIS-PMEHT.          "计量单位
        DATA MEEHT LIKE CKIS-MEEHT.          "计量单位

        DATA WERTN TYPE P DECIMALS 4.        "价格
        DATA PEINH TYPE P DECIMALS 4.        "单位价格
        DATA LSTAR LIKE CKIS-LSTAR.          "活动类型
        DATA INFNR LIKE CKIS-INFNR.          "信息记录
        DATA KSTAR LIKE CKIS-KSTAR.          "成本要素
        DATA KOSTL LIKE CKIS-KOSTL.          "成本中心
        DATA ARBID LIKE CKIS-ARBID.          "对象ID
        DATA ARBPL LIKE CRHD-ARBPL.          "工作中心
        DATA MATNR_FATHER LIKE MBEW-MATNR.   "上层物料号
        DATA SH TYPE P DECIMALS 4.           "物料的工序损耗金额
        DATA SH2 TYPE P DECIMALS 4.
        DATA ISUSED TYPE I.                  "是否被使用过
        DATA AMOUNT2 TYPE P DECIMALS 2.      "行业成本
DATA: END OF ITABS.

DATA: BEGIN OF ITAB_01 OCCURS 0.
        DATA FLAG.
        DATA KALNR LIKE KEKO-KALNR.          "成本估算号 - 产品成本核算
        DATA LOSGR LIKE KEKO-LOSGR.          "项目类别
        DATA MEINS LIKE KEKO-MEINS.          "基本计量单位
        DATA FWAER_KPF LIKE KEKO-FWAER_KPF.  "币别
DATA: END OF ITAB_01.

DATA: BEGIN OF ITAB_SHL OCCURS 0.
        DATA FLAG.
        DATA AUSCH LIKE STPO-AUSCH.          "组件报废
        DATA AVOAU LIKE STPO-AVOAU.          "工序废品
        DATA IDNRK LIKE STPO-IDNRK.          "组件
DATA: END OF ITAB_SHL.

*往数据库增加运行日志
  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,
      A10 TYPE I VALUE 0,
      A11 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,
      B9 TYPE I VALUE 0,
      B10 TYPE I VALUE 0.

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

DATA: ZHS TYPE I VALUE 0.          "总行数
DATA: PAGENUM TYPE I VALUE 0.      "总的页数
DATA: PAGE_CURR TYPE I.            "当前页数

DATA: L_TEMP LIKE CKIS-WERTN VALUE 0.
DATA: G_KALNR LIKE KEKO-KALNR,
      G_UKALN LIKE CKIS-UKALN,
      G_KALNR1 LIKE KEKO-KALNR,
      G_UKALN1 LIKE CKIS-UKALN,
      G_MENGE LIKE CKIS-MENGE,        "物料批量
      G_PEINH TYPE P DECIMALS 6,      "价格单位
      G_TIERNO TYPE I.                "BOM层次
DATA: V_MATNR2 LIKE STPO-IDNRK,
      V_MATKL2 LIKE MARA-MATKL.

DATA: G_DAY(2),
      G_LEN TYPE I,
      G_MOD TYPE I,
      G_DATE1 LIKE LIKP-ERDAT,
      G_DATE2 LIKE LIKP-ERDAT,
      G_KUNNR LIKE KNA1-KUNNR,          "客户代码
      G_NAME1(100),                     "客户名称
      G_KBETR LIKE KONP-KBETR,          "客户报价
      G_CLASS(30).                      "类别

DATA G_FLAG TYPE I.
DATA G_CLASS_01 LIKE MAKT-MAKTX.       "产品形态(单品/组合品)
DATA G_CLASS_02 LIKE MAKT-MAKTX.       "大分类
DATA G_CLASS_021 LIKE MAKT-MAKTX.      "制造成型方式
DATA G_CLASS_04 LIKE MAKT-MAKTX.       "粗分类
DATA G_CLASS_03 LIKE MAKT-MAKTX.       "产品线/用途

*用于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 GRID1.               "画表格
  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.
  WRITE: AT  B9   &9.
  WRITE: AT  A10  SY-VLINE.
END-OF-DEFINITION.
DEFINE GRID2.               "画表格
  WRITE: AT  B10   &1.
  WRITE: AT  A11   SY-VLINE.
END-OF-DEFINITION.
************************************************************************
*  SELECTION SCREEN : 定义报表筛选条件
************************************************************************
*确定过滤参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_001 WITH FRAME. TITLE BLK_001.
    PARAMETERS : P_MATNR LIKE KEKO-MATNR OBLIGATORY MEMORY ID 021_1.  "物料号
    PARAMETERS : P_BUKRS LIKE GLT0-BUKRS OBLIGATORY MEMORY ID 021_2.  "公司代码
    PARAMETERS : P_RYEAR(4) TYPE C OBLIGATORY DEFAULT SY-DATUM+0(4).  "报表年度
    PARAMETERS : P_PERID(2) TYPE C OBLIGATORY DEFAULT SY-DATUM+4(2).  "报表期间
SELECTION-SCREEN END OF BLOCK BLK_001.

*过滤客户报价参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_004 WITH FRAME. TITLE BLK_004 .
    PARAMETERS: P_KUNNR LIKE KNA1-KUNNR.           "客户代码
SELECTION-SCREEN END OF BLOCK BLK_004.

*特殊汇总类型参数
SELECTION-SCREEN BEGIN OF BLOCK BLK_003 WITH FRAME. TITLE BLK_003 .
*    PARAMETERS: P_TYPE1 AS CHECKBOX.           "显示完全的记录名称
SELECTION-SCREEN END OF BLOCK BLK_003.

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


*===============================事    件===============================*
************************************************************************
* INITIALIZATION.启动程序开始执行
************************************************************************
INITIALIZATION.
  BLK_001 = '检索参数'.
  BLK_002 = '报表类型'.
  BLK_003 = '特殊参数处理'.
  BLK_004 = '过滤客户报价参数'.

  PERFORM. SUB_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. CAL_DAY.                "每月天数判断

  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. SUB_HEAD.
************************************************************************
* END OF PAGE
************************************************************************
END-OF-PAGE.
*  PERFORM. SUB_BOTTOM.


*===============================子 例 程===============================*
*&---------------------------------------------------------------------*
*过滤条件有效性检查
*&---------------------------------------------------------------------*
FORM. F_CHECK_INPUT.
DATA L_TEMP(20).
  "日期处理
  IF P_PERID+1(1) = ''.
    CONCATENATE '0' P_PERID INTO P_PERID.
  ENDIF.
  IF ( P_PERID < '01' ) OR ( P_PERID > '16' ).
    MESSAGE E000.    "该会计期间不存在!
  ENDIF.

  "物料判断
  SELECT MATNR
    INTO L_TEMP
    FROM MARA
    WHERE ( MTART = 'FERT' OR MTART = 'HALB' )
      AND MATNR = P_MATNR.
  ENDSELECT.

  IF SY-SUBRC <> 0.
    MESSAGE E071. "不存在该物料或该物料不是产成品!
  ENDIF.

  SELECT MATNR
    INTO MARC-MATNR
    FROM MARC
    WHERE MATNR = P_MATNR
      AND WERKS = P_BUKRS.
  ENDSELECT.
  IF SY-SUBRC <> 0.
    MESSAGE E072. "该物料不存在该工厂中!
  ENDIF.

  "公司代码判断
  IF P_BUKRS = '2000' OR  P_BUKRS = '4000'.
    MESSAGE E074. "请选择1000、3000、5000、6000、7000、8000的公司代码!!
  ENDIF.
ENDFORM.                    " F_CHECK_INPUT
*&---------------------------------------------------------------------*
*从数据库中读取数据,填充报表输出时所用的内表
*&---------------------------------------------------------------------*
FORM. F_READ_DATA .
DATA: L_TOTAL TYPE P DECIMALS 4,
      L_TOTAL1 TYPE P DECIMALS 4,
      L_NAME1 LIKE MAKT-MAKTX,
      L_NAME2 LIKE MAKT-MAKTX,
      L_TEMP(10).
  "日期重定位
  PERFORM. F_DO_DATE USING P_MATNR.

  "取产品分类名
  PERFORM. F_DO_CLASS.

  "取该产品的客户号及报价
  PERFORM. F_GET_CUSTIFNO.

  "获取成本估算明细表(只取第一层数据)
  PERFORM. F_GET_DETAIL USING P_MATNR.

  "处理A类材料
  PERFORM. F_DO_A.

  "处理B类材料
  PERFORM. F_DO_B.

  "处理C类材料
  PERFORM. F_DO_C.

  "处理费用分摊
  PERFORM. F_DO_FY.

  "行业成本处理
  PERFORM. F_DO_HYCB.

  "小计处理
  LOOP AT IT_PRINT_001.
    ITAB_TEMP-ITEM_NAME_ALL = IT_PRINT_001-ITEM_NAME_ALL.
    ITAB_TEMP-ITEM_NAME_ALL2 = IT_PRINT_001-ITEM_NAME_ALL2.
    ITAB_TEMP-AMOUNT = IT_PRINT_001-AMOUNT.
    APPEND ITAB_TEMP.
  ENDLOOP.
  LOOP AT IT_PRINT_001.
    L_TOTAL = 0.
    LOOP AT ITAB_TEMP.
      IF ITAB_TEMP-ITEM_NAME_ALL = IT_PRINT_001-ITEM_NAME_ALL
       AND ITAB_TEMP-ITEM_NAME_ALL2 = IT_PRINT_001-ITEM_NAME_ALL2.
        L_TOTAL = L_TOTAL + ITAB_TEMP-AMOUNT.
      ENDIF.
    ENDLOOP.

    IT_PRINT_001-TOTAL = L_TOTAL.
    MODIFY IT_PRINT_001.
  ENDLOOP.

  "格式处理1
*  IF P_TYPE1 <> 'X'.
  LOOP AT IT_PRINT_001.
    IF IT_PRINT_001-ITEM_NAME_ALL = L_NAME1.
      IT_PRINT_001-ITEM_NAME_ALL = ''.
      MODIFY IT_PRINT_001.
    ELSE.
      L_NAME1 = IT_PRINT_001-ITEM_NAME_ALL.
    ENDIF.

    IF IT_PRINT_001-ITEM_NAME_ALL2 = L_NAME2.
      IT_PRINT_001-ITEM_NAME_ALL2 = ''.
      IT_PRINT_001-TOTAL = ''.
      IT_PRINT_001-RATE = ''.
      MODIFY IT_PRINT_001.
    ELSE.
      L_NAME2 = IT_PRINT_001-ITEM_NAME_ALL2.
    ENDIF.
  ENDLOOP.

  "占比处理
  L_TOTAL = 0.
  LOOP AT IT_PRINT_001.
    L_TOTAL = L_TOTAL + IT_PRINT_001-TOTAL.
  ENDLOOP.
  LOOP AT IT_PRINT_001.
    IF L_TOTAL <> 0.
      IT_PRINT_001-RATE = IT_PRINT_001-TOTAL / L_TOTAL.
    ELSE.
      IT_PRINT_001-RATE = 0.
    ENDIF.
    MODIFY IT_PRINT_001.
  ENDLOOP.

*ELSE.
*"占比处理
*  L_TOTAL1 = 0.
*  LOOP AT IT_PRINT_001.
*    L_TOTAL1 = L_TOTAL1 + IT_PRINT_001-AMOUNT.
*  ENDLOOP.
*  LOOP AT IT_PRINT_001.
*    IF L_TOTAL1 <> 0.
*      IT_PRINT_001-RATE = IT_PRINT_001-TOTAL / L_TOTAL1.
**      IF IT_PRINT_001-ITEM_NAME_ALL2 = L_NAME2.
**         IT_PRINT_001-RATE = ''.
**      ELSE.
**         L_NAME2 = IT_PRINT_001-ITEM_NAME_ALL2.
**      ENDIF.
*    ELSE.
*      IT_PRINT_001-RATE = 0.
*    ENDIF.
*    MODIFY IT_PRINT_001.
*  ENDLOOP.
*ENDIF.

  "格式处理2
  LOOP AT IT_PRINT_001.
    "小计
    IF IT_PRINT_001-TOTAL <> 0.
      IT_PRINT_001-TOTAL_C = IT_PRINT_001-TOTAL.
      MODIFY IT_PRINT_001.
    ENDIF.

    "占比
    IF IT_PRINT_001-RATE <> 0.
      L_TEMP = ( IT_PRINT_001-RATE * 10000 ) / 100.
      CONCATENATE L_TEMP '%'  INTO IT_PRINT_001-RATE_C.
      MODIFY IT_PRINT_001.
    ENDIF.
  ENDLOOP.

ENDFORM.                    " F_READ_DATA
*&---------------------------------------------------------------------*
*日期重定位处理
*&---------------------------------------------------------------------*
FORM. F_DO_DATE USING P_PRODNO.
  SELECT KALNR
    FROM KEKO
    INTO KEKO-KALNR
    WHERE MATNR = P_PRODNO
        AND WERKS = P_BUKRS
        AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
        AND KALKA = '01'                 "成本核算类型=PPC1
        AND TVERS = '01'                 "成本核算版本
        AND LOEKZ = ''                   "产品成本核算的删除标志
        AND BZOBJ = '0'                  "参考对象
        AND BWVAR = '001'                "成本核算中的估算变式
        AND KKZMA = ''                   "在附加或自动成本估算中手工输入的成本
        AND FREIUSR <> ''.               "被...发布(判断是否被成功释放)
  ENDSELECT.

  IF SY-SUBRC <> 0 AND G_DATE1+0(4) >= '2005'.
    G_DATE1 = G_DATE1 - 1.
    CONCATENATE G_DATE1+0(4) G_DATE1+4(2) '01' INTO G_DATE1.
    PERFORM. F_DO_DATE USING P_PRODNO.
  ENDIF.
ENDFORM.
*&---------------------------------------------------------------------*
*获取取该产品的客户号及报价信息
*&---------------------------------------------------------------------*
FORM. F_GET_CUSTIFNO.
DATA: L_CUSTNAEM LIKE KNA1-NAME1.

  CALL FUNCTION 'Z_GET_PRICE_XS'
       EXPORTING
           PA_BUKRS = P_BUKRS
           PA_CUSTNO = P_KUNNR
           PA_MATNR = P_MATNR
           PA_DATE = G_DATE2
           PA_DATESTATE = 1
       IMPORTING
           PA_PRICE = G_KBETR
           PA_CUSTNAME = L_CUSTNAEM.

  CONCATENATE L_CUSTNAEM G_NAME1 INTO G_NAME1.
ENDFORM.
*&---------------------------------------------------------------------*
*获取成本估算明细表
*&---------------------------------------------------------------------*
FORM. F_GET_DETAIL USING P_PRODNO.
DATA: L_MAKTX LIKE MAKT-MAKTX,
      L_TOTAL TYPE P DECIMALS 4,
      L_NO TYPE I VALUE 0,
      L_MATNR LIKE MBEW-MATNR,
      L_FIRST TYPE I,
      L_NEXT TYPE I.

  REFRESH ITAB_01.
  CLEAR ITAB_01.

*--物料的成本核算号及物料批量
  SELECT KALNR LOSGR MEINS FWAER_KPF
    FROM KEKO
    INTO CORRESPONDING FIELDS OF TABLE ITAB_01
    WHERE MATNR = P_PRODNO
        AND WERKS = P_BUKRS
        AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
        AND KALKA = '01'                 "成本核算类型=PPC1
        AND TVERS = '01'                 "成本核算版本
        AND LOEKZ = ''                   "产品成本核算的删除标志
        AND BZOBJ = '0'                  "参考对象
        AND BWVAR = '001'                "成本核算中的估算变式
        AND KKZMA = ''.                  "在附加或自动成本估算中手工输入的成本

  LOOP AT ITAB_01.
    "将第0层数据加入内表中
    PERFORM. F_INSERT_TABLE USING P_BUKRS 0 'M'
                                 P_PRODNO '' ''
                                 '' '' ''
                                 0 1 ITAB_01-FWAER_KPF
                                 ITAB_01-LOSGR ITAB_01-MEINS '' 0 ''.

    "调用下层数据
    G_MENGE = ITAB_01-LOSGR.           "物料批量
    G_PEINH = 1.
    G_TIERNO = 1.
    PERFORM. F_SUB USING ITAB_01-KALNR.
    EXIT.
  ENDLOOP.

*--总计值(由第一层汇总至0层)
*  L_TOTAL = 0.
*  LOOP AT IT_PRINT_001.
*    IF ITABS-TIERNO = 1.
*      L_TOTAL = L_TOTAL + ITABS-TOTAL.
*    ENDIF.
*  ENDLOOP.
*  LOOP AT ITABS.
*    IF ITABS-TIERNO = 0.
*      ITABS-TOTAL = L_TOTAL.
*      MODIFY ITABS.
*    ENDIF.
*  ENDLOOP.

*--处理记录序号
  LOOP AT ITABS.
    L_NO = L_NO + 1.
    ITABS-NO = L_NO.
    MODIFY ITABS.
  ENDLOOP.

*--批量处理
  LOOP AT ITABS.
    IF G_MENGE <> 0.
      ITABS-TOTAL = ITABS-TOTAL / G_MENGE.
      ITABS-MENGE = ITABS-MENGE / G_MENGE.
      MODIFY ITABS.
    ENDIF.
  ENDLOOP.

*--去掉下层之下的所有记录,只保留第一层记录
  LOOP AT ITABS.
    IF ITABS-TIERNO <> 1.
      DELETE ITABS.
    ENDIF.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*递归调用程序
*&---------------------------------------------------------------------*
FORM. F_SUB USING P_KALNR.
DATA : L_UKALN LIKE CKIS-UKALN,
       L_UKALN1 LIKE CKIS-UKALN,
       L_PEINH TYPE P DECIMALS 6,      "价格单位
       L_TIERNO TYPE I,                "BOM层次
       L_MAKTX LIKE MAKT-MAKTX,
       L_TOTAL TYPE P DECIMALS 6,
       L_MATNR LIKE MBEW-MATNR,
       L_ISEND TYPE I.                 "判断是否是最低层物料
DATA: N TYPE I.
DATA: ITAB_02 LIKE ITABS OCCURS 10 WITH HEADER LINE.

  L_PEINH = G_PEINH.
  L_TIERNO = G_TIERNO.

  SELECT UKALN AS KALNR         "输入的成本估算的成本估算编号
         WERTN                  "控制区域货币的值
         TYPPS                  "项目类别
         MENGE                  "数量
         PMEHT                  "价格数量单位
         MEEHT                  "基本单位
         PEINH                  "以控制范围货币记价的单位价格
         MATNR                  "物料
         WERKS                  "工厂
         FWAER_KPF              "货币
         LSTAR                  "活动类型
         INFNR                  "信息记录
         KSTAR                  "成本要素
         KOSTL                  "成本中心
         ARBID                  "对象ID
         FEHLKZ                 "错误状态
    FROM CKIS
    INTO CORRESPONDING FIELDS OF TABLE ITAB_02
    WHERE KALNR = P_KALNR        "成本估算号
      AND KADKY = G_DATE1        "成本核算日期
      AND KALKA = '01'           "成本核算类型=PPC1
      AND TVERS = '1'            "成本核算版本
      AND ( TYPPS = 'L' OR       "项目类别=托工
            TYPPS = 'E' OR       "项目类别=装配费用、自制费用
            TYPPS = 'G' OR       "项目类别=附加费
            TYPPS = 'I' OR       "项目类别=本层的直采物料
            TYPPS = 'M' )        "项目类别=含有下层的半成品
      AND LEDNR = '00'           "控制对象的分类帐
      AND BZOBJ = 0              "参考对象
      AND BWVAR = '001'          "成本核算中的估算变式
      AND KKZMA = ''             "在附加或自动成本估算中手工输入的成本
      AND POSNR <> ''.           "单位成本核算行项号

  LOOP AT ITAB_02.
    IF ITAB_02-TYPPS = 'M'.
      "将本层数据加入内表中
      PERFORM. F_GET_PRODNO USING P_KALNR CHANGING L_MATNR.
      L_ISEND = 0.               "判断是否是最低层物料;1为最底层
      IF ITAB_02-KALNR = 0.
        L_ISEND = 1.
      ENDIF.
      PERFORM. F_INSERT_TABLE USING ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                   ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                   ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                   ITAB_02-WERTN L_PEINH ITAB_02-FWAER_KPF
                                   ITAB_02-MENGE ITAB_02-MEEHT L_MATNR L_ISEND
                                   ITAB_02-FEHLKZ.
      IF ITAB_02-KALNR <> 0.
*-------递归处理开始
        SELECT KALNR
          FROM CKIS
          INTO CKIS-KALNR
          WHERE KALNR = ITAB_02-KALNR
            AND KADKY = G_DATE1
            AND KALKA = '01'
            AND TVERS = '1'
            AND TYPPS = 'I'           "项目类别
            AND LEDNR = '00'
            AND BZOBJ = 0
            AND BWVAR = '001'
            AND KKZMA = ''
            AND POSNR <> ''.
        ENDSELECT.

        IF SY-SUBRC = 0.
          "如果找到相关记录,本层数据加入内表中
          PERFORM. F_GET_PRODNO USING ITAB_02-KALNR CHANGING L_MATNR.
          PERFORM. F_INSERT_TABLE USING ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                       ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                       ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                       0 L_PEINH ITAB_02-FWAER_KPF
                                       ITAB_02-MENGE ITAB_02-MEEHT L_MATNR 0
                                       ITAB_02-FEHLKZ.
        ELSE.
          "修改上一层的汇总金额(取最后一条记录)
          PERFORM. F_GET_TOTAL USING ITAB_02-KALNR CHANGING L_TOTAL.
          IF L_TOTAL <> 0.
            G_PEINH = L_PEINH * ( ITAB_02-WERTN / L_TOTAL ). "倍数处理
          ELSE.
            G_PEINH = 1.
          ENDIF.

          N = 0.
          DESCRIBE TABLE ITABS LINES N.
          LOOP AT ITABS.
            IF SY-TABIX = N.
              ITABS-TOTAL = L_TOTAL * G_PEINH.
              MODIFY ITABS.
            ENDIF.
          ENDLOOP.

          L_TIERNO = L_TIERNO + 1.
          G_TIERNO = L_TIERNO.
          PERFORM. F_SUB USING ITAB_02-KALNR.
          L_TIERNO = L_TIERNO - 1.
          G_TIERNO = L_TIERNO.
        ENDIF.
*-------递归处理结束
      ENDIF.
    ELSE.
      "无子层的记录直接更新到内表中
      "将本层数据加入内表中
      PERFORM. F_GET_PRODNO USING P_KALNR CHANGING L_MATNR.
      PERFORM. F_INSERT_TABLE USING ITAB_02-WERKS L_TIERNO ITAB_02-TYPPS
                                   ITAB_02-MATNR ITAB_02-INFNR ITAB_02-LSTAR
                                   ITAB_02-KSTAR ITAB_02-KOSTL ITAB_02-ARBID
                                   ITAB_02-WERTN L_PEINH ITAB_02-FWAER_KPF
                                   ITAB_02-MENGE ITAB_02-MEEHT L_MATNR 0
                                   ITAB_02-FEHLKZ.
    ENDIF.

  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*下层成本之和
*&---------------------------------------------------------------------*
FORM. F_GET_TOTAL USING P_KALNR CHANGING P_TOTAL.
  SELECT SUM( WERTN )
    FROM CKIS
    INTO P_TOTAL
    WHERE KALNR = P_KALNR
      AND KALKA = '01'           "成本核算类型=PPC1
      AND TVERS = '1'            "成本核算版本DEVK901121
      AND KADKY = G_DATE1
      AND TYPPS <> ''            "项目类别
      AND LEDNR = '00'
      AND BZOBJ = 0
      AND BWVAR = '001'
      AND KKZMA = ''
      AND POSNR <> ''.
ENDFORM.
*&---------------------------------------------------------------------*
*由成本估算号取物料号
*&---------------------------------------------------------------------*
FORM. F_GET_PRODNO USING P_KALNR CHANGING P_PRODNO.
  SELECT MATNR
    FROM KEKO
    INTO P_PRODNO
    WHERE KALNR = P_KALNR
        AND WERKS = P_BUKRS
        AND KADKY = G_DATE1              "成本核算日期(每月只有一条记录)
        AND KALKA = '01'                 "成本核算类型=PPC1
        AND TVERS = '01'                 "成本核算版本
        AND LOEKZ = ''                   "产品成本核算的删除标志
        AND BZOBJ = '0'                  "参考对象
        AND BWVAR = '001'                "成本核算中的估算变式
        AND KKZMA = ''.                  "在附加或自动成本估算中手工输入的成本
   ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用增加内表数据
*&---------------------------------------------------------------------*
FORM. F_INSERT_TABLE USING V_BUKRS V_TIERNO V_TYPPS
                          V_MATNR V_INFNR V_LSTAR
                          V_KSTAR V_KOSTL V_ARBID
                          V_WERTN V_PEINH V_FWAER_KPF
                          V_MENGE V_PMEHT V_MATNR_FATHER
                          V_ISEND V_FEHLKZ.
DATA: L_MAKTX LIKE MAKT-MAKTX,
      L_TEMP LIKE MAKT-MAKTX.

  ITABS-WERKS = V_BUKRS.
  ITABS-TIERNO = V_TIERNO.        "BOM层次
  ITABS-TYPPS = V_TYPPS.          "记录类别
  IF V_TYPPS = 'I' OR V_TYPPS = 'M'.
    ITABS-RECO_CODE = V_MATNR.    "记录代码(用于存放物料号、信息记录)
    PERFORM. F_GET_PRODNAME USING V_MATNR CHANGING L_MAKTX.
  ELSEIF V_TYPPS = 'L'.
    ITABS-RECO_CODE = V_INFNR.                       "取供应商编号
    PERFORM. F_GET_LIFNR USING V_INFNR CHANGING L_MAKTX.
  ELSEIF V_TYPPS = 'E'.
    ITABS-RECO_CODE = V_LSTAR.
    L_MAKTX = V_KOSTL+5(5).                                 "取成本中心

    PERFORM. F_GET_ARBID USING V_ARBID CHANGING L_TEMP.      "取工作中心
    CONCATENATE L_MAKTX '   &  ' L_TEMP INTO L_MAKTX.
  ELSEIF V_TYPPS = 'G'.
    ITABS-RECO_CODE = V_KSTAR.
    PERFORM. F_GET_CBYSNAME USING V_KSTAR CHANGING L_MAKTX.  "取附加费名称
  ENDIF.

  ITABS-RECO_NAME = L_MAKTX.       "记录名称
  ITABS-TOTAL = V_WERTN * V_PEINH. "总计值
  ITABS-FWAER_KPF = V_FWAER_KPF.   "货币
  ITABS-MENGE = V_MENGE * V_PEINH. "数量
  ITABS-PMEHT = V_PMEHT.           "计量单位
  ITABS-MATNR_FATHER = V_MATNR_FATHER.
  ITABS-ISEND = V_ISEND.
  ITABS-ARBPL = L_TEMP.            "工作中心
  ITABS-FEHLKZ = V_FEHLKZ.         "错误状态
  APPEND ITABS.
ENDFORM.
*&---------------------------------------------------------------------*
*调用物料名称
*&---------------------------------------------------------------------*
FORM. F_GET_PRODNAME USING P_PRODNO CHANGING P_MAKTX.
  SELECT MAKTX
    FROM MAKT
    INTO P_MAKTX
    WHERE SPRAS = '1'
      AND MATNR = P_PRODNO.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用成本要素名称
*&---------------------------------------------------------------------*
FORM. F_GET_CBYSNAME USING P_KSTAR CHANGING P_KTEXT.
  SELECT KTEXT
    FROM CSKU
    INTO P_KTEXT
    WHERE SPRAS = '1'
      AND KTOPL = '1000'
      AND KSTAR = P_KSTAR.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用供应商账号
*&---------------------------------------------------------------------*
FORM. F_GET_LIFNR USING P_INFNR CHANGING P_LIFNR.
  SELECT LIFNR
    FROM EINA
    INTO P_LIFNR
    WHERE INFNR = P_INFNR.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*调用OH/LABOR的工作中心
*&---------------------------------------------------------------------*
FORM. F_GET_ARBID USING P_ARBID CHANGING P_ARBPL.
  SELECT ARBPL
    FROM CRHD
    INTO P_ARBPL
    WHERE BJTY = 'A'
      AND BJID = P_ARBID.
  ENDSELECT.
ENDFORM.
*&---------------------------------------------------------------------*
*处理A类材料
*玩铜(V10005)\华来(V20109)\华鼎()\水力士(V20236)\松霖(V10001)\易洁(V10003);益周()
*松霖不可能向易洁采购,所以A类材料不可以有松霖向易洁采购的物料
*&---------------------------------------------------------------------*
FORM. F_DO_A.
*-处理益周(V10002)\玩铜(V10005)\华来(V20109)\华鼎()\水力士(V20236)\松霖(V10001)\易洁(V10003)
  PERFORM. F_SUB_A USING 'V10002' '益周'.

  PERFORM. F_SUB_A USING 'V10005' '玩铜'.

  PERFORM. F_SUB_A USING 'V20109' '华来'.

  PERFORM. F_SUB_A USING 'V20236' '水力士'.

  PERFORM. F_SUB_A USING 'V10001' '松霖'.

*-处理益周的承接件(注:20060516解开该功能!200602曾经将该功能注释。)
  LOOP AT ITABS.
    IF ( ITABS-WERKS = '2000' ) AND ( ITABS-ISUSED <> 1 ).
      IT_PRINT_001-WERKS = ITABS-WERKS.
      IT_PRINT_001-CLASS = ITABS-TYPPS.
      IT_PRINT_001-ITEM_NAME_ALL = 'A类材料'.
      IT_PRINT_001-ITEM_NAME_ALL2 = '益周'.
      IT_PRINT_001-ITEM_CODE = ITABS-RECO_CODE.
      IT_PRINT_001-ITEM_NAME = ITABS-RECO_NAME.
      IT_PRINT_001-PMEHT = ITABS-PMEHT.
      IT_PRINT_001-MENGE = ITABS-MENGE.
      IT_PRINT_001-AMOUNT = ITABS-TOTAL.
      APPEND IT_PRINT_001.

      ITABS-ISUSED = 1.
      MODIFY ITABS.
    ENDIF.
  ENDLOOP.

*-取附加费
  LOOP AT ITABS.
    IF ITABS-WERKS = P_BUKRS AND ITABS-TYPPS = 'G'.
      IT_PRINT_001-WERKS = ITABS-WERKS.
      IT_PRINT_001-CLASS = ITABS-TYPPS.
      IT_PRINT_001-ITEM_NAME_ALL = 'A类材料'.
      IT_PRINT_001-ITEM_NAME_ALL2 = '益周'.
      IT_PRINT_001-ITEM_CODE = ITABS-RECO_CODE.
      IT_PRINT_001-ITEM_NAME = ITABS-RECO_NAME.
      IT_PRINT_001-PMEHT = ITABS-PMEHT.
      IT_PRINT_001-MENGE = ITABS-MENGE.
      IT_PRINT_001-AMOUNT = ITABS-TOTAL.
      APPEND IT_PRINT_001.
    ENDIF.
  ENDLOOP.

*-处理自制件
  LOOP AT ITABS.
    IF ( ITABS-WERKS = P_BUKRS ) AND ( ITABS-TYPPS = 'M' ) AND ( ITABS-ISEND = 0 )
     AND ( ITABS-ISUSED <> 1 ).
      IT_PRINT_001-WERKS = ITABS-WERKS.
      IT_PRINT_001-CLASS = ITABS-TYPPS.
      IT_PRINT_001-ITEM_NAME_ALL = 'A类材料'.
      IT_PRINT_001-ITEM_NAME_ALL2 = '自制件'.
      IT_PRINT_001-ITEM_CODE = ITABS-RECO_CODE.
      IT_PRINT_001-ITEM_NAME = ITABS-RECO_NAME.
      IT_PRINT_001-PMEHT = ITABS-PMEHT.
      IT_PRINT_001-MENGE = ITABS-MENGE.
      IT_PRINT_001-AMOUNT = ITABS-TOTAL.
      APPEND IT_PRINT_001.

      ITABS-ISUSED = 1.
      MODIFY ITABS.
    ENDIF.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*A类的调用程序
*&---------------------------------------------------------------------*
FORM. F_SUB_A USING P_LIFNR P_LIFNR_NAME.
DATA: L_INFNR LIKE EINA-INFNR.

  LOOP AT ITABS.
    L_INFNR = ''.
    IF ITABS-WERKS = P_BUKRS AND ITABS-TYPPS = 'M' AND ITABS-ISUSED <> 1.
*    IF ITABS-TYPPS = 'M' AND ITABS-ISUSED <> 1.
      "判断信息记录是否是唯一的公司间交易的供应商
      SELECT A~INFNR
        INTO L_INFNR
        FROM EINA AS A INNER JOIN EINE AS B ON A~INFNR = B~INFNR
        WHERE A~MATNR = ITABS-RECO_CODE
          AND A~LIFNR <> 'V10002'
          AND A~LIFNR <> 'V10005' AND A~LIFNR <> 'V20109'
          AND A~LIFNR <> 'V20236' AND A~LIFNR <> 'V10001'
          AND A~LOEKZ = ''
          AND B~EKORG = P_BUKRS
          AND B~WERKS = P_BUKRS
          AND B~EBELN <> ''.
      ENDSELECT.

      "若是公司间的供应商,进行如下处理
      IF L_INFNR = ''.
        SELECT A~INFNR
          INTO L_INFNR
          FROM EINA AS A INNER JOIN EINE AS B ON A~INFNR = B~INFNR
          WHERE A~MATNR = ITABS-RECO_CODE
            AND A~LIFNR = P_LIFNR
            AND A~LOEKZ = ''
            AND B~EKORG = P_BUKRS
            AND B~WERKS = P_BUKRS.
        ENDSELECT.
        IF L_INFNR <> ''.
          IT_PRINT_001-WERKS = ITABS-WERKS.
          IT_PRINT_001-CLASS = ITABS-TYPPS.
          IT_PRINT_001-ITEM_NAME_ALL = 'A类材料'.
          IT_PRINT_001-ITEM_NAME_ALL2 = P_LI

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值