VBA 靠嘴编程实战 · 第 61 期
不用手工拆 BOM:
用 WorkBuddy + VBAYYDS 自动计算物料需求
从生产计划读取数量,递归展开多层 BOM,汇总最底层物料,并生成一键刷新按钮

本期案例:工厂 BOM 物料一键分解汇总
郑广学老师 | Excel VBA 实战系列
不需要先学会递归、字典和按钮控件。先把业务目标说清楚,再让 AI 读取真实工作簿、写代码、运行并检查结果。
手工拆 BOM,真正麻烦的不是乘法
单层 BOM 看起来只是“计划数量 × 单位用量”,但一旦子件下面还有子件,计算就会变成多层树状展开。同一个底层物料还可能来自不同成品、不同分支,既要继续向下拆,又要把相同编码合并。
本案例只保留四个核心动作:读取两张表、逐层展开、汇总底层物料、通过工作表按钮刷新。没有窗体,也没有复杂图表,适合第一次体验“靠嘴编程”的读者。
本次目标 输入两项生产计划,自动得到 6 种最底层物料需求;再次点击按钮时只刷新结果,不重复生成按钮和记录。
最终要交付的功能
- 读取“生产计划”中的成品编码和计划数量。
- 读取“BOM结构”,如果子件仍是父件,就继续向下分解。
- 只汇总没有下级子件的最底层物料,并按编码合并数量。
- 清空旧结果后批量写入“物料需求”,保持原始两张表不变。
- 在“生产计划”顶部创建“分解BOM”按钮,重复运行时复用该按钮。
验收结果
| 物料编码 | 物料名称 | 需求数量 | 单位 |
|---|---|---|---|
| M100 | 机架 | 50 | 件 |
| M201 | 电机 | 80 | 台 |
| M202 | 控制器 | 50 | 个 |
| M203 | 传感器 | 130 | 只 |
| M301 | 线缆 | 80 | 卷 |
| M302 | 连接器 | 160 | 个 |
先理解两张原始表
生产计划:告诉程序要做多少成品
示例中有两项计划:P100 智能装配套件 30 套,P110 标准装配套件 20 套。程序并不依赖固定行号,而是先找到“成品编码”表头,再向下读取有效记录。

图 1 生产计划:成品编码与计划数量
读表原则 让 AI 根据表头和有效数据范围读取,而不是把行号写死。这样新增计划记录时,代码仍然可以继续使用。
BOM 结构:父件下面还可能有下一层
“BOM结构”保存父件、子件和单位用量。P100、P110 是成品;A100、A110、P200 是中间层;M100、M201 等没有下级记录的编码才是最底层物料。

图 2 产品 BOM 结构:父件、子件与单位用量
判断“是不是底层”的关键很简单:如果某个子件编码也出现在父件编码集合中,就继续递归;如果没有,就把它加入最终需求字典。
计算链路 生产计划 -> 父件到子件字典 -> 递归展开 -> 底层物料汇总 -> 一次性写回工作表
把 VBA 项目交给 WorkBuddy
在 WPS 中打开 VBA 编辑器,展开 VBAYYDS 菜单,点击“复制项目路径”。新版插件会在复制路径的同时自动导出当前 VBA 工程,因此不需要再单独执行“导出项目”。
进入 WorkBuddy 后新建任务,选择刚才导出的工作空间。工作空间里包含工作簿结构、VBA 模块和项目规则,AI 才能真正围绕当前文件工作,而不是只给一段脱离现场的示例代码。

图 3 在 WorkBuddy 中选择 VBAYYDS 自动导出的项目目录
直接输入这段提示词
WorkBuddy 提问 请按 VBA 技能处理当前工作簿。读取“生产计划”和“BOM结构”,编写 VBA 按计划数量逐层分解 BOM,直到最底层物料,并把相同物料的需求数量汇总输出到“物料需求”。请在“生产计划”表顶部创建一个“分解BOM”按钮。不要修改原始 BOM 和生产计划;重复运行时刷新原结果,不要产生重复按钮或重复记录。完成后自行编译、运行并检查结果。
提示词为什么有效
普通用户不需要预先知道最终代码长什么样,但要把业务边界讲完整。上面的提问包含六类信息,既给 AI 足够空间解决问题,又避免结果偏离实际工作簿。
- 指定工作方式:“请按 VBA 技能处理当前工作簿”,让 AI 先读取项目规则和真实文件。
- 说清输入:明确使用“生产计划”和“BOM结构”,避免 AI 猜测数据来源。
- 描述算法目标:要求“逐层分解直到最底层”,而不是只做一层乘法。
- 定义输出:相同物料合并,并写入“物料需求”,输出位置和粒度都很清楚。
- 增加交互入口:在工作表顶部创建按钮,让非技术用户也能重复执行。
- 写出安全与验收:不改原始数据、重复运行不重复、完成后编译运行并检查。

图 4 WorkBuddy 读取真实表结构并规划 VBA 模块
提问技巧 不要把未知的中间实现写得过细。普通人只需要说清数据、目标、限制和验收,让 AI 自己选择合适的代码结构。
WorkBuddy 实际完成了哪些工作
- 检查当前 VBA 项目和宿主环境,确认工作簿可以访问。
- 读取“生产计划”和“BOM结构”的真实数据,识别表头与层级关系。
- 创建标准模块 mBOM分解,写入递归展开、汇总、输出和按钮逻辑。
- 同步 VBA 代码,编译并运行主过程“分解BOM并输出”。
- 读取输出表与日志,对照预期数量,并再次运行检查幂等性。

图 5 WorkBuddy 回读结果并继续验证重复运行
这一步的价值不是“让 AI 写一段代码”,而是让它完成读取、编码、运行、纠错和复核的闭环。对于普通学习者,重点是看懂业务逻辑与验收结果,而不是先背完所有 VBA 语法。
看懂核心代码:三个技术点就够了

图 6 核心代码:字典记录已访问节点,递归函数逐层展开
父件字典:快速找到下一层子件
代码先把 BOM 读取到内存数组,再构建“父件编码 -> 子件集合”的字典。这样递归时不需要反复扫描整张工作表。
Dim BOM As Object
Set BOM = 构建BOM字典(wsBOM)
Dim 需求 As Object
Set 需求 = CreateObject("scripting.dictionary")
递归展开:把倍数一直传到叶子节点
每进入一层,都用“上层需求倍数 × 当前单位用量”得到下一层需求。如果子件还有下级,就继续调用展开过程;没有下级时,才汇总为底层物料。已访问字典用于发现循环依赖,避免无限递归。
需求数量 = 倍数 * 子用量
If BOM.Exists(子编码) Then
Call 展开单层(子编码, 需求数量, BOM, 需求, 已访问)
Else
'按物料编码累加最终需求
End If
批量写回与按钮复用
一次性写回,比逐格循环更稳定
最终结果先装入二维数组,再通过 Resize 一次性写回“物料需求”。这种方式速度更快,也更适合后续扩大数据量。
ws.Range("A5").Resize(需求.Count, 4).Value = 结果
ws.Range("C5:C" & (4 + 需求.Count)).NumberFormat = "0"
重复执行不产生重复对象
程序先查找名为 btn分解BOM 的按钮:存在就复用,只重新绑定 OnAction;不存在才创建。结果表每次先清空旧内容,再写入新结果,因此修改计划数量或 BOM 后可以放心刷新。
Set btn = ws.Shapes("btn分解BOM")
If btn Is Nothing Then
Set btn = ws.Shapes.AddFormControl(…)
End If
btn.OnAction = "mBOM分解.分解BOM并输出"
技术小结 数组负责高效读写,Dictionary 负责按编码查找和汇总,递归负责逐层展开,已访问集合负责防止循环,按钮复用保证重复运行安全。
运行结果与业务验收
回到 WPS,在“生产计划”顶部点击“分解BOM”。程序读取 P100×30 和 P110×20,自动输出 6 种最底层物料。

图 7 完成后的“物料需求”表:6 种底层物料已按编码汇总
结果中不包含 A100、A110、P200 这类仍有下级的中间组件,只保留最终采购或备料需要关注的叶子物料。例如 M100 同时来自 P100 和 P110,各使用 1 件,所以 30 + 20 = 50 件。
重复运行验证 再次点击“分解BOM”后,结果保持 6 行;按钮仍只有一个;旧数量被刷新,没有追加重复记录。
WorkBuddy 的最终交付

图 8 WorkBuddy 汇报已完成代码、运行与结果检查
把这个方法迁移到你自己的 BOM
替换工作表名称、表头字段和按钮名称,就可以把同样的提问方式迁移到自己的生产计划。下面这份模板适合直接复制后修改方括号内容。
可复用提示词 请按 VBA 技能处理当前工作簿。读取“[计划表]”和“[BOM表]”,按照计划数量逐层展开 BOM,直到没有下级的最底层物料,并按[物料编码]汇总需求数量,输出到“[结果表]”。请在“[计划表]”顶部创建“[按钮文字]”按钮。不要修改原始计划和 BOM;重复运行时刷新原结果,不要产生重复按钮或重复记录。完成后自行编译、运行,并对照原始数据检查结果。
使用前检查四件事
- 父件编码、子件编码和单位用量列必须有清晰表头。
- 数量列应是真正的数值,不要把单位和数量混在同一个文本单元格。
- 如果 BOM 可能存在循环引用,要明确要求检测并跳过循环依赖。
- 先保留一份原始工作簿备份,再让 AI 在真实项目中编译、运行和复核。
最后总结
这个案例最值得学习的,不只是递归函数,而是一套更容易复制的 AI 编程流程:先把业务数据准备清楚,再用一句完整提示词说明输入、目标、边界和验收,让 WorkBuddy 结合 VBAYYDS 读取真实 VBA 项目,完成代码生成、运行与检查。
完全零基础也可以先从结果出发:看懂数据关系,确认输出正确,再逐步理解字典、递归和批量写回。这样学习 VBA,比从语法表开始更容易获得成就感。
本期一句话 多层 BOM 不必手工逐层拆;把需求说清楚,WorkBuddy + VBAYYDS 就能让 VBA 自动算清。

