利用函数WS_DELIVERY_UPDATE进行发货过账(vl02n发货过账),而函数本身是不返回凭证号的,但客户需求要在接口中返回过账成功的凭证号,可以下几种方式获取到凭证号:
方法一:这种方法是最原始的方法,判断函数执行成功后,首先判断交货单是否已完全交货(vbuk-wbstk = 'C'),然后根据交货单号去凭证流表(vbfa)中获取最大凭证号,代码如下:
FORM FRM_POST.
CLEAR p_vbeln.
CLEAR input.
READ TABLE input INDEX 1.
IF sy-subrc EQ 0.
p_vbeln = input-vbeln.
ENDIF.
CLEAR i_vbkok.
CLEAR i_ef_error_any_0.
MOVE-CORRESPONDING input TO output.
i_vbkok-vbeln_vl = p_vbeln. "DELIVERY NUMBER
i_vbkok-wabuc = 'X'. "AUTOMATIC PGI
i_vbkok-wadat_ist = p_budat.
LOOP AT input.
SELECT SINGLE * INTO g_lips FROM lips
WHERE vbeln = input-vbeln
AND posnr = input-posnr.
i_vbpok_tab-vbeln_vl = g_lips-vbeln. "DELIVERY NUMBER
i_vbpok_tab-posnr_vl = g_lips-posnr.
i_vbpok_tab-vbeln = g_lips-vgbel. "You must assign Sales order & Item number
i_vbpok_tab-posnn = g_lips-vgpos. "Sales Order item
i_vbpok_tab-matnr = g_lips-matnr.
i_vbpok_tab-lfimg = input-lfimg.
i_vbpok_tab-charg = input-charg.
i_vbpok_tab-lgort = input-lgort.
gv_14 = input-lfimg.
CONDENSE gv_14.
i_vbpok_tab-pikmg = gv_14 .
APPEND i_vbpok_tab.
ENDLOOP.
SORT input_pccf BY ywlx vbeln posnr.
CLEAR lv_posnr_vl.
lv_posnr_vl = '900000'.
LOOP AT input_pccf.
CLEAR wa_input.
MOVE-CORRESPONDING input_pccf TO wa_input.
AT NEW posnr.
ENDAT.
lv_posnr_vl = lv_posnr_vl + 1.
SELECT SINGLE * INTO g_lips FROM lips
WHERE vbeln = input_pccf-vbeln
AND posnr = input_pccf-posnr.
i_vbpok_tab-vbeln_vl = g_lips-vbeln. "DELIVERY NUMBER
i_vbpok_tab-posnr_vl = lv_posnr_vl.
i_vbpok_tab-vbeln = g_lips-vgbel. "You must assign Sales order & Item number
i_vbpok_tab-posnn = g_lips-vgpos. "Sales Order item
i_vbpok_tab-matnr = g_lips-matnr.
i_vbpok_tab-charg = input_pccf-charg.
i_vbpok_tab-lfimg = input_pccf-lfimg.
i_vbpok_tab-lgmng = input_pccf-lfimg.
i_vbpok_tab-lgort = input_pccf-lgort.
gv_14 = input_pccf-lfimg.
CONDENSE gv_14.
i_vbpok_tab-pikmg = gv_14 .
APPEND i_vbpok_tab.
ENDLOOP.
* ---发货过账
REFRESH i_prott.
CLEAR i_prott.
CALL FUNCTION 'WS_DELIVERY_UPDATE'
EXPORTING
vbkok_wa = i_vbkok
commit = 'X'
delivery = p_vbeln
update_picking = 'X'
IMPORTING
ef_error_any_0 = i_ef_error_any_0
ef_error_in_item_deletion_0 = i_ef_error_in_item_deletion_0
ef_error_in_pod_update_0 = i_ef_error_in_pod_update_0
ef_error_in_interface_0 = i_ef_error_in_interface_0
ef_error_in_goods_issue_0 = i_ef_error_in_goods_issue_0
ef_error_in_final_check_0 = i_ef_error_in_final_check_0
TABLES
vbpok_tab = i_vbpok_tab
prot = i_prott
EXCEPTIONS
error_message = 1
OTHERS = 2.
CLEAR i_prott.
READ TABLE i_prott WITH KEY msgty = 'E'.
IF sy-subrc EQ 0.
LOOP AT i_prott WHERE msgty = 'E'.
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = i_prott-msgid
msgnr = i_prott-msgno
msgv1 = i_prott-msgv1
msgv2 = i_prott-msgv2
msgv3 = i_prott-msgv3
msgv4 = i_prott-msgv4
IMPORTING
message_text_output = output-notes.
output-vbeln = i_prott-vbeln.
output-posnr = i_prott-posnr.
output-flag = 'E'.
CONCATENATE '发货过账失败:交货单' output-vbeln ',行项目' output-posnr ',' output-notes INTO output-notes.
APPEND output.
CLEAR output.
ENDLOOP.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' " call FM to
EXPORTING
wait = 'X'.
WAIT UP TO 2 SECONDS.
CLEAR lv_wbstk.
SELECT SINGLE
wbstk
INTO lv_wbstk
FROM vbuk WHERE vbeln = p_vbeln.
IF lv_wbstk = 'C'.
SELECT MAX( vbeln )
INTO output-mblnr
FROM vbfa
WHERE vbelv = p_vbeln
AND vbtyp_n = 'R'.
IF output-mblnr <> ''.
output-flag = 'S'.
output-notes = '发货过账成功!'.
ELSE.
output-flag = 'E'.
output-notes = '发货过账失败:找不到交货单对应的物料凭证!'.
ENDIF.
ELSE.
output-flag = 'E'.
output-notes = '发货过账失败:交货单货物移动状态不为C!'.
ENDIF.
APPEND output.
CLEAR output.
ENDIF.
ENDFORM.
方法二:可以使用程序SAPFV50W中的全局变量g_belnr或者获取SAPFV50W程序中的MEMORY ID 'BORGR_MATDOC',这种方法不需要直接从后台表中获取,直接从过账程序的变量中获取,代码如下:
FORM FRM_POST.
CLEAR p_vbeln.
CLEAR input.
READ TABLE input INDEX 1.
IF sy-subrc EQ 0.
p_vbeln = input-vbeln.
ELSE.
CLEAR input_pccf.
READ TABLE input_pccf INDEX 1.
IF sy-subrc EQ 0.
p_vbeln = input_pccf-vbeln.
ENDIF.
ENDIF.
IF p_budat IS INITIAL.
p_budat = sy-datum.
ENDIF.
CLEAR i_vbkok.
CLEAR i_ef_error_any_0.
MOVE-CORRESPONDING input TO output.
* ---交货抬头数据
i_vbkok-vbeln_vl = p_vbeln. "DELIVERY NUMBER
i_vbkok-wabuc = 'X'. "AUTOMATIC PGI
i_vbkok-wadat_ist = p_budat.
LOOP AT input.
SELECT SINGLE * INTO g_lips FROM lips
WHERE vbeln = input-vbeln
AND posnr = input-posnr.
i_vbpok_tab-vbeln_vl = g_lips-vbeln. "DELIVERY NUMBER
i_vbpok_tab-posnr_vl = g_lips-posnr.
i_vbpok_tab-vbeln = g_lips-vgbel. "You must assign Sales order & Item number
i_vbpok_tab-posnn = g_lips-vgpos. "Sales Order item
i_vbpok_tab-matnr = g_lips-matnr.
i_vbpok_tab-lfimg = input-lfimg.
i_vbpok_tab-charg = input-charg.
i_vbpok_tab-lgort = input-lgort.
gv_14 = input-lfimg.
CONDENSE gv_14.
i_vbpok_tab-pikmg = gv_14 .
APPEND i_vbpok_tab.
ENDLOOP.
SORT input_pccf BY ywlx vbeln posnr.
CLEAR lv_posnr_vl.
lv_posnr_vl = '900000'.
LOOP AT input_pccf.
CLEAR wa_input.
MOVE-CORRESPONDING input_pccf TO wa_input.
AT NEW posnr.
ENDAT.
lv_posnr_vl = lv_posnr_vl + 1.
SELECT SINGLE * INTO g_lips FROM lips
WHERE vbeln = input_pccf-vbeln
AND posnr = input_pccf-posnr.
i_vbpok_tab-vbeln_vl = g_lips-vbeln. "DELIVERY NUMBER
i_vbpok_tab-posnr_vl = lv_posnr_vl.
i_vbpok_tab-vbeln = g_lips-vgbel. "You must assign Sales order & Item number
i_vbpok_tab-posnn = g_lips-vgpos. "Sales Order item
i_vbpok_tab-matnr = g_lips-matnr.
i_vbpok_tab-charg = input_pccf-charg.
i_vbpok_tab-lfimg = input_pccf-lfimg.
i_vbpok_tab-lgmng = input_pccf-lfimg.
i_vbpok_tab-lgort = input_pccf-lgort.
gv_14 = input_pccf-lfimg.
CONDENSE gv_14.
i_vbpok_tab-pikmg = gv_14 .
APPEND i_vbpok_tab.
ENDLOOP.
* ---发货过账
REFRESH i_prott.
CLEAR i_prott.
CALL FUNCTION 'WS_DELIVERY_UPDATE'
EXPORTING
vbkok_wa = i_vbkok
commit = 'X'
delivery = p_vbeln
update_picking = 'X'
IMPORTING
ef_error_any_0 = i_ef_error_any_0
ef_error_in_item_deletion_0 = i_ef_error_in_item_deletion_0
ef_error_in_pod_update_0 = i_ef_error_in_pod_update_0
ef_error_in_interface_0 = i_ef_error_in_interface_0
ef_error_in_goods_issue_0 = i_ef_error_in_goods_issue_0
ef_error_in_final_check_0 = i_ef_error_in_final_check_0
TABLES
vbpok_tab = i_vbpok_tab
prot = i_prott
EXCEPTIONS
error_message = 1
OTHERS = 2.
CLEAR i_prott.
READ TABLE i_prott WITH KEY msgty = 'E'.
IF sy-subrc EQ 0.
LOOP AT i_prott WHERE msgty = 'E'.
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = i_prott-msgid
msgnr = i_prott-msgno
msgv1 = i_prott-msgv1
msgv2 = i_prott-msgv2
msgv3 = i_prott-msgv3
msgv4 = i_prott-msgv4
IMPORTING
message_text_output = output-notes.
output-vbeln = i_prott-vbeln.
output-posnr = i_prott-posnr.
output-flag = 'E'.
CONCATENATE '发货过账失败:交货单' output-vbeln ',行项目' output-posnr ',' output-notes INTO output-notes.
APPEND output.
CLEAR output.
ENDLOOP.
ELSE.
DATA:matdoc(10) TYPE c.
CLEAR matdoc.
IMPORT matdoc FROM MEMORY ID 'BORGR_MATDOC'.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT' " call FM to
EXPORTING
wait = 'X'.
WAIT UP TO 2 SECONDS.
IF matdoc <> ''.
output-mblnr = matdoc.
output-flag = 'S'.
output-notes = '发货过账成功!'.
ELSE.
output-flag = 'E'.
output-notes = '发货过账失败.
ENDIF.
APPEND output.
CLEAR output.
ENDIF.
ENDFORM.
相关知识:
You can use global structure emkpf with help of field-symbols after call function WS_DELIVERY_UPDATE2.
For example: assign ('(SAPLV50S)emkpf') to <fs_emkpf>.
Material document number = <fs_emkpf>-mblnr.
Material document year = <fs_emkpf>-mjahr.
Or you can use value global variable g_belnr in program SAPFV50W
Or you can use IMPORT material document from MEMORY ID 'BORGR_MATDOC'.