第二章:物料主数据管理

各位同学,今天我们来聊聊物料主数据管理。说实话,这是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的层级关系:

成品 A 半成品 B 半成品 C 原材料 1 原材料 2 原材料 3 原材料 4 成品 半成品 原材料

这张图展示了典型的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