1. 独立需求与相关需求:MRP逻辑的基石,你真的分清了吗?
刚接触SAP PP模块的朋友,一听到MRP(物料需求计划)运行,是不是就觉得头大?后台参数一大堆,跑出来的结果有时候跟预想的完全不一样。别急,这事儿我当年也经历过,踩过不少坑。今天咱们就从一个最基础,但也最容易混淆的概念聊起:独立需求和相关需求。这俩要是搞不明白,后面看MRP结果就跟看天书没区别。
你可以把物料需求想象成一场家庭聚餐。独立需求,就像是你的客人直接点名要的菜。比如,你儿子说:“爸,我想吃红烧排骨。”这个“红烧排骨”的需求,是直接、明确地来自于最终消费者(销售订单)或者你自己的计划(计划独立需求)。在SAP里,销售订单、计划独立需求(PIR)产生的需求,就是典型的独立需求。系统会把它当作一个必须被满足的“最终目标”来处理。
那相关需求呢?它就像是做“红烧排骨”这道菜本身需要的各种食材。你儿子要的是排骨(成品),但为了做出这道菜,你需要去准备:排骨、酱油、生姜、白糖等等。这些酱油、生姜的需求,并不是客人直接要的,而是因为你要做“排骨”这道菜(生产订单或计划订单)才派生出来的。在SAP中,当你为成品创建计划订单或生产订单时,系统会根据BOM(物料清单)一层层展开,计算出所有下级原材料、半成品的需求,这些就是相关需求。
我举个实际项目里的例子。我们当时有个产品A,是直接卖给客户的。客户下了销售订单,要100个A。这100个A的需求,就是独立需求。系统运行MRP后,会为A生成计划订单。当我们把这个计划订单转成生产订单(或者MRP直接建议转),系统就会去读A的BOM,发现生产1个A需要2个零件B和5个零件C。那么,系统就会自动产生对200个B和500个C的相关需求。你看,B和C的需求,完全是因为A的需求而“相关”产生的。
这里有个关键点,直接影响MRP结果:需求类型的配置。在物料主数据的MRP1视图里,有个“需求类型”字段。对于成品A,我们通常配成“独立需求”相关的类型,比如LFF(由销售订单消耗的计划独立需求)或VSE(销售订单需求)。而对于零件B和C,我们通常配成“相关需求”类型,比如KB。如果配反了,比如把零件B也配成了独立需求类型,那系统可能会“双倍”跑出需求:一次是作为A的相关需求,另一次是系统以为它自己也有独立的销售需求,那就乱套了。
所以,下次看MD04(库存/需求清单)时,先分清哪些行项目是“独立需求”,哪些是“相关需求”。独立需求是需求的源头,相关需求是衍生的枝叶。理解了这个,你就看懂了MRP故事的第一页。
2. MRP vs MPS:不只是事务代码不同,更是计划层级的战略分野
很多朋友,包括一些有几年经验的顾问,可能都认为MRP和MPS(主生产计划)就是一回事,只不过用的T-CODE不同:MRP用MD01/MD02,MPS用MD41/MD42。我以前也这么想过,直到在一个项目上吃了大亏。实际上,它们的核心差别在于计划层级和管控对象,这直接决定了你的计划稳定性和可执行性。
你可以把整个生产计划体系看作一场战争。MPS就是战略指挥部,负责制定关键战役(关键产品)的总攻计划;而MRP是后勤部和各个兵团,负责根据总攻计划,去调度具体的兵力(半成品)、粮草(原材料)、弹药(采购件)。MPS管的是“龙头”物料,通常是那些直接面对市场的最终产品、重要的半成品或者有产能瓶颈的关键物料。这些物料需求波动会直接影响整个供应链,所以需要被单独、稳定地计划。
而MRP则负责所有物料,包括那些被MPS计划的关键物料的下级所有组件。MPS运行后,其计划结果(计划独立需求)会成为MRP运行的输入之一。举个例子,我们有个汽车组装厂,整车X就是MPS物料。销售部门给出了未来三个月的销售预测,我们将其录入为计划独立需求(PIR)。每周,我们只对整车X运行MPS(MD41)。MPS运行会综合考虑预测、现有库存、已接订单,产出一个稳定的、未来几周的主生产计划(比如每周生产200台X)。
这个“每周200台”的主计划一旦确定,短期内就不会轻易变动,给生产车间一个稳定的节奏。然后,我们再运行MRP(MD01)。此时,MRP会把“每周200台X”这个MPS结果,当作独立需求来源之一,再结合其他零散的销售订单,去计算生产200台X所需要的所有发动机、轮胎、玻璃、螺丝钉……的需求。这样,MPS起到了一个需求缓冲和稳定器的作用,避免市场销售的微小波动直接冲击到底层成千上万的原材料采购计划。
那怎么在SAP里体现呢?关键就在物料主数据的MRP类型和计划策略上。对于整车X,它的MRP类型可能被设置为M0(MPS物料),计划策略可能是40(按预测生产,销售订单消耗预测)。对于轮胎,它的MRP类型就是PD(物料需求计划)。运行MPS时,系统只会处理MRP类型为M0,M1,M2等的物料。运行MRP时,系统会处理所有物料(包括MPS物料),但对于MPS物料,MRP会直接采用MPS运行已产生的计划订单,而不会重新计算、覆盖它,从而保证了主计划的稳定性。
所以,简单记住:MPS管重点、管节奏、求稳定;MRP管全面、管细节、保供应。在项目上,一定要和客户一起识别出哪些是适合做MPS的“关键物料”,这往往是提升计划体系稳健性的第一步。
3. 未清期间:控制采购申请生成的“时间阀门”
MRP跑完后,你可能会疑惑:为什么有些物料明明缺料,系统却不给我产生采购申请(PR)?或者反过来,为什么交货日期还很远的物料,系统现在就急吼吼地让我下单?这背后,很可能是一个叫“未清期间”(Scheduling Margin Key)的参数在“作怪”。这是我早期踩过的一个经典大坑,当时差点导致生产线停线。
未清期间,说白了就是系统在计算“什么时候该下单”时,设置的一个时间缓冲阀门。它的逻辑公式,用大白话翻译一下就是:系统会判断,从今天开始,到物料需求的那一天,中间的时间还够不够我完成“采购处理”和“供应商交货”。如果时间很充裕(大于未清期间),系统就认为“不急,再等等看”;如果时间紧张(小于或等于未清期间),系统就会立刻产生采购申请。
我们来拆解一下这个逻辑。假设你需要一批零件,它的需求日期是2023年10月30日。这个日期怎么来的?可能是成品生产订单的开始日期,减去物料的主数据里维护的“收货处理时间”(GR Processing Time)得到的。
现在,系统要决定今天(假设是2023年10月10日)要不要为你产生采购申请。它会做如下计算:
- 需求日期:2023年10月30日
- 减去 收货处理时间:比如1天。这是指货物送到仓库后,质检、上架等需要的时间。此时得到“应下达采购订单的日期”为10月29日。
- 减去 计划交货时间:比如15天。这是物料主数据里维护的“计划交货时间”,代表供应商正常的供货周期。此时得到“采购申请最晚应创建的日期”为10月14日。
- 用这个日期(10月14日)减去当前日期(10月10日),得到4天。
关键来了:系统会拿这4天,去和你配置的未清期间(比如设为5天)进行比较。4天 < 5天吗?是的。那么,系统判定:“时间已经不够5天的缓冲期了,必须立刻行动!”于是,它就会在MRP运行结果中,为你生成一个采购申请,并且建议的交货日期就是10月30日。
如果未清期间设的是3天呢?4天 > 3天,系统会认为:“还有超过3天的缓冲时间,暂时不用下单,也许未来需求会有变化,或者有库存调入,再等等。”这样,这次MRP运行就不会产生采购申请。
这个参数在哪里配置?主要在两个地方起作用:
- 物料主数据层面:在MRP2视图的“采购”字段,可以分配一个“计划边际码”(Scheduling Margin Key),里面就包含了未清期间等时间参数。
- MRP组层面:通过事务代码
OPPQ维护MRP组参数,也可以设定未清期间。物料主数据如果没填,会默认采用工厂级或MRP组级的参数。
设置未清期间的好处是避免过早产生采购申请,减少计划订单的频繁变动对采购部门的干扰。但设置过长(比如30天),可能导致紧急需求来不及下单;设置过短(比如0天),则会让采购申请过早生成,失去灵活性。根据我的经验,对于采购周期长、价格波动大的物料,未清期间可以设短一点,让系统早点提醒;对于本地随时可得的物料,可以设长一点。这需要结合供应链实际情况反复调试。
4. 采购申请日期跑偏?揪出工厂参数与MRP组的幕后设置
你有没有遇到过这种诡异情况:MRP跑出来的采购申请,建议的交货日期居然是个“过去式”?比如今天都10号了,它建议的交货日期是5号。这显然无法执行,采购同事肯定会来找你“算账”。这个问题,十有八九出在后台的日期计算规则上,核心就是工厂的MRP参数和MRP组里的相关设置。
系统在计算采购申请的建议交货日期时,有一套复杂的逻辑。除了我们上一节提到的需求日期、收货处理时间、计划交货时间外,它还会考虑几个关键的“时间调整”参数。当这些参数设置不当时,日期就可能被“推”到过去。
第一个要检查的地方:工厂参数(事务代码OPPQ或OMD1)。 在SPRO路径“生产 -> 物料需求计划 -> 工厂参数 -> 执行工厂参数总体维护”里,你可以找到对应工厂的配置。这里有几个关键字段:
- 计划边际码:这个码里包含了一系列时间,比如“未清期间”、“产前缓冲时间”、“产后缓冲时间”等。如果“产前缓冲时间”被设置了一个很大的正数,系统会在计算出的日期上再加这么多天,可能导致日期被推到未来很远,甚至反过来,如果某些设置是负数逻辑(虽然不常见),可能引发混乱。
- 向前/向后消耗期间:这个主要影响需求覆盖,但间接也会影响日期对齐。
- 覆盖范围参数文件:这里定义了如何用现有库存、在途采购订单、生产订单去覆盖需求。如果覆盖策略设置成“仅在需求日期当天覆盖”,而你的需求日期已经过去,系统可能会为“已过期”的需求生成一个新的、日期奇怪的采购申请。
第二个关键点是:MRP组(MRP Group)的设置。 事务代码OPPQ也可以维护MRP组的参数。MRP组是比工厂更细化的计划单位,可以将不同计划策略的物料分组管理。物料主数据MRP1视图里的“MRP组”字段如果维护了,其优先级会高于工厂参数。所以,如果某个物料的采购申请日期总是出问题,一定要去检查它所属的MRP组里的“计划边际码”等设置是否合理。
一个实战案例:我们项目上曾有一种进口原材料,计划交货时间很长(90天)。客户反映MRP跑出的PR交货日期总是比预期早一周。检查后发现,该物料主数据没有指定MRP组,因此沿用工厂参数。工厂参数中“计划边际码”里定义的“未清期间”是7天。根据我们上一节讲的公式,系统会在(需求日期 - 收货处理时间 - 计划交货时间)再提前7天就生成PR。客户认为这个缓冲太长了,希望更紧凑些。于是,我们为这类进口料单独创建了一个MRP组,将其中的“未清期间”改为2天。这样,系统就会在更晚的时间点(更接近需求)才产生采购申请,符合了他们的供应链管理习惯。
所以,当出现采购申请日期问题时,请按这个顺序排查:
- 检查该物料主数据的MRP1、MRP2、MRP3、MRP4视图,确认计划交货时间、收货处理时间等基础数据无误。
- 检查该物料所属的MRP组(如果已分配)在
OPPQ中的配置。 - 检查工厂参数在
OPPQ中的全局配置。 - 回顾覆盖范围策略是否合理,需求是否已被其他库存元素覆盖。
5. 库存排除与MRP元素过滤:让MRP只关注“可用”资源
跑MRP的目标是计算“净需求”,也就是缺多少。那么,哪些库存应该算作“可用”来抵消需求呢?默认情况下,SAP会把所有类型的库存都考虑在内。但在实际业务中,仓库里可能有一部分物料是“质检状态”的,正在等待检验结果;还有一部分是“冻结状态”的,可能因为质量问题被锁定。这些库存明明在物理仓库里,却不能立刻用于生产或销售。如果不告诉MRP排除它们,系统算出来的净需求就会偏少,导致计划数量不足,这才是大问题。
如何排除特定库存类型?SAP通过一个叫“仓储地点MRP”的配置来控制。具体路径在SPRO:“物料需求计划 -> MRP计算 -> 计划 -> 定义仓储地点MRP”。在这里,你可以为每个“仓储地点+库存类型”的组合,指定一个“标识”。比如:
- 库存类型
01(非限制使用)标识为1,代表参与MRP。 - 库存类型
02(质检)标识为2,代表不参与MRP。 - 库存类型
03(冻结)标识为2,同样不参与MRP。
这样设置后,每次运行MRP,系统会自动忽略标识为2的库存。在MD04查看时,你会发现“库存”栏位的数量,只包含了非限制使用的库存,质检和冻结库存被单独列示或不计入可用性计算。这个配置是工厂级别的,一旦设置对所有物料生效,非常管用。
更高级的需求:过滤特定MRP元素有时候,你还需要更精细的控制。比如,你们公司集团内部有工厂间的调拨,产生了公司间的采购订单(Inter-Company PO)。在接收工厂运行MRP时,你可能不希望这些“在途”的公司间订单参与MRP计算,因为它们的供应是由发送方工厂控制的,接收方工厂无需为此生成采购申请。但SAP标准逻辑会把这些订单当作供应元素。
这时,就需要用到增强(User Exit)了。SAP提供了一个经典的增强点:MD_CHANGE_MRP_DATA。在这个增强的接口方法里,你可以编写逻辑,告诉系统在运行MRP时忽略特定的MRP元素。
就像原始文章里提到的那个例子,代码如下(这是一个概念示例,具体实现需在ABAP开发环境中进行):
DATA: lv_reswk TYPE reswk, " 供应工厂 lv_werks TYPE werks. " 需求工厂 " 假设 IM_MDUB 是传入的MRP元素结构 lv_reswk = im_mdub-reswk. " 获取供应工厂(发送方) lv_werks = im_mdub-werks. " 获取需求工厂(接收方) " 判断:如果是一个从‘发送工厂’到‘接收工厂’的公司间采购订单 IF lv_reswk = '发送工厂代码' AND lv_werks = '接收工厂代码'. " 设置删除标志和更改标志 ch_exit = 'X'. " 告诉系统:这个元素要排除 ch_changed = 'X'. " 告诉系统:数据已更改 ENDIF.这段代码的意思是,当MRP运行到每一个供应元素时,都会进入这个增强点。我们判断如果这个元素是来自于特定发送工厂、去往特定接收工厂的公司间PO,我们就打上标记把它“踢出”MRP运算列表。这样,在接收工厂的MRP结果和MD04中,你就看不到这个公司间PO的供应了,从而避免了重复计划。
这个功能非常强大,除了过滤公司间订单,还可以用来处理一些特殊的预留、计划协议行项目等。不过,它属于开发范畴,需要ABAP顾问配合实现,并在测试系统充分验证,确保不会误删正常的供应元素。