第二章:物料主数据管理
各位同学,今天我们来聊聊物料主数据管理。说实话,这是MES系统里最基础也最容易出问题的一块。我见过太多项目,因为物料编码没设计好,后面追溯、排产、成本核算全乱套了。咱们今天就把这块彻底讲透。
2.1 物料编码规则设计
物料编码,说白了就是给每个物料发一张「身份证」。这张身份证怎么设计,直接决定了后续所有系统的运行效率。
我个人习惯,编码规则要满足三个原则:唯一性、可读性、扩展性。
- 唯一性:一个编码只能对应一个物料,不能重码
- 可读性:看到编码能大概猜出是什么物料
- 扩展性:预留足够的位数,别用两年就满了
举个例子,我参与过的一个汽车零部件项目,编码规则是这样的:
编码结构:XX-XXX-XXXX-XX
第1-2位:物料大类(01=原材料,02=半成品,03=成品)
第3-5位:物料小类(001=钢材,002=塑料,003=电子元件)
第6-9位:流水号(从0001开始)
第10-11位:版本号(01=初版,02=改版)
实际编码长这样:01-001-0001-01,代表「原材料-钢材-第1种-初版」。
避坑指南:我曾经见过一个项目,编码里包含了供应商代码。结果供应商一换,所有物料编码都得改,那叫一个惨。记住,编码里不要放会变的信息。
2.2 物料属性定义
物料属性,就是描述物料的各种特征。你想想看,一个螺丝钉和一个电路板,它们的属性肯定不一样。所以我们需要把属性分成两类:
2.2.1 通用属性
所有物料都有的属性:
- 物料编码(唯一标识)
- 物料名称(中文描述)
- 物料规格(尺寸、重量等)
- 计量单位(个、公斤、米等)
- 物料类型(原材料/半成品/成品)
- 状态(启用/停用/待审核)
2.2.2 专用属性
不同物料特有的属性:
- 原材料:材质、供应商、批次号
- 半成品:加工工序、检验标准
- 成品:包装规格、保质期、客户代码
嗯,这里要注意。属性定义不是越多越好。我在项目中就吃过亏,一开始定义了几十个属性,结果录入数据时工人嫌麻烦,随便填。后来精简到核心的15个属性,反而数据质量上来了。
我的建议:属性定义遵循「够用就好」原则。先定义核心属性,后续有需要再加。数据库设计时预留扩展字段,比如10个备用字段,随时可以启用。
2.3 物料BOM结构
BOM(Bill of Material),物料清单。说白了就是「做这个产品需要哪些东西」。但BOM不是简单的列表,它有层级结构。
我画了一张图,帮你理解BOM的层级关系:
这张图展示了典型的BOM结构。成品A由半成品B和C组成,而半成品B又由原材料1和2组成,半成品C由原材料3和4组成。
在MES系统中,BOM结构用数据库表来存储,大概长这样:
-- BOM主表
CREATE TABLE bom_header (
bom_id INT PRIMARY KEY,
product_code VARCHAR(20), -- 成品编码
bom_version VARCHAR(10), -- BOM版本
effective_date DATE, -- 生效日期
status VARCHAR(10) -- 状态
);
-- BOM明细表
CREATE TABLE bom_detail (
detail_id INT PRIMARY KEY,
bom_id INT, -- 关联主表
parent_code VARCHAR(20), -- 父项编码
child_code VARCHAR(20), -- 子项编码
quantity DECIMAL(10,2), -- 用量
scrap_rate DECIMAL(5,2) -- 损耗率
);
注意:BOM版本管理非常重要。我曾经遇到一个项目,生产部门用了旧版BOM,采购部门用了新版BOM,结果原材料买多了,半成品做错了。后来我们强制要求:生产工单必须绑定BOM版本,系统自动校验。
2.4 物料状态管理
物料不是一成不变的。从采购入库到生产消耗,再到成品出货,物料状态一直在变。我们需要一套状态机来管理。
常见的物料状态包括:
| 状态编码 | 状态名称 | 说明 | 可操作 |
|---|---|---|---|
| 01 | 待审核 | 新创建的物料,尚未审核 | 编辑、删除 |
| 02 | 已启用 | 审核通过,可以用于生产 | 生产领料、采购 |
| 03 | 已停用 | 不再使用,但保留历史数据 | 仅查询 |
| 04 | 待报废 | 质量不合格,等待处理 | 报废、退回 |
| 05 | 已报废 | 确认报废,不可恢复 | 无 |
状态流转的逻辑,我用代码实现一下:
class MaterialStatus:
def __init__(self):
# 定义状态流转规则
self.transitions = {
'待审核': ['已启用', '已停用'],
'已启用': ['已停用', '待报废'],
'已停用': ['已启用'],
'待报废': ['已报废', '已启用'],
'已报废': []
}
def can_transition(self, current_status, target_status):
"""检查状态是否可以转换"""
if current_status not in self.transitions:
return False
return target_status in self.transitions[current_status]
def transition(self, material_code, current_status, target_status):
"""执行状态转换"""
if not self.can_transition(current_status, target_status):
raise ValueError(f"不允许从 {current_status} 转换到 {target_status}")
# 记录状态变更日志
log_entry = {
'material_code': material_code,
'from_status': current_status,
'to_status': target_status,
'timestamp': datetime.now(),
'operator': get_current_user()
}
save_log(log_entry)
# 更新物料状态
update_material_status(material_code, target_status)
return True
避坑指南:我曾经犯过一个错误,允许「已启用」直接跳转到「已报废」。结果生产线上正在用的物料突然被报废了,导致产线停线。后来我加了一条规则:状态变更必须经过「待报废」中间状态,并且要有质检报告。
好了,物料主数据管理这块,核心就是编码规则、属性定义、BOM结构和状态管理。这四个点搞清楚了,MES系统的数据基础就稳了。实际项目中,我建议你先从编码规则开始,把物料身份证设计好,后面的工作会顺畅很多。
公众号:蓝海资料掘金营,微信deep3321