尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

SAP ABAP开发:使用BAPI_OUTB_DELIVERY_CHANGE取消外向交货单拣配

SAP ABAP开发:使用BAPI_OUTB_DELIVERY_CHANGE取消外向交货单拣配 1. 项目概述为什么需要取消外向交货单的拣配数量在SAP的物流执行模块中外向交货单Outbound Delivery是连接销售订单与货物实际出库的关键单据。拣配Picking是其中核心的一步它意味着仓库人员根据交货单从库存中“锁定”并准备出相应数量的货物。然而在实际业务中取消拣配数量的需求非常普遍。比如客户临时更改订单、发现拣配的货物有质量问题需要换货、或者仓库操作员误操作提前完成了拣配这些情况都需要将已经确认的拣配数量“回退”到未拣配状态以便后续进行修正、重新拣配或直接取消发货。这个功能在SAP的标准事务码VL02N更改外向交货单中虽然提供了“取消拣配”的按钮或菜单项但其背后的逻辑和影响却并不简单。很多ABAP开发新手甚至是有经验的顾问在处理相关增强、报表或接口时如果直接去修改底层数据库表如LIPS-VSPEM往往会引发数据不一致、状态混乱甚至导致后续发货过账Post Goods Issue失败。因此深入理解SAP标准提供的取消拣配接口并掌握其正确的调用方式是每个涉及LELogistics Execution模块开发的ABAPer必须啃下的硬骨头。这不仅关乎功能实现更关乎系统数据的完整性与稳定性。2. 核心逻辑与标准功能解析2.1 外向交货单的拣配状态管理要理解如何取消必须先明白SAP如何管理拣配状态。外向交货单的行项目数据主要存储在LIPS表中。其中与拣配相关的关键字段有VSPEM拣配状态这是一个单字符的状态标识。A代表“已计划拣配”B代表“部分拣配”C代表“完全拣配”。当数量全部取消后此字段应被清空。PKIMG已拣配数量这是一个数值字段记录了当前行项目已被确认拣配的数量总和。KOMUE部分数量已移交与WM仓库管理模块集成时相关。拣配数量的确认通常通过事务码VL06O创建拣配单或VL02N中的拣配功能完成最终会更新LIPS-PKIMG和LIPS-VSPEM。核心原则是永远不要通过直接UPDATELIPS表来修改这些值。因为这绕过了SAP标准的所有业务逻辑检查、凭证流更新和后续操作锁极易产生脏数据。2.2 标准取消拣配的入口BAPI与函数模块SAP为业务操作封装了标准的函数模块Function Module和BAPIBusiness Application Programming Interface。对于取消拣配最核心、最推荐使用的是BAPI_OUTB_DELIVERY_CHANGE。这个BAPI功能强大可以处理外向交货单的多种更改其中就包括“取消拣配确认”。它的设计理念是基于“更改凭证头”和“更改凭证项”的结构化输入。对于取消拣配我们需要在行项目层级上指定更改类型。此外底层还有一个更直接的函数模块WS_REVERSE_GOODS_ISSUE。 虽然它的名字是“冲销发货”但其参数设计可以用于冲销取消包括拣配、包装、发货在内的多种前期操作。不过它的使用需要更谨慎因为参数复杂且直接作用于凭证流。在我们的实现场景中BAPI_OUTB_DELIVERY_CHANGE是首选因为它更面向业务、有更好的错误处理机制并且与SAP标准的更改逻辑保持一致。3. 使用BAPI_OUTB_DELIVERY_CHANGE实现取消拣配3.1 BAPI调用参数详解调用BAPI_OUTB_DELIVERY_CHANGE的关键在于构建正确的输入参数。主要关注以下两个内表HEADER_DATA交货单头数据通常只需要传入DELIV_NUMB交货单号。其他字段如发货点、过账日期等除非需要同时更改否则保持初始值。ITEM_DATA行项目数据这是实现取消拣配的核心。对于需要操作的每一个行项目都需要在此内表中指定一行。关键字段包括DELIV_NUMB: 交货单号。DELIV_ITEM: 交货单行项目号。CHG_DELQTY: 更改类型对于取消拣配此处必须填入U。U代表“更新”在这个上下文中特指更新与数量确认相关的操作。PICK_QTY:这里是最容易出错的地方要取消拣配不是将PICK_QTY设为0而是应该传入你希望取消后剩余的已拣配数量。例如如果某行PKIMG当前已拣配为10 EA你想全部取消则PICK_QTY应传入0。如果只想取消5个剩余5个仍保持拣配状态则PICK_QTY应传入5。ITEM_DATA_OV行项目控制数据此内表用于控制哪些字段的更改需要被检查和处理。通常对于PICK_QTY的更改需要在此内表中对应行的PICK_QTY字段置为X表示该字段是待更改的。RETURN返回消息表这是BAPI调用的标准返回参数用于接收成功、警告、错误等信息。必须在调用后检查此内表。3.2 完整的ABAP实现代码示例与步骤下面是一个完整的函数方法演示如何针对单个外向交货单的指定行项目取消其全部拣配数量。FUNCTION zfm_delivery_cancel_picking. *---------------------------------------------------------------------- **本地接口 * IMPORTING * VALUE(IV_VBELN) TYPE VBELN_VL * VALUE(IV_POSNR) TYPE POSNR_VL * EXPORTING * VALUE(ET_RETURN) TYPE BAPIRET2_T *---------------------------------------------------------------------- DATA: lt_header_data TYPE TABLE OF bapiobdlvhdrchg, ls_header_data TYPE bapiobdlvhdrchg, lt_item_data TYPE TABLE OF bapiobdlvitemchg, ls_item_data TYPE bapiobdlvitemchg, lt_item_data_ov TYPE TABLE OF bapiobdlvitemchgx, ls_item_data_ov TYPE bapiobdlvitemchgx, lt_return TYPE TABLE OF bapiret2. DATA: lv_delivery TYPE vbeln_vl. DATA: lv_picked_qty TYPE lfimg. CLEAR: et_return. * 1. 数据准备与检查 lv_delivery iv_vbeln. SHIFT lv_delivery LEFT DELETING LEADING 0. * 读取当前交货单行项目的已拣配数量 SELECT SINGLE pkimg FROM lips INTO lv_picked_qty WHERE vbeln iv_vbeln AND posnr iv_posnr. IF sy-subrc 0 OR lv_picked_qty IS INITIAL. APPEND VALUE #( type E id ZDELIVERY_MSG number 001 message_v1 |{ iv_vbeln }/{ iv_posnr }| ) TO et_return. RETURN. ENDIF. * 2. 构建BAPI调用参数 * 2.1 头数据 ls_header_data-deliv_numb lv_delivery. APPEND ls_header_data TO lt_header_data. * 2.2 行项目数据关键步骤 ls_item_data-deliv_numb lv_delivery. ls_item_data-deliv_item iv_posnr. ls_item_data-chg_delqty U. 更改类型U - 更新数量相关 ls_item_data-pick_qty 0. 目标已拣配数量0意味着全部取消 APPEND ls_item_data TO lt_item_data. * 2.3 行项目控制数据指明要更改PICK_QTY字段 ls_item_data_ov-deliv_numb lv_delivery. ls_item_data_ov-deliv_item iv_posnr. ls_item_data_ov-pick_qty X. X 表示此字段需要被更改 APPEND ls_item_data_ov TO lt_item_data_ov. * 3. 调用BAPI执行取消拣配 CALL FUNCTION BAPI_OUTB_DELIVERY_CHANGE EXPORTING header_data ls_header_data header_control VALUE #( ) 头控制通常为空 delivery lv_delivery TABLES item_data lt_item_data item_control lt_item_data_ov return lt_return. * 4. 错误处理与提交 READ TABLE lt_return TRANSPORTING NO FIELDS WITH KEY type E OR type A. IF sy-subrc 0. * 存在错误或终止消息不提交直接返回错误 et_return lt_return. ELSE. * 没有严重错误执行提交 CALL FUNCTION BAPI_TRANSACTION_COMMIT EXPORTING wait X. * 可以添加成功消息 APPEND VALUE #( type S id ZDELIVERY_MSG number 002 message_v1 |{ iv_vbeln }/{ iv_posnr }| ) TO lt_return. et_return lt_return. ENDIF. ENDFUNCTION.3.3 关键注意事项与实操心得数量逻辑是“目标值”不是“增减值”这是最关键的坑。ITEM_DATA-PICK_QTY传入的是执行操作后你希望系统记录的已拣配数量而不是要减少的数量。传入0是清零传入比当前PKIMG小的值则是部分取消。必须指定更改类型CHG_DELQTY U这个字段告诉BAPI你要进行的是与交货数量相关的更改。如果省略或填错BAPI可能忽略你对PICK_QTY的修改或者报错。控制表ITEM_DATA_OV必须配套如果你在ITEM_DATA中修改了PICK_QTY就必须在ITEM_DATA_OV的对应行将PICK_QTY字段标记为X。否则BAPI会认为你并没有意图修改这个字段你的输入值会被忽略。提交事务BAPI_OUTB_DELIVERY_CHANGE本身不执行数据库提交。必须在检查RETURN内表没有E/A类错误后显式调用BAPI_TRANSACTION_COMMIT。如果是在一个更大的事务中调用此BAPI则需要根据整体逻辑决定提交时机。交货单号前导零处理BAPI通常期望传入没有前导零的交货单号外部编号格式而从LIPS-VBELN直接读取的是带前导零的内部编号。使用SHIFT ... LEFT DELETING LEADING 0是常见的处理方式。务必保持所有参数中使用的交货单号格式一致。4. 高级场景与深度处理4.1 批量取消与部分取消的实现实际业务中更常见的是批量操作。例如根据某些条件如销售订单、工厂、发货点筛选出一批需要取消拣配的交货单行项目。实现思路是使用SELECT语句从LIPS表中获取符合条件的行项目列表包含VBELN,POSNR,PKIMG。循环内表为每一行构建上述的ITEM_DATA和ITEM_DATA_OV条目。注意BAPI_OUTB_DELIVERY_CHANGE一次调用可以处理单个交货单的多个行项目。但通常不建议一次性跨多个交货单调用同一个BAPI。更好的做法是外层循环交货单内层为该单构建所有行项目参数然后逐单调用BAPI。这样错误隔离性好便于处理。对于部分取消只需在构建ls_item_data-pick_qty时传入计算后的目标值即可。例如目标值 当前PKIMG - 欲取消数量。4.2 与WM仓库管理集成的特殊考量如果启用了SAP WMWarehouse Management模块拣配操作会生成传输单Transfer Order。此时取消外向交货单的拣配必须首先冲销或删除相关的WM传输单。步骤通常是使用函数TO_DISPLAY或通过事务码LT24检查该交货单行项目关联的传输单号。使用函数L_TO_DELETE或BAPIBAPI_TRANSFERORDER_DELETE需注意权限和前提条件删除或冲销传输单。待WM层面的操作完成后再执行上述取消交货单拣配的步骤。 如果跳过WM直接取消交货单拣配系统会报错例如“存在开放的WM凭证”导致操作失败。4.3 增强与校验BADI/USEREXIT的触发当你通过BAPI取消拣配时SAP标准的相关增强点如BADILE_SHP_DELIVERY_PROC和用户出口User Exit会被正常触发。这意味着你需要考虑自定义逻辑的影响如果系统中存在针对拣配确认/取消的增强校验你的BAPI调用可能会被这些增强拦截或附加额外操作。在开发测试时务必确认这些增强的逻辑。你可以利用这些增强点如果业务要求在取消拣配时执行一些特殊操作如写自定义日志、调用外部接口可以在相应的增强点例如CHANGE_DELIVERY_HEADER或CHANGE_DELIVERY_ITEM方法中实现确保无论是前台VL02N操作还是后台BAPI调用逻辑都能统一执行。5. 常见错误排查与调试技巧5.1 典型错误消息与解决方案错误消息/现象可能原因解决方案Delivery is not changeable(交货单不可更改)交货单已发货过账状态为C或已被后续凭证锁定。使用VL03N查看交货单状态。已过账的发货单需先冲销发货VL09。No change items passed(未传递更改项)ITEM_DATA内表为空或CHG_DELQTY字段未填写或值不正确。检查是否成功填充了ITEM_DATA并确保CHG_DELQTY U。Field PICK_QTY is not marked for change(字段PICK_QTY未标记为更改)未在ITEM_DATA_OV控制表中将对应行的PICK_QTY字段置为X。确保为每个在ITEM_DATA中修改的行在ITEM_DATA_OV中都有对应且PICK_QTY X。Picked quantity cannot be reduced to (拣配数量不能减少到)传入的PICK_QTY目标值不合理。例如试图取消的数量超过了当前已拣配量或目标值为负数。检查计算逻辑。确保目标值 当前PKIMG - 取消数且目标值 0。WM transfer order exists for delivery item(存在WM传输单)启用了WM且存在未完成的传输单。先处理WM传输单冲销或删除再取消交货单拣配。5.2 调试与日志记录建议使用系统调试器在BAPI_OUTB_DELIVERY_CHANGE函数内部设置断点可以清晰地看到参数是如何被传递和处理的以及错误是在哪个检查点抛出的。重点关注函数组MV50AFZ1中的子例程。检查RETURN表BAPI调用后务必循环RETURN内表将所有类型S, W, E, A, I的消息都记录下来用于分析。可以使用函数MESSAGE_STORE或直接写入应用日志。模拟VL02N操作在测试时先在GUI中用VL02N手动取消一次拣配同时用/h激活调试观察系统在后台调用了哪些函数和使用了哪些参数。这能为你的程序开发提供最准确的参考。数据一致性检查操作前后使用SE16N查看LIPS表相关字段VSPEM,PKIMG的变化同时也可以检查相关凭证流表如VBFA是否正常。确保你的操作与标准前台操作产生的结果一致。取消外向交货单拣配数量是一个典型的“知其然更要知其所以然”的ABAP开发任务。它要求开发者不仅会调用BAPI更要理解SAP LE模块的底层状态管理和业务流程。遵循标准接口谨慎处理数据充分考虑集成场景才能开发出稳定、可靠且易于维护的程序。在实际项目中将上述代码封装成一个可重用的函数或类方法并辅以完善的错误处理和日志能极大地提升后续运维的效率。
返回列表