SAP WS_DELIVERY_UPDATE2库存地点LGORT增强与BAPI过账一体化实践

张开发
2026/4/24 10:44:33 15 分钟阅读

分享文章

SAP WS_DELIVERY_UPDATE2库存地点LGORT增强与BAPI过账一体化实践
1. 为什么需要增强WS_DELIVERY_UPDATE2的库存地点功能在SAP的标准交货单处理流程中WS_DELIVERY_UPDATE2函数模块是个关键角色。它负责处理交货单的创建、修改和过账等核心操作。但实际业务中我们经常会遇到一个棘手的问题标准功能不允许在过账时直接修改库存地点LGORT。这个限制会给仓库管理带来不少麻烦。想象一下这样的场景某批货物原本计划存放在A仓库但在实际发货时发现A仓库已经爆仓需要临时调整到B仓库。按照标准流程你不得不先修改交货单的库存地点然后再单独执行过账操作。这不仅操作繁琐还增加了出错的风险。特别是在高频次、大批量处理的物流环境中这种效率损耗会被成倍放大。更麻烦的是两次操作之间的时间差可能导致数据不一致。比如修改了库存地点但还没来得及过账时系统显示的库存状态就会和实际情况有出入。这对需要实时掌握库存信息的仓库管理员来说简直就是个噩梦。2. BADI增强的核心原理与实现步骤2.1 认识LE_SHP_DELIVERY_UPDATE这个BADISAP其实早就考虑到了这种需求所以提供了标准的增强点LE_SHP_DELIVERY_UPDATE。这个BADIBusiness Add-In就像是系统预留的一个后门让我们可以在标准流程中插入自定义逻辑。它的UPDATE_ITEM方法会在每次处理交货单项目时被调用这正是我们需要的关键时机。我刚开始接触这个BADI时发现它的文档说明相当简略。经过多次测试才搞清楚它的is_vbpok参数包含了调用WS_DELIVERY_UPDATE2时传入的所有项目数据而cs_lips参数则是系统当前处理的交货单项目。这两个参数的结构体非常重要is_vbpok来自调用方的输入数据cs_lips系统内部处理的交货单项目数据2.2 实现库存地点修改的关键代码实际的增强代码比想象中简单得多。核心逻辑就是检查输入参数中是否指定了新的库存地点如果有就直接用它覆盖系统默认值。下面是我在项目中实际使用的代码片段METHOD if_ex_le_shp_delivery_update~update_item. IF is_vbpok-lgort IS NOT INITIAL. cs_lips-lgort is_vbpok-lgort. ENDIF. ENDMETHOD.这段代码虽然简短但有几点需要注意一定要先检查is_vbpok-lgort是否有值否则会清空原有库存地点赋值操作是直接修改cs_lips-lgort这是系统实际使用的字段整个方法没有返回值修改是通过引用参数cs_lips直接生效的3. 完整的一体化过账实现方案3.1 准备调用参数的关键要点要让这个增强真正发挥作用调用WS_DELIVERY_UPDATE2时的参数准备很关键。下面这个DEMO程序展示了完整的调用流程我加了详细注释说明每个参数的作用REPORT zprtest_dn_post. DATA: ls_vbkok_wa TYPE vbkok, 抬头控制参数 lv_delivery TYPE likp-vbeln, 交货单号 lt_prot TYPE STANDARD TABLE OF prott, 返回消息 lt_vbpok TYPE STANDARD TABLE OF vbpok, 项目数据 ls_vbpok TYPE vbpok, ls_prot TYPE prott. 假设要处理的交货单号 DATA: lv_vbeln TYPE vbeln VALUE 0070005866. 先获取交货单现有项目数据 SELECT vbeln, posnr, vgbel, vgpos, matnr, lfimg, charg, vrkme, meins, umvkz, umvkn, lgort INTO TABLE DATA(lt_lips) FROM lips WHERE vbeln lv_vbeln. 设置抬头控制参数 ls_vbkok_wa-vbeln_vl lv_vbeln. 交货单号 ls_vbkok_wa-wadat_ist sy-datlo. 实际发货日期 ls_vbkok_wa-wabuc abap_true. 更新库存 ls_vbkok_wa-komue abap_true. 更新凭证流 lv_delivery lv_vbeln. 准备项目数据关键是要设置lgort字段 LOOP AT lt_lips INTO DATA(ls_lips). ls_vbpok-vbeln_vl ls_lips-vbeln. 交货单号 ls_vbpok-posnr_vl ls_lips-posnr. 交货单项目 ls_vbpok-vbeln ls_lips-vgbel. 参考单据 ls_vbpok-posnn ls_lips-vgpos. 参考项目 ls_vbpok-pikmg ls_lips-lfimg. 数量 ls_vbpok-matnr ls_lips-matnr. 物料号 ls_vbpok-charg ls_lips-charg. 批次 ls_vbpok-vrkme ls_lips-vrkme. 销售单位 ls_vbpok-meins ls_lips-meins. 基本单位 ls_vbpok-umvkz ls_lips-umvkz. 分子转换因子 ls_vbpok-umvkn ls_lips-umvkn. 分母转换因子 ls_vbpok-lgort 9999. 关键指定新库存地点 APPEND ls_vbpok TO lt_vbpok. CLEAR ls_vbpok. ENDLOOP.3.2 执行过账与错误处理参数准备好后实际的函数调用反而很简单。但错误处理部分需要特别注意这是保证数据一致性的关键 调用WS_DELIVERY_UPDATE_2 CALL FUNCTION WS_DELIVERY_UPDATE_2 EXPORTING vbkok_wa ls_vbkok_wa 抬头控制参数 delivery lv_delivery 交货单号 update_picking abap_true 执行过账 TABLES vbpok_tab lt_vbpok 项目数据 prot lt_prot. 返回消息 处理返回消息 IF lt_prot IS NOT INITIAL. 检查是否有错误 LOOP AT lt_prot INTO ls_prot WHERE msgty E. 格式化错误消息 MESSAGE ID ls_prot-msgid TYPE ls_prot-msgty NUMBER ls_prot-msgno WITH ls_prot-msgv1 ls_prot-msgv2 ls_prot-msgv3 ls_prot-msgv4 INTO DATA(lv_message). WRITE:/ ,lv_message. ENDLOOP. 有错误时回滚 CALL FUNCTION BAPI_TRANSACTION_ROLLBACK. ELSE. 成功时提交 CALL FUNCTION BAPI_TRANSACTION_COMMIT EXPORTING wait X. MESSAGE Change and Post Successful.. TYPE S. ENDIF.4. 实际应用中的注意事项与优化建议4.1 增强实现的常见问题排查在实际项目中实现这个方案时我踩过几个坑值得分享第一个问题是增强没生效。检查发现是BADI实现没激活。解决方法是在SE18事务中检查实现是否激活并确保过滤条件正确。有时候开发系统激活了但测试或生产系统忘记激活也会导致看似代码正确但就是不生效。第二个问题是库存地点修改了但过账失败。这是因为增强只修改了交货单数据但过账时还可能受到其他限制比如库存地点是否允许该物料存放、是否有足够库存等。建议在调用前先做必要的检查避免部分成功部分失败的情况。第三个问题是性能影响。当处理大批量交货单时增强会被频繁调用。如果代码逻辑复杂可能拖慢整体处理速度。我们的优化方案是只在必要时才处理lgort字段避免在增强方法中执行数据库查询对大批量处理考虑分批提交4.2 业务校验的增强建议标准增强只做了简单的赋值实际业务中可能需要更多校验。比如METHOD if_ex_le_shp_delivery_update~update_item. 检查是否指定了新库存地点 IF is_vbpok-lgort IS NOT INITIAL. 检查新库存地点是否有效 SELECT SINGLE abap_true FROM t001l INTO DATA(lv_valid) WHERE lgort is_vbpok-lgort AND werks cs_lips-werks. IF lv_valid abap_true. cs_lips-lgort is_vbpok-lgort. ELSE. 记录错误日志 MESSAGE e398(00) WITH Invalid storage location is_vbpok-lgort INTO DATA(lv_msg). ENDIF. ENDIF. ENDMETHOD.这种增强虽然增加了安全性但要注意数据库查询会影响性能错误处理要合理避免中断整个流程考虑使用缓存机制优化频繁查询5. 与BAPI的协同工作模式5.1 在BAPI中集成库存地点修改很多企业喜欢用BAPI来集成外部系统这时我们的增强同样适用。关键是在调用BAPI前准备好vbpok_tab参数DATA: lt_vbpok TYPE TABLE OF vbpok, ls_vbpok LIKE LINE OF lt_vbpok. 为每个项目设置新库存地点 LOOP AT lt_items INTO DATA(ls_item). ls_vbpok-vbeln_vl ls_item-delivery. ls_vbpok-posnr_vl ls_item-item. ls_vbpok-lgort ls_item-new_storage_loc. 外部系统传入的新库存地点 APPEND ls_vbpok TO lt_vbpok. ENDLOOP. 调用BAPI CALL FUNCTION BAPI_OUTB_DELIVERY_CONFIRM_DEC EXPORTING handling_unit X TABLES vbpok_tab lt_vbpok return lt_return.这种模式下外部系统可以灵活指定每个项目的目标库存地点而无需担心标准限制。5.2 批量处理的性能优化当需要处理大量交货单时直接逐个调用效率很低。我们开发了一个批量处理程序核心思路是先收集所有需要处理的交货单一次性读取所有主数据使用FOR ALL ENTRIES优化数据库查询分批提交比如每100单提交一次 批量获取交货单数据 SELECT vbeln, posnr, lgort, werks FROM lips INTO TABLE DATA(lt_lips) FOR ALL ENTRIES IN lt_deliveries WHERE vbeln lt_deliveries-vbeln. 分批处理 DATA(lv_batch_size) 100. DATA(lv_total) lines( lt_deliveries ). DATA(lv_batches) ceil( lv_total / lv_batch_size ). DO lv_batches TIMES. DATA(lv_from) ( sy-index - 1 ) * lv_batch_size 1. DATA(lv_to) sy-index * lv_batch_size. 处理当前批次 LOOP AT lt_deliveries FROM lv_from TO lv_to INTO DATA(ls_delivery). 准备参数... ENDLOOP. 提交当前批次 CALL FUNCTION BAPI_TRANSACTION_COMMIT EXPORTING wait X. ENDDO.这种方案在我们的一个物流中心上线后处理效率提升了近10倍。特别是月末高峰时段原本需要2小时的作业现在只需15分钟左右就能完成。

更多文章