记录下项目过程中用到BAPI_ACC_DOCUMENT_POST时的问题
1.凭证货币与本币 不一致时,在curr_type 里区分本币金额和凭证金额(汇率会自己换算)
如果不区分本币和凭证货币,在处理外币时 报错消息如下:
Inconsistent currency information(货币信息不一致)
2.记账码是供应商类型时,供应商的前导0需要添加处理,报错消息如下:
Vendor 970773 is not defined in company code 1000(公司代码1000中未定义供应商970773)
3.部分字段在标准bapi结构中没有找到,需要增强里去处理,然后传入的结构中增加。
增强:
参考:link
4.传入的客户,填在accountgl里,需要区分清楚供应商和客户(前台过的去,BAPI过不去,搞半天原来是客户,前台双击对应的供应商/客户,跳转后显示供应商/客户)
5.有些字段前台有,在BAPI字段里找,却没有(例如:付款参考,在供应商的字段里有,但是在总账里却没有),这种情况需要在extension2里传进去就OK了
接口的代码如下。
CLASS zfi_feikong_item DEFINITION FINAL.
PUBLIC SECTION.
DATA:gl_account TYPE hkont, "总分类帐帐目
costcenter TYPE kostl, "成本中心
item_text TYPE sgtxt, "项目文本
alloc_nmbr TYPE acpi_zuonr, "分配号
tr_part_ba TYPE pargb, "贸易伙伴的业务范围
amt_doccur TYPE bapidoccur, "本币金额
wrbtr TYPE wrbtr, "凭证金额
currency TYPE waers, "货币码
rstgr TYPE rstgr, "付款原因代码
bschl TYPE bschl, "记帐代码
umskz TYPE umskz, "特别总账标识
quantity TYPE menge_d, "数量
base_uom TYPE meins, "基本计量单位
tax_code TYPE mwskz, "销售/购买税代码
material TYPE matnr, "物料编号
zterm TYPE dzterm, "付款条件代码
zfbdt TYPE dzfbdt, "到期日期计算的起算日期
zbd1t TYPE dzbd1t, "现金折扣天数 1
zbd2t TYPE dzbd2t, "现金折扣天数 2
skfbt TYPE acfbt, "以货币类型中的货币计的现金折扣金额合法化
rmvct TYPE rmvct, "事务类型
vendor_no TYPE lifnr. "供应商或债权人的帐号
ENDCLASS.
CLASS zfi_feikong_req DEFINITION FINAL.
PUBLIC SECTION.
DATA:username TYPE usnam, "录入用户(必输)
comp_code TYPE bukrs, "公司代码(必输)
doc_date TYPE bldat, "凭证日期(必输)
pstng_date TYPE budat, "过账日期(必输)
doc_type TYPE blart, "凭证类型(必输)
header_txt TYPE bktxt, "凭证抬头文本
ppnam TYPE usnam, "预制人
lt_item TYPE STANDARD TABLE OF REF TO zfi_feikong_item.
ENDCLASS.
CLASS zfi_feikong_cl DEFINITION FINAL.
PUBLIC SECTION.
DATA: interfaceid TYPE string.
DATA: reqdata TYPE REF TO zfi_feikong_req.
ENDCLASS.
FUNCTION zfi_feikong.
*"----------------------------------------------------------------------
*"*"本地接口:
*" IMPORTING
*" VALUE(INJSON) TYPE STRING
*" EXPORTING
*" VALUE(O_CODE) TYPE CHAR1
*" VALUE(O_DESC) TYPE CHAR100
*" VALUE(OUTJSON) TYPE STRING
*"----------------------------------------------------------------------
DATA tp_input TYPE REF TO zfi_feikong_cl.
DATA: gd_documentheader LIKE bapiache09,
lt_accountgl LIKE TABLE OF bapiacgl09
WITH HEADER LINE,
lt_accountpayable LIKE TABLE OF bapiacap09
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: ls_zcos0002 LIKE zcos0002.
DATA: e_monat LIKE bkpf-monat,
e_gjahr LIKE bkpf-gjahr.
DATA: ld_item TYPE i .
DATA lv_belnr TYPE belnr_d.
* 传入参数转换判断
IF injson IS INITIAL.
o_code = 'E'.
o_desc = 'Query ParamData is Required!'.
ELSE.
/ui2/cl_json=>deserialize( EXPORTING json = injson pretty_name = /ui2/cl_json=>pretty_mode-camel_case CHANGING data = tp_input ).
IF tp_input IS NOT INITIAL.
ASSIGN tp_input->reqdata TO FIELD-SYMBOL(<fs_head>).
REFRESH : lt_accountgl[],lt_currencyamount[],lt_extension[].
REFRESH : lt_return[].
CLEAR : gd_documentheader.
e_gjahr = <fs_head>->pstng_date+0(4).
e_monat = <fs_head>->pstng_date+4(2).
gd_documentheader-username = <fs_head>->username. "录入用户(必输)
gd_documentheader-comp_code = <fs_head>->comp_code. "公司代码(必输)
gd_documentheader-doc_date = <fs_head>->doc_date. "凭证日期(必输)
gd_documentheader-pstng_date = <fs_head>->pstng_date. "过账日期(必输)
gd_documentheader-doc_type = <fs_head>->doc_type. "凭证类型(必输)
gd_documentheader-fis_period = e_monat. "过账期间(必输)
gd_documentheader-fisc_year = e_gjahr. "会计年度
gd_documentheader-header_txt = <fs_head>->header_txt. "凭证抬头文本
* GD_DOCUMENTHEADER-BUS_ACT = 'RMWE'. "业务事务
* GD_DOCUMENTHEADER-OBJ_TYPE = 'BKPFF'. "参考交易
LOOP AT <fs_head>->lt_item INTO DATA(ls_item).
ADD 1 TO ld_item.
IF ls_item->gl_account IS NOT INITIAL.
lt_accountgl-itemno_acc = ld_item. "会计凭证行项目编号
lt_accountgl-gl_account = ls_item->gl_account. "总分类帐帐目
"lt_accountgl-VENDOR_NO = ls_item->gl_account. "总分类帐帐目
"lt_accountgl-costcenter = ls_item->costcenter. "成本中心
* LT_ACCOUNTGL-BUS_AREA = P_WS_COS-GSBER. "业务范围
lt_accountgl-item_text = ls_item->item_text. "项目文本
lt_accountgl-alloc_nmbr = ls_item->alloc_nmbr. "分配
lt_accountgl-tr_part_ba = ls_item->tr_part_ba. "贸易伙伴的业务范围
lt_accountgl-quantity = ls_item->quantity. "数量
lt_accountgl-base_uom = ls_item->base_uom. "基本计量单位
lt_accountgl-tax_code = ls_item->tax_code. "销售/购买税代码
lt_accountgl-material = ls_item->material. "物料编号
lt_accountgl-customer = |{ ls_item->customer ALPHA = IN }|. "客户编号
APPEND lt_accountgl.
CLEAR lt_accountgl.
ENDIF.
IF ls_item->vendor_no IS NOT INITIAL.
lt_accountpayable-itemno_acc = ld_item.
lt_accountpayable-vendor_no = |{ ls_item->vendor_no ALPHA = IN }|..
lt_accountpayable-comp_code = <fs_head>->comp_code.
APPEND lt_accountpayable.
CLEAR lt_accountpayable.
ENDIF.
"添加金额
lt_currencyamount-itemno_acc = ld_item.
lt_currencyamount-amt_doccur = ls_item->amt_doccur. "本币金额
lt_currencyamount-curr_type = '10'.
lt_currencyamount-currency = 'CNY'."ls_item->currency.
APPEND lt_currencyamount.
CLEAR lt_currencyamount.
"添加金额(**重复添加金额就是解决不能冲销的问题**)
lt_currencyamount-itemno_acc = ld_item.
lt_currencyamount-amt_doccur = ls_item->wrbtr."amt_doccur. "凭证货币金额
lt_currencyamount-curr_type = '00'.
lt_currencyamount-currency = ls_item->currency.
APPEND lt_currencyamount.
CLEAR lt_currencyamount.
"添加记账码
ls_zcos0002-posnr = ld_item. "Item No
ls_zcos0002-bschl = ls_item->bschl. "记帐码
ls_zcos0002-umskz = ls_item->umskz. "特别总账标识
ls_zcos0002-rstgr = ls_item->rstgr. "付款原因代码
ls_zcos0002-zterm = ls_item->zterm. "付款条件代码
ls_zcos0002-zfbdt = ls_item->zfbdt. "到期日期计算的起算日期
ls_zcos0002-zbd1t = ls_item->zbd1t. "现金折扣天数1
ls_zcos0002-zbd2t = ls_item->zbd2t. "现金折扣天数2
ls_zcos0002-skfbt = ls_item->skfbt. "以货币类型中的货币计的现金折扣金额合法化
ls_zcos0002-rmvct = ls_item->rmvct. "事务类型
*是否创建预制凭证,否则凭证直接过账
lt_extension-structure = 'ZCOS0002'.
lt_extension-valuepart1 = ls_zcos0002.
APPEND lt_extension.
CLEAR : lt_extension,ls_zcos0002.
ENDLOOP.
ENDIF.
CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
EXPORTING
documentheader = gd_documentheader
TABLES
accountgl = lt_accountgl
accountpayable = lt_accountpayable
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'.
o_code = 'S'.
o_desc = 'Acc_Document Create Success!'.
READ TABLE lt_return INTO DATA(ls_return) INDEX 1.
lv_belnr = ls_return-message_v2+(10).
SELECT SINGLE belnr INTO @DATA(lv_c_belnr)
FROM bkpf
WHERE belnr = @lv_belnr
AND gjahr = @e_gjahr.
IF sy-subrc EQ 0.
IF <fs_head> IS ASSIGNED.
UPDATE bkpf SET ppnam = <fs_head>->ppnam WHERE belnr = lv_c_belnr AND gjahr = e_gjahr.
COMMIT WORK.
ENDIF.
ENDIF.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
o_code = 'E'.
o_desc = 'Acc_Document Create Failed!'.
ENDIF.
ENDIF.
* 返回结果数据JSON封装
outjson = /ui2/cl_json=>serialize( data = lt_return[] pretty_name = /ui2/cl_json=>pretty_mode-none numc_as_string = abap_true ).
outjson = '{"RETURNCODE":"' && o_code && '", "MESSAGE":"' && o_desc && '", "DATA":' && outjson && '}'.
ENDFUNCTION.
补充一点,一次性客户、一次性供应商BSEC表
内容填在抬头的customercpd里
如下:
IF ls_item->bschl = '25' or ls_item->bschl = '31'.
ls_customercpd-name = ls_item->name1.
ls_customercpd-city = ls_item->ort01.
ls_customercpd-country = 'CN'.
ls_customercpd-street = ls_item->name1.
ls_customercpd-postl_code = '528200'.
ls_customercpd-title = ls_item->anred.
ENDIF.
CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
EXPORTING
documentheader = gd_documentheader
customercpd = ls_customercpd
TABLES
accountgl = lt_accountgl
accountreceivable = lt_accountreceivable
accountpayable = lt_accountpayable
currencyamount = lt_currencyamount
return = lt_return
extension2 = lt_extension.
效果如下:
供应商
客户
上面的BAPI执行W类型的过账时会报F5 246的错误。link
此时,无法使用BAPI_ACC_DOCUMENT_POST创建凭证,
在上面的链接里已经给出解决办法
跟BDC一样,如果找不到字段,直接SHDB执行之后,把对应的字段复制过来就OK
DATA: ls_ftpost TYPE ftpost,
lt_ftpost TYPE TABLE OF ftpost,
lt_fttax TYPE TABLE OF fttax,
lt_blntab TYPE TABLE OF blntab,
lv_subrc TYPE sy-subrc,
lv_msg TYPE bapiret2.
DEFINE macro.
ls_ftpost-fnam = &1.
ls_ftpost-fval = &2.
APPEND ls_ftpost TO lt_ftpost.
END-OF-DEFINITION.
CALL FUNCTION 'POSTING_INTERFACE_START'
EXPORTING
* I_CLIENT = SY-MANDT
i_function = 'C'
i_group = 'ZTESTFIBDC'
* I_HOLDDATE = ' '
i_keep = 'X'
* I_MODE = 'N'
* I_UPDATE = 'S'
i_user = sy-uname
* I_XBDCC = ' '
EXCEPTIONS
client_incorrect = 1
function_invalid = 2
group_name_missing = 3
mode_invalid = 4
update_invalid = 5
user_invalid = 6
OTHERS = 7.
IF sy-subrc <> 0.
* Implement suitable error handling here
ENDIF.
"header:
ls_ftpost-stype = 'K'. "Header indicator
ls_ftpost-count = '001'. "First item
macro: 'BKPF-BLDAT' '20230801',
'BKPF-BLART' 'SA',
'BKPF-BUKRS' '1000',
'BKPF-BUDAT' '20230801'.
*"items:
ls_ftpost-stype = 'P'.
ls_ftpost-count = '001'.
macro: 'RF05A-NEWBS' '19',
'RF05A-NEWKO' '102361',
'RF05A-NEWUM' 'W',
'BSEG-ZFBDT' '20230904',
'BSEG-WRBTR' '100'.
"macro: 'RF05A-NEWBS' '40',
" 'COBL-PARGB' '0099',
" 'BSEG-RSTGR' 'A10',
" 'BSEG-ZUONR' '20230904',
" 'BSEG-HKONT' '1009010101',
" 'BSEG-WRBTR' '100'.
ls_ftpost-stype = 'P'.
ls_ftpost-count = '002'.
macro: 'RF05A-NEWBS' '25',
'RF05A-NEWKO' '6',
'BSEC-ANRED' '标题',
'BSEC-NAME1' '名称',
'BSEC-ORT01' '城市',
'BSEC-LAND1' 'CN',
'BSEG-WRBTR' '100'.
"macro: 'RF05A-NEWBS' '50',
" 'COBL-GSBER' '0099',
" 'COBL-KOSTL' '1700902',
" 'BSEG-ZUONR' '20230904',
" 'BSEG-WRBTR' '100',
" 'BSEG-HKONT' '6609000101'.
BREAK-POINT.
*
CALL FUNCTION 'POSTING_INTERFACE_DOCUMENT'
EXPORTING
i_tcode = 'FB01' "Name of t-code for Posting
i_sgfunct = 'C' "Batch input session
IMPORTING
e_subrc = lv_subrc
e_msgid = lv_msg-id "Error handling
e_msgty = lv_msg-type "Error handling
e_msgno = lv_msg-number "Error handling
e_msgv1 = lv_msg-message_v1 "Error handling
e_msgv2 = lv_msg-message_v2 "Error handling
e_msgv3 = lv_msg-message_v3 "Error handling
e_msgv4 = lv_msg-message_v4 "Error handling
TABLES
t_ftpost = lt_ftpost "Internal table populated in Step 2
t_fttax = lt_fttax "Relevant for Tax calculation manually
t_blntab = lt_blntab "Relevant only for Call Trans…
EXCEPTIONS
OTHERS = 1.
CALL FUNCTION 'POSTING_INTERFACE_END'.
LOOP AT lt_blntab INTO DATA(ls_blntab).
WRITE: ls_blntab-belnr,
ls_blntab-gjahr.
ENDLOOP.
SAP链接link
使用内部过账接口
此主题仅针对已在 SAP 系统中生成自己的报表或程序,并且之前一直使用批输入更新数据库数据的应用程序程序员及顾问。
用途
可通过财务会计中的内部过账接口,使用批输入或调用事务来生成过账。
特征
使用此接口时不再需要输入程序名称或屏幕编号。上述两项内容均由接口根据过账数据来确定。这一功能的优势在于即使数据结构发生更改,您也不需要修改程序。
过账接口旨在简化批输入流程。仅在标准功能无法满足需要等例外情况下才使用此接口。
可以通过下列功能模块使用此接口:
|功能模块 | 事务 |
|POSTING_INTERFACE_START-- | |
| POSTING_INTERFACE_DOCUMENT | FB01、FBS1、FB41、ABF1、FBB1、FBVB、FBV1、FBD5 |
| POSTING_INTERFACE_CLEARING | FB05|
| POSTING_INTERFACE_END | |
| POSTING_INTERFACE_RESET_CLEAR | FBRA |
| POSTING_INTERFACE_REVERSE_DOC | FB08|
各功能模块在线记录在 SAP 系统中。