SAP BAPI_ACC_DOCUMENT_POST

328 篇文章 133 订阅

1.    举个我们这次系统中的一个业务场景
前面讲到我们需要把一个Oracle应付发票的凭证导入到SAP中,但是导入的字段比较多,就会出现如下的问题:
SAP系统中把凭证中的[分支号]作为不同系统的来源,例如凭证来源于Oracle,金蝶,用友,那么分支号分别是'001','002','003'。
我们这里使用BAPI_ACC_DOCUMENT_POST来导入凭证,
大家可以看一下在BKPF表中存在[分支号]字段       

但是在BAPIACHE09(操作代码SE37)结构中却没有[分支号]这个字段,BAPIACHE09是BAPI_ACC_DOCUMENT_POST导入凭证头的入口结构        
        
那么标准API没有[分支号],SAP采用何种方法才能将[分支号]导入系统哪?

很高兴看到SAP提供了增强BAdi(客户化创建BAdi)来导入标准API没有的字段
一般情况下,不需要对BAdi作增强,但是当需要将某个不常用的字段导入到SAP,但是标准的BAPI又不能够支持这个字段,则需要对BAdi作增强,那么如何对BAdi作增强那?
下面简单做个讲解:
1)首先需要我们对标准的BAdi(操作代码SE19)做个实例化,本场景中,我们对ACC_DOCUMENT这个标准的BAdi实例化      

        
关键是上图中的CHANGE部分,双击就可以进入BAdi的ABAP程序源代码,是不是感觉很爽,不过别高兴太早,因为进入源代码的编辑器之后,是空的,当然,源代码是需要自己添加的,请看下图:
        
上面的代码看不懂没关系,我来解释一下:
DATA部分是定义变量,liw_accit TYPE accit就是定义一个accit的结构类型的变量liw_accit;
LOOP部分就是对BAPI中的extension2的数据作循环
Liw_accit-bschl就是对bschl这个字段根据实际传入的数据作赋值,当然,bschl就是类似[分支号]的字段;
MODIFY就是将bashl等字段写入到c_accit结构中,相当于更新accit表中的数据


大家看到这里,可能已经明白了BAdi是怎么回事。但是大家可能会问,BAPI怎么会去调用BAdi来做这个事情哪?这个问题可能比较复杂,但是我把他简化了说:
在下图中,BAPI一般会有
[Import]传入参数
[Export]传出参数
[Tabellen]这个是table类型的,用来传入和传出数组类型或table类型的数据,在table类型的数据中有个参数是extension2,作为扩展导入的字段,只要在extension2中作了定义,那么就会执行所有实例化的BAdi,所以这也算是SAP的一个缺点,因为假设你定义了2个相同类型的BAdi,它们都会被执行,假设这两个BAdi逻辑相悖,则会导致所无的数据,所以要在SAP的开发中避免

1.    SAP导入多个凭证
不过讲到这里,我们也只是一个凭证,但是在我们实际的业务场景中,我们大部分都需要导入多个凭证,那么如果想要导入多个凭证,使用SAP的API如何来实现那?

既然可以使用BAPI_ACC_DOCUMENT_POST可以导入单个凭证,只要对它循环操作就可以实现多个凭证的导入了,大家看了下面的代码就会理解,红色的部分就是循环调用BAPI_ACC_DOCUMENT_POST就可以批量导入凭证

主要关于BAPI_ACC_DOCUMENT_POST的用法,懂ABAP的人都知道这是用于过账的,而BAPI_ACC_DOCUMENT_CHECK是用于做过账前的Check处理的。
我程序里明明设置好了参数,但是Debug测试时只看到Post Successfully的消息,却看不到我要的会计凭证号,当时很奇怪。百翻思考,网上查资料,后来问题终于得到解决。原来是因为我在 documentheader里多传进去了三个参数:OBJ_TYPE, OBJ_KEY,OBJ_SYS。如果删除这三个参数的话就能在返回的内部table里抓去我想要的凭证号码了。呵呵!问题搞定,当时真的很兴奋!

如果谁对BAPI_ACC_DOCUMENT_POST和BAPI_ACC_DOCUMENT_CHECK这两个BAPI不太熟悉的话,那麽在 SAP ECC6.0以上的版本上有一本系统程序ACC_BAPI_TEST_DOCUMENT,可供参考。里面有关于他们的用法以及参数设置

实例代码:
*         当前行过账-header信息设定
          PERFORM FRM_HEADER_DOCUMENT    USING LV_INDEX
                                      CHANGING LW_HEADER_DOCU.
*         当前行过账-明细信息设定
          PERFORM FRM_EDIT_BAPIITEMS    USING LV_INDEX
                                              LW_ALVDATA.
*         登录会计凭证
          PERFORM FRM_CALL_BAPI         USING LW_HEADER_DOCU.

*&---------------------------------------------------------------------*
*&      Form  FRM_HEADER_DOCUMENT
*&---------------------------------------------------------------------*
*       header信息设定
*----------------------------------------------------------------------*
*      -->P_IN_FLG          处理FLG
*      <--PW_OUT_HEADER     表头
*----------------------------------------------------------------------*
FORM FRM_HEADER_DOCUMENT     USING P_IN_FLG TYPE CHAR01
                          CHANGING PW_OUT_HEADER TYPE BAPIACHE09.
  DATA: LV_TEXT   TYPE BKTXT.

  CLEAR PW_OUT_HEADER.

* YYYY年MM月总额法坏账准备计提
  CONCATENATE P_YEMON+0(4) TEXT-005 P_YEMON+4(2) TEXT-006
         INTO LV_TEXT.

  PW_OUT_HEADER-USERNAME   = SY-UNAME.   "用户名
  PW_OUT_HEADER-HEADER_TXT = LV_TEXT.    "凭证抬头文本
  PW_OUT_HEADER-COMP_CODE  = P_BUKRS.    "公司代码
  PW_OUT_HEADER-DOC_DATE   = GV_EDATE.   "凭证中的凭证日期
  PW_OUT_HEADER-DOC_TYPE   = 'ZG'.       "凭证类型

* 处理FLG
  CASE P_IN_FLG.
*   当月的坏账会计凭证
    WHEN '1'.
      PW_OUT_HEADER-PSTNG_DATE = GV_EDATE.    "凭证过帐日期
      PW_OUT_HEADER-FISC_YEAR  = P_YEMON+0(4)."会计年度
      PW_OUT_HEADER-FIS_PERIOD = P_YEMON+4(2)."会计期间

*   下月的冲销会计凭证
    WHEN '2'.
*     下个会计期间的设定
      PERFORM FRM_GET_NEXTMONTH
                       CHANGING PW_OUT_HEADER-PSTNG_DATE "凭证过帐日期
                                PW_OUT_HEADER-FISC_YEAR  "会计年度
                                PW_OUT_HEADER-FIS_PERIOD."会计期间
    WHEN OTHERS.
  ENDCASE.

ENDFORM.                    " FRM_HEADER_DOCUMENT
*&---------------------------------------------------------------------*
*&      Form  FRM_EDIT_BAPIITEMS
*&---------------------------------------------------------------------*
*       当前行过账-明细信息设定
*----------------------------------------------------------------------*
*      -->P_IN_FLG             当月凭证与下一个月凭证标志
*      -->P_IN_ALVDATA         alv数据
*----------------------------------------------------------------------*
FORM FRM_EDIT_BAPIITEMS  USING P_IN_FLG      TYPE CHAR01
                               P_IN_ALVDATA  TYPE TYP_ALVDATA.

  REFRESH: GT_ACCOUNTGL,
           GT_CURRAMOUNT,
           GT_ACCOUNTAR,
           GT_EXTENSION2.

****第一个分录
*   各明细项目的作成
  PERFORM FRM_APPEND_ITEMS  USING P_IN_FLG
                                  '1'
                                  P_IN_ALVDATA.

****第二个分录
*   各明细项目的作成
  PERFORM FRM_APPEND_ITEMS  USING P_IN_FLG
                                  '2'
                                  P_IN_ALVDATA.

ENDFORM.                    " FRM_EDIT_BAPIITEMS
*&---------------------------------------------------------------------*
*&      Form  FRM_APPEND_ITEMS
*&---------------------------------------------------------------------*
*       各明细项目的作成
*----------------------------------------------------------------------*
*      -->P_IN_CLFLG    当月凭证标志与下一个月凭证标志
*      -->P_IN_INDEX    第一分录与第二分录标志
*      -->P_IN_DATA     alv数据
*----------------------------------------------------------------------*
FORM FRM_APPEND_ITEMS  USING    P_IN_CLFLG  TYPE CHAR01
                                P_IN_INDEX  TYPE CHAR01
                                P_IN_DATA   TYPE TYP_ALVDATA.

  DATA: LW_ACCOUNTGL  TYPE BAPIACGL09,
        LW_CURRAMOUNT TYPE BAPIACCR09,
        LW_ACCOUNTAR  TYPE BAPIACAR09,
        LW_EXTENSION2 TYPE BAPIPAREX,
        LW_ZEXTEN     TYPE ZEXTEN.

* 第一分录的时候
  IF P_IN_INDEX     = '1'.

*   会计凭证行项目编号
    LW_ACCOUNTGL-ITEMNO_ACC = 1.
*   利润中心
    LW_ACCOUNTGL-PROFIT_CTR = P_IN_DATA-PRCTR.
*   总账科目
    LW_ACCOUNTGL-GL_ACCOUNT = '0670100100'.

    APPEND LW_ACCOUNTGL TO GT_ACCOUNTGL.

  ELSEIF P_IN_INDEX = '2'.
*   会计凭证行项目编号
    LW_ACCOUNTAR-ITEMNO_ACC = 2.
*   客户编号
    LW_ACCOUNTAR-CUSTOMER   = P_IN_DATA-KUNNR.
*   到期日计算的基限日期
    LW_ACCOUNTAR-BLINE_DATE = GV_EDATE.
*   利润中心
    LW_ACCOUNTAR-PROFIT_CTR = P_IN_DATA-PRCTR.

    APPEND LW_ACCOUNTAR TO GT_ACCOUNTAR.
  ENDIF.

* 会计凭证行项目编号
  LW_CURRAMOUNT-ITEMNO_ACC = LINES( GT_CURRAMOUNT ) + 1.
* 货币码
  LW_CURRAMOUNT-CURRENCY   = P_IN_DATA-WAERS.
* 货币类型
  LW_CURRAMOUNT-CURR_TYPE  = '00'.

* 第一分录的时候
  IF P_IN_INDEX     = '1'.

    CASE P_IN_CLFLG.
*     当月的坏账会计凭证
      WHEN '1'.
*       凭证货币金额(正值) --- 40 ---
        LW_CURRAMOUNT-AMT_DOCCUR = ABS( P_IN_DATA-DMBTRP_SUM ).

*     下月的冲销会计凭证
      WHEN '2'.
*       凭证货币金额(负值) --- 50 ---
        LW_CURRAMOUNT-AMT_DOCCUR = ABS( P_IN_DATA-DMBTRP_SUM ) * -1.
      WHEN OTHERS.
    ENDCASE.

* 第二分录的时候
  ELSEIF P_IN_INDEX = '2'.

    CASE P_IN_CLFLG.
*     当月的坏账会计凭证 --- 19 ---
      WHEN '1'.
*       凭证货币金额(负值)
        LW_CURRAMOUNT-AMT_DOCCUR = ABS( P_IN_DATA-DMBTRP_SUM ) * -1.

*     下月的冲销会计凭证
      WHEN '2'.
*       凭证货币金额(负值) --- 09 ---
        LW_CURRAMOUNT-AMT_DOCCUR = ABS( P_IN_DATA-DMBTRP_SUM ).
      WHEN OTHERS.
    ENDCASE.

  ENDIF.

  APPEND LW_CURRAMOUNT TO GT_CURRAMOUNT.

  CLEAR LW_ZEXTEN.

* 第一分录的时候
  IF P_IN_INDEX     = '1'.

    CASE P_IN_CLFLG.
*     当月的坏账会计凭证
      WHEN '1'.
*       记帐代码
        LW_ZEXTEN-BSCHL  = '40'.

*     下月的冲销会计凭证
      WHEN '2'.
*       记帐代码
        LW_ZEXTEN-BSCHL  = '50'.
      WHEN OTHERS.
    ENDCASE.

* 第二分录的时候
  ELSEIF P_IN_INDEX = '2'.

    CASE P_IN_CLFLG.
*     当月的坏账会计凭证
      WHEN '1'.
*       记帐代码
        LW_ZEXTEN-BSCHL  = '19'.

*     下月的冲销会计凭证
      WHEN '2'.
*       记帐代码
        LW_ZEXTEN-BSCHL  = '09'.
      WHEN OTHERS.
    ENDCASE.
*   特殊总帐标识
    LW_ZEXTEN-UMSKZ      = 'H'.

  ENDIF.

* 会计凭证行项目编号
  LW_ZEXTEN-POSNR          = LINES( GT_EXTENSION2 ) + 1.
* 到期日
  LW_ZEXTEN-ZFBDT          = GV_EDATE.
* BAPI 表扩展的结构名称
  LW_EXTENSION2-STRUCTURE  = 'ZEXTEN'.
* BAPI 扩展参数的数据部分
  LW_EXTENSION2-VALUEPART1 = LW_ZEXTEN.
  APPEND LW_EXTENSION2 TO GT_EXTENSION2.

ENDFORM.                    " FRM_APPEND_ITEMS
*&---------------------------------------------------------------------*
*&      Form  FRM_CALL_BAPI
*&---------------------------------------------------------------------*
*       登录会计凭证
*----------------------------------------------------------------------*
*      -->P_IN_HEADER         header信息
*----------------------------------------------------------------------*
FORM FRM_CALL_BAPI  USING  P_IN_HEADER  TYPE BAPIACHE09.

  DATA: LW_RETURN  TYPE BAPIRET2,
        LT_RETURN  TYPE STANDARD TABLE OF BAPIRET2.


  CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
    EXPORTING
      DOCUMENTHEADER    = P_IN_HEADER
    TABLES
      ACCOUNTGL         = GT_ACCOUNTGL
      ACCOUNTRECEIVABLE = GT_ACCOUNTAR
      CURRENCYAMOUNT    = GT_CURRAMOUNT
      RETURN            = LT_RETURN
      EXTENSION2        = GT_EXTENSION2.

* S 成功,E 错误,W 警告,I 信息,A 中断
  LOOP AT LT_RETURN INTO LW_RETURN WHERE TYPE = 'E'
                                      OR TYPE = 'A'.
    CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.

    MESSAGE ID LW_RETURN-ID TYPE 'E' NUMBER LW_RETURN-NUMBER
                                       WITH LW_RETURN-MESSAGE_V1
                                            LW_RETURN-MESSAGE_V2
                                            LW_RETURN-MESSAGE_V3
                                            LW_RETURN-MESSAGE_V4.

  ENDLOOP.

* 创建成功
  IF SY-SUBRC <> 0.
    CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
      EXPORTING
        WAIT = 'X'.

*   凭证过账运行结束!
    MESSAGE S067(ZFI01).

  ENDIF.

ENDFORM.                    " FRM_CALL_BAPI

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值