实时发送 SAP 会计凭证到外部系统

作者:ABAP老白 约 6 分钟阅读 更新日期:2024-02-22 2 年前更新 标签:CO, FI, 财务

实时发送SAP会计凭证到外部系统

原创 ABAP老白 ABAP老白 2023-01-29 19:17 发表于上海

最近几年做的接口类型的开发比较多,有一类接口是把SAP的凭证类型数据或者主数据发送到外部系统。在对实时性要求不高的时候,通常会通过筛选创建日期、时间等使用JOB程序推送到外部,但是如果对实时性要求比较高这个方法就不再适合了。这个时候可以使用Message以IDOC的方式发出去,或者在增强里面使用自开发程序直接推出去。

本例使用BTE的方式,实时的把SAP会计凭证推送到外部的Oracle数据库。

和物料凭证的POST不同,并没有一个出口/BADI能够包含会计凭证的所有创建/更改,如果使用BTE的话,需要下面三个:

1、事件00001030    直接生成的会计凭证,比如F-02

2、事件00001050    VF01 MIRO等间接生成的凭证数据

3、事件00001110    FB02 更改凭证数据

详细过程:

1、配置BTE,事务码FIBF

2、程序

FUNCTION zbte_send_bseg_to_gb.

*"----------------------------------------------------------------------

*"*"更新函数模块:

*"

*"*"局部接口:

*" IMPORTING

*" VALUE(UPDKZ) TYPE UPDKZ_D OPTIONAL

*" VALUE(I_XBKPF) TYPE BKPF OPTIONAL

*" VALUE(I_YBKPF) TYPE BKPF OPTIONAL

*" TABLES

*" T_BKPF STRUCTURE BKPF OPTIONAL

*" T_BSEG STRUCTURE BSEG OPTIONAL

*" XBSEG STRUCTURE FBSEG OPTIONAL

*"----------------------------------------------------------------------

DATA: lt_bseg TYPE TABLE OF bseg WITH HEADER LINE.
DATA: lt_gb TYPE TABLE OF zbte_send_bseg_to_gb_s1 WITH HEADER LINE.

CHECK s_hkont[] IS NOT INITIAL.

IF updkz = 'I'.
LOOP AT t_bseg WHERE hkont IN s_hkont.
READ TABLE t_bkpf WITH KEY bukrs = t_bseg-bukrs

belnr = t_bseg-belnr

gjahr = t_bseg-gjahr.

MOVE-CORRESPONDING t_bseg TO lt_gb.

MOVE-CORRESPONDING t_bkpf TO lt_gb.

APPEND lt_gb.CLEAR lt_gb.
ENDLOOP.

ELSEIF updkz = 'U'.

IF i_xbkpf-bktxt <> i_ybkpf-bktxt OR

i_xbkpf-xblnr <> i_ybkpf-xblnr OR

i_xbkpf-xref1_hd <> i_ybkpf-xref1_hd OR

i_xbkpf-xref2_hd <> i_ybkpf-xref2_hd OR

xbseg[] IS INITIAL.

SELECT * INTO CORRESPONDING FIELDS OF TABLE lt_bseg

FROM bseg

WHERE bukrs = i_xbkpf-bukrs AND

belnr = i_xbkpf-belnr AND

gjahr = i_xbkpf-gjahr AND

hkont IN s_hkont.

CHECK sy-subrc = 0.

LOOP AT lt_bseg.
READ TABLE xbseg WITH KEY buzei = lt_bseg-buzei.
IF sy-subrc = 0.

MOVE-CORRESPONDING xbseg TO lt_bseg.

ENDIF.

MOVE-CORRESPONDING lt_bseg TO lt_gb.

MOVE-CORRESPONDING i_xbkpf TO lt_gb.

APPEND lt_gb.CLEAR lt_gb.
ENDLOOP.

ELSE.

LOOP AT xbseg WHERE hkont IN s_hkont.

MOVE-CORRESPONDING xbseg TO lt_gb.

MOVE-CORRESPONDING i_xbkpf TO lt_gb.

APPEND lt_gb.CLEAR lt_gb.
ENDLOOP.
ENDIF.
ENDIF.

CHECK lt_gb[] IS NOT INITIAL.

CALL FUNCTION 'ZBTE_PUSH_BSEG_TO_GB' "IN BACKGROUND TASK

EXPORTING

updkz = updkz

commit = ''

TABLES

gbtab = lt_gb.
ENDFUNCTION.
FUNCTION zbte_push_bseg_to_gb.

*"----------------------------------------------------------------------

*"*"Local interface

*" IMPORTING

*" VALUE(UPDKZ) TYPE UPDKZ_D OPTIONAL

*" VALUE(COMMIT) TYPE CHAR1 OPTIONAL

*" TABLES

*" GBTAB STRUCTURE ZBTE_SEND_BSEG_TO_GB_S1

*"----------------------------------------------------------------------

DATA: connam TYPE dbcon-con_name VALUE 'EDWP'.
DATA: lt_log TYPE TABLE OF zgbt2 WITH HEADER LINE.
DATA: cxserr TYPE REF TO cx_sy_native_sql_error,

excmsg TYPE string,

rtmsg TYPE bapi_msg.

DATA: BEGIN OF lt_error OCCURS 0,

bukrs TYPE zgbt2-bukrs,

belnr TYPE zgbt2-belnr,

gjahr TYPE zgbt2-gjahr,

buzei TYPE zgbt2-buzei,

exmsg TYPE zgbt2-exmsg,

END OF lt_error.
LOOP AT gbtab.
lt_log-bukrs = gbtab-bukrs.
lt_log-belnr = gbtab-belnr.
lt_log-gjahr = gbtab-gjahr.
lt_log-buzei = gbtab-buzei.
lt_log-hkont = gbtab-hkont.
lt_log-aedat = sy-datum.
lt_log-aezet = sy-uzeit.
lt_log-aenam = sy-uname.
APPEND lt_log.
ENDLOOP.
MODIFY zgbt2 FROM TABLE lt_log.
IF commit = 'X'.

COMMIT WORK.

ENDIF.
TRY .

EXEC SQL.

connect to :connam

ENDEXEC.
CATCH cx_sy_native_sql_error INTO cxserr.

excmsg = cxserr->sqlmsg.

CONCATENATE '连接' connam '失败:' excmsg INTO excmsg.

LOOP AT lt_log.

UPDATE zgbt2 SET exmsg = excmsg

WHERE bukrs = lt_log-bukrs AND
belnr = lt_log-belnr AND
gjahr = lt_log-gjahr AND
buzei = lt_log-buzei.

MOVE-CORRESPONDING lt_log TO lt_error.

lt_error-exmsg = excmsg.
APPEND lt_error.
ENDLOOP.
ENDTRY.
IF lt_error[] IS INITIAL.
LOOP AT gbtab.

CLEAR excmsg.

TRY.
IF updkz = 'U'.

EXEC SQL.

delete from zodss700_bseg

where mandt = :gbtab-mandt and

bukrs = :gbtab-bukrs and

belnr = :gbtab-belnr and

gjahr = :gbtab-gjahr and

buzei = :gbtab-buzei

ENDEXEC.
ENDIF.

CLEAR sy-subrc.

EXEC SQL.

insert into zodss700_bseg

( mandt ,bukrs ,belnr ,gjahr ,buzei ,blart ,bldat ,budat ,monat ,cpudt ,

cputm ,aedat ,upddt ,usnam ,tcode ,bvorg ,xblnr ,stjah ,bktxt ,waers ,

kursf ,hwaer ,awsys ,stgrd ,ppnam ,numpg ,bstat ,glvor ,awtyp ,awkey ,

augdt ,augbl ,bschl ,koart ,umskz ,umsks ,shkzg ,gsber ,mwskz ,dmbtr ,

wrbtr ,pswbt ,pswsl ,valut ,zuonr ,sgtxt ,kokrs ,kostl ,aufnr ,vbeln ,

vbel2 ,posn2 ,anln1 ,bzdat ,xkres ,xpanz ,xzahl ,saknr ,hkont ,kunnr ,

lifnr ,zfbdt ,zterm ,matnr ,werks ,menge ,meins ,ebeln ,bwkey ,bwtar ,

rstgr ,prctr ,kstrg ,projk ,lokkt ,xref1 ,xref2 ,fkber ,xnegp ,kkber ,

xref3 ,zzcfi,anln2 ,anbwa ,load_dt )

values

( :gbtab-mandt ,

:gbtab-bukrs ,

:gbtab-belnr ,

:gbtab-gjahr ,

:gbtab-buzei ,

:gbtab-blart ,

:gbtab-bldat ,

:gbtab-budat ,

trim( :gbtab-monat ) ,

:gbtab-cpudt,

:gbtab-cputm ,

:gbtab-aedat ,

:gbtab-upddt ,

trim( :gbtab-usnam ) ,

trim( :gbtab-tcode ) ,

trim( :gbtab-bvorg ) ,

trim( :gbtab-xblnr ) ,

trim( :gbtab-stjah ) ,

trim( :gbtab-bktxt ) ,

trim( :gbtab-waers ) ,

trim( :gbtab-kursf ) ,

trim( :gbtab-hwaer ) ,

trim( :gbtab-awsys ) ,

trim( :gbtab-stgrd ) ,

trim( :gbtab-ppnam ) ,

trim( :gbtab-numpg ) ,

trim( :gbtab-bstat ) ,

trim( :gbtab-glvor ) ,

trim( :gbtab-awtyp ) ,

trim( :gbtab-awkey ) ,

:gbtab-augdt ,

trim( :gbtab-augbl ),

trim( :gbtab-bschl ),

trim( :gbtab-koart ),

trim( :gbtab-umskz ),

trim( :gbtab-umsks ),

trim( :gbtab-shkzg ),

trim( :gbtab-gsber ),

trim( :gbtab-mwskz ),

trim( :gbtab-dmbtr ),

trim( :gbtab-wrbtr ),

trim( :gbtab-pswbt ),

trim( :gbtab-pswsl ),

:gbtab-valut,

trim( :gbtab-zuonr ) ,

trim( :gbtab-sgtxt ) ,

trim( :gbtab-kokrs ) ,

trim( :gbtab-kostl ) ,

trim( :gbtab-aufnr ) ,

trim( :gbtab-vbeln ) ,

trim( :gbtab-vbel2 ) ,

trim( :gbtab-posn2 ) ,

trim( :gbtab-anln1 ) ,

:gbtab-bzdat ,

trim( :gbtab-xkres ) ,

trim( :gbtab-xpanz ) ,

trim( :gbtab-xzahl ) ,

trim( :gbtab-saknr ) ,

trim( :gbtab-hkont ) ,

trim( :gbtab-kunnr ) ,

trim( :gbtab-lifnr ) ,

:gbtab-zfbdt ,

trim( :gbtab-zterm ) ,

trim( :gbtab-matnr ) ,

trim( :gbtab-werks ) ,

trim( :gbtab-menge ) ,

trim( :gbtab-meins ) ,

trim( :gbtab-ebeln ) ,

trim( :gbtab-bwkey ) ,

trim( :gbtab-bwtar ) ,

trim( :gbtab-rstgr ) ,

trim( :gbtab-prctr ) ,

trim( :gbtab-kstrg ) ,

trim( :gbtab-projk ) ,

trim( :gbtab-lokkt ) ,

trim( :gbtab-xref1 ) ,

trim( :gbtab-xref2 ) ,

trim( :gbtab-fkber ) ,

trim( :gbtab-xnegp ) ,

trim( :gbtab-kkber ) ,

trim( :gbtab-xref3 ) ,

trim( :gbtab-zzcfi ) ,

trim( :gbtab-anln2 ) ,

trim( :gbtab-anbwa ) ,

sysdate

)

ENDEXEC.
IF sy-subrc <> 0.

WRITE sy-subrc TO rtmsg LEFT-JUSTIFIED.

UPDATE zgbt2 SET exmsg = rtmsg

WHERE bukrs = gbtab-bukrs AND

belnr = gbtab-belnr AND

gjahr = gbtab-gjahr AND

buzei = gbtab-buzei.

CONTINUE.

ENDIF.

EXEC SQL.

commit

ENDEXEC.
CATCH cx_sy_native_sql_error INTO cxserr.

excmsg = cxserr->sqlmsg.

UPDATE zgbt2 SET exmsg = excmsg

WHERE bukrs = gbtab-bukrs AND

belnr = gbtab-belnr AND

gjahr = gbtab-gjahr AND

buzei = gbtab-buzei.

MOVE-CORRESPONDING gbtab TO lt_error.

lt_error-exmsg = excmsg.
APPEND lt_error.
ENDTRY.
ENDLOOP.
ENDIF.
ENDFUNCTION.

说明:

ZBTE_SEND_BSEG_TO_GB为UPDATE Module,

ZBTE_SEND_BSEG_TO_GB为RFC

重发程序:

因为网络或者Oracle的原因,发送失败是在所难免的,所以还需要一个重发程序,此程序既能够看到发送日志,也可以进行重发。

*&---------------------------------------------------------------------*

*& Report ZGB_ZGBT2_RESEND

*&

*&---------------------------------------------------------------------*

*&

*& 重新发送管报凭证数据

*&---------------------------------------------------------------------*

REPORT zgb_resend_docs NO STANDARD PAGE HEADING.

TYPE-POOLS: sscr,slis.

DATA: fldct TYPE lvc_t_fcat WITH HEADER LINE,

slayt TYPE lvc_s_layo,

varnt TYPE disvariant,

repid TYPE sy-repid.

DATA: BEGIN OF it_out OCCURS 0,

bukrs TYPE zgbt2-bukrs,

belnr TYPE zgbt2-belnr,

gjahr TYPE zgbt2-gjahr,

buzei TYPE zgbt2-buzei,

hkont TYPE zgbt2-hkont,

aedat TYPE zgbt2-aedat,

aezet TYPE zgbt2-aezet,

aenam TYPE zgbt2-aenam,

exmsg TYPE zgbt2-exmsg,

seled,

END OF it_out.
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE t01.
SELECT-OPTIONS s_bukrs FOR it_out-bukrs.
SELECT-OPTIONS s_belnr FOR it_out-belnr.
SELECT-OPTIONS s_gjahr FOR it_out-gjahr.
SELECT-OPTIONS s_aedat FOR it_out-aedat.
SELECT-OPTIONS s_aenam FOR it_out-aenam.
SELECT-OPTIONS s_exmsg FOR it_out-exmsg.
SELECTION-SCREEN END OF BLOCK b1.

AT SELECTION-SCREEN OUTPUT.

t01 = '选择条件'.

%_s_bukrs_%_app_%-text = '公司代码'.

%_s_belnr_%_app_%-text = '凭证号'.

%_s_gjahr_%_app_%-text = '年度'.

%_s_aedat_%_app_%-text = '发送日期'.

%_s_aenam_%_app_%-text = '发送账号'.

%_s_exmsg_%_app_%-text = '错误文本'.

START-OF-SELECTION.

PERFORM getdata.

PERFORM outdata.

*&---------------------------------------------------------------------*

*& Form getdata

*&---------------------------------------------------------------------*

FORM getdata.

CLEAR it_out[].

SELECT * INTO CORRESPONDING FIELDS OF TABLE it_out

FROM zgbt2

WHERE bukrs IN s_bukrs AND

belnr IN s_belnr AND

gjahr IN s_gjahr AND

aedat IN s_aedat AND

aenam IN s_aenam AND

exmsg IN s_exmsg

ORDER BY PRIMARY KEY .

MESSAGE s000(oo) WITH '数据条数:' sy-dbcnt.

ENDFORM. "getdata

*&---------------------------------------------------------------------*

*& Form outdata

*&---------------------------------------------------------------------*

FORM outdata.

repid = sy-repid.

slayt-zebra = 'X'.

slayt-no_toolbar = 'X'.

slayt-detailinit = 'X'.

slayt-box_fname = 'SELED'.

varnt-report = sy-repid.

varnt-handle = 1.

PERFORM catset TABLES fldct

USING: 'BUKRS' '' '' '公司代码',

'BELNR' '' '' '凭证号',

'GJAHR' '' '' '年度',

'BUZEI' '' '' '项目号',

'HKONT' '' '' '科目',

'AEDAT' '' '' '发送日期',

'AEZET' '' '' '时间',

'AENAM' '' '' '账号',

'EXMSG' '' '' '错误消息'.

CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY_LVC'

EXPORTING

it_fieldcat_lvc = fldct[]

...

ABAP老白

关于作者:ABAP老白

企业信息化与 SAP 技术顾问,长期专注 SAP ABAP、FI/CO、MM、SD 等模块的技术分享与实战经验总结。查看更多介绍

来源说明:本文内容由「实时发送SAP会计凭证到外部系统.docx」整理生成,仅用于内部技术分享与学习交流。