实时发送SAP会计凭证到外部系统
原创 ABAP老白 ABAP老白 2023-01-29 19:17 发表于上海
最近几年做的接口类型的开发比较多,有一类接口是把SAP的凭证类型数据或者主数据发送到外部系统。在对实时性要求不高的时候,通常会通过筛选创建日期、时间等使用JOB程序推送到外部,但是如果对实时性要求比较高这个方法就不再适合了。这个时候可以使用Message以IDOC的方式发出去,或者在增强里面使用自开发程序直接推出去。
本例使用BTE的方式,实时的把SAP会计凭证推送到外部的Oracle数据库。
和物料凭证的POST不同,并没有一个出口/BADI能够包含会计凭证的所有创建/更改,如果使用BTE的话,需要下面三个:
详细过程:
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-bukrsbelnr = 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 ORi_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_bsegFROM 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 TASKEXPORTING
updkz = updkz
commit = ''
TABLES
gbtab = lt_gb.ENDFUNCTION.FUNCTION zbte_push_bseg_to_gb.*"----------------------------------------------------------------------
*" 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 ANDbelnr = lt_log-belnr ANDgjahr = lt_log-gjahr ANDbuzei = 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_outFROM 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[]
...