FI-交货单发出商品-差异处理(开发笔记)

*&---------------------------------------------------------------------*
*& Report ZFIR120
*&---------------------------------------------------------------------*
*& Author              :  NathanSun
*& Create Date         :  2018-12-12
*& Program Type        :  Report
*& Description         :  交货单发出商品-差异处理
*&---------------------------------------------------------------------*
REPORT ZFIR120.

*&---------------------------------------------------------------------*
*& 包含               ZFIR092_TOP
*&---------------------------------------------------------------------*

TABLES:ACDOCA,BKPF,EKKN,VBAP.

TYPE-POOLS:SLIS.

"定义ALV输出所需变量
DATAS_LAYOUT    TYPE SLIS_LAYOUT_ALV,
      GT_FIELDCAT TYPE SLIS_T_FIELDCAT_ALV.
DATAGT_RETURN   LIKE BAPIRET2 OCCURS WITH HEADER LINE.
DATAU_BUDAT     TYPE BUDAT.
DATAN_BUDAT     TYPE BUDAT.
DATAP_BUDAT     TYPE ACDOCA-BUDAT.
DATAGT_SETLEAF  TYPE TABLE OF ZSETLEAF WITH HEADER LINE.

TYPESBEGIN OF GTS_DATA,
        flagC        TYPE  C,                       "删除标记
        RACCT        TYPE  ACDOCA-RACCT,            "成本科目
        MATNR        TYPE  ACDOCA-MATNR,            "物料
        RBUKRS       TYPE  ACDOCA-RBUKRS,           "公司代码
        GJAHR        TYPE  ACDOCA-GJAHR,            "年度
        POPER        TYPE  ACDOCA-POPER,            "期间
        WERKS        TYPE  ACDOCA-WERKS,            "工厂
        PRCTR        TYPE  ACDOCA-PRCTR,            "利润中心
        ZUONR        TYPE  ACDOCA-ZUONR,            "分配编号
        MAKTG        TYPE  MAKT-MAKTG,              "物料描述
        HSL          TYPE  ACDOCA-HSL,              "金额
        RHCUR        TYPE  ACDOCA-RHCUR,            "币别
        VBUND        TYPE  KNA1-VBUND,              "贸易伙伴
        KUNNR        TYPE  MSEG-KUNNR,              "客户
        VBELN_IM     TYPE  MSEG-VBELN_IM,           "交货单
        VBELP_IM     TYPE  MSEG-VBELP_IM,           "行项目
        MEINS        TYPE  MSEG-MEINS,              "基本单位
        MENGE        TYPE  MSEG-MENGE,              "交货数量
        BUDAT_MKPF   TYPE  MSEG-BUDAT_MKPF,         "交货日期
        HSLFT        TYPE  ACDOCA-HSL,              "分摊金额
        GZDAT        TYPE  VBRK-FKDAT,              "过账日期

        BELNR        TYPE  ACDOCA-BELNR,            "会计凭证号码
        DOCLN        TYPE  ACDOCA-DOCLN,            "分类账 6 字符过账项目

        MBLNR        TYPE  MSEG-MBLNR,              "物料凭证编号
        MJAHR        TYPE  MSEG-MJAHR,              "物料凭证年度
        ZEILE        TYPE  MSEG-ZEILE,              "物料凭证中的项目
        SHKZG        TYPE  MSEG-SHKZG,              "借方/贷方标识
        DMATNR       TYPE  MSEG-MATNR,              "成品
        DWERKS       TYPE  MSEG-WERKS,              "工厂
        WEMPF        TYPE  MSEG-WEMPF,              "收货方
        ZMENGE       TYPE  MSEG-MENGE,              "物料的科目对应的交货数量的汇总数
        SJAHR        TYPE  MSEG-SJAHR,              "被冲销物料凭证年度
        SMBLN        TYPE  MSEG-SMBLN,              "被冲销物料凭证
        SMBLP        TYPE  MSEG-SMBLP,              "被冲销物料凭证行项目
        BUDAT_MKPC   TYPE  MSEG-BUDAT_MKPF,         "被冲销物料凭证过账日期
      END OF GTS_DATA.

DATAGLAG_N    TYPE  C  .
DATAGLAG_E    TYPE  C  .
DATAGLAG_P    TYPE  C  .
DATAGT_DATA   TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_A TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_B TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_C TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_D TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_E TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_F TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_G TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_H TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_I TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_J TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGT_DATA_K TYPE TABLE OF GTS_DATA WITH HEADER LINE.
DATAGS_DATA   TYPE GTS_DATA .
DATAGT_REVERSAL TYPE TABLE OF BAPIACREV WITH HEADER LINE.
DATAGT_ZTFI120  TYPE TABLE OF ZTFI120 WITH HEADER LINE.

SELECTION-SCREEN BEGIN OF BLOCK B1 WITH FRAME.
PARAMETERSP_BUKRS LIKE ACDOCA-RBUKRS MODIF ID C1 OBLIGATORY ,              "公司代码
            P_GJAHR LIKE ACDOCA-GJAHR  MODIF ID C1 OBLIGATORY ,              "年度
            P_MONAT LIKE BKPF-MONAT    MODIF ID C1 OBLIGATORY .              "期间
SELECTION-SCREEN END OF BLOCK B1.
*&---------------------------------------------------------------------*
*& 包含               ZFIR101_CLASS
*&---------------------------------------------------------------------*
*----------------------------------------------------------------------*
*       CLASS DEMO DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS DEMO DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      MAIN.
ENDCLASS.

CLASS DEMO IMPLEMENTATION.
  METHOD MAIN.
    DATA(OUT) = CL_DEMO_OUTPUT=>NEW( ).

    OUT->BEGIN_SECTION`报错信息回执`
      )->WRITEGT_RETURN[] ).

    OUT->DISPLAY( ).
  ENDMETHOD.
ENDCLASS.
*&---------------------------------------------------------------------*
*& 包含               ZFIR092_FOM
*&---------------------------------------------------------------------*
*&---------------------------------------------------------------------*
*&      Form  FRM_EXCLUDE_OPTION
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*  -->  p1        text
*  <--  p2        text
*----------------------------------------------------------------------*
FORM FRM_EXCLUDE_OPTION .

ENDFORM.
*&---------------------------------------------------------------------*
*& Form SCREEN_OUTPUT
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM SCREEN_OUTPUT .
  LOOP AT SCREEN.
    CASE SCREEN-GROUP1.
      WHEN 'M1'.
        SCREEN-INPUT '0'.
    ENDCASE.
    MODIFY SCREEN.
  ENDLOOP.
ENDFORM.
*&---------------------------------------------------------------------*
*& Form SCREEN_SETTING
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM SCREEN_SETTING .
 AUTHORITY-CHECK OBJECT 'F_BKPF_BUK'
  ID 'BUKRS' FIELD P_BUKRS.
  IF SY-SUBRC <> 0.
    MESSAGE '您没有公司:'&& P_BUKRS && '  的权限!TYPE 'E' .
  ENDIF.

*  MESSAGE I000(0K) WITH TEXT-115 SPACE SPACE SPACE.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FOM_GETDATA
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FOM_GETDATA .
  FIELD-SYMBOLS <FS> .
  DATAG_FIELD(40).
*取所选期间的第一天
  U_BUDAT P_GJAHR && P_MONAT && '01' .
*取所选期间的最后一天
  CALL FUNCTION 'BKK_GET_MONTH_LASTDAY'
    EXPORTING
       I_DATE        U_BUDAT
    
IMPORTING
       E_DATE        P_BUDAT
       
.
**取所选期间次月的第一天
  N_BUDAT P_BUDAT + .

*  CLEAR GT_SETLEAF[] .
*  SELECT * INTO CORRESPONDING FIELDS OF TABLE GT_SETLEAF[] FROM SETLEAF
*    WHERE SETNAME = 'ZFI001'
*    .

*  IF GT_SETLEAF[] IS NOT INITIAL.

    LOOP AT GT_SETLEAF.
      GT_SETLEAF-RACCT GT_SETLEAF-VALFROM .
      MODIFY GT_SETLEAF .
      CLEAR  GT_SETLEAF .
    ENDLOOP.

    CLEAR GT_DATA[] .
    SELECT
      ACDOCA~RBUKRS
      ACDOCA
~GJAHR
      ACDOCA
~POPER
      ACDOCA
~WERKS
      ACDOCA
~BELNR
      ACDOCA
~DOCLN
      ACDOCA
~PRCTR
      ACDOCA
~MATNR
      ACDOCA
~RACCT
      ACDOCA
~HSL
      ACDOCA
~RHCUR
      ACDOCA
~ZUONR
    
INTO CORRESPONDING FIELDS OF TABLE GT_DATA[]
      
FROM ACDOCA
*      FOR ALL ENTRIES IN GT_SETLEAF[]
      WHERE ACDOCA~RBUKRS  =  P_BUKRS
        
AND ACDOCA~GJAHR   =  P_GJAHR
        
AND ACDOCA~BUDAT  =>  U_BUDAT
        
AND ACDOCA~BUDAT  <=  P_BUDAT
        
AND ACDOCA~BLART   =  'ML'
        AND ACDOCA~RACCT   =  '1406010500'
*        AND ACDOCA~MATNR   =  '12.029.004.0000033'
*        AND ACDOCA~KTOSL  <>  'UMB'
        .

    CLEAR GT_DATA_C[] .
    GT_DATA_C[] GT_DATA[] .
    SORT GT_DATA BY RBUKRS WERKS MATNR RACCT .
    DELETE ADJACENT DUPLICATES FROM GT_DATA[] COMPARING RBUKRS WERKS MATNR RACCT.
    LOOP AT GT_DATA.
      CLEAR GT_DATA-HSL .
      LOOP AT GT_DATA_C WHERE WERKS  GT_DATA-WERKS
                          
AND RBUKRS GT_DATA-RBUKRS
                          
AND MATNR  GT_DATA-MATNR
                          
AND RACCT  GT_DATA-RACCT
                          
.
        GT_DATA-HSL GT_DATA-HSL + GT_DATA_C-HSL .
        CLEAR GT_DATA_C .
      ENDLOOP.

      IF GT_DATA-HSL IS INITIAL.
        DELETE GT_DATA .
      ELSE .
        MODIFY GT_DATA .
      ENDIF.
      CLEAR GT_DATA .
    ENDLOOP.

    IF GT_DATA[] IS NOT INITIAL.

      CLEAR GT_SETLEAF[] .
      SELECT INTO CORRESPONDING FIELDS OF TABLE GT_SETLEAF[] FROM SETLEAF
        
WHERE SETNAME 'ZFI002'
        .

      IF GT_SETLEAF[] IS NOT INITIAL .

        DATAGR_BWART TYPE RANGE OF BWART,
              GW_BWART LIKE LINE  OF GR_BWART.

        LOOP AT GT_SETLEAF.
          GT_SETLEAF-BWART GT_SETLEAF-VALFROM .
          GW_BWART-SIGN   'I'.
          GW_BWART-OPTION 'EQ'.
          GW_BWART-LOW    GT_SETLEAF-BWART.
          APPEND GW_BWART TO GR_BWART.
          CLEAR  GW_BWART .
        ENDLOOP.

        CLEAR GT_DATA_D[].
        SELECT
          MSEG~MBLNR
          MSEG
~MJAHR
          MSEG
~ZEILE
          MSEG
~SHKZG
          MSEG
~KUNNR
          MSEG
~WEMPF
          MSEG
~VBELN_IM
          MSEG
~VBELP_IM
          MSEG
~MEINS
          MSEG
~MENGE
          MSEG
~BUDAT_MKPF
          MSEG
~MATNR AS DMATNR
          MSEG
~WERKS AS DWERKS
          MSEG
~SJAHR
          MSEG
~SMBLN
          MSEG
~SMBLP
        
INTO CORRESPONDING FIELDS OF TABLE GT_DATA_D[]
          
FROM MSEG
          
FOR ALL ENTRIES IN GT_DATA[]
          
WHERE MSEG~MATNR  GT_DATA-MATNR
            
AND MSEG~WERKS  GT_DATA-WERKS
            
AND MSEG~BWART IN GR_BWART
            
AND MSEG~BUDAT_MKPF => U_BUDAT
            
AND MSEG~BUDAT_MKPF <= P_BUDAT
*            AND MSEG~MATNR   =  '20.001.012.0000003'
            .

        LOOP AT GT_DATA_D.
          SELECT SINGLE BUDAT_MKPF INTO GT_DATA_D-BUDAT_MKPC FROM MSEG
            
WHERE MJAHR GT_DATA_D-SJAHR
              
AND MBLNR GT_DATA_D-SMBLN
              
AND ZEILE GT_DATA_D-SMBLP
              
.
          IF SY-SUBRC 0.
            IF GT_DATA_D-BUDAT_MKPC < U_BUDAT.
              DELETE GT_DATA_D .
            ENDIF.
          ENDIF.
          CLEAR GT_DATA_D .
        ENDLOOP.

*        DELETE GT_DATA_D[] WHERE DMATNR <> '20.001.012.0000003' .

        CLEAR GT_DATA_E[] .
        GT_DATA_E[] GT_DATA_D[] .
        SORT GT_DATA_D BY VBELN_IM VBELP_IM BUDAT_MKPF DESCENDING.
        DELETE ADJACENT DUPLICATES FROM GT_DATA_D[] COMPARING VBELN_IM VBELP_IM.
        LOOP AT GT_DATA_D.
          CLEAR GT_DATA_D-MENGE .
          LOOP AT GT_DATA_E WHERE VBELN_IM GT_DATA_D-VBELN_IM
                              
AND VBELP_IM GT_DATA_D-VBELP_IM
                              
.
            IF GT_DATA_E-SHKZG 'S'.
              GT_DATA_E-MENGE GT_DATA_E-MENGE * -.
            ENDIF.
            GT_DATA_D-MENGE GT_DATA_D-MENGE + GT_DATA_E-MENGE .
            CLEAR GT_DATA_E .
          ENDLOOP.
          IF GT_DATA_D-KUNNR IS INITIAL .
            GT_DATA_D-KUNNR GT_DATA_D-WEMPF .
          ENDIF.

          MODIFY GT_DATA_D .
          CLEAR GT_DATA_D .
        ENDLOOP.

        GT_DATA_A[] GT_DATA_D[] .
        CLEAR GT_DATA_D[] .
        LOOP AT GT_DATA_A.

          LOOP AT GT_DATA WHERE MATNR GT_DATA_A-DMATNR AND WERKS GT_DATA_A-DWERKS.
            GT_DATA_A-RBUKRS      GT_DATA-RBUKRS .
            GT_DATA_A-GJAHR       GT_DATA-GJAHR .
            GT_DATA_A-POPER       GT_DATA-POPER .
            GT_DATA_A-WERKS       GT_DATA-WERKS .
            GT_DATA_A-MATNR       GT_DATA-MATNR .
            GT_DATA_A-RACCT       GT_DATA-RACCT .
            GT_DATA_A-HSL         GT_DATA-HSL   .
            GT_DATA_A-RHCUR       GT_DATA-RHCUR .
            GT_DATA_A-BELNR       GT_DATA-BELNR .
            GT_DATA_A-DOCLN       GT_DATA-DOCLN .
            GT_DATA_A-PRCTR       GT_DATA-PRCTR .
            GT_DATA_A-ZUONR       GT_DATA-ZUONR .
            CLEAR GT_DATA .
            APPEND GT_DATA_A TO GT_DATA_D[] .
          ENDLOOP.

          CLEAR  GT_DATA_A .
        ENDLOOP.

        DELETE GT_DATA_D[] WHERE MENGE IS INITIAL .
        GT_DATA_F[] GT_DATA_D[] .
        SORT GT_DATA_F[] BY MATNR RACCT .
        DELETE ADJACENT DUPLICATES FROM GT_DATA_F[] COMPARING MATNR RACCT.
        LOOP AT GT_DATA_F.
          LOOP AT GT_DATA_D WHERE MATNR GT_DATA_F-MATNR AND RACCT GT_DATA_F-RACCT.
            GT_DATA_F-ZMENGE GT_DATA_F-ZMENGE + GT_DATA_D-MENGE .
            CLEAR GT_DATA_D .
          ENDLOOP.

          SELECT SINGLE VBUND INTO GT_DATA_F-VBUND FROM KNA1
            
WHERE KUNNR GT_DATA_F-KUNNR
            
.

          MODIFY GT_DATA_F .
          CLEAR GT_DATA_F .
        ENDLOOP.

        SORT GT_DATA_F[] BY MATNR RACCT .
        SORT GT_DATA_D[] BY MATNR RACCT .
        LOOP AT GT_DATA_D.
          CLEAR GLAG_N .
          CLEAR GLAG_E .
          AT NEW MATNR .
            GLAG_N 'X' .
          ENDAT .
          AT END OF MATNR .
            GLAG_E 'X' .
          ENDAT .

          READ TABLE GT_DATA_F WITH KEY MATNR GT_DATA_D-MATNR RACCT GT_DATA_D-RACCT BINARY SEARCH.
          IF SY-SUBRC 0.
            GT_DATA_D-ZMENGE GT_DATA_F-ZMENGE .
          ENDIF.

*该物料、科目最后一行的分摊金额采用倒挤相减方式得到
          IF GLAG_N IS NOT INITIAL.
            CLEAR GT_DATA_I .
            GT_DATA_I-HSL GT_DATA_D-HSL .
          ENDIF.

          IF GLAG_E IS NOT INITIAL.
*该物料、科目最后一行的分摊金额采用倒挤相减方式得到
            GT_DATA_D-HSLFT GT_DATA_I-HSL .

          ELSE .
*分摊金额:按条目 物料的成本科目的金额乘以 该条目的交货数量
*除以 该物料的科目对应的交货数量的汇总数(该物料、科目最后一行的分摊金额采用倒挤相减方式得到)。
            GT_DATA_D-HSLFT GT_DATA_D-HSL * GT_DATA_D-MENGE .
            IF GT_DATA_D-ZMENGE IS NOT INITIAL.
              GT_DATA_D-HSLFT GT_DATA_D-HSLFT / GT_DATA_D-ZMENGE .
            ENDIF.
            GT_DATA_I-HSL GT_DATA_I-HSL GT_DATA_D-HSLFT .
          ENDIF.

          SELECT SINGLE MAKTG INTO GT_DATA_D-MAKTG FROM MAKT
            
WHERE MATNR GT_DATA_D-MATNR
             
AND SPRAS 1
            .

          SELECT SINGLE VBUND INTO GT_DATA_D-VBUND FROM KNA1
            
WHERE KUNNR GT_DATA_D-KUNNR
            
.

          GT_DATA_D-GZDAT P_BUDAT .
          MODIFY GT_DATA_D .
          CLEAR GT_DATA_D .
        ENDLOOP.

        SORT GT_DATA_D[] BY MATNR RACCT VBELN_IM VBELP_IM .

      ENDIF.

    ENDIF.

*  ENDIF.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DISPLAY
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_DISPLAY .
  CLEAR S_LAYOUT.
  S_LAYOUT-ZEBRA 'X'.
  S_LAYOUT-COLWIDTH_OPTIMIZE 'X'.
*  s_layout-box_fieldname    = 'BOX'.
  PERFORM FRM_FILL_FIELD .

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
    EXPORTING
      IS_LAYOUT                S_LAYOUT
      IT_FIELDCAT              
GT_FIELDCAT
      I_CALLBACK_PROGRAM       
SY-REPID
      I_CALLBACK_PF_STATUS_SET 
'PF_STATUS_SET'
*     i_callback_html_top_of_page = 'HTML_TOP_OF_PAGE'
      I_CALLBACK_USER_COMMAND  'USER_COMMAND'
    TABLES
      T_OUTTAB                 GT_DATA_D[].
ENDFORM.

FORM FRM_FILL_FIELD .
  DATA:  WA_FIELDCAT TYPE SLIS_FIELDCAT_ALV.
  DEFINE FILL_FIELD.
    wa_fieldcat-fieldname &1.
    wa_fieldcat-seltext_l &2.
*    IF wa_fieldcat-fieldname =  'MSLJH' or wa_fieldcat-fieldname =  'WCBJH'.
*      wa_fieldcat-EMPHASIZE = 'C600'. "设置字段的颜色
*    ENDIF.
*
*    IF wa_fieldcat-fieldname =  'MSLMB' or wa_fieldcat-fieldname =  'WCBMB'.
*      wa_fieldcat-EMPHASIZE = 'C710'. "设置字段的颜色
*    ENDIF.

    IF wa_fieldcat-fieldname 'PLNBEZ' OR wa_fieldcat-fieldname 'MATNR' .
      wa_fieldcat-ref_tabname 'MARA'.
      wa_fieldcat-ref_fieldname 'MATNR'.
    ENDIF.

    IF wa_fieldcat-fieldname 'ARKTX' OR wa_fieldcat-fieldname 'WAKTX' .
      wa_fieldcat-ref_tabname 'VBAP'.
      wa_fieldcat-ref_fieldname 'ARKTX'.
    ENDIF.

    IF wa_fieldcat-fieldname 'AUFNR' .
      wa_fieldcat-ref_tabname 'AUFK'.
      wa_fieldcat-ref_fieldname 'AUFNR'.
    ENDIF.

    APPEND wa_fieldcat TO gt_fieldcat.
    CLEAR wa_fieldcat.
  END-OF-DEFINITION.
  FILL_FIELD :
        'RBUKRS'         '公司代码',
        'GJAHR'          '年度',
        'POPER'          '期间',
        'WERKS'          '工厂',
        'PRCTR'          '利润中心',
        'MATNR'          '物料',
        'MAKTG'          '物料描述',
        'RACCT'          '成本科目',
        'HSL'            '金额',
        'RHCUR'          '币别',
        'KUNNR'          '客户',
        'VBUND'          '贸易伙伴',
        'VBELN_IM'       '交货单',
        'VBELP_IM'       '行项目',
        'MEINS'          '基本单位',
        'MENGE'          '交货数量',
        'BUDAT_MKPF'     '交货日期',
        'HSLFT'          '分摊金额',
        'GZDAT'          '过账日期'.

ENDFORM.

FORM PF_STATUS_SET USING RT_EXTAB TYPE SLIS_T_EXTAB.
  SET PF-STATUS 'STANDARD_FULLSCREEN'.
ENDFORM.

FORM USER_COMMAND USING I_UCOMM LIKE SY-UCOMM
                    IS_SELFIELD 
TYPE SLIS_SELFIELD.
  DATA:   REF TYPE REF TO CL_GUI_ALV_GRID.
  DATA :  LV_STABLE TYPE LVC_S_STBL.   "刷新稳定性
  RANGESL_WERKS FOR T001W-WERKS.
  RANGESL_MATNR FOR MARA-MATNR.
  DATA:   L_BUKRS TYPE T001K-BUKRS.

  LV_STABLE-ROW '1'.
  LV_STABLE-COL '1'.

  CALL FUNCTION 'GET_GLOBALS_FROM_SLVC_FULLSCR'
    IMPORTING
      E_GRID REF.
  CALL METHOD REF->CHECK_CHANGED_DATA.

  CASE I_UCOMM.
    WHEN 'POST_T'.
      CLEAR GT_RETURN[] .
      PERFORM FRM_DATA_POST_T .
      LOOP AT GT_RETURN WHERE TYPE 'E'.
      ENDLOOP.
      IF SY-SUBRC 0.
        DEMO=>MAIN( ).
      ELSE .
        MESSAGE '模拟过账成功,可以进行正式过账!' TYPE 'S' .
      ENDIF.
    WHEN 'POST'.

      IF GT_RETURN[] IS INITIAL.
        MESSAGE '请先进行模拟过账!TYPE 'S' DISPLAY LIKE 'W'.
      ELSE .
        LOOP AT GT_RETURN WHERE TYPE 'E'.
        ENDLOOP.
        IF SY-SUBRC 0.
          MESSAGE '模拟过账时出错!TYPE 'S' DISPLAY LIKE 'E'.
        ELSE .
          CLEAR GT_ZTFI120 .
          SELECT SINGLE INTO CORRESPONDING FIELDS OF GT_ZTFI120 FROM ZTFI120
          
WHERE RBUKRS P_BUKRS
            
AND FISCYEARPER P_BUDAT(6)
            .

          DATA LV_FLAG TYPE C .
          CLEAR LV_FLAG .
          SELECT SINGLE ZFLAG INTO LV_FLAG FROM ZTIR094
            
WHERE ZPNAME 'ZFI120'
            .

          IF LV_FLAG IS NOT INITIAL.

            IF GT_ZTFI120 IS NOT INITIAL.
              MESSAGE '当前选择的期间已经过账,不能重复执行!' TYPE 'S' DISPLAY LIKE 'E'.
            ELSE .

              CLEAR GT_RETURN[] .
              PERFORM FRM_DATA_POST .

              LOOP AT GT_RETURN WHERE TYPE 'E'.
              ENDLOOP.
              IF SY-SUBRC 0.
                DEMO=>MAIN( ).
              ELSE .
                CLEAR GT_ZTFI120[].
                LOOP AT GT_DATA_D.
                  MOVE-CORRESPONDING GT_DATA_D TO GT_ZTFI120 .
                  GT_ZTFI120-FISCYEARPER P_BUDAT(6) .
                  APPEND GT_ZTFI120 .
                  CLEAR  GT_ZTFI120 .
                ENDLOOP.
                MODIFY ZTFI120 FROM TABLE GT_ZTFI120[] .
                COMMIT WORK .
                MESSAGE '期间过账成功TYPE 'S' .
              ENDIF.

            ENDIF.

          ELSE .

              CLEAR GT_RETURN[] .
              PERFORM FRM_DATA_POST .

              LOOP AT GT_RETURN WHERE TYPE 'E'.
              ENDLOOP.
              IF SY-SUBRC 0.
                DEMO=>MAIN( ).
              ELSE .
                CLEAR GT_ZTFI120[].
                LOOP AT GT_DATA_D.
                  MOVE-CORRESPONDING GT_DATA_D TO GT_ZTFI120 .
                  GT_ZTFI120-FISCYEARPER P_BUDAT(6) .
                  APPEND GT_ZTFI120 .
                  CLEAR  GT_ZTFI120 .
                ENDLOOP.
                MODIFY ZTFI120 FROM TABLE GT_ZTFI120[] .
                COMMIT WORK .
                MESSAGE '期间过账成功TYPE 'S' .
              ENDIF.

            IF GT_ZTFI120 IS NOT INITIAL.
              MESSAGE '当前选择的期间已经过账,未启用重复过帐检查!' TYPE 'W' .
            ENDIF.

          ENDIF.

        ENDIF.
      ENDIF.

  ENDCASE.

  CALL METHOD REF->REFRESH_TABLE_DISPLAY
    
EXPORTING
      IS_STABLE LV_STABLE.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DATA_POST_T
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_DATA_POST_T .
  DATA:
    TEMP_MONTH(2),            "输入月份
    HEADER_TXT(25),           "取会计年月+固定文本制费及研发费分摊
    TEMP_AUT_MSG(30),
    LAST_DATA          LIKE SY-DATUM"一个月的最后一天
    TEMP_OBJ_KEY       TYPE AWKEY,  "是否生成
    HEADER             LIKE BAPIACHE09  OCCURS WITH HEADER LINE,
    WA_ACCOUNTGL       LIKE BAPIACGL09  OCCURS WITH HEADER LINE,
    LT_ACCOUNTGL       TYPE STANDARD TABLE OF BAPIACGL09,
    WA_CURRENCY_AMOUNT LIKE BAPIACCR09  OCCURS WITH HEADER LINE,
    LT_CURRENCY_AMOUNT TYPE STANDARD TABLE OF BAPIACCR09 WITH HEADER LINE,
    IT_EXTENSION2      TYPE STANDARD TABLE OF BAPIPAREX WITH HEADER LINE,
    LT_RETURN          LIKE BAPIRET2 OCCURS WITH HEADER LINE,
    GST_RETURN         LIKE BAPIRET2 OCCURS WITH HEADER LINE,
    LS_ZFI002          TYPE ZFI002,
    FT_FLAG   ,               "= ‘X'表示分摊过
    LV_ANSWER(1),
    TEMP_BWTAR_AUFNR   LIKE AFPO-AUFNR.
  DATAGS_EXTENSION2  TYPE ZSFI_EXTEN,                              "会计凭证过账增强extension2
        LT_EXTENSION2  TYPE TABLE OF BAPIPAREX WITH HEADER LINE.     "返回参数

  DATALV_OBJ_TYPE    LIKE BAPIACHE09-OBJ_TYPE,
        LV_OBJ_KEY     LIKE BAPIACHE09-OBJ_KEY,
        LV_OBJ_SYS     LIKE BAPIACHE09-OBJ_SYS.

  DATALV_DMBTR       TYPE BAPIWRBTR,
        LV_LINES       TYPE SY-TABIX,
        ZCOUNT         TYPE SY-TABIX,
        ZCOUNTA        TYPE SY-TABIX,
        ZCOUNTB        TYPE SY-TABIX,
        ZCOUNTC        TYPE SY-TABIX,
        LV_WRBTR       TYPE BSEG-WRBTR,
        DO_POST        TYPE CHAR1,
        LS_EXTEN       TYPE ZSFI_EXTEN.
  DATALS_BKPF        TYPE BKPF,
        LS_REVERSAL    TYPE BAPIACREV.
  DATAGV_OBJ_TYPE    TYPE BAPIACHE09-OBJ_TYPE,                      "参考过程
        GV_OBJ_KEY     TYPE BAPIACHE09-OBJ_KEY,                       "对象键值
        GV_OBJ_SYS     TYPE BAPIACHE09-OBJ_SYS.
  DATA LV_BELNR_01     TYPE BKPF-BELNR.
  DATA LV_WAERS        TYPE T001-WAERS.

  CLEAR GST_RETURN[] .
*会计凭证抬头数据
  CLEAR HEADER.
  HEADER_TXT '物料账发出商品差异分摊到DN - ' && P_GJAHR && '&& P_MONAT && ''.
  HEADER-DOC_DATE   P_BUDAT.       "凭证日期
  HEADER-PSTNG_DATE P_BUDAT.       "凭证中的过帐日期
  HEADER-USERNAME   SY-UNAME.      "用户名
  HEADER-DOC_TYPE   'ML'.          "凭证类型
  HEADER-COMP_CODE  P_BUKRS.       "公司代码
*  HEADER-BUS_ACT    = 'RFBU'.        "业务事务
  HEADER-FISC_YEAR  P_BUDAT(4).    "财年
  HEADER-FIS_PERIOD P_BUDAT+4(2).  "会计期间
  HEADER-HEADER_TXT HEADER_TXT.    "凭证抬头文本

  DATA LV_ROWCNT TYPE I.
  DATA LV_ZCOUNT TYPE I.
  DATA LV_ZCOUNT_01 TYPE I.
  DESCRIBE TABLE GT_DATA_D[] LINES LV_ROWCNT.
  CLEAR GST_RETURN .
  IF LV_ROWCNT < 499.
    LOOP AT GT_DATA_F.
*    写入物料、科目的金额
      ADD TO LV_LINES.

      CLEAR WA_CURRENCY_AMOUNT.
      WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
      WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_F-RHCUR.                        "货币码
      WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_F-HSL * -1.                   "金额
      APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

      CLEAR WA_ACCOUNTGL.
      WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
      WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_F-RACCT.                             "成本科目
      WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
      WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_F-PRCTR.                             "利润中心
      WA_ACCOUNTGL-PLANT       GT_DATA_F-WERKS.                             "工厂

      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_F-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_F-KUNNR.                             "客户
      ENDIF.

      WA_ACCOUNTGL-MATERIAL    GT_DATA_F-MATNR.                             "物料编号(18 个字符)
      WA_ACCOUNTGL-BASE_UOM    GT_DATA_F-MEINS.                             "基本计量单位 个字符)
      WA_ACCOUNTGL-QUANTITY    GT_DATA_F-ZMENGE  .                          "数量
      WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_F-ZUONR  .                           "分配号
      APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

      CLEAR GS_EXTENSION2.
      CLEAR LT_EXTENSION2.
      GS_EXTENSION2-POSNR LV_LINES.
      IF GT_DATA_F-HSL  > 0.
        GS_EXTENSION2-BSCHL '50'.
      ELSE.
        GS_EXTENSION2-BSCHL '40'.
      ENDIF.
      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        GS_EXTENSION2-VBUND    GT_DATA_F-VBUND.                               "贸易伙伴
      ENDIF.
      IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
        GS_EXTENSION2-MENGE      GT_DATA_F-ZMENGE.                            "数量
        GS_EXTENSION2-MEINS      GT_DATA_F-MEINS.                             "基本计量单位
      ENDIF.
      LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
      LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
      APPEND LT_EXTENSION2.

*    写入物料、科目对应的交货单分摊金额
      LOOP AT GT_DATA_D WHERE MATNR GT_DATA_F-MATNR AND RACCT GT_DATA_F-RACCT.

        ADD TO LV_LINES.
        CLEAR WA_CURRENCY_AMOUNT.
        WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
        WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_D-RHCUR.                        "货币码
        WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_D-HSLFT.                        "金额
        APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

        CLEAR WA_ACCOUNTGL.
        WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
        WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_D-RACCT.                             "成本科目
        WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
        WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_D-PRCTR.                             "利润中心
        WA_ACCOUNTGL-PLANT       GT_DATA_D-WERKS.                             "工厂
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_D-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_D-KUNNR.                             "客户
*        WA_ACCOUNTGL-REF_KEY_1   = GT_DATA_D-KUNNR.                             "业务伙伴参考码
        WA_ACCOUNTGL-MATERIAL    GT_DATA_D-MATNR.                             "物料编号(18 个字符)
        WA_ACCOUNTGL-BASE_UOM    GT_DATA_D-MEINS.                             "基本计量单位 个字符)
        WA_ACCOUNTGL-QUANTITY    GT_DATA_D-MENGE .                            "数量
        WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_D-VBELN_IM && GT_DATA_D-VBELP_IM .   "分配号
        APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

        CLEAR GS_EXTENSION2.
        CLEAR LT_EXTENSION2.
        GS_EXTENSION2-POSNR LV_LINES.
        IF GT_DATA_D-HSLFT  > 0.
          GS_EXTENSION2-BSCHL '40'.
        ELSE.
          GS_EXTENSION2-BSCHL '50'.
        ENDIF.
        GS_EXTENSION2-VBUND    GT_DATA_D-VBUND.                             "贸易伙伴
        IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
          GS_EXTENSION2-MENGE      GT_DATA_D-MENGE.                          "数量
          GS_EXTENSION2-MEINS      GT_DATA_D-MEINS.                          "基本计量单位
        ENDIF.
        LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
        LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
        APPEND LT_EXTENSION2.

      ENDLOOP.

    ENDLOOP.

    LOOP AT LT_CURRENCY_AMOUNT WHERE AMT_DOCCUR <> 0.
    ENDLOOP.
    IF SY-SUBRC 0.
      CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK'
        EXPORTING
          DOCUMENTHEADER HEADER
*        IMPORTING
*          OBJ_TYPE       = LV_OBJ_TYPE
*          OBJ_KEY        = LV_OBJ_KEY
*          OBJ_SYS        = LV_OBJ_SYS
        TABLES
          ACCOUNTGL      LT_ACCOUNTGL         "总帐科目项
          CURRENCYAMOUNT LT_CURRENCY_AMOUNT   "货币项目
          EXTENSION2     LT_EXTENSION2
          
RETURN         LT_RETURN.           "返回值

        CLEAR LT_RETURN.
        LOOP AT LT_RETURN .
          APPEND LT_RETURN TO GST_RETURN .
          CLEAR LT_RETURN .
        ENDLOOP.

      CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
    ENDIF.

    FREE:LT_ACCOUNTGL,LT_CURRENCY_AMOUNT,LT_RETURN.

  ELSE .

*    LV_ZCOUNT = LV_ROWCNT.
*    CLEAR :LV_LINES,LV_ZCOUNT_01.
*    CLEAR ZCOUNT.
    ZCOUNTA LV_ROWCNT .
    CLEAR ZCOUNTB .

    LOOP AT GT_DATA_F.

*      IF GLAG_P IS NOT INITIAL.
*        CLEAR:LT_ACCOUNTGL,LT_CURRENCY_AMOUNT,LT_EXTENSION2[],LT_RETURN,GLAG_P.
*      ENDIF.

*    写入物料、科目的金额
      ADD TO LV_LINES.

      CLEAR WA_CURRENCY_AMOUNT.
      WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
      WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_F-RHCUR.                        "货币码
      WA_CURRENCY_AMOUNT-AMT_DOCCUR =  GT_DATA_F-HSL * -1.                    "金额
      APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

      CLEAR WA_ACCOUNTGL.
      WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
      WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_F-RACCT.                             "成本科目
      WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
      WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_F-PRCTR.                             "利润中心
      WA_ACCOUNTGL-PLANT       GT_DATA_F-WERKS.                             "工厂

      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_F-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_F-KUNNR.                             "客户
      ENDIF.

      WA_ACCOUNTGL-MATERIAL    GT_DATA_F-MATNR.                             "物料编号(18 个字符)
      WA_ACCOUNTGL-BASE_UOM    GT_DATA_F-MEINS.                             "基本计量单位 个字符)
      WA_ACCOUNTGL-QUANTITY    GT_DATA_F-ZMENGE  .                          "数量
      WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_F-ZUONR  .                           "分配号
      APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

      CLEAR GS_EXTENSION2.
      CLEAR LT_EXTENSION2.
      GS_EXTENSION2-POSNR LV_LINES.
      IF GT_DATA_F-HSL  > 0.
        GS_EXTENSION2-BSCHL '50'.
      ELSE.
        GS_EXTENSION2-BSCHL '40'.
      ENDIF.
      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        GS_EXTENSION2-VBUND    GT_DATA_F-VBUND.                             "贸易伙伴
      ENDIF.
      IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
        GS_EXTENSION2-MENGE      GT_DATA_F-ZMENGE.                            "数量
        GS_EXTENSION2-MEINS      GT_DATA_F-MEINS.                             "基本计量单位
      ENDIF.
      LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
      LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
      APPEND LT_EXTENSION2.

*    写入物料、科目对应的交货单分摊金额
      LOOP AT GT_DATA_D WHERE MATNR GT_DATA_F-MATNR AND RACCT GT_DATA_F-RACCT.

          ADD TO ZCOUNTB .

*        ZCOUNT = ZCOUNT + 1.
*
*        LV_ZCOUNT_01 = LV_ZCOUNT_01 + 1.
*
*        IF ( LV_ZCOUNT >= 499 AND ZCOUNT = 499 ) OR ( LV_ZCOUNT < 499 AND LV_ZCOUNT = ZCOUNT ) .
*          DO_POST = 'X'.
*        ENDIF.

*      写入借方
        ADD TO LV_LINES.

        CLEAR WA_CURRENCY_AMOUNT.
        WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
        WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_D-RHCUR.                        "货币码
        WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_D-HSLFT.                        "金额
        APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

        CLEAR WA_ACCOUNTGL.
        WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
        WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_D-RACCT.                             "成本科目
        WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
        WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_D-PRCTR.                             "利润中心
        WA_ACCOUNTGL-PLANT       GT_DATA_D-WERKS.                             "工厂
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_D-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_D-KUNNR.                             "客户
*        WA_ACCOUNTGL-REF_KEY_1   = GT_DATA_D-KUNNR.                             "业务伙伴参考码
        WA_ACCOUNTGL-MATERIAL    GT_DATA_D-MATNR.                             "物料编号(18 个字符)
        WA_ACCOUNTGL-BASE_UOM    GT_DATA_D-MEINS.                             "基本计量单位 个字符)
        WA_ACCOUNTGL-QUANTITY    GT_DATA_D-MENGE .                            "数量
        WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_D-VBELN_IM && GT_DATA_D-VBELP_IM .   "分配号
        APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

        CLEAR GS_EXTENSION2.
        CLEAR LT_EXTENSION2.
        GS_EXTENSION2-POSNR LV_LINES.
        IF GT_DATA_D-HSLFT  > 0.
          GS_EXTENSION2-BSCHL '40'.
        ELSE.
          GS_EXTENSION2-BSCHL '50'.
        ENDIF.
        GS_EXTENSION2-VBUND    GT_DATA_D-VBUND.                             "贸易伙伴
        IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
          GS_EXTENSION2-MENGE      GT_DATA_D-MENGE.                          "数量
          GS_EXTENSION2-MEINS      GT_DATA_D-MEINS.                          "基本计量单位
        ENDIF.
        LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
        LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
        APPEND LT_EXTENSION2.

      ENDLOOP.

      IF ZCOUNTB >= 499 OR ZCOUNTB ZCOUNTA.
        DO_POST 'X'.
        ZCOUNTA ZCOUNTA ZCOUNTB .
        CLEAR ZCOUNTB .
      ENDIF.

*      IF ZCOUNT > 499.
*        GLAG_P = 'X'.
*        LV_LINES = 0.
*        ZCOUNT = 1.
*        LV_ZCOUNT = LV_ROWCNT - LV_ZCOUNT_01.
*        CLEAR LV_LINES.
*      ENDIF.

      IF DO_POST 'X'.

        LOOP AT LT_CURRENCY_AMOUNT WHERE AMT_DOCCUR <> 0.
        ENDLOOP.
        IF SY-SUBRC 0.
          CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK'
            EXPORTING
              DOCUMENTHEADER HEADER
*            IMPORTING
*              OBJ_TYPE       = LV_OBJ_TYPE
*              OBJ_KEY        = LV_OBJ_KEY
*              OBJ_SYS        = LV_OBJ_SYS
            TABLES
              ACCOUNTGL      LT_ACCOUNTGL          "总帐科目项
              CURRENCYAMOUNT LT_CURRENCY_AMOUNT    "货币项目
              EXTENSION2     LT_EXTENSION2
              
RETURN         LT_RETURN.            "返回值

          CLEAR LT_RETURN.
          LOOP AT LT_RETURN .
            APPEND LT_RETURN TO GST_RETURN .
            CLEAR LT_RETURN .
          ENDLOOP.

          CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
        ENDIF .
*        FREE:LT_ACCOUNTGL,LT_CURRENCY_AMOUNT,LT_RETURN.
        CLEAR:LT_ACCOUNTGL[],LT_CURRENCY_AMOUNT[],LT_EXTENSION2[],LT_RETURN[].
        CLEAR LV_LINES .
        DO_POST ''.
      ENDIF.

    ENDLOOP.

  ENDIF.

  SORT GST_RETURN[] BY MESSAGE .
  DELETE ADJACENT DUPLICATES FROM GST_RETURN[] COMPARING MESSAGE.

  LOOP AT GST_RETURN.
    GST_RETURN-MESSAGE '模拟过账: ' && GST_RETURN-MESSAGE .
    APPEND GST_RETURN TO GT_RETURN .
    CLEAR  GST_RETURN .
  ENDLOOP.

ENDFORM.
*&---------------------------------------------------------------------*
*& Form FRM_DATA_POST
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM FRM_DATA_POST .
  DATA:
    TEMP_MONTH(2),            "输入月份
    HEADER_TXT(25),           "取会计年月+固定文本制费及研发费分摊
    TEMP_AUT_MSG(30),
    LAST_DATA          LIKE SY-DATUM"一个月的最后一天
    TEMP_OBJ_KEY       TYPE AWKEY,  "是否生成
    HEADER             LIKE BAPIACHE09  OCCURS WITH HEADER LINE,
    WA_ACCOUNTGL       LIKE BAPIACGL09  OCCURS WITH HEADER LINE,
    LT_ACCOUNTGL       TYPE STANDARD TABLE OF BAPIACGL09,
    WA_CURRENCY_AMOUNT LIKE BAPIACCR09  OCCURS WITH HEADER LINE,
    LT_CURRENCY_AMOUNT TYPE STANDARD TABLE OF BAPIACCR09 WITH HEADER LINE,
    IT_EXTENSION2      TYPE STANDARD TABLE OF BAPIPAREX WITH HEADER LINE,
    LT_RETURN          LIKE BAPIRET2 OCCURS WITH HEADER LINE,
    GST_RETURN         LIKE BAPIRET2 OCCURS WITH HEADER LINE,
    LS_ZFI002          TYPE ZFI002,
    FT_FLAG   ,               "= ‘X'表示分摊过
    LV_ANSWER(1),
    TEMP_BWTAR_AUFNR   LIKE AFPO-AUFNR.
  DATAGS_EXTENSION2  TYPE ZSFI_EXTEN,                              "会计凭证过账增强extension2
        LT_EXTENSION2  TYPE TABLE OF BAPIPAREX WITH HEADER LINE.     "返回参数

  DATALV_OBJ_TYPE    LIKE BAPIACHE09-OBJ_TYPE,
        LV_OBJ_KEY     LIKE BAPIACHE09-OBJ_KEY,
        LV_OBJ_SYS     LIKE BAPIACHE09-OBJ_SYS.

  DATALV_DMBTR       TYPE BAPIWRBTR,
        LV_LINES       TYPE SY-TABIX,
        ZCOUNT         TYPE SY-TABIX,
        ZCOUNTA        TYPE SY-TABIX,
        ZCOUNTB        TYPE SY-TABIX,
        ZCOUNTC        TYPE SY-TABIX,
        LV_WRBTR       TYPE BSEG-WRBTR,
        DO_POST        TYPE CHAR1,
        LS_EXTEN       TYPE ZSFI_EXTEN.
  DATALS_BKPF        TYPE BKPF,
        LS_REVERSAL    TYPE BAPIACREV.
  DATAGV_OBJ_TYPE    TYPE BAPIACHE09-OBJ_TYPE,                      "参考过程
        GV_OBJ_KEY     TYPE BAPIACHE09-OBJ_KEY,                       "对象键值
        GV_OBJ_SYS     TYPE BAPIACHE09-OBJ_SYS.
  DATA LV_BELNR_01     TYPE BKPF-BELNR.
  DATA LV_WAERS        TYPE T001-WAERS.

  CLEAR GST_RETURN[] .
*会计凭证抬头数据
  CLEAR HEADER.
  HEADER_TXT '物料账发出商品差异分摊到DN - ' && P_GJAHR && '&& P_MONAT && ''.
  HEADER-DOC_DATE   P_BUDAT.       "凭证日期
  HEADER-PSTNG_DATE P_BUDAT.       "凭证中的过帐日期
  HEADER-USERNAME   SY-UNAME.      "用户名
  HEADER-DOC_TYPE   'ML'.          "凭证类型
  HEADER-COMP_CODE  P_BUKRS.       "公司代码
*  HEADER-BUS_ACT    = 'RFBU'.        "业务事务
  HEADER-FISC_YEAR  P_BUDAT(4).    "财年
  HEADER-FIS_PERIOD P_BUDAT+4(2).  "会计期间
  HEADER-HEADER_TXT HEADER_TXT.    "凭证抬头文本

  DATA LV_ROWCNT TYPE I.
  DATA LV_ZCOUNT TYPE I.
  DATA LV_ZCOUNT_01 TYPE I.
  DESCRIBE TABLE GT_DATA_D LINES LV_ROWCNT.
  CLEAR GST_RETURN .
  IF LV_ROWCNT < 499.
    LOOP AT GT_DATA_F.
*    写入物料、科目的金额
      ADD TO LV_LINES.

      CLEAR WA_CURRENCY_AMOUNT.
      WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
      WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_F-RHCUR.                        "货币码
      WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_F-HSL * -1.                   "金额
      APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

      CLEAR WA_ACCOUNTGL.
      WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
      WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_F-RACCT.                             "成本科目
      WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
      WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_F-PRCTR.                             "利润中心
      WA_ACCOUNTGL-PLANT       GT_DATA_F-WERKS.                             "工厂

      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_F-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_F-KUNNR.                             "客户
      ENDIF.

      WA_ACCOUNTGL-MATERIAL    GT_DATA_F-MATNR.                             "物料编号(18 个字符)
      WA_ACCOUNTGL-BASE_UOM    GT_DATA_F-MEINS.                             "基本计量单位 个字符)
      WA_ACCOUNTGL-QUANTITY    GT_DATA_F-ZMENGE  .                          "数量
      WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_F-ZUONR  .                           "分配号
      APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

      CLEAR GS_EXTENSION2.
      CLEAR LT_EXTENSION2.
      GS_EXTENSION2-POSNR LV_LINES.
      IF GT_DATA_F-HSL  > 0.
        GS_EXTENSION2-BSCHL '50'.
      ELSE.
        GS_EXTENSION2-BSCHL '40'.
      ENDIF.
      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        GS_EXTENSION2-VBUND    GT_DATA_F-VBUND.                             "贸易伙伴
      ENDIF.
      IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
        GS_EXTENSION2-MENGE      GT_DATA_F-ZMENGE.                            "数量
        GS_EXTENSION2-MEINS      GT_DATA_F-MEINS.                             "基本计量单位
      ENDIF.
      LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
      LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
      APPEND LT_EXTENSION2.

*    写入物料、科目对应的交货单分摊金额
      LOOP AT GT_DATA_D WHERE MATNR GT_DATA_F-MATNR AND RACCT GT_DATA_F-RACCT.

        ADD TO LV_LINES.
        CLEAR WA_CURRENCY_AMOUNT.
        WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
        WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_D-RHCUR.                        "货币码
        WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_D-HSLFT.                        "金额
        APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

        CLEAR WA_ACCOUNTGL.
        WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
        WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_D-RACCT.                             "成本科目
        WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
        WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_D-PRCTR.                             "利润中心
        WA_ACCOUNTGL-PLANT       GT_DATA_D-WERKS.                             "工厂
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_D-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_D-KUNNR.                             "客户
*        WA_ACCOUNTGL-REF_KEY_1   = GT_DATA_D-KUNNR.                             "业务伙伴参考码
        WA_ACCOUNTGL-MATERIAL    GT_DATA_D-MATNR.                             "物料编号(18 个字符)
        WA_ACCOUNTGL-BASE_UOM    GT_DATA_D-MEINS.                             "基本计量单位 个字符)
        WA_ACCOUNTGL-QUANTITY    GT_DATA_D-MENGE .                            "数量
        WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_D-VBELN_IM && GT_DATA_D-VBELP_IM .   "分配号
        APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

        CLEAR GS_EXTENSION2.
        CLEAR LT_EXTENSION2.
        GS_EXTENSION2-POSNR LV_LINES.
        IF GT_DATA_D-HSLFT  > 0.
          GS_EXTENSION2-BSCHL '40'.
        ELSE.
          GS_EXTENSION2-BSCHL '50'.
        ENDIF.
        GS_EXTENSION2-VBUND    GT_DATA_D-VBUND.                             "贸易伙伴
        IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
          GS_EXTENSION2-MENGE      GT_DATA_D-MENGE.                          "数量
          GS_EXTENSION2-MEINS      GT_DATA_D-MEINS.                          "基本计量单位
        ENDIF.
        LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
        LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
        APPEND LT_EXTENSION2.

      ENDLOOP.

    ENDLOOP.

    LOOP AT LT_CURRENCY_AMOUNT WHERE AMT_DOCCUR <> 0.
    ENDLOOP.
    IF SY-SUBRC 0.
     CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
       EXPORTING
         DOCUMENTHEADER HEADER
       IMPORTING
         OBJ_TYPE       LV_OBJ_TYPE
         OBJ_KEY        
LV_OBJ_KEY
         OBJ_SYS        
LV_OBJ_SYS
       
TABLES
         ACCOUNTGL      LT_ACCOUNTGL         "总帐科目项
         CURRENCYAMOUNT LT_CURRENCY_AMOUNT   "货币项目
         EXTENSION2     LT_EXTENSION2
         
RETURN         LT_RETURN.           "返回值

     CLEAR LT_RETURN.
     LOOP AT LT_RETURN .
       APPEND LT_RETURN TO GST_RETURN .
       CLEAR LT_RETURN .
     ENDLOOP.

     LOOP AT LT_RETURN WHERE TYPE 'E'.
     ENDLOOP.

     IF SY-SUBRC .
       CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
     ELSE.
       CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
         EXPORTING
           WAIT 'X'.
     ENDIF.

    ENDIF .
    FREE:LT_ACCOUNTGL,LT_CURRENCY_AMOUNT,LT_RETURN.

  ELSE .

*    LV_ZCOUNT = LV_ROWCNT.
*    CLEAR :LV_LINES,LV_ZCOUNT_01.
*    CLEAR ZCOUNT.
    ZCOUNTA LV_ROWCNT .
    CLEAR ZCOUNTB .

    LOOP AT GT_DATA_F.

*      IF GLAG_P IS NOT INITIAL.
*        CLEAR:LT_ACCOUNTGL,LT_CURRENCY_AMOUNT,LT_EXTENSION2[],LT_RETURN,GLAG_P.
*      ENDIF.

*    写入物料、科目的金额
      ADD TO LV_LINES.

      CLEAR WA_CURRENCY_AMOUNT.
      WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
      WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_F-RHCUR.                        "货币码
      WA_CURRENCY_AMOUNT-AMT_DOCCUR =  GT_DATA_F-HSL * -1.                    "金额
      APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

      CLEAR WA_ACCOUNTGL.
      WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
      WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_F-RACCT.                             "成本科目
      WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
      WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_F-PRCTR.                             "利润中心
      WA_ACCOUNTGL-PLANT       GT_DATA_F-WERKS.                             "工厂

      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_F-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_F-KUNNR.                             "客户
      ENDIF.

      WA_ACCOUNTGL-MATERIAL    GT_DATA_F-MATNR.                             "物料编号(18 个字符)
      WA_ACCOUNTGL-BASE_UOM    GT_DATA_F-MEINS.                             "基本计量单位 个字符)
      WA_ACCOUNTGL-QUANTITY    GT_DATA_F-ZMENGE  .                          "数量
      WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_F-ZUONR  .                           "分配号
      APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

      CLEAR GS_EXTENSION2.
      CLEAR LT_EXTENSION2.
      GS_EXTENSION2-POSNR LV_LINES.
      IF GT_DATA_F-HSL  > 0.
        GS_EXTENSION2-BSCHL '50'.
      ELSE.
        GS_EXTENSION2-BSCHL '40'.
      ENDIF.
      IF GT_DATA_F-ZUONR IS NOT INITIAL.
        GS_EXTENSION2-VBUND    GT_DATA_F-VBUND.                             "贸易伙伴
      ENDIF.
      IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
        GS_EXTENSION2-MENGE      GT_DATA_F-ZMENGE.                            "数量
        GS_EXTENSION2-MEINS      GT_DATA_F-MEINS.                             "基本计量单位
      ENDIF.
      LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
      LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
      APPEND LT_EXTENSION2.

*    写入物料、科目对应的交货单分摊金额
      LOOP AT GT_DATA_D WHERE MATNR GT_DATA_F-MATNR AND RACCT GT_DATA_F-RACCT.

          ADD TO ZCOUNTB .

*        ZCOUNT = ZCOUNT + 1.
*
*        LV_ZCOUNT_01 = LV_ZCOUNT_01 + 1.
*
*        IF ( LV_ZCOUNT >= 499 AND ZCOUNT = 499 ) OR ( LV_ZCOUNT < 499 AND LV_ZCOUNT = ZCOUNT ) .
*          DO_POST = 'X'.
*        ENDIF.

*      写入借方
        ADD TO LV_LINES.

        CLEAR WA_CURRENCY_AMOUNT.
        WA_CURRENCY_AMOUNT-ITEMNO_ACC LV_LINES.                               "会计凭证行项目编号
        WA_CURRENCY_AMOUNT-CURRENCY   GT_DATA_D-RHCUR.                        "货币码
        WA_CURRENCY_AMOUNT-AMT_DOCCUR GT_DATA_D-HSLFT.                        "金额
        APPEND WA_CURRENCY_AMOUNT TO LT_CURRENCY_AMOUNT .

        CLEAR WA_ACCOUNTGL.
        WA_ACCOUNTGL-ITEMNO_ACC  LV_LINES .                                   "会计凭证行项目编号
        WA_ACCOUNTGL-GL_ACCOUNT  GT_DATA_D-RACCT.                             "成本科目
        WA_ACCOUNTGL-ITEM_TEXT   HEADER_TXT.                                  "项目文本
        WA_ACCOUNTGL-PROFIT_CTR  GT_DATA_D-PRCTR.                             "利润中心
        WA_ACCOUNTGL-PLANT       GT_DATA_D-WERKS.                             "工厂
        WA_ACCOUNTGL-TRADE_ID    GT_DATA_D-VBUND.                             "贸易伙伴
        WA_ACCOUNTGL-CUSTOMER    GT_DATA_D-KUNNR.                             "客户
*        WA_ACCOUNTGL-REF_KEY_1   = GT_DATA_D-KUNNR.                             "业务伙伴参考码
        WA_ACCOUNTGL-MATERIAL    GT_DATA_D-MATNR.                             "物料编号(18 个字符)
        WA_ACCOUNTGL-BASE_UOM    GT_DATA_D-MEINS.                             "基本计量单位 个字符)
        WA_ACCOUNTGL-QUANTITY    GT_DATA_D-MENGE .                            "数量
        WA_ACCOUNTGL-ALLOC_NMBR  GT_DATA_D-VBELN_IM && GT_DATA_D-VBELP_IM .   "分配号
        APPEND WA_ACCOUNTGL TO LT_ACCOUNTGL.

        CLEAR GS_EXTENSION2.
        CLEAR LT_EXTENSION2.
        GS_EXTENSION2-POSNR LV_LINES.
        IF GT_DATA_D-HSLFT  > 0.
          GS_EXTENSION2-BSCHL '40'.
        ELSE.
          GS_EXTENSION2-BSCHL '50'.
        ENDIF.
        GS_EXTENSION2-VBUND      GT_DATA_D-VBUND.                             "贸易伙伴
        IF WA_ACCOUNTGL-ALLOC_NMBR IS NOT INITIAL.
          GS_EXTENSION2-MENGE      GT_DATA_D-MENGE.                          "数量
          GS_EXTENSION2-MEINS      GT_DATA_D-MEINS.                          "基本计量单位
        ENDIF.
        LT_EXTENSION2-STRUCTURE  'ZSFI_EXTEN'.
        LT_EXTENSION2-VALUEPART1 GS_EXTENSION2.
        APPEND LT_EXTENSION2.

      ENDLOOP.

      IF ZCOUNTB >= 499 OR ZCOUNTB ZCOUNTA.
        DO_POST 'X'.
        ZCOUNTA ZCOUNTA ZCOUNTB .
        CLEAR ZCOUNTB .
      ENDIF.

*      IF ZCOUNT > 499.
*        GLAG_P = 'X'.
*        LV_LINES = 0.
*        ZCOUNT = 1.
*        LV_ZCOUNT = LV_ROWCNT - LV_ZCOUNT_01.
*        CLEAR LV_LINES.
*      ENDIF.

      IF DO_POST 'X'.

        LOOP AT LT_CURRENCY_AMOUNT WHERE AMT_DOCCUR <> 0.
        ENDLOOP.
        IF SY-SUBRC 0.
          CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
            EXPORTING
              DOCUMENTHEADER HEADER
            IMPORTING
              OBJ_TYPE       LV_OBJ_TYPE
              OBJ_KEY        
LV_OBJ_KEY
              OBJ_SYS        
LV_OBJ_SYS
            
TABLES
              ACCOUNTGL      LT_ACCOUNTGL          "总帐科目项
              CURRENCYAMOUNT LT_CURRENCY_AMOUNT    "货币项目
              EXTENSION2     LT_EXTENSION2
              
RETURN         LT_RETURN.            "返回值

          CLEAR LT_RETURN.
          LOOP AT LT_RETURN .
            APPEND LT_RETURN TO GST_RETURN .
            CLEAR LT_RETURN .
          ENDLOOP.

          LOOP AT LT_RETURN WHERE TYPE 'E'.
          ENDLOOP.

          IF SY-SUBRC .
            CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
          ELSE.
            CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
              EXPORTING
                WAIT 'X'.
          ENDIF.
        ENDIF .
        CLEAR:LT_ACCOUNTGL[],LT_CURRENCY_AMOUNT[],LT_EXTENSION2[],LT_RETURN[].
        CLEAR LV_LINES .
        DO_POST ''.
      ENDIF.

    ENDLOOP.

  ENDIF.

  SORT GST_RETURN[] BY MESSAGE .
  DELETE ADJACENT DUPLICATES FROM GST_RETURN[] COMPARING MESSAGE.

  LOOP AT GST_RETURN.
    GST_RETURN-MESSAGE '正式过账: ' && GST_RETURN-MESSAGE .
    APPEND GST_RETURN TO GT_RETURN .
    CLEAR  GST_RETURN .
  ENDLOOP.

ENDFORM.

INITIALIZATION.
  PERFORM FRM_EXCLUDE_OPTION.

AT SELECTION-SCREEN OUTPUT.
  PERFORM SCREEN_OUTPUT.

AT SELECTION-SCREEN.
  PERFORM SCREEN_SETTING.

START-OF-SELECTION.
  PERFORM FOM_GETDATA.
  PERFORM FRM_DISPLAY.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值