SAP 实战笔记:BAPI_OUTB_DELIVERY_CONFIRM_DEC 详解------外向交货单过账的利器
作者 :爱喝水的鱼丶
适用系统 :SAP S/4HANA / ECC
关键词:外向交货、发货过账、BAPI、VL02N、批次拆分
在物流执行中,外向交货单(Outbound Delivery) 的过账确认是连接仓库发货与财务记账的关键一步。标准事务 VL02N 可以手工完成拣配、过账,但在接口、自动化、后台批处理场景中,必须依赖可调用的函数或 BAPI 来实现。本文要拆解的 BAPI_OUTB_DELIVERY_CONFIRM_DEC 正是 SAP 标准提供的、专门用于外向交货单过账确认的 BAPI。
一、BAPI 的作用与定位
BAPI_OUTB_DELIVERY_CONFIRM_DEC 的核心作用一句话概括:对外向交货单执行发货过账(Post Goods Issue)。
它常用于以下场景:
- 仓库系统通过 RFC 调用 SAP 完成自动发货过账
- EDI/IDoc 处理发货确认后,后台自动过账
- 批量处理某段时间内所有已拣配的交货单
- MES 系统反馈生产发料完成后,触发销售发货过账
与手工事务 VL02N 不同,该 BAPI 是异步 的,调用成功后需要执行 BAPI_TRANSACTION_COMMIT 才会真正过账。同时,BAPI 内部会调用一系列检查(如状态、物料可用性、批次等),相比手工操作更严格。
二、BAPI 接口参数说明
该 BAPI 的功能较为专一,参数列表相对简洁,主要分为传入表参数 和传出表参数。
📥 导入表参数(TABLES)
| 参数名 | 类型 | 说明 |
|---|---|---|
DELIVERY |
BAPIOBDLVHDRCON |
交货单号及控制参数(抬头层级) |
DELIVERYITEM |
BAPIOBDLVITEMCON |
交货单行项目确认数据,如实际数量、批次等 |
DELIVERY 结构体关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
DELIV_NUMB |
VBELN_VL |
交货单号(必填) |
POST_GI_FLG |
XFELD |
是否执行发货过账(通常设为 'X') |
DELIVERYITEM 结构体关键字段:
| 字段 | 类型 | 说明 |
|---|---|---|
DELIV_NUMB |
VBELN_VL |
交货单号(必填) |
DELIV_ITEM |
POSNR_VL |
交货单行项目号(必填) |
DELIV_QTY |
LFIMG |
实际发货数量(可选,若不填则默认全量) |
FACT_UNIT |
MEINS |
单位(可选) |
BATCH |
CHARG_D |
批次号(若物料批次管理则必填) |
📤 导出表参数(TABLES)
| 参数名 | 类型 | 说明 |
|---|---|---|
RETURN |
BAPIRET2_T |
返回消息表,包含成功/错误/警告信息 |
此外还有几个不太常用的 Extension 参数,通常可以忽略。
三、调用示例
场景:对交货单 80000001 执行发货过账,部分行指定批次
abap
REPORT ztest_outb_delivery_confirm.
DATA: lt_delivery TYPE TABLE OF bapiobdlvhdrcon,
ls_delivery TYPE bapiobdlvhdrcon,
lt_deliveryitem TYPE TABLE OF bapiobdlvitemcon,
ls_deliveryitem TYPE bapiobdlvitemcon,
lt_return TYPE TABLE OF bapiret2.
" 设置交货单抬头
ls_delivery-deliv_numb = '80000001'.
ls_delivery-post_gi_flg = 'X'. " 执行发货过账
APPEND ls_delivery TO lt_delivery.
" 设置行项目确认 (10 行全量发货)
ls_deliveryitem-deliv_numb = '80000001'.
ls_deliveryitem-deliv_item = '10'.
ls_deliveryitem-deliv_qty = '100'.
ls_deliveryitem-fact_unit = 'PC'.
APPEND ls_deliveryitem TO lt_deliveryitem.
" 设置行项目 20,指定批次
CLEAR ls_deliveryitem.
ls_deliveryitem-deliv_numb = '80000001'.
ls_deliveryitem-deliv_item = '20'.
ls_deliveryitem-batch = 'BATCH001'.
APPEND ls_deliveryitem TO lt_deliveryitem.
" 调用 BAPI
CALL FUNCTION 'BAPI_OUTB_DELIVERY_CONFIRM_DEC'
TABLES
delivery = lt_delivery
deliveryitem = lt_deliveryitem
return = lt_return.
" 检查返回消息
DATA(lv_has_error) = abap_false.
LOOP AT lt_return INTO DATA(ls_ret) WHERE type CA 'EAX'.
WRITE: / 'Error:', ls_ret-message.
lv_has_error = abap_true.
ENDLOOP.
IF lv_has_error = abap_false.
CALL FUNCTION 'BAPI_TRANSACTION_COMMIT'
EXPORTING
wait = 'X'.
WRITE: / '交货单过账成功'.
ELSE.
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
WRITE: / '过账失败,已回滚'.
ENDIF.
返回结果处理
RETURN 表会按 BAPI 标准消息结构返回:
- E:错误,交货单未过账
- A:终止,整个处理中断
- W:警告,过账已完成但存在轻微问题
- I/S:成功/成功消息
务必遍历 RETURN 检查类型,而不是仅凭 sy-subrc。
四、内部执行流程
该 BAPI 典型内部逻辑如下:
#mermaid-svg-FNfhv5qvWVNNVhht{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-FNfhv5qvWVNNVhht .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-FNfhv5qvWVNNVhht .error-icon{fill:#552222;}#mermaid-svg-FNfhv5qvWVNNVhht .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-FNfhv5qvWVNNVhht .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-FNfhv5qvWVNNVhht .marker{fill:#333333;stroke:#333333;}#mermaid-svg-FNfhv5qvWVNNVhht .marker.cross{stroke:#333333;}#mermaid-svg-FNfhv5qvWVNNVhht svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-FNfhv5qvWVNNVhht p{margin:0;}#mermaid-svg-FNfhv5qvWVNNVhht .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-FNfhv5qvWVNNVhht .cluster-label text{fill:#333;}#mermaid-svg-FNfhv5qvWVNNVhht .cluster-label span{color:#333;}#mermaid-svg-FNfhv5qvWVNNVhht .cluster-label span p{background-color:transparent;}#mermaid-svg-FNfhv5qvWVNNVhht .label text,#mermaid-svg-FNfhv5qvWVNNVhht span{fill:#333;color:#333;}#mermaid-svg-FNfhv5qvWVNNVhht .node rect,#mermaid-svg-FNfhv5qvWVNNVhht .node circle,#mermaid-svg-FNfhv5qvWVNNVhht .node ellipse,#mermaid-svg-FNfhv5qvWVNNVhht .node polygon,#mermaid-svg-FNfhv5qvWVNNVhht .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-FNfhv5qvWVNNVhht .rough-node .label text,#mermaid-svg-FNfhv5qvWVNNVhht .node .label text,#mermaid-svg-FNfhv5qvWVNNVhht .image-shape .label,#mermaid-svg-FNfhv5qvWVNNVhht .icon-shape .label{text-anchor:middle;}#mermaid-svg-FNfhv5qvWVNNVhht .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-FNfhv5qvWVNNVhht .rough-node .label,#mermaid-svg-FNfhv5qvWVNNVhht .node .label,#mermaid-svg-FNfhv5qvWVNNVhht .image-shape .label,#mermaid-svg-FNfhv5qvWVNNVhht .icon-shape .label{text-align:center;}#mermaid-svg-FNfhv5qvWVNNVhht .node.clickable{cursor:pointer;}#mermaid-svg-FNfhv5qvWVNNVhht .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-FNfhv5qvWVNNVhht .arrowheadPath{fill:#333333;}#mermaid-svg-FNfhv5qvWVNNVhht .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-FNfhv5qvWVNNVhht .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-FNfhv5qvWVNNVhht .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FNfhv5qvWVNNVhht .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-FNfhv5qvWVNNVhht .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FNfhv5qvWVNNVhht .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-FNfhv5qvWVNNVhht .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-FNfhv5qvWVNNVhht .cluster text{fill:#333;}#mermaid-svg-FNfhv5qvWVNNVhht .cluster span{color:#333;}#mermaid-svg-FNfhv5qvWVNNVhht div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-FNfhv5qvWVNNVhht .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-FNfhv5qvWVNNVhht rect.text{fill:none;stroke-width:0;}#mermaid-svg-FNfhv5qvWVNNVhht .icon-shape,#mermaid-svg-FNfhv5qvWVNNVhht .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-FNfhv5qvWVNNVhht .icon-shape p,#mermaid-svg-FNfhv5qvWVNNVhht .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-FNfhv5qvWVNNVhht .icon-shape .label rect,#mermaid-svg-FNfhv5qvWVNNVhht .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-FNfhv5qvWVNNVhht .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-FNfhv5qvWVNNVhht .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-FNfhv5qvWVNNVhht :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
输入校验:交货单号、行项目、批次必填
锁定交货单
检查交货单状态
(是否可过账)
检查物料可用性、批次
执行发货过账 (Post GI)
过账成功?
写入物料凭证
收集错误到 RETURN,错误计数+1
解锁交货单
返回结果
与手工 VL02N 不同,BAPI 会自动执行拣配确认(若未拣配则先拣配),然后直接过账。如果不需要自动拣配,需确保调用前交货单状态已经是拣配完成。
五、使用注意事项(避坑指南)
-
异步提交
调用成功后必须执行
BAPI_TRANSACTION_COMMIT,否则不会生成物料凭证。建议批量处理时,每 50 个交货单提交一次,避免 LUW 过大导致性能问题。 -
外向交货限制
此 BAPI 只能用于外向交货 (Outbound Delivery),不能用于内向交货或转储单。内向交货请使用
BAPI_INB_DELIVERY_CONFIRM。 -
批次管理物料必须传批次
若物料启用批次管理,
DELIVERYITEM中必须指定BATCH字段,否则 BAPI 会报错"批次未确定"或"请指定批次"。 -
交货单状态与前置条件
交货单必须处于"未过账"状态,且拣配已完成(或允许 BAPI 自动拣配)。如果交货单已过账或已冻结,BAPI 会报错。
-
数量与单位
指定实际发货数量时,建议同时填写
FACT_UNIT,确保单位与交货单行项目单位一致。若不填写数量,系统默认以交货单计划数量全量过账。 -
权限对象
执行此 BAPI 需要以下权限:
V_LIKP_VST(交货单的仓库权限)M_MSEG_BWA(物料凭证的移动类型权限)- 外向交货对应的 RFC 调用权限(对象
S_RFC)
-
批次拆分的处理
如果一个行项目需要拆分为多个批次,可在
DELIVERYITEM中传入多条具有相同DELIV_NUMB和DELIV_ITEM但不同BATCH和DELIV_QTY的记录,系统会自动进行批次拆分。 -
后续凭证自动生成
发货过账后,系统会自动生成物料凭证(
MSEG、MKPF),并根据后台配置自动产生财务凭证(ACDOCA)。如果财务凭证生成失败,过账也会整体回滚。
六、与 VL02N 手工过账的对比
| 维度 | VL02N 手工过账 | BAPI_OUTB_DELIVERY_CONFIRM_DEC |
|---|---|---|
| 操作方式 | 图形界面逐单操作 | 批量 RFC 调用 |
| 批次处理 | 手工指定 | 通过内表多行传入实现拆分 |
| 拣配自动完成 | 可配置 | BAPI 内自动触发拣配 |
| 错误处理 | 对话框提示 | RETURN 表返回 |
| 事务控制 | 自动提交 | 需显式 COMMIT |
| 适用场景 | 仓库手工操作 | 接口、后台、批量处理 |
七、总结
BAPI_OUTB_DELIVERY_CONFIRM_DEC 是外向交货单过账的标准 BAPI,准确理解其接口和异步机制,是实现自动化发货的关键。使用时,重点把握以下三点:
- 输入数据完整性:交货单号、行项目、批次(若需要)、数量必须准确
- 返回消息检查 :不要忽略
RETURN表中的警告和错误 - 提交策略 :调用后务必执行
COMMIT,批量处理时注意分块提交
掌握这个 BAPI 后,无论是开发仓库接口、批量过账程序,还是构建自动化物流系统,都能得心应手。
文档版本 :V1.0
最后更新:2026年7月
💬 你在使用外向交货过账相关 BAPI 时踩过哪些坑?欢迎留言分享!