SAP VL10B 创建交货单禁止拆分为多个(详解例程的用法)

发布于:2025-06-25 ⋅ 阅读:(19) ⋅ 点赞:(0)


前言

      本文 8000 字+,这篇文章会持续更新优化,先 点赞 关注 收藏 制作不易 谢谢🤞

      公司最近提了这么一个需求 就是用VL10B创建STO交货单的时候不要按照交货日期去拆分为多个交货单,但根据交期拆分是SAP的标准逻辑,所以第一时间我们找了相应的增强和配置发现并没有增强或者配置让我们去限制这个,最终也是根据SAP社区提到的方式和SAP Note 377501 解决了此问题。


01、案例介绍/笔者需求

        首先我们会演示SAP系统标准拆单的效果,我们会有一个STO的采购订单 然后用VL10B创建交货单并查看生成的交货单,然后会提供参考链接和资料并解释资料里面的内容,最后我们会实操如何解决这个问题。


02、演示拆单效果

          这里如果不会不懂数据和业务的话可以让业务顾问帮忙做点数据。我这边就不会演示如何创建STO订单了 直接介绍我们的采购订单 并用VL10B进行交货单的创建。

            a.ME21N查看STO采购订单

                      这里我们主要观察交期字段即可 后面会介绍到SAP会根据哪些字段进行拆单的标准逻辑。
                       a.ME21N
                            可以看到我们前5个行项目交货日期都是20250718最后一行交期是20250618。
在这里插入图片描述

            b.VL10B根据采购订单创建交货单

                      这里我们使用事务码VL10B参考上面的采购订单来创建交货单。
                       a.VL10B选择界面
                            按照如下图操作 只输入对应的采购订单 其余输入框字段都可以删掉。
在这里插入图片描述
                       b.创建交货单
                            全选然后点后台在这里插入图片描述
                       c.查看交货单
                            后台点击完等待创建完之后 点击车车标志 可以看到创建出来了两个交货单。VL03N(直接点击也可以)查看创建出来的两个交货单 可以看到它是按照交期拆分的,这个就是拆单的效果,现在业务不想让他拆开 想取最近的交期 合并为一个交货单。
在这里插入图片描述
在这里插入图片描述

03、参考链接资料解读

          这里我们找到SAP社区和Note提到的解决方式。

            a.社区解读

                      这里我们详解社区里面提到的问题和大神们提出的解决方式
                       a.社区链接
                            点击跳转 社区里面提到的问题 也就是我现在讲的问题。

                       b.社区提到的问题和场景
                            1、 问题: 如何在使用事务代码 VL10B 创建外向交货单时,将多个具有不同交货日期的采购订单(STO - 库存转储订单)合并到一张交货单中。
                            2、 场景: 公司内部的库存转储(STO),从工厂(Plant)转到仓库(Warehouse)。
                            3、 流程: ① MRP(物料需求计划)运行后,会根据不同的需求日期在计划协议(Scheduling Agreement)中生成多个具有 不同交货日期 的计划行。② 工厂使用事务代码 VL10B 基于这些计划协议或采购订单来创建外向交货单。
                            4、 问题点: SAP的标准行为是,如果采购订单的计划交货日期不同,VL10B 会为每个不同的日期 创建一张单独的交货单(即交货单被拆分了)。
                            5、 业务痛点: 这种拆分导致了物料处理(收发货)和仓库管理(入库)的巨大困难,因为实际上这些货物可能是一起运输的。他们希望无论计划交货日期是否相同,都能合并成 一张 交货单。

                       c.社区专家们的回答与讨论要点:
                            1、 确认标准系统行为: 专家们首先确认,交货日期是SAP系统中合并拆分交货单的 关键标准之一。如果以下任何一个关键字段不同,系统就会拆分交货单:交货日期 (Delivery Date)收货方 (Ship-to Party)发货点 (Shipping Point)装运条件 (Shipping condition)路线 (Route) 所以提问者遇到的情况是SAP的标准设计。
                            2、 为什么系统这样设计: 交货日期被视为计划和可用性检查(ATP)的核心。将不同交-货日期的项目合并,可能会绕过系统的计划逻辑,导致数据不一致。因此,SAP不推荐轻易修改这个逻辑。
                            3、 提出的解决方案(需要ABAP开发): 社区专家们普遍认为,没有标准的配置 可以直接实现这个需求。解决方案指向了 增强(Enhancement)和代码修改。核心方向: 通过修改后台的代码逻辑,在创建交货单时,强制让系统忽略原始的计划交货日期,或者将它们统一成一个相同的日期(比如当天的日期)。
                       d.具体技术点:
                            1、 复制控制 (Copying Control): 这是从源单据(如采购订单)到目标单据(如交货单)的数据传输规则。事务代码是 VTLA
                            2、 数据传输例程 (Data Transfer Routine): 在复制控制的配置中,可以指定一个例程(一个ABAP程序)。讨论中多次提到了 例程 301(通常用于订单到交货单的抬头)。
                            3、 修改建议: 在这个例程中加入代码,在创建交货单时,将交货单抬头层面的计划交货日期字段 (LIKP-LFDAT) 硬编码 (hard-code) 为一个统一的日期,例如 sy-datum(系统当前日期)。这样,所有被选中的采购订单项目在交货单创建时都会被视为拥有相同的交货日期,从而实现合并。
                            4、 警告: 专家也提醒,直接修改这种核心逻辑需要非常谨慎,要充分测试,因为它可能会对计划、运输和报告产生意想不到的副作用。

            b.SAP Note 377501 解读

                      SAP Note 377501的核心内容是关于 “由于计划行(Schedule Lines)中的交货日期不同而导致交货单被拆分” 的问题,并提供了通过ABAP代码修改来解决这个问题的具体方案。点击跳转
                       a.问题症状 (Symptom)
                            当用户尝试(例如通过事务代码 VL10B, VL10D, VL10G 等)为一个采购订单(通常是库存转储订单 STO)创建外向交货单时,如果这个采购订单的多个计划行(Schedule Lines)中包含了不同的交货日期,系统会为每一个不同的日期创建一张单独的交货单。例如,一个STO有两个计划行,一个要求在6月10日交货,另一个要求在6月15日交货。在标准系统中,运行 VL10B 或类似事务代码会产生两张而不是一张交货单。这会导致运输和仓库处理效率低下。
                            这个问题在处理库存转储订单(STO)或计划协议时尤其常见,因为这些订单中可能包含许多具有不同交货日期的计划行(Schedule Lines),其中很多交货日期可能已经过期(在过去)。

                       b.原因 (Reason and Prerequisites)
                            1、 SAP标准设计: 交货日期 (LFDAT) 是交货单抬头(表 LIKP)的一个关键字段。在创建交货单时,如果系统发现多个参考项目(来自一个或多个采购订单)的计划交货日期不同,为了保持计划的准确性,它会为每个不同的日期创建一个单独的交货单,这是SAP后勤执行(Logistics Execution)模块的核心设计之一,确保了交货单的计划、拣配、过账日期等信息的一致性。
                            2、 业务需求冲突: 用户的实际业务需求(例如,将一周内的所有货物一次性发运)与SAP的标准计划逻辑发生了冲突。

                       c.解决方案 (Solution)
                            该SAP Note提供了一个具体的 ABAP开发解决方案,它不是通过标准配置实现的,而是通过修改系统后台的代码。方案的核心是修改 复制控制 (Copying Control) 中的 数据传输例程 (Data transfer routine)。
                            1、 定位到例程: 需要修改的例程是 301(或其拷贝),这个例程通常用于处理“订单到交货单(抬头层面)”的数据复制。可以通过事务代码 VTLA (复制控制:交货凭证到销售凭证) 来查看和配置。
                            2、 修改代码逻辑: Note中提供了一段示例代码,需要由ABAP开发人员添加到例程 301 中。这段代码的核心作用是在创建交货单的 瞬间,强行将交货单抬头的 计划交货日期 (LIKP-LFDAT) 设置为一个固定的值。最常用的做法是将其设置为 系统当前日期 (sy-datum)。
                            3、 实现效果: 当代码被激活后,无论源采购订单的计划行中有多少个不同的交货日期,当它们被一起处理以创建交货单时,系统在后台会将它们的交货日期“视为”同一个(即当天的日期)。由于这个关键的拆分标准(交货日期)被人为地统一了,系统就不会再拆分交货单,从而将所有项目合并到 一张交货单 中。

                       d.关键点
                            它不是SAP的标准功能,在系统升级时可能需要重新评估和调整。它需要ABAP开发人员介入,业务顾问无法通过后台配置(SPRO)完成。

            c.SAP Note 386340 解读

                      这篇 SAP Note 386340 提供了一个 “咨询方案” (Consulting Solution),旨在解决 库存转储订单(STO)在创建外向交货单时,因交货日期不同而导致交货单被拆分 的问题。与上面提到的Note不同,这个Note提供了一个全新的、可配置的ABAP功能,让用户可以自己选择如何处理不同的交货日期,从而控制交货单的合并。
                       a.问题症状 (Symptom)
                            同上

                       b.解决方案 (Solution):
                            这个Note不再是简单的代码修改建议,而是提供了一个完整的“增强包”。它需要ABAP开发人员实现一个新的功能模块(Function Module)和相关的代码,一旦实现,业务用户就可以通过设置参数来控制交货单的合并行为了。
                            它提供了以下三种不同的处理模式,让用户可以根据自己的业务需求来选择:
                            1、 模式 1:所有项目使用最早的日期 (Option 1: Earliest Date): 在所有被选中要创建交货单的STO项目中,找出最早的那个计划交货日期,然后把这个日期作为统一的交货日期,应用到最终生成的那一张交货单上。
                            2、 模式 2:所有项目使用创建交货单的当天日期 (Option 2: Creation Date): 忽略所有STO项目中原始的计划交货日期,强制使用创建交货单的当天日期 (sy-datum) 作为统一的交货日期。
                            3、 模式 3:在指定时间范围内的项目使用最早日期 (Option 3: Earliest Date within a Timeframe): 这个模式最灵活。它允许用户设定一个时间窗口(比如7天)。系统会找出所有被选项目中最早的交货日期,然后将这个日期之后7天内所有其他的项目都“拉”到这个最早日期上,合并成一张交货单。超出这个7天时间窗口的项目,则会单独创建交货单。可以实现“把未来一周内的订单合并发货”这样的灵活业务场景。

                       c.与上个Note的对比和总结
                            此Note是一个强大的“工具箱”。它通过一次性开发,提供多种可配置的选项,不仅能处理过去和今天的日期,还能灵活处理未来的日期,甚至可以按时间窗口进行合并。它是一个更完整、更具扩展性的咨询解决方案。是一个强大的“工具箱”。它通过一次性开发,提供多种可配置的选项,不仅能处理过去和今天的日期,还能灵活处理未来的日期,甚至可以按时间窗口进行合并。它是一个更完整、更具扩展性的解决方案。但是笔者目前也不知道具体怎么实现。

04、实操解决

          这里我们将采用SAP Note 377501 中提到的解决方案来实现 也就是通过复制控制例程的方法,同时我们也能了解学习例程是什么以及如何使用。

            a.复制控制 和 例程 是什么

                      既然我们要用到复制控制 和 例程 那么就得先了解学会使用这个东西。
                       a.简单比喻
                            想象一下你在复印一份文件,但你有一些特殊要求:
                            1、 复制控制 (Copying Control): 就像是复印机的 “设置面板”。你在这里设定基本规则,比如:“从A文件(原件)复制到B文件(复印件)”、“只复制第一页和第三页”、“复印件的页眉要自动加上‘复印’二字”。
                            2、 例程 (Routine): 就像是你给复印机下达的一个 “特殊指令程序”。标准设置面板满足不了你的复杂需求,比如你说:“如果原件的第一页上有‘机密’两个字,那就在复印件的每一页都盖上红色的‘保密’章”。这个“如果…那么…”的复杂判断逻辑,就是一个“例程”。

                       b.复制控制 (Copying Control) 是什么
                            在SAP中,复制控制 是一套后台配置规则,它定义了当一个凭证被参考创建另一个凭证时,数据应该如何从源凭证传输到目标凭证。简单来说,它是SAP系统中 数据流动的“规则手册”。

                            复制控制的作用👇
                            1、 决定能否创建: 设定什么类型的订单可以创建什么类型的交货单或发票。例如,你可以设定 OR (标准订单) 可以创建 LF (外向交货单),但不能创建 RE (退货交货单)。
                            2、 控制数据传输: 精确定义哪些字段的数据需要从源凭证(如销售订单)复制到目标凭证(如交货单),以及如何复制。比如,客户信息、物料、数量、价格、合作伙伴等。
                            3、 确保业务流程的连续性和一致性: 它是连接销售、发货、开票等各个环节的桥梁。

                            复制控制用哪些事务码配置👇
                            1、 SPRO: 熟悉后台配置的顾问可以从SPRO找
                            2、 VTAA: 销售订单 -> 销售订单 (如:报价单 -> 订单)
                            3、 VTLA: 销售订单 -> 交货单
                            4、 VTAF: 销售订单 -> 发票
                            5、 VTFL: 交货单 -> 发票

                            在以上这些配置界面,你可以设定源单据类型和目标单据类型之间的复制关系,包括对抬头(Header)、项目(Item)和计划行(Schedule Line)层级的详细控制。

                       c.例程 (Routine) 是什么?
                            例程 是一小段专门的ABAP代码程序,它被嵌入到“复制控制”的特定节点上,用来执行标准的配置无法实现的 复杂逻辑判断或数据处理。
                            例程的作用👇
                            1、 数据传输例程 (Data Transfer Routine): 在数据从源单据复制到目标单据的过程中,对某个字段进行特殊的修改或计算。Note 377501 中提到的就是这种例程。比如,在复制交货日期时,不直接复制,而是先判断一下,如果日期是过去,就改成今天。
                            2、 复制条件例程 (Copying Requirement Routine): 用来判断一个项目或整个凭证是否满足被复制的条件。比如,你可以写一个例程规定:“只有当订单中的项目库存已经确认时,才允许创建交货单”。如果例程的判断结果为“不满足”,则该项目或凭证就会被阻止复制。

                            例程怎么用👇
                            1、 例程是在上述的复制控制配置界面中进行指派的。
                            2、 ABAP程序员先通过事务代码 VOFM 创建或复制一个新的例程,并在其中编写特定的ABAP代码逻辑。
                            3、 后台顾问在 VTLA 等复制控制配置中,将系统标准的例程编号,替换成程序员新创建的例程编号。

                       d.总结
                            也就是说我们SAP系统中是存在许多标准例程的,这些例程都是对各种单据做数据的处理,这些例程在哪里用是通过复制控制来决定的,可能我创建内向外向交货单都会用到302这个例程 而我sto交货单可能配置的又是301这个例程,复制控制其实是在业务类型单据类型级别的 如果类型不对应也就不会调用对应的例程对单据数据做特殊的处理。
                            也可以这么举例更好的理解👇
                            1、 SAP系统是一个巨大的“工具箱: 里面预置了成百上千个标准例程 (Standard Routines)。每一个例程就是一个实现特定功能的“小工具”(比如:检查信贷、合并文本、计算日期等)。
                            2、 例程本身只是待命的“工具”: 它们静静地存放在代码库中 (VOFM),如果不被调用,就什么也不会发生。
                            3、 复制控制是“项目计划书”或“总开关”: 它详细规定了整个业务流程(如“从订单到交货”)的每一个步骤。在计划书的特定节点上,它会明确指出:“在这一步,请调用XXX号例程(工具)来完成工作”。

                            正是通过复制控制的灵活配置,顾问可以选择使用SAP的标准例程,或者让ABAP程序员开发一个新的自定义例程,并把它指派到相应的业务流程中,从而在不修改SAP核心代码的情况下,实现企业个性化的需求。

            b.DEBUG测试验证

                      上面我们已经了解清楚了复制控制和例程是什么 再加上社区和Note提到的解决方案我们可以验证一下使用例程301是否能实现我们的需求。
                       a.查找301这个例程
                            事务码 VOFM 可以找到这个标准的例程 301
在这里插入图片描述
                       b.打上断点
                            我们双击例程301进入代码界面 搜索 交期相关字段 社区中提到了字段 LFDAT 是交期,或者我们在LIKP交货单抬头表搜索 交货日期也可以搜到此字段。
在这里插入图片描述
                            按照下图操作步骤给84行打上断点
在这里插入图片描述
                       c.上面说错了纠正一下
                            针对我们当前的业务场景对应的include 程序是SAPLV50S,虽然这两个条目点进去都是同一个perform 但是在打断点的时候还是要进入对应的程序,如果你给 SAPFV50C 对应的perform 打上断点,但系统实际运行时调用的是 SAPLV50S对应的 perform,那你打的 GUI 断点是不会命中的。如果你给这个perform中写了 BREAK-POINT. 是硬断点,不管在哪个程序 include 进来都会卡住。我在做这一步的时候就发现昨天断点还可以顺利进入 写到这里做案例的时候 断点死活都不起作用 ,但是我清楚例程是被调用了的 因为我已经有禁止拆分的例程了 我配置了该例程之后 发现不会拆分了 然后给代码里面写了BREAK-POINT 发现可以卡住,但是手动断点就是卡不住(进错了include),所以在遇到断点卡不住的情况 大概率是 include 程序不对。
在这里插入图片描述
                       c.手动干预修改赋值数据
                            断点打好之后就可以去VL10B 创建交货单了,点击后台之后就会进入我们断点的位置 然后可以观察一下断点界面的一些数据。进入断点界面之后可以看到我们采购订单的行项目存在于XKOMDLGN[]内表中 最后一行的行项目交期和前5行是不一样的,我们要做的就是给84行的 likp-lfdat 赋值的时候一定要赋值为一样的日期,我们可以按F8一共需要按5次就会到第6个行项目赋值交期的时候 然后把这个交期赋值改为 20250718 这样我们会发现创建完之后只有一个交货单。
在这里插入图片描述
                            手动干预修改交期赋值之后效果如下👇
在这里插入图片描述

            c.复制例程代码编写

                      经过上面的验证之后 我们已经清楚vl10b交货单创建的时候一定会调用这个例程,那么也就可以推断出来系统中的复制控制一定配置了这个301例程,不然不会被调用。所以现在我们需要做的就是找到对应的配置点 然后把标准的例程替换掉。
                       a.找到对应的配置点
                            这一步我们可以请教业务顾问协助我们查找,因为我们是涉及交货单的所以对应事务码应该是VTLA,当然SPRO也是可以找到的。我问了业务顾问之后业务顾问指出我们当前对应的业务应该是 NLCC 跨公司补货 。进入之后发现确实配置了301这个例程,我们还会发现其他的交货类型也配置了301例程 所以这个例程是通用的,但是我们公司的需求只是针对公司间采购订单也就是跨公司补货这种类型,所以我们不能直接去改301例程的代码,一般也都是参考301创建一个新的例程然后配置到对应的复制控制,这也体现出了复制控制和例程的灵活性。
在这里插入图片描述
在这里插入图片描述
                       b.复制例程修改代码
                            1、 创建新的例程:
在这里插入图片描述
                            2、 插入: 可以看到我们创建出来的包含文件是 RV50C<例程编号>,所以我们只能用插入代码的这种形式写代码。
在这里插入图片描述
                            3、 复制301的代码 和 修改代码: 把301的代码复制到我们902之后 激活 会弹出增强点的弹框 这一步可以按照如下图操作,我这个操作不知道是不是一个合理的方式,反正让我们902这个程序激活即可。然后把交期赋值那一行改为sy-datum 我这个只是测试 实际情况可以根业务商量怎么赋值交期。
在这里插入图片描述

在这里插入图片描述

                            4、 激活VOFM例程: 上面我们是代码的激活 现在还要针对VOFM的例程激活。
在这里插入图片描述

            d.配置例程

                      当我们例程创建编写好激活之后就可以把标准的例程替换掉了。
                       a.替换
                            具体的配置替换点我们上面已经说过了,如下图所示。这个生产机的配置最好让业务顾问去配置 因为配置的传输路径 业务比较清楚一点 ,我们测试机配完之后 就可以去VL10B创建交货单 了之后就会发现交期始终是当前日期了。也就不会拆分去创建交货单了。
在这里插入图片描述
                       c.生产机例程激活
                            如果传输到生产机之后发现例程没有激活那么就se38跑一下 RV80HGEN 程序

END、总结

        以上就是今天要讲的内容,本文仅仅简单介绍了SAP交货单禁止拆单的方法,感觉这篇文章自己有学到东西或者在今后的工作中能派上用场,可以点赞收藏支持!!!制作不易非常感谢,当然如果有说错或者不好的地方还望大家提出来见谅,欢迎大家评论指出不好的地方。谢谢!


网站公告

今日签到

点亮在社区的每一天
去签到