以下为正文
在使用BAPI:BAPI_ACC_DOCUMENT_POST进行资产过账的时候遇到了一些问题,过账的需求如下:
遇到的问题主要有三个:
第一个问题:如上图中的行项目,第一行是固定的科目编码,第二行是根据内表中的不同资产号进行填充科目编码,在手工过账的时候,输入第一个行项目之后回车会自动带出一个统驭科目编号,然后输入第二个行项目就可以过账了,但是在BAPI中不能自动带出统驭科目;
第二个问题:对于资产过账,一定要有资产号和负资产号,否则过账的时候会报告“资产不属于公司xxxx的错误”。
第三个问题:当前两个问题解决了之后,成功过账,发现过账的凭证号不能冲销,对比手工和自己程序产生的凭证号,看起来的不同点,如下图所示:
但是这个只是表面上的不同,因为我到BSEG表中修改了对应的金额字段之后还是不能成功冲销,根本原因是因为货币。
只对以上载开发中遇到的问题,自己找到了一个解决方式,可能不是最好的,如果有大神有更好的方法,还望提醒。
说明: F-02对应的bapi是BAPI_ACC_DOCUMENT_POST,这个是最常用的产生凭证的bapi,但是在SAP系统中还有资产报废过账的标准事务代码和对应的bapi(BAPI_ASSET_RETIREMENT_POST),本文实现的是用F-02对应的BAPI进行资产过账。
注:在过账的时候一定要保证所有行项目的金额之和为0,手工过账的时候金额都是写的负数,但是BAPI中要写清楚是正还是负。
下面是实现步骤:
第一步:对于过账中的记账码,付款原因代码和事务类型等需要进行增强,增强的方式网上有不少,这里还是说明一下。
1.SE11创建一个结构,示例如图:
其中项目编号必须有,下面的字段根据自己的需要添加。
2.SE19实现BADI增强
ACC_DOCUMENT 这个增强是用来将BAPI_ACC_DOCUMENT_POST参数表EXTENSION2传入系统表,如果没有增强点,则新建一个增强点:
需要注意的是要参考业务类型,这个一定要选对,不然执行BAPI的时候不会调用这个BADI,常用的是BKPFF,BKPF,如图:
创建完成之后,找到change方法,这个方法用来完成字段的扩展,双击进入(可以查看ACC_DOCUMENT 的实现例子CL_EXM_IM_ACC_DOCUMENT 参考学习change方法的实现)我这里添加如下代码:
METHOD IF_EX_ACC_DOCUMENT~CHANGE. DATA: WA_EXTENSION TYPE BAPIPAREX, EXT_VALUE(960) TYPE C, WA_ACCIT TYPE ACCIT, L_REF TYPE REF TO DATA. DATA: WA_ZEXTEN TYPE ZEXTEN. FIELD-SYMBOLS: <ACCIT> TYPE ACCIT. FIELD-SYMBOLS: <L_STRUC> TYPE ANY, <L_FIELD> TYPE ANY. SORT C_EXTENSION2 BY STRUCTURE. LOOP AT C_EXTENSION2 INTO WA_EXTENSION WHERE STRUCTURE = 'ZEXTEN'. "对应于SE11创建的结构 WA_ZEXTEN = WA_EXTENSION-VALUEPART1. READ TABLE C_ACCIT ASSIGNING <ACCIT> WITH KEY POSNR = WA_ZEXTEN-ITEMNO_ACC. IF SY-SUBRC = 0. <ACCIT>-RSTGR = WA_ZEXTEN-RSTGR. <ACCIT>-BSCHL = WA_ZEXTEN-BSCHL. <ACCIT>-UMSKZ = WA_ZEXTEN-UMSKZ. <ACCIT>-ANBWA = WA_ZEXTEN-ANBWA. <ACCIT>-XNEGP = WA_ZEXTEN-XNEGP. ENDIF. ENDLOOP. ENDMETHOD.
第二步:实现资产过账,这里直接给出演示代码:
FORM FRM_BAPI_DO_ACCDOCMENT CHANGING P_WS_COS LIKE WA_SHOW_COS. DATA: GD_DOCUMENTHEADER LIKE BAPIACHE09, LT_ACCOUNTGL LIKE TABLE OF BAPIACGL09 WITH HEADER LINE, LT_CURRENCYAMOUNT LIKE TABLE OF BAPIACCR09 WITH HEADER LINE, LT_RETURN LIKE TABLE OF BAPIRET2 WITH HEADER LINE. DATA: LW_EXTENSION TYPE BAPIEXTC, LT_EXTENSION TYPE STANDARD TABLE OF BAPIPAREX WITH HEADER LINE. DATA: E_MONAT LIKE BKPF-MONAT, E_GJAHR LIKE BKPF-GJAHR. DATA: LD_GL_ACOUNT TYPE STRING. DATA: L_HEADTEXT TYPE STRING. "抬头文本 DATA: LD_ITEM TYPE I, LD_ITEM_TEMP TYPE I. DATA: E_SAKNR LIKE BSEG-SAKNR. DATA: LW_ZFIDOCEXT TYPE ZEXTEN."ZFIDOCEXT. DATA: GL_MESSAGE TYPE STRING. REFRESH : LT_ACCOUNTGL[],LT_CURRENCYAMOUNT[],LT_EXTENSION[]. REFRESH : LT_RETURN[]. CLEAR : GD_DOCUMENTHEADER,LW_ZFIDOCEXT. LD_ITEM = 1. E_GJAHR = SY-DATUM+0(4). E_MONAT = SY-DATUM+4(2). L_HEADTEXT = '模具财务报废凭证'. GD_DOCUMENTHEADER-USERNAME = SY-UNAME. "录入用户(必输) GD_DOCUMENTHEADER-COMP_CODE = P_BUKRS. "公司代码(必输) GD_DOCUMENTHEADER-DOC_DATE = SY-DATUM. "凭证日期(必输) GD_DOCUMENTHEADER-PSTNG_DATE = P_WS_COS-ZCWBFD. "过账日期(必输) GD_DOCUMENTHEADER-FIS_PERIOD = E_MONAT. "过账期间(必输) GD_DOCUMENTHEADER-DOC_TYPE = 'SA'. "凭证类型(必输) GD_DOCUMENTHEADER-FISC_YEAR = E_GJAHR. "会计年度 * GD_DOCUMENTHEADER-BUS_ACT = 'RMWE'. "业务事务 * GD_DOCUMENTHEADER-OBJ_TYPE = 'BKPFF'. "参考交易 CONCATENATE '模具报废' SY-DATUM INTO LD_GL_ACOUNT. LT_ACCOUNTGL-ITEMNO_ACC = LD_ITEM. "会计凭证行项目编号 LT_ACCOUNTGL-GL_ACCOUNT = '6602010100'. "总分类帐帐目 LT_ACCOUNTGL-COSTCENTER = P_WS_COS-KOSTL. "成本中心 * LT_ACCOUNTGL-BUS_AREA = P_WS_COS-GSBER. "业务范围 LT_ACCOUNTGL-ITEM_TEXT = LD_GL_ACOUNT. "项目文本 LT_ACCOUNTGL-ALLOC_NMBR = LD_GL_ACOUNT. "分配 APPEND LT_ACCOUNTGL. CLEAR LT_ACCOUNTGL. "添加金额 LT_CURRENCYAMOUNT-ITEMNO_ACC = LD_ITEM. LT_CURRENCYAMOUNT-AMT_DOCCUR = P_WS_COS-ZMOJZ. "凭证货币金额 LT_CURRENCYAMOUNT-CURR_TYPE = '10'. LT_CURRENCYAMOUNT-CURRENCY = 'CNY'. APPEND LT_CURRENCYAMOUNT. CLEAR LT_CURRENCYAMOUNT. "添加金额(**重复添加金额就是解决不能冲销的问题**) LT_CURRENCYAMOUNT-ITEMNO_ACC = LD_ITEM. LT_CURRENCYAMOUNT-AMT_DOCCUR = P_WS_COS-ZMOJZ. "凭证货币金额 LT_CURRENCYAMOUNT-CURR_TYPE = '00'. LT_CURRENCYAMOUNT-CURRENCY = 'CNY'. APPEND LT_CURRENCYAMOUNT. CLEAR LT_CURRENCYAMOUNT. "添加记账码 LW_ZFIDOCEXT-ITEMNO_ACC = LD_ITEM. "Item No LW_ZFIDOCEXT-BSCHL = '40'. "记帐码 *是否创建预制凭证,否则凭证直接过账 LT_EXTENSION-STRUCTURE = 'ZEXTEN'. LT_EXTENSION-VALUEPART1 = LW_ZFIDOCEXT. APPEND LT_EXTENSION. CLEAR : LT_EXTENSION,LW_ZFIDOCEXT. "记账码75 LD_ITEM = LD_ITEM + 1. LT_ACCOUNTGL-ITEMNO_ACC = LD_ITEM. LT_ACCOUNTGL-ASSET_NO = P_WS_COS-ANLN1. "主资产号 LT_ACCOUNTGL-ACCT_TYPE = 'A'. "科目类型 LT_ACCOUNTGL-SUB_NUMBER = P_WS_COS-ANLN2. "次资产号 LT_ACCOUNTGL-COSTCENTER = P_WS_COS-KOSTL. "成本中心 LT_ACCOUNTGL-ALLOC_NMBR = LD_GL_ACOUNT. "分配 LT_ACCOUNTGL-ITEM_TEXT = LD_GL_ACOUNT. "文本 * LT_ACCOUNTGL-COMP_CODE = P_BUKRS. APPEND LT_ACCOUNTGL. CLEAR LT_ACCOUNTGL. "添加金额 LT_CURRENCYAMOUNT-ITEMNO_ACC = LD_ITEM. LT_CURRENCYAMOUNT-AMT_DOCCUR = P_WS_COS-ZMOJZ * ( -1 ). "凭证货币金额 LT_CURRENCYAMOUNT-CURR_TYPE = '10'. LT_CURRENCYAMOUNT-CURRENCY = 'CNY'. APPEND LT_CURRENCYAMOUNT. CLEAR LT_CURRENCYAMOUNT. "添加金额 LT_CURRENCYAMOUNT-ITEMNO_ACC = LD_ITEM. LT_CURRENCYAMOUNT-AMT_DOCCUR = P_WS_COS-ZMOJZ * ( -1 ). "凭证货币金额 LT_CURRENCYAMOUNT-CURR_TYPE = '00'. LT_CURRENCYAMOUNT-CURRENCY = 'CNY'. APPEND LT_CURRENCYAMOUNT. CLEAR LT_CURRENCYAMOUNT. "记账码 LW_ZFIDOCEXT-ITEMNO_ACC = LD_ITEM. "Item No LW_ZFIDOCEXT-BSCHL = '75'. "记帐码 LW_ZFIDOCEXT-ANBWA = '100'. *是否创建预制凭证,否则凭证直接过账 LT_EXTENSION-STRUCTURE = 'ZEXTEN'. LT_EXTENSION-VALUEPART1 = LW_ZFIDOCEXT. APPEND LT_EXTENSION. CLEAR : LT_EXTENSION,LW_ZFIDOCEXT. CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST' EXPORTING DOCUMENTHEADER = GD_DOCUMENTHEADER TABLES ACCOUNTGL = LT_ACCOUNTGL CURRENCYAMOUNT = LT_CURRENCYAMOUNT RETURN = LT_RETURN EXTENSION2 = LT_EXTENSION. READ TABLE LT_RETURN WITH KEY TYPE = 'E'. * BREAK-POINT. IF SY-SUBRC <> 0. CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' EXPORTING WAIT = 'X' IMPORTING RETURN = LT_RETURN. READ TABLE LT_RETURN INDEX 1. IF SY-SUBRC = 0. "报废凭证 P_WS_COS-ZCWBFI = LT_RETURN-MESSAGE_V2+0(10). "清空冲销凭证 CLEAR : P_WS_COS-ZCXBFI,P_WS_COS-ZCXBFD. ENDIF. ELSE. CLEAR GL_MESSAGE. LOOP AT LT_RETURN WHERE TYPE = 'E'. IF SY-TABIX = 1. CONTINUE. ENDIF. CONCATENATE GL_MESSAGE '|' LT_RETURN-MESSAGE INTO GL_MESSAGE. ENDLOOP. CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK' IMPORTING RETURN = LT_RETURN. MESSAGE E001(Z001) WITH GL_MESSAGE. ENDIF. ENDFORM. " FRM_BAPI_DO_ACCDOCMENT
可以发现代码中重复添加了金额,对应的“CURR_TYPE”分别是“00”和“10”,这样产生的凭证号就可以和手工产生的一样正常冲销成功了。
至于冲销就使用BDC,很简单就可以冲销了,这里就不多介绍了。