ARTICLE · 1148162
从两份Excel到一套排产系统:一次家电代工厂的数据初始化实战
引子:一个真实的PMC困境
今天,我接触了一家做厨电代工的中型工厂。车间里12条总装线并行运转,同时给美的、老板、名气、海信、苏泊尔等七八个品牌做ODM。月排产量万台级别,产品型号超过150个。
工厂的ERP是某鼎(国内知名ERP厂商),管着物料主数据、BOM和采购订单。但到了排产这一层,画面就变了——
PMC主管的电脑上开着三个Excel文件:“某邦排期表”(汇总)、“明细”、“10月烟机100%”。每天的工作流是这样的:从ERP导出新产品编码,手动VLOOKUP到排期表里做“编码验证”,然后在日期列里一格一格填数量。算到尾数不够了,就手动调公式:=800-59、=700-392。
这不是个例。行业调研数据显示,75%的制造企业仍然依赖Excel手工排产,计划调整导致的返工率高达30%。当产品种类超过50个、订单数量达到数百级别时,手工排产的耗时就会超过2小时,而且“一改就乱”。
问题的根子不在ERP。ERP管好了“账本”,但车间决策层——PMC排产——仍然是断裂的。ERP系统的MRP运算基于批处理算法,夜间跑一次要1-4小时,且无法处理“插单”、“换线”、“并行产线分配”这些实时决策。
这篇文章要讲的,就是我们如何用轻排 PMClite,把客户积攒多年的Excel数据一键转换成可运行的排产系统。整个过程不写一行代码,当天上线。
轻排 PMClite 的官网是 轻排 PMClite | 本地部署轻量级生产管理系统 · 替代 Excel 打通销售/采购/仓库/车间/财务 ,产品定位是面向中小制造企业的本地部署、买断制、轻量级PMC工具,聚焦多级BOM、齐套检查、排产、领料、追溯这几个核心场景。
一、先搞清楚:客户的数据长什么样
要解决问题,先得看数据。
客户发来两份Excel:
第一份:BOM数据(从某鼎ERP导出的“新系统BOM格式”)
包含28个字段:主件品号、主件图名、元件品号、元件品名、元件规格、单层用量、成品累计用量、品号类型、材质、长宽厚、开料件数……这是一份5级BOM。以“美的吸油烟机CXW-xxx-xxx PRO”为例,它的结构是:
text
成品(S1.1.01.0001 美的吸油烟机) ├─ 自制件(S2.1.01.10.0002 箱体地线插片) │ └─ 采购件(S4.1.05.0042 镀锌板) ├─ 自制件(S2.1.02.04.0001 箱体背板组件) │ └─ 自制件(S2.1.01.04.0001 箱体背板) │ └─ 采购件(S4.1.05.0251 镀锌板) ├─ 自制件(S2.1.03.05.0001 箱体围板) │ └─ 自制件(S2.1.01.02.0001 箱体围板未喷涂) │ └─ 采购件(S4.1.06.0318 冷板) └─ ...品号类型只有两种值:“自制件”和“采购件”。自制件既可能是产品,也可能是半成品;采购件就是最终要买的物料。
第二份:排产数据(“2026年XXX日XX排产”)
包含三个sheet:“汇总”、“明细”、“10月烟机100%”。
“汇总”sheet里,每一行是“线别 + 某捷新产品编码 + 型号 + 客户 + 排产合计”,后面跟着几十列日期,每天的数量用公式串联:=K2+1、=L2+1……“明细”sheet更细,把每个“车间/线别 + 客户 + 编码 + 型号 + 生产任务单号”拆到每一行,日期列同样用公式递推。
几个关键观察:
一个产品可能出现在多条产线上。比如AK10 PRO既在1线排,也在2线排。
同一产品的多行数据需要合并。1线排了800+59+659,2线排了700+700+192+392……这些加在一起才是产品的总生产量。
客户信息隐含在行里。美的、老板、名气、海信、苏泊尔——这些是客户名称,但从没被单独整理成客户表。
二、数据初始化的核心难题
拿到这两份Excel,要导入一套排产系统,面临三个核心问题:
问题1:产品和物料怎么区分?
在BOM表里,“主件品号”列里的编码是产品,“元件品号”列里的编码可能是物料,也可能是另一个产品(半成品)。判断规则是:
凡出现在“主件品号”列 → 一定是产品
只出现在“元件品号”列,且品号类型=采购件 → 物料
既出现在主件列、又出现在元件列 → 半成品
这套规则看起来简单,但150+产品、几百个物料,手工分类一天都做不完。
问题2:生产计划怎么算?
排产表里一个产品跨多条产线、多行数据。系统需要的是:每个产品一条生产计划(总数量),每条产线一条工单(该产线的数量)。
以AK10 PRO为例:1线排了1518台,2线排了1400+700+700+308=3108台,合计4626台。系统里应该生成1条生产计划(4626台)和2条工单(1线1518台、2线3108台)。
手工算这个,排产员得拿着计算器一行一行加。
问题3:日期怎么确定?
排产表里日期是横排的,每天一列。工单的“计划开始日期”和“计划结束日期”需要从这些列里自动推导——找到第一列有数量的日期作为开始,最后一列有数量的日期作为结束。
三、解决方案:一个“数据转换器”就够
整个方案的核心思路是:在导入PMClite之前,先用一个转换工具把鼎捷数据“翻译”成PMClite能读的JSON格式。
这个工具不写代码,用浏览器打开就能用。客户的操作流程是:
上传BOM Excel
上传排产Excel
点击“转换”
下载JSON,到PMClite里导入
3.1 整体架构
text
鼎捷ERP导出Excel(2份) ↓ 【转换工具】浏览器端运行 ├── 读取BOM:解析主件/元件/用量 ├── 读取排产:解析线别/编码/客户/数量 ├── 自动分类:产品 vs 物料 vs 半成品 ├── 自动聚合:产品→计划,产线+产品→工单 └── 输出:PMClite标准JSON ↓ 轻排 PMClite 导入3.2 BOM解析逻辑
工具读取BOM表后,先扫描所有行,收集两份数据:
javascript
// 收集所有出现过的编码 const allItems = new Map(); // code → {name, spec, type, isParent} const bomRaw = []; // [{parentCode, childCode, qty}] dataRows.forEach(row => { const parentCode = row[主件品号列]; const childCode = row[元件品号列]; const qty = row[单层用量列]; // 标记父级 allItems.get(parentCode).isParent = true; // 记录BOM关系 if (childCode && qty > 0) { bomRaw.push({ parentCode, childCode, qty }); } });然后按规则分类:
isParent === true→ 产品isParent === false && type === '采购件'→ 物料产品被其他产品引用为子件 → 标记为半成品
最后生成三条数据流:
json
{ "products": [ {"id": 1, "code": "S1.1.01.0001", "name": "美的吸油烟机", "type": "finished"}, {"id": 2, "code": "S2.1.01.10.0002", "name": "箱体地线插片", "type": "semi"} ], "materials": [ {"id": 1, "code": "S4.1.05.0042", "name": "镀锌板", "spec": "0.59*65*C"} ], "bomItems": [ {"productId": 1, "subProductId": 2, "quantity": 1, "type": "subproduct"}, {"productId": 2, "materialId": 1, "quantity": 0.0046, "type": "material"} ] }3.3 排产解析逻辑
排产表的解析更复杂一些。核心是聚合:
javascript
// 聚合键:线别 + 产品编码 const agg = new Map(); dataRows.forEach(row => { const line = row[线别列]; const code = row[编码列]; const key = line + '|' + code; // 累加每日数量 let rowTotal = 0; dateCols.forEach(dc => { const q = parseFloat(row[dc.idx]) || 0; if (q > 0) { rowTotal += q; // 记录起止日期 if (!a.startDate || dc.date < a.startDate) a.startDate = dc.date; if (!a.endDate || dc.date > a.endDate) a.endDate = dc.date; } }); agg.get(key).qty += rowTotal; });聚合之后,按产品再汇总一次:
每个产品 → 1条生产计划(
plannedQuantity= 所有产线之和)每个“产线+产品”组合 → 1条工单(
assignedLine= 线别,quantity= 该线数量)客户名称去重 → 客户档案表
3.4 日期列的智能识别
排产表的日期列有两种情况:
汇总sheet的表头直接是日期(如
46023这种Excel序列号)明细sheet的日期藏在第2行(
=K2+1这样的公式)
工具的处理逻辑是:先试汇总sheet表头,识别失败就从明细sheet第2行读。两个都失败就用当天日期兜底。
javascript
function parseDateValue(val) { if (val instanceof Date) return val; if (typeof val === 'number' && val > 20000 && val < 80000) { // Excel日期序列号 → JavaScript Date return new Date((val - 25569) * 86400 * 1000); } if (typeof val === 'string') { // 尝试 "2026/09/23" 格式 const m = val.match(/^(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})/); if (m) return new Date(+m[1], +m[2] - 1, +m[3]); } return null; }四、导入之后,客户看到了什么
转换完成,客户在轻排 PMClite 里导入JSON,然后:
仪表盘立刻刷新——物料数量、产品数量、BOM条数、生产计划数、工单数、客户数,全部实时显示。
产品页看到完整的产品树——150+个产品,每个产品的BOM层级、物料数量、被引用次数一目了然。半成品用蓝色标记,成品用绿色标记。
生产页看到12条产线的工单列表——每条工单带着产线名、数量、优先级、齐套状态。齐套状态是系统自动算的:递归展开多级BOM,对比库存,缺料标红。

甘特图自动生成——每条产线的排产时间线可视化,绿色正常、黄色即将到期、红色已逾期。

多级齐套分析——点击任意工单的“齐套详情”,系统展示该工单需要哪些物料、库存多少、缺多少、缺的物料有没有在途采购单。对于这家客户,5级BOM的齐套分析,Excel手工做要20分钟,系统算0.3秒。

轻排 PMClite 的定位不是替代ERP,而是补足ERP到车间之间的“最后一公里”。ERP管账,PMClite管排产、管齐套、管领料。两者数据可以通过JSON导入导出打通,客户不需要换系统,不需要漫长实施周期。
五、这个案例的方法论提炼
回头看,这个案例的成功不在于技术多复杂,而在于找对了切入点。
第一,从数据初始化入手,而不是从功能演示入手。
客户最怕的是“又一个系统要填数据”。我们反过来:客户已有的Excel数据,我们帮他自动导入。客户不需要从零开始录入150个产品、几百个物料、几十条BOM关系。
第二,把“转换”做成一个独立工具,而不是系统内嵌功能。
原因很简单:客户的Excel格式各不相同。某鼎的BOM格式、某蝶的BOM格式、某友的BOM格式,字段名、层级表示、类型编码都不一样。如果把转换逻辑写死在系统里,每接一个客户就要改代码。
做成独立工具后,转换逻辑可以按客户定制,系统本身保持稳定。
第三,聚合逻辑是核心,不是附加。
排产表里“一个产品跨多条产线”是常态,不是异常。系统的数据模型必须支持“一个产品对应多个工单”,这个设计从第一天就要考虑进去。
第四,日期处理要做多层兜底。
Excel日期格式千奇百怪:数字序列号、文本日期、公式递推。工具必须能识别多种格式,并且在识别失败时有合理的默认值,保证导入不会因为日期列而失败。
六、结语
这家客户的故事不是“又上了一套系统”。他们的ERP还在跑,Excel也还在用——但排产这一层,从“每天2小时手工凑数”变成了“30秒自动重排”。
轻排 PMClite 做的事情很朴素:用轻量的方式,解决重的问题。
多级BOM、齐套检查、排产排程、领料管理、扫码追溯——这几个PMC最痛的场景,ERP覆盖不到,大APS太重,Excel太乱。中间的位置,就是轻排 PMClite 的定位。
如果你也在做制造业数字化,也在面对“ERP用起来了但车间还是Excel”的困境,可以了解一下轻排 PMClite:
👉 官网:轻排 PMClite | 本地部署轻量级生产管理系统 · 替代 Excel 打通销售/采购/仓库/车间/财务
(本文案例数据已脱敏处理,不涉及具体客户信息。轻排 PMClite 为独立产品,与文中提到的ERP厂商无商业关联。)
标签:制造业数字化 生产管理 排产系统 APS 轻排PMClite