MPS展开10万行卡住了,子序号4种写法实测,大数据只有1种能扛

Lv.4 核心创作者
🧮 MPS展开10万行卡住了,子序号4种写法实测,大数据只有1种能扛
MPS计划按子件数量展开成明细长表,这个上篇文章讲过了。
但展开之后马上遇到新问题:每一块要补一个1~n的组内序号。
比如WK-001展开5行,序号1、2、3、4、5;WK-002展开8行,又从1开始。
手拖填充?数据一动就断链。今天把4种公式写法全测一遍,包括一次10万行的压测——结果有点意外。
一、先搭好链路:展开流的三段式骨架
序号不是孤立的一列,它站在一条链的末端。
第一段:组界辅助列。源表每行一个"子件数量",SCAN把它累积起来,得到每个任务块的终点行号:
公式:组界(I2)
=SCAN(,G2:.G1000,SUM)子件数量是5、8、6、7……SCAN跑完就是5、13、19、26——第1个任务占1~5行,第2个占6~13行,边界一目了然。
第二段:父序号。用行号SEQUENCE+XLOOKUP区间定位,把源表的序号列(1、2、3……每个任务唯一)展开成长表:
公式:父序号(K2)
=LET(a,A2:.A1000,y,G2:.G1000,s,I2#,q,SEQUENCE(SUM(y)),XLOOKUP(q,s,a,,1))第几行属于第几个任务,一查便知。XLOOKUP第5参数=1是升序模糊匹配,行号落在哪个组界区间就返回哪个任务号。
第三段才是序号。下面4种写法,比的就是这最后一公里。
图1:MPS工作表——A~G列源表(序号、生产任务、子件数量)与I列组界辅助列并排,显示5、13、19、26的累积值
二、方法一:SCAN组内计数,一个函数搞定
这是我和灵犀讨论出来的写法,思路很直接:任务号变了就归1,没变就加1。
公式:SCAN组内计数(L2)
=SCAN(0,K2:.K60000,LAMBDA(X,Y,IF(Y<>OFFSET(Y,-1,),1,X+1)))三个角色:X是累积值,Y是当前行扫到的值,OFFSET(Y,-1,)取上一行。
边界判断一行搞定,全链O(n)扫一遍。
这里有个被推翻的预判:本来以为SCAN遍历时Y是个标量值,OFFSET取不到上一行。实测打脸——WPS云端的SCAN遍历值保留引用语义,OFFSET(Y,-1,)能正确拿到邻居。这个结论值钱,少造一层错位数组。
图2:MPS工作表公式栏——K2单元格的SCAN组内计数公式,L列输出1~n递增的序号流
但它有个暗雷,下面第三部分讲。
三、同名任务的BUG:父序号救场
测试数据里WK-001出现了两次(两个不同批次的同一任务)。
源表按任务名一排序,坏了个大的:两个批次的WK-001在展开流里挨着,SCAN的判断条件Y<>上一行失效——序号从5直接连到6,不归1。
原因想通了:SCAN的判据用任务名,任务名不是唯一键。
修法是给SCAN换一个锚:父序号。源表加一列行号(1~9),父序号列按组界展开,天然唯一。两个批次的WK-001,父序号一个是1一个是9,怎么排序都不会混。
改完再扫,56行逐行校验,一块不乱。
图3:MPS工作表——K列父序号(1、1、1、2、2…9)与L列子序号并排,WK-001两个批次各自从1重开
四、方法二:XLOOKUP回查,大数据唯一解
SCAN版的死穴在架构:第n行要等第n-1行,9995个格子排成一条串行链,云端引擎只能逐格推进。
回查版把串行链拆了。思路:子序号=当前行号−所在块起点+1,而块起点不用SCAN,组界终点减子件数量直接反推:
公式:XLOOKUP回查(M2)
=LET(a,A2:.A1000,y,G2:.G1000,s,I2#,q,SEQUENCE(SUM(y)),st,s-y,q-XLOOKUP(K2#,a,st,0))每行独立查表,互不等待,计算引擎整批并行。
组界列一箭三雕:区间定位用、终点反推起点用、还兼源侧唯一一次SCAN。
五、方法三:REDUCE压栈,小数据之王
如果只是小表,别整这些,压栈版最短最直观:
公式:REDUCE压栈(N2)
=DROP(REDUCE("",G2:.G1000,LAMBDA(X,Y,IF(Y<>"",VSTACK(X,SEQUENCE(Y)),X))),1)遍历子件数量,每块SEQUENCE(Y)天然生成1~Y,VSTACK纵向一摞,DROP甩掉空种子。
序号根本不用"算",它是堆出来时自带的。
IF(Y<>"",...)是空行守卫——扩容预留的空区,数量为空时不触发SEQUENCE(0)报错。
六、压测:10万行,公式链断了
光说不练假把式。造了两张虚拟数据表实测:
1万档(1千任务展开9995行):底座1.4秒就绪,三版输出56…不对,9995行逐行一致,零差异。
10万档:翻车了。卡住的甚至不是序号公式——是底座那张近10万行的父序号spill,3分钟没算出来,列里恒空。
图4:压测10万工作表——G列父序号整列空白,公式已写入但溢出计算未完成的状态
结论扎心但真实:公式能写,不等于云端算得动。
你工厂的单表数据要是10万级,公式方案让位——算一次把值落盘,或者拆表,别指望一条10万行的活公式实时重算。
七、选型表(直接抄)
数据量 | 用哪版 | 理由 |
≤100行 | REDUCE压栈 | 最短最直观,小数据无性能压力 |
100行~1万 | XLOOKUP回查 | 行间独立可并行,大表唯一解 |
有长表无组界 | SCAN组内计数 | 一个函数,孤立补序号最省事 |
10万级 | 公式让位 | 算好落值或拆表,云端扛不动活公式 |
三版在56行和9995行上输出完全一致,选型的依据不是对错,是速度。
最后说一句
这一轮最大的收获不是哪个公式,是那个被推翻的预判:SCAN里的Y能不能用OFFSET取邻居,我判断不能,实测能。
所以公式学习这件事,AI的推演、你的手感、云端的真实反应,三者要互相校验。写了不算数,跑通了才算数。
我是古哥计划的古老师,下一篇把这条链接到BOM展开,父序号和子序号拼成复合键,毛需求一路贯通。
买排产系统前,先把这篇的压测数据看一遍——你花几万块买的系统,底层可能就是这条扛不住10万行的链路。
术语解释
MPS(Master Production Schedule,主生产计划):工厂"准备做什么成品、做多少、什么时候做"的计划表,MRP运算的源头。
SCAN:动态数组函数,像扫描仪一样从上到下逐行累积计算,每行输出一个累积结果。工厂类比:流水线上每过一件,记一次累计数。
REDUCE:动态数组函数,把一组数据逐个"压"进一个累积结果里,常用来把多行堆成一张长表。
溢出:一个公式自动向下或向右生成多行多列结果的现象,也叫spill,写一次覆盖一大片。
语法糖:简化写法。A2:.A1000是"从A2取到有数据的最后一行"的缩写,比固定A2:A1000能随数据自动伸展。
XLOOKUP:查找函数,按一个值去表里找对应结果,第5参数=1时支持区间匹配。
组界:每段数据在长表里的截止行号,像楼层索引——5、13、19表示第1层到5楼、第2层到13楼。
位置主键:用行号这类天然唯一的位置编号做判断依据,而不是用可能重复的业务字段。
古老师(古哥计划)|AI落地专家 · 制造业FDE实践者|中小制造数字化专家|金山 KVP(金山办公最有价值专家)|金山多维表格应用场景专家|金山 WPS 社区优秀创作者
深耕中小制造业数字化落地,擅长用 WPS 多维表格 + AI 低代码方案,帮工厂快速搭建进销存、生产计划、质量追溯等轻量化系统。不用复杂 IT,低成本落地,已服务数百家制造企业,实战经验丰富。
#多维表格 #工厂管理 #AI落地 #AI应用 #FDE #MPS排程
本文由 AI 辅助创作
工具:AI 灵犀专业版
模式:Pro 模式(智能判断模型)