财务凭证¶
过账¶
BAPI_ACC_DOCUMENT_CHECK,测试创建财务凭证
BAPI_ACC_DOCUMENT_POST,创建财务凭证
示例代码
*&---------------------------------------------------------------------*
*& Form frm_post
*&---------------------------------------------------------------------*
*& 创建财务凭证
*&---------------------------------------------------------------------*
FORM frm_post USING i_test TYPE xfeld.
DATA l_mtype TYPE bapi_mtype.
DATA l_msg TYPE bapi_msg.
*&---------------------------------------------------------------------*
*& 记账码配置
*&---------------------------------------------------------------------*
SELECT
bschl,
shkzg,
koart,
stbsl,
xsonu
FROM tbsl
INTO TABLE @DATA(lt_bschl).
SORT lt_bschl BY bschl.
*&---------------------------------------------------------------------*
*& BAPI数据声明
*&---------------------------------------------------------------------*
DATA: ls_documentheader TYPE bapiache09, "Header
lt_accountgl TYPE STANDARD TABLE OF bapiacgl09,
ls_accountgl TYPE bapiacgl09, "G/L account item
lt_accountreceivable TYPE STANDARD TABLE OF bapiacar09,
ls_accountreceivable TYPE bapiacar09, "Customer Item
lt_accountpayable TYPE STANDARD TABLE OF bapiacap09,
ls_accountpayable TYPE bapiacap09, "Vendor Item
lt_currencyamount TYPE STANDARD TABLE OF bapiaccr09,
ls_currencyamount TYPE bapiaccr09, "Currency Items
lt_criteria TYPE STANDARD TABLE OF bapiackec9,
ls_criteria TYPE bapiackec9, " CO-PA
lt_extension2 TYPE STANDARD TABLE OF bapiparex,
ls_extension2 TYPE bapiparex, "Reference Structure for BAPI Parameters EXTENSIONIN/EXTENSIONOUT
lt_return TYPE STANDARD TABLE OF bapiret2,
ls_return TYPE bapiret2, "Return parameter
l_obj_key TYPE bapiache09-obj_key.
LOOP AT gt_data INTO DATA(ls_data)
WHERE zsel = 'X' " 取勾选项进行处理
AND mtype <> 'E' " 校验无误的
AND belnr = '' " 还没创建的
GROUP BY (
bldat = ls_data-bldat
budat = ls_data-budat
blart = ls_data-blart
bukrs = ls_data-bukrs
monat = ls_data-monat
waers = ls_data-waers
xblnr = ls_data-xblnr
bktxt = ls_data-bktxt
) INTO DATA(ls_data_grp).
CLEAR: ls_documentheader ,
lt_accountgl ,
ls_accountgl ,
lt_accountreceivable,
ls_accountreceivable,
lt_accountpayable ,
ls_accountpayable ,
lt_currencyamount ,
ls_currencyamount ,
lt_criteria ,
ls_criteria ,
lt_extension2 ,
ls_extension2 ,
lt_return ,
ls_return ,
l_obj_key .
" 任取一行作为抬头
LOOP AT GROUP ls_data_grp INTO DATA(ls_head). EXIT. ENDLOOP.
CLEAR ls_documentheader.
ls_documentheader-comp_code = ls_head-bukrs. " 公司代码
ls_documentheader-header_txt = ls_head-bktxt. " 凭证抬头文本
ls_documentheader-doc_date = ls_head-bldat. " 凭证日期
ls_documentheader-pstng_date = ls_head-budat. " 过账日期
ls_documentheader-doc_type = ls_head-blart. " 凭证类型
ls_documentheader-username = sy-uname. " 用户名
ls_documentheader-bus_act = 'RFBU'. " 业务事务
ls_documentheader-obj_type = 'BKPFF'. " 参考交易
ls_documentheader-fis_period = ls_head-monat. " 会计期间
ls_documentheader-fisc_year = ls_head-budat+0(4). " 会计年度
ls_documentheader-ref_doc_no = ls_head-xblnr. " 参考凭证
" 任取一行作为抬头
DATA l_itemno_acc TYPE posnr_acc.
DATA l_gl_acount TYPE hkont.
CLEAR l_itemno_acc.
LOOP AT GROUP ls_data_grp INTO ls_data.
l_itemno_acc = l_itemno_acc + 1.
READ TABLE lt_bschl INTO DATA(ls_bschl) WITH KEY bschl = ls_data-bschl BINARY SEARCH.
CASE ls_bschl-koart.
WHEN 'D'. " 客户
" 总帐科目
CLEAR l_gl_acount.
IF ls_data-hkont IS NOT INITIAL.
l_gl_acount = ls_data-hkont.
ELSE.
SELECT SINGLE akont FROM knb1
WHERE kunnr = @ls_data-kunnr
AND bukrs = @ls_data-bukrs
INTO @l_gl_acount.
" 特别总账
IF ls_data-umskz IS NOT INITIAL.
SELECT SINGLE skont FROM t074
WHERE ktopl = @l_ktopl
AND koart = @ls_bschl-koart
AND umskz = @ls_data-umskz
AND hkont = @l_gl_acount
INTO @l_gl_acount.
ENDIF.
ENDIF.
ls_accountreceivable-itemno_acc = l_itemno_acc . " 会计凭证行项目编号
ls_accountreceivable-gl_account = l_gl_acount. " 总账科目
ls_accountreceivable-customer = ls_data-kunnr. " 客户号
ls_accountreceivable-sp_gl_ind = ls_data-umskz. " 特殊总账标识
ls_accountreceivable-tax_code = ls_data-mwskz. " 税码
ls_accountreceivable-item_text = ls_data-sgtxt. " 项目文本
ls_accountreceivable-alloc_nmbr = ls_data-zuonr. " 分配
ls_accountreceivable-profit_ctr = ls_data-prctr. " 利润中心
ls_accountreceivable-pmnttrms = ls_data-zterm. " 付款条件
ls_accountreceivable-bline_date = ls_data-zfbdt. " 付款起算日期
ls_accountreceivable-bus_area = ls_data-gsber. " 业务范围
INSERT ls_accountreceivable INTO TABLE lt_accountreceivable.
WHEN 'K'. " 供应商
" 总帐科目
CLEAR l_gl_acount.
IF ls_data-hkont IS NOT INITIAL.
l_gl_acount = ls_data-hkont.
ELSE.
SELECT SINGLE akont FROM lfb1
WHERE lifnr = @ls_data-lifnr
AND bukrs = @ls_data-bukrs
INTO @l_gl_acount.
" 特别总账
IF ls_data-umskz IS NOT INITIAL.
SELECT SINGLE skont FROM t074
WHERE ktopl = @l_ktopl
AND koart = @ls_bschl-koart
AND umskz = @ls_data-umskz
AND hkont = @l_gl_acount
INTO @l_gl_acount.
ENDIF.
ENDIF.
ls_accountpayable-itemno_acc = l_itemno_acc. " 会计凭证行项目编号
ls_accountpayable-gl_account = l_gl_acount. " 总账科目
ls_accountpayable-item_text = ls_data-sgtxt. " 项目文本
ls_accountpayable-vendor_no = ls_data-lifnr. " 供应商编号
ls_accountpayable-sp_gl_ind = ls_data-umskz. " 特殊总账标识
ls_accountpayable-alloc_nmbr = ls_data-zuonr. " 分配
ls_accountpayable-profit_ctr = ls_data-prctr. " 利润中心
ls_accountpayable-tax_code = ls_data-mwskz. " 税码
ls_accountpayable-pmnttrms = ls_data-zterm. " 付款条件
ls_accountpayable-bline_date = ls_data-zfbdt. " 付款起算日期
ls_accountpayable-bus_area = ls_data-gsber. " 业务范围
INSERT ls_accountpayable INTO TABLE lt_accountpayable.
WHEN 'S'. " 总分类帐科目
l_gl_acount = ls_data-hkont.
ls_accountgl-itemno_acc = l_itemno_acc. " 会计凭证行项目编号
ls_accountgl-item_text = ls_data-sgtxt. " 项目文本
ls_accountgl-gl_account = l_gl_acount. " 总分类帐帐目
ls_accountgl-costcenter = ls_data-kostl. " 成本中心
ls_accountgl-alloc_nmbr = ls_data-zuonr. " 分配编号
ls_accountgl-orderid = ls_data-aufnr. " 内部订单号
ls_accountgl-tax_code = ls_data-mwskz. " 税号
ls_accountgl-po_number = ls_data-ebeln. " 采购凭证号
ls_accountgl-po_item = ls_data-ebelp. " 采购凭证行项目号
ls_accountgl-profit_ctr = ls_data-prctr. " 利润中心
ls_accountgl-material_long = ls_data-matnr. " 物料
INSERT ls_accountgl INTO TABLE lt_accountgl.
WHEN 'A'. " 资产
" 资产统御科目
CLEAR l_gl_acount.
IF ls_data-hkont IS NOT INITIAL.
l_gl_acount = ls_data-hkont.
ELSE.
SELECT SINGLE ktogr FROM anla
WHERE bukrs = @ls_data-bukrs
AND anln1 = @ls_data-anln1
INTO @l_gl_acount.
IF sy-subrc = 0.
SELECT SINGLE ktansw FROM t095
WHERE ktopl = @l_ktopl
AND ktogr = @l_gl_acount
INTO @l_gl_acount.
ENDIF.
ENDIF.
ls_accountgl-itemno_acc = l_itemno_acc. " 会计凭证行项目编号
ls_accountgl-item_text = ls_data-sgtxt. " 项目文本
ls_accountgl-gl_account = l_gl_acount. " 统御科目
ls_accountgl-acct_type = ls_bschl-koart. " 业务类型
ls_accountgl-asset_no = ls_data-anln1. " 主资产号
ls_accountgl-sub_number = '0000'. "次资产号
ls_accountgl-costcenter = ls_data-kostl. " 成本中心
ls_accountgl-alloc_nmbr = ls_data-zuonr. " 分配编号
ls_accountgl-orderid = ls_data-aufnr. " 内部订单号
ls_accountgl-tax_code = ls_data-mwskz. " 税号
ls_accountgl-po_number = ls_data-ebeln. " 采购凭证号
ls_accountgl-po_item = ls_data-ebelp. " 采购凭证行项目号
ls_accountgl-profit_ctr = ls_data-prctr. " 利润中心
ls_accountgl-material_long = ls_data-matnr. " 物料
ls_accountgl-bus_area = ls_data-gsber. " 业务范围
INSERT ls_accountgl INTO TABLE lt_accountgl.
WHEN 'M'. " 物料
WHEN OTHERS.
ENDCASE.
" 货币项目
ls_currencyamount-itemno_acc = l_itemno_acc. "行项目编号
IF ls_bschl-shkzg = 'S'.
ls_currencyamount-amt_doccur = ls_data-wrbtr. " 金额
ls_currencyamount-tax_amt = ls_data-xmwst. " 税额
ELSE.
ls_currencyamount-amt_doccur = ls_data-wrbtr * -1. " 金额
ls_currencyamount-tax_amt = ls_data-xmwst * -1. " 税额
ENDIF.
ls_currencyamount-currency = ls_head-waers. "货币
INSERT ls_currencyamount INTO TABLE lt_currencyamount.
" 增强字段
DATA ls_ext TYPE zsfi0001.
ls_ext-posnr = l_itemno_acc. " 会计凭证行项目编号
ls_ext-bschl = ls_data-bschl. " 记帐代码
ls_ext-rstgr = ls_data-rstgr. " 付款原因代码
CLEAR ls_extension2.
ls_extension2-structure = 'ZSFI0001'.
MOVE ls_ext TO ls_extension2+30.
INSERT ls_extension2 INTO TABLE lt_extension2.
ENDLOOP.
IF i_test = 'X'.
CALL FUNCTION 'BAPI_ACC_DOCUMENT_CHECK'
EXPORTING
documentheader = ls_documentheader
TABLES
accountgl = lt_accountgl
accountreceivable = lt_accountreceivable
accountpayable = lt_accountpayable
currencyamount = lt_currencyamount
criteria = lt_criteria
return = lt_return
extension2 = lt_extension2.
ELSE.
CALL FUNCTION 'BAPI_ACC_DOCUMENT_POST'
EXPORTING
documentheader = ls_documentheader
IMPORTING
obj_key = l_obj_key
TABLES
accountgl = lt_accountgl
accountreceivable = lt_accountreceivable
accountpayable = lt_accountpayable
currencyamount = lt_currencyamount
criteria = lt_criteria
return = lt_return
extension2 = lt_extension2.
ENDIF.
" 整理BAPI消息
CLEAR l_msg.
LOOP AT lt_return INTO ls_return WHERE type CA 'AEX'.
MESSAGE ID ls_return-id TYPE ls_return-type NUMBER ls_return-number
WITH ls_return-message_v1 ls_return-message_v2 ls_return-message_v3 ls_return-message_v4
INTO ls_return-message.
l_mtype = 'E'.
l_msg = |{ l_msg }{ ls_return-message };|.
ENDLOOP.
IF sy-subrc <> 0.
l_mtype = 'S'.
IF i_test = 'X'.
l_msg = |测试运行成功|.
ELSE.
l_msg = |会计凭证{ l_obj_key(10) }已处理|.
ENDIF.
ENDIF.
" 回写报表
LOOP AT GROUP ls_data_grp REFERENCE INTO DATA(lr_data).
lr_data->mtype = l_mtype.
lr_data->msg = l_msg.
lr_data->belnr = l_obj_key(10).
ENDLOOP.
IF i_test = 'X'.
" 测试运行结束
CONTINUE.
ELSE.
" 提交数据库
IF l_mtype = 'E'.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
ENDIF.
ENDIF.
ENDLOOP. " LOOP AT gt_data GROUP BY
ENDFORM.
增强¶
BAPI的EXTENSION2增强代码差异不大,对于上面BAPI来说,需要在ACC_DOCUMENT(BADI)增强,IF_EX_ACC_DOCUMENT~CHANGE方法中加入下面代码。
示例代码
***********************************************************************
* Example to move fields from BAPI parameter EXTENSION2 to structure *
* ACCIT (accounting document line items). *
* The dictionary structure (content for EXTENSION2-STRUCTURE) must *
* contain field POSNR, (TYPE POSNR_ACC) to indentify the correct line *
* item of the internal table ACCIT. *
***********************************************************************
DATA: wa_extension TYPE bapiparex,
ext_value(960) TYPE c,
wa_accit TYPE accit,
l_ref TYPE REF TO data.
FIELD-SYMBOLS: <l_struc> TYPE ANY,
<l_field> TYPE ANY.
SORT c_extension2 BY structure.
LOOP AT c_extension2 INTO wa_extension.
AT NEW structure.
CREATE DATA l_ref TYPE (wa_extension-structure).
ASSIGN l_ref->* TO <l_struc>.
ENDAT.
CONCATENATE wa_extension-valuepart1 wa_extension-valuepart2
wa_extension-valuepart3 wa_extension-valuepart4
INTO ext_value.
MOVE ext_value TO <l_struc>.
ASSIGN COMPONENT 'POSNR' OF STRUCTURE <l_struc> TO <l_field>.
READ TABLE c_accit WITH KEY posnr = <l_field>
INTO wa_accit.
IF sy-subrc IS INITIAL.
MOVE-CORRESPONDING <l_struc> TO wa_accit.
MODIFY c_accit FROM wa_accit INDEX sy-tabix.
ENDIF.
ENDLOOP.