在ABAP的开发中,根据业务的需要,有时可能要对后台多个数据表进行更新,为了保证数据的完整性、一致性,需要把这些操作写在同一个事务中。对数据的操作,要么全部成功,要么全部失败回滚。结合在项目中的应用,下面阐述一下实现方法。
本例是在用BAPI创建物料凭证的同时,要更新自定义状态表,实现物料凭证的创建和更新自定义状态表在同一事务中。
一、首先用SE37创建一个Update Module 类型的函数:
函数里面的代码如下:
FUNCTION ZMM_PULL_LIST_POST_AUFNR.
*"----------------------------------------------------------------------
*"*"Update function module:
*"
*"*"Local interface:
*" IMPORTING
*" VALUE(PLANT) TYPE BAPI2017_GM_ITEM_CREATE-PLANT OPTIONAL
*" VALUE(STGE_LOC) TYPE BAPI2017_GM_ITEM_CREATE-STGE_LOC OPTIONAL
*" VALUE(MOVE_TYPE) TYPE BAPI2017_GM_ITEM_CREATE-MOVE_TYPE
*" OPTIONAL
*" VALUE(MOVE_PLANT) TYPE BAPI2017_GM_ITEM_CREATE-MOVE_PLANT
*" OPTIONAL
*" VALUE(MOVE_STLOC) TYPE BAPI2017_GM_ITEM_CREATE-MOVE_STLOC
*" OPTIONAL
*" VALUE(ENTRY_QNT) TYPE BAPI2017_GM_ITEM_CREATE-ENTRY_QNT
*" OPTIONAL
*" VALUE(ISWBS) TYPE CHAR1 OPTIONAL
*" TABLES
*" INPUT STRUCTURE ZMM_PD_PULL_LIST OPTIONAL
*"----------------------------------------------------------------------
data:goodsmvt_header type bapi2017_gm_head_01.
data:goodsmvt_code type bapi2017_gm_code.
data:materialdocument type bapi2017_gm_head_ret-mat_doc.
data:matdocumentyear type bapi2017_gm_head_ret-doc_year.
data:goodsmvt_item type table of bapi2017_gm_item_create with header line.
data:return type table of bapiret2 WITH HEADER LINE.
DATA:ITRESULT TYPE TABLE OF zmm_311PD_result WITH HEADER LINE.
DATA:ITRESULTLOG TYPE TABLE OF ZMM03_PD_LOG WITH HEADER LINE.
DATA:IT_ERROR TYPE TABLE OF ZMM03_ERROR WITH HEADER LINE.
DATA:m_POSTMSG(200).
DATA:G_WBS_ELEM TYPE PRPS-POSKI,
G_PSPNR TYPE PRPS-PSPNR.
*使用之前先清空
REFRESH IT_ERROR.
CLEAR IT_ERROR.
LOOP AT INPUT.
CLEAR G_PSPNR.
CLEAR G_WBS_ELEM.
CLEAR GOODSMVT_HEADER.
CLEAR GOODSMVT_CODE.
CLEAR MATERIALDOCUMENT.
CLEAR MATDOCUMENTYEAR.
REFRESH GOODSMVT_ITEM.
CLEAR GOODSMVT_ITEM.
SELECT SINGLE
GRPNR
FROM GRPGA
INTO G_PSPNR
WHERE PSPNR = INPUT-PSPEL.
IF G_PSPNR IS INITIAL.
G_PSPNR = INPUT-PSPEL.
ENDIF.
SELECT SINGLE
POSKI
FROM PRPS
INTO G_WBS_ELEM
WHERE PSPNR = G_PSPNR.
goodsmvt_header-pstng_date = sy-datum.
goodsmvt_header-doc_date = sy-datum.
goodsmvt_code-gm_code = '04'.
* 抬头文本填批次/WBS号,物料单填网络号
concatenate INPUT-PICI '/' g_wbs_elem into goodsmvt_header-header_txt.
condense goodsmvt_header-header_txt.
goodsmvt_header-REF_DOC_NO_LONG = INPUT-aufnr.
goodsmvt_item-material = INPUT-matnr.
goodsmvt_item-plant = PLANT.
goodsmvt_item-stge_loc = STGE_LOC.
goodsmvt_item-move_type = MOVE_TYPE.
IF ISWBS = '1'.
goodsmvt_item-spec_stock = INPUT-SOBKZ.
ENDIF.
goodsmvt_item-entry_qnt = ENTRY_QNT.
goodsmvt_item-entry_uom = INPUT-meins.
goodsmvt_item-move_plant = MOVE_PLANT.
goodsmvt_item-move_stloc = MOVE_STLOC.
IF ISWBS = '1'.
goodsmvt_item-wbs_elem = g_wbs_elem.
goodsmvt_item-VAL_WBS_ELEM = G_WBS_ELEM.
ENDIF.
append goodsmvt_item.
clear goodsmvt_item.
call function 'BAPI_GOODSMVT_CREATE'
exporting
goodsmvt_header = goodsmvt_header
goodsmvt_code = goodsmvt_code
importing
materialdocument = materialdocument
matdocumentyear = matdocumentyear
tables
goodsmvt_item = goodsmvt_item
return = return.
IF MATERIALDOCUMENT NE ''.
* 从数据库中获取当前的出库数量
SELECT SINGLE
MENGE_CK
INTO INPUT-MENGE_CK
FROM ZMM_PD_PULL_LIST
WHERE AUFNR = INPUT-AUFNR AND RSPOS = INPUT-RSPOS AND PICI = INPUT-PICI AND MATNR = INPUT-MATNR.
INPUT-MENGE_CK = INPUT-MENGE_CK + ENTRY_QNT.
INPUT-MENGE_QF = INPUT-MENGE_LL - INPUT-MENGE_CK.
IF INPUT-MENGE_QF <= 0.
INPUT-FLAG = 'X'.
ENDIF.
ITRESULT-MBLNR = MATERIALDOCUMENT.
ITRESULT-MJAHR = matdocumentyear.
ITRESULT-WERKS = INPUT-WERKS.
ITRESULT-MATNR = INPUT-MATNR.
ITRESULT-AUFNR = INPUT-AUFNR.
ITRESULT-RSPOS = INPUT-RSPOS.
ITRESULT-MENGE = ENTRY_QNT.
ITRESULT-MEINS = INPUT-MEINS.
APPEND ITRESULT.
CLEAR ITRESULT.
ITRESULTLOG-MBLNR = MATERIALDOCUMENT.
ITRESULTLOG-MJAHR = matdocumentyear.
ITRESULTLOG-UNAME = SY-UNAME.
ITRESULTLOG-WERKS = INPUT-WERKS.
ITRESULTLOG-MATNR = INPUT-MATNR.
ITRESULTLOG-AUFNR = INPUT-AUFNR.
ITRESULTLOG-RSPOS = INPUT-RSPOS.
ITRESULTLOG-MENGE = ENTRY_QNT.
ITRESULTLOG-MEINS = INPUT-MEINS.
APPEND ITRESULTLOG.
CLEAR ITRESULTLOG.
ELSE.
CLEAR m_POSTMSG.
m_POSTMSG = '创建凭证失败:'.
LOOP AT RETURN WHERE TYPE = 'E'.
CONCATENATE m_POSTMSG '/' RETURN-MESSAGE INTO m_POSTMSG.
ENDLOOP.
MOVE-CORRESPONDING INPUT TO IT_ERROR.
IT_ERROR-MESSAGE = m_POSTMSG.
IT_ERROR-UNAME = SY-UNAME.
APPEND IT_ERROR.
CLEAR IT_ERROR.
ENDIF.
MODIFY INPUT.
CLEAR INPUT.
ENDLOOP.
*以上代码过帐
IF MATERIALDOCUMENT NE ''.
MODIFY ZMM_PD_PULL_LIST FROM TABLE INPUT.
MODIFY zmm_311PD_result FROM TABLE ITRESULT.
MODIFY ZMM03_PD_LOG FROM TABLE ITRESULTLOG.
ELSE.
IF IT_ERROR[] IS NOT INITIAL.
MODIFY ZMM03_ERROR FROM TABLE IT_ERROR.
ENDIF.
ENDIF.
ENDFUNCTION.
二、外部调用:
SET UPDATE TASK LOCAL.
CALL FUNCTION 'ZMM_PULL_LIST_POST_AUFNR' IN UPDATE TASK
EXPORTING
PLANT = IT-WERKS
STGE_LOC = it_temp-lgort
MOVE_TYPE = '311'
MOVE_PLANT = IT-WERKS
MOVE_STLOC = IT-lgort
ENTRY_QNT = g_prlab
ISWBS = ''
TABLES
INPUT = it_li.
COMMIT WORK AND WAIT.