在昨天的文章中,我们已完成关键的前置准备工作:通过分析物料清单(BOM),提取每个产品的子件总数;同时,在主生产计划(MPS)表中构建了任务顺序编号作为唯一索引。这些辅助列的设计并非孤立操作,而是为今天的核心主题——MRP物料需求运算——打下坚实的数据基础。
从本章开始,我们将正式进入需求展开的“实战阶段”。借助前期建立的索引体系,把生产计划与BOM结构高效联动,实现从“生产什么”到“需要什么物料、需要多少”的自动推导。
接下来,我们将一步步构建一个无需VBA、纯函数驱动的MRP计算引擎,真正实现“一键生成物料需求”的智能化管理目标。
重复行数
MRP需求分解的核心逻辑,本质上是将MPS主计划中的每一行生产任务,根据其对应产品的子件总数,展开为多行物料需求记录——即“一行变多行”的结构转换。为了实现这一关键变形,我们需要将MPS计划中的任务信息(如任务序号、生产任务、产品、排程数量等)按子件数量进行纵向重复,为后续与BOM明细逐一对齐做好准备。
✅ 核心思路:基于子件总数的数组复制
我们利用动态数组函数,构建一个与最大子件数对齐的二维逻辑矩阵,通过条件判断控制有效值的填充,再使用 TOCOL 将结果转换为垂直数组,实现高效重复。
录入公式:
顺序号:A2=LET(X,MPS输出!F2#,Y,MPS输出!E2#,TOCOL(IF(SEQUENCE(,MAX(Y))<=Y,X,A),3))
参数说明:
X:原始任务序号数组(如 1, 2, 3…)
Y:每个任务对应的子件总数(如产品A有4个子件,则Y=4)
SEQUENCE(,MAX(Y)):生成横向序列 {1,2,3,…,最大子件数}
<= Y:判断当前列位置是否小于等于该行的子件数,决定是否复制
IF(…, X, A):满足条件则保留对应任务序号,否则为空
TOCOL(…, 3):将二维数组压缩为单列,忽略空值(参数 3 表示忽略错误和空) 最终效果:若任务1有4个子件,则任务序号 1 被重复4次;任务2有6个子件,则 2 被重复6次,依此类推。
同理生产任务的公式:
生产任务:B2=LET(X,MPS输出!A2#,Y,MPS输出!E2#,TOCOL(IF(SEQUENCE(,MAX(Y))<=Y,X,A),3))
该公式逻辑与上例一致,仅数据源由“任务序号”变为“生产任务”本身。类似地,产品、排程数量、排程日期等所有MPS相关字段均可采用相同模式进行重复扩展,实现整行信息的结构化复制。

查找引用
在完成MPS计划数据的“一行变多行”重复扩展后,我们已为每个子件需求预留了对应的行结构。接下来的关键步骤是——通过查找引用,将BOM中的具体物料信息填充到展开后的需求表中。
这一步的核心依赖于前期构建的两个关键辅助字段:
✅ MPS侧的“任务序号”与“子件顺序”组合;
✅ BOM侧的“父件&子件顺序号”唯一标识。
步骤一:生成子件顺序号(1,2,3,…)
在展开后的数据中,虽然MPS信息已按子件总数重复,但尚未明确每行对应的是第几个子件。因此,我们需要为每一组任务内的记录生成连续的子件顺序号,如 1,2,3,4 重复出现。
使用 SCAN 函数实现自动编号:
子件顺序=SCAN(0,A2#,LAMBDA(X,Y,IF(Y<>OFFSET(Y,-1,),1,X+1)))

公式说明:
A2#:当前任务序号列(已展开,如 {1;1;1;1;2;2;2;2;2})
OFFSET(Y, -1, ):获取上一行的任务序号
当前任务序号 ≠ 上一行 → 表示进入新任务组,重置为 1,否则 → 在前一个值基础上 +1
✅ 输出结果示例:{1;2;3;4;1;2;3;4;5} —— 每组内子件顺序从1开始递增。
步骤二:拼接唯一键,进行查找引用
有了“任务序号”和“子件顺序”后,我们将其拼接为“产品-顺序”格式(如 PROD-A-1),与BOM输出表中的“父件&子件顺序号”字段进行匹配。
1. 查找子件编码
子件:=XLOOKUP(C2#&”-“&E2#,BOM输出!F2#,BOM输出!C2#)

公式解释:通过拼接唯一序号,返回BOM清单中的子件
- 查找用量:=XLOOKUP(C2#&”-“&E2#,BOM输出!F2#,BOM输出!D2#)

公式解释:同上,返回用量;
子件需求:=D2#*G2#;用量和MPS的计划量运算,得到需求;

至此,我们成功生成了不含替代料的第一级MRP物料需求表,实现了从“生产什么”到“需要什么、需要多少”的完整推导。
未完待续……
