前言部分
大家可以關注我的公眾號,公眾號里的排版更好,閱讀更舒適。
正文部分
在使用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,很簡單就可以沖銷了,這里就不多介紹了。