在对检验批做决策时可以使用BAPI:BAPI_INSPLOT_SETUSAGEDECISION。此BAPI 其实也可以过帐,但不能针对不同的类型过帐,比如有部分数量进入非限制库存,有部分数量进入冻结库存,有部分数量要退货等,只能是一次性对所有数量进行非限制库存过帐。
BAPI调用如下:
DATA ud_data LIKE bapi2045ud.
DATA:ud_return_data LIKE bapi2045ud_return,
stock_data LIKE bapi2045d_il2,
ls_return LIKE bapireturn1.
data re_subrc type sy-subrc.
data it_return like table of bapiret2 .
ud_data-insplot = p_inslot.
ud_data-ud_code = '2'.
ud_data-ud_plant = '6000'.
ud_data-ud_code_group = 'Z1'.
ud_data-ud_selected_set = 'Z1'.
* ud_data-ud_stock_posting = 'X'. "是否进行过帐
CALL FUNCTION 'BAPI_INSPLOT_SETUSAGEDECISION'
EXPORTING
number = p_inslot
ud_data = ud_data
* LANGUAGE =
IMPORTING
ud_return_data = ud_return_data
stock_data = stock_data
return = ls_return
* TABLES
* SYSTEM_STATUS =
* USER_STATUS =
如果传入参数ud_data-ud_stock_posting = 'X' 要过帐时,当过帐遇到错误时,并不能知道具体是什么错误,BAPI 返回的是类似“过帐错误,需要手动过帐"的提示,所以用此BAPI 过帐完全不理想。
经过研究,过帐可以如下处理:(经测试过帐成功,库存处理成功,但是否还有其它隐藏问题,需要进一步验证)
TABLES:qals.
FIELD-SYMBOLS <f_rqeva> TYPE rqeva.
FIELD-SYMBOLS <f_qals> TYPE qals.
DATA ls_qals LIKE qals.
data ls_zubmg like rqevb.
data :re_mblnr type mblnr,
re_mjahr type mjahr.
DATA: g_prottab LIKE rqevp OCCURS 9.
DATA: c_rc00 LIKE sy-subrc VALUE 0,
c_rc01 LIKE sy-subrc VALUE 1,
c_rc02 LIKE c_rc00 VALUE 2,
c_rc03 LIKE c_rc00 VALUE 3,
c_rc04 LIKE c_rc00 VALUE 4,
c_rc08 LIKE c_rc00 VALUE 8,
c_rc10 LIKE c_rc00 VALUE 10,
c_rc11 LIKE c_rc00 VALUE 11,
c_rc12 LIKE c_rc00 VALUE 12,
c_rc13 LIKE c_rc00 VALUE 13,
c_rc14 LIKE c_rc00 VALUE 14,
c_rc15 LIKE c_rc00 VALUE 15,
c_rc18 LIKE c_rc00 VALUE 18,
ci_0 TYPE i VALUE 0,
ci_1 TYPE i VALUE 1,
ci_2 TYPE i VALUE 2,
ci_3 TYPE i VALUE 3,
ci_4 TYPE i VALUE 4,
ci_5 TYPE i VALUE 5,
ci_6 TYPE i VALUE 6,
ci_7 TYPE i VALUE 7,
ci_8 TYPE i VALUE 8,
ci_9 TYPE i VALUE 9,
ci99 TYPE i VALUE 99,
c_kreuz LIKE qm00-qkz VALUE 'X',
hk_wefert LIKE qals-herkunft VALUE '04'.
DATA g_qbefu_classif LIKE qbefu. "note 1724424
if ls_return-type = 'E' or ls_return-type = 'A'.
re_subrc = 4.
MOVE-CORRESPONDING ls_return TO it_return.
APPEND it_return.
EXIT.
endif.
* 以上BAPI 会调用QA11 事务码对应的主程序 SAPMQEVA, 接下来需要获取 程序 sapmqeva 中的全局变量
ASSIGN ('(SAPMQEVA)RQEVA') TO <f_rqeva>.
IF NOT <f_rqeva> IS ASSIGNED.
re_subrc = 4.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' `ASSIGN ('(SAPMQEVA)RQEVA') TO <f_rqeva> 错误!`.
EXIT.
ENDIF.
ASSIGN ('(SAPMQEVA)QALS') TO <f_qals>.
IF <f_qals> IS ASSIGNED.
ls_qals = <f_qals>.
ELSE.
re_subrc = 4.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' `AASSIGN ('(SAPMQEVA)QALS') TO <f_qals> 错误!`.
EXIT.
ENDIF.
SELECT SINGLE *
FROM qals
WHERE prueflos = i_header-prueflos.
* 执行检验库存过帐
PERFORM ud_goodsmvt_post TABLES it_return
USING i_header "自定义结构,包含决策码等,如上图1
is_goodsmvt "自定义结构,包含工厂,各种需要过帐的数量如上图2
ls_qals
<f_rqeva>
CHANGING re_subrc re_mblnr re_mjahr.
if re_subrc = 0.
COMMIT WORK AND WAIT.
endif.
*--------------------------------------------------------------------*
* 执行检验库存过帐
FORM ud_goodsmvt_post TABLES it_return STRUCTURE bapiret2
USING i_header STRUCTURE zmes_post_header
is_goodsmvt STRUCTURE zmes_post_item
is_qals STRUCTURE qals
is_rqeva STRUCTURE rqeva
CHANGING re_subrc re_mblnr re_mjahr.
DATA lt_mseg LIKE STANDARD TABLE OF imseg WITH HEADER LINE.
DATA et_mseg LIKE STANDARD TABLE OF emseg WITH HEADER LINE.
DATA imkpf LIKE imkpf.
DATA emkpf LIKE emkpf.
DATA es_mkpf LIKE mkpf.
DATA: BEGIN OF ls_gebmg.
INCLUDE STRUCTURE rqevb.
DATA: END OF ls_gebmg.
DATA: lt_prottab LIKE rqevp OCCURS 9 with header line.
data is_zubmg type rqevb.
MOVE-CORRESPONDING is_goodsmvt to is_zubmg.
"过帐抬头数据
IF i_header-budat IS INITIAL.
imkpf-budat = sy-datum.
ELSE.
imkpf-budat = i_header-budat.
ENDIF.
imkpf-bktxt = i_header-bktxt.
PERFORM get_tqss1 USING is_qals-werk.
"各数量过帐的库存地点
PERFORM move_qlgo USING is_rqeva is_goodsmvt.
"参照 QA11 的包含程序 MQEVAF12 中的 form buche_bestaende 部分代码
"根据 ls_zubmg 不同数量字段 确定 移动类型,物料凭证项目
"其实 MQEVAF12 中的 form buche_bestaende 中已有过帐代码 ,但是过帐中如果产生错误,错误信息被以下语句转移为
"过帐检验批 & 时出错,要求手动处理,外部调用程序不能获取具体是什么错误,只有在QA11前台才能知道。因此以下form 复制
" MQEVAF12 中的 form buche_bestaende 中的代码,去掉 过帐部分.
" IF rqautoud-modus_ud CA 'ABDFG'. "Dialog nicht möglich !
" MESSAGE e054 WITH qals-prueflos.
" ENDIF.
PERFORM buche_bestaende TABLES lt_mseg lt_prottab
USING is_qals
is_zubmg
tqss1-lgortrlage
tqss1-kostlschr
tqss1-kostlzerst
is_rqeva
9 "对应 is_zubmg 中 9 个字段
CHANGING
ls_gebmg
re_subrc.
IF re_subrc <> 0.
loop at lt_prottab.
PERFORM store_message TABLES it_return
USING lt_prottab-msgty lt_prottab-msgid lt_prottab-msgno
lt_prottab-msgv1 lt_prottab-msgv2 lt_prottab-msgv3 lt_prottab-msgv4 .
ENDLOOP.
EXIT.
ENDIF.
IF lt_mseg[] IS INITIAL.
re_subrc = 4.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' '确定移动类型错误!'.
EXIT.
ENDIF.
CALL FUNCTION 'QAAT_QM_ACTIVE_INACTIVE'
EXPORTING
aktiv = space. "必须调用此function,否则会提示 不允许QM的凭证过帐
CALL FUNCTION 'MB_CREATE_GOODS_MOVEMENT'
EXPORTING
imkpf = imkpf
xallp = 'X'
xallb = 'X'
xallr = 'X'
ctcod = 'QA11'
IMPORTING
emkpf = emkpf
es_mkpf = es_mkpf
TABLES
emseg = et_mseg
imseg = lt_mseg .
CALL FUNCTION 'QAAT_QM_ACTIVE_INACTIVE'
EXPORTING
aktiv = 'X'.
IF emkpf-subrc > 1. "大于1 是错误
re_subrc = 4.
if emkpf-msgid is not INITIAL.
MESSAGE ID emkpf-msgid TYPE 'E' NUMBER emkpf-msgno
WITH emkpf-msgv1 emkpf-msgv2 emkpf-msgv3 emkpf-msgv4
INTO it_return-message.
it_return-type = 'E'.
it_return-id = emkpf-msgid.
it_return-number = emkpf-msgno.
it_return-message_v1 = emkpf-msgv1.
it_return-message_v2 = emkpf-msgv2.
it_return-message_v3 = emkpf-msgv3.
it_return-message_v4 = emkpf-msgv4.
APPEND it_return.
else.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' '检验批过帐错误!'.
endif.
ENDIF.
LOOP AT et_mseg WHERE msgty = 'E' OR msgty = 'A'.
re_subrc = 4.
MESSAGE ID et_mseg-msgid TYPE 'I' NUMBER et_mseg-msgno
WITH et_mseg-msgv1 et_mseg-msgv2 et_mseg-msgv3 et_mseg-msgv4
INTO it_return-message.
it_return-type = 'E'.
it_return-id = et_mseg-msgid.
it_return-number = et_mseg-msgno.
it_return-message_v1 = et_mseg-msgv1.
it_return-message_v2 = et_mseg-msgv2.
it_return-message_v3 = et_mseg-msgv3.
it_return-message_v4 = et_mseg-msgv4.
APPEND it_return.
ENDLOOP.
IF re_subrc <> 0.
EXIT.
ENDIF.
"汇总物料凭证到表 QAMB
LOOP AT et_mseg.
CALL FUNCTION 'QAMB_COLLECT_RECORD'
EXPORTING
lotnumber = i_header-prueflos
docyear = es_mkpf-mjahr
docnumber = es_mkpf-mblnr
docposition = et_mseg-mblpo
type = '3'.
ENDLOOP.
"过帐物料凭证
DATA ps_emkpf LIKE emkpf.
CALL FUNCTION 'MB_POST_GOODS_MOVEMENT'
IMPORTING
emkpf = ps_emkpf
EXCEPTIONS
OTHERS = 9.
IF ps_emkpf-subrc <> 0 or sy-subrc <> 0.
re_subrc = 4.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' 'MB_POST_GOODS_MOVEMENT 过帐失败!'.
exit.
ENDIF.
"更新检验批状态
PERFORM inslot_status_change.
IF sy-subrc <> 0.
re_subrc = 4.
PERFORM append_message TABLES it_return USING 'E' 'Z001' '001' '检验批状态更新失败!'.
exit.
ENDIF.
re_mblnr = es_mkpf-mblnr.
re_mjahr = es_mkpf-mjahr.
ENDFORM.
*--------------------------------------------------------------------*
FORM get_tqss1 USING i_werk.
CLEAR tqss1.
SELECT SINGLE *
FROM tqss1
WHERE werks