
简介这份《钢铁企业产销一体化整体解决方案》PDF文档面向钢铁行业信息化从业者、ERP与MES实施顾问及企业生产管理人员聚焦产销衔接不畅、计划脱节、质量管理不完善等典型痛点提供可落地的整体解决思路。资源包共1个PDF文件大小约771KB内容以文字方案为主便于快速查阅与打印研读。文档以邯钢产销一体化咨询项目为背景系统梳理了ERP环境下钢铁企业一般产销模式的工作流程剖析了销售、生产、质量、发运等环节的衔接缺陷并给出涵盖ERP R3系统、高级计划系统、MES制造执行与作业排程模块、PCS过程控制系统的产销一体化整体架构同时探讨了计划与调度体系、质量管理体系等实施要点。目前已有83人学习下载适合需要理解钢铁行业产销协同架构、ERP与MES集成方案及有限能力计划、ATP/CTP等关键技术的读者参考借鉴。1. 钢铁企业产销一体化整体解决方案从「以销定产」到「算得准、排得下、交得出」很多钢铁企业的产销协同表面看是销售和生产两个部门在吵架根子上是「合同—订单—炉次—轧批—准发」这条链路的数据断了。销售签了 3000 吨冷轧卷交期 25 天生产说原料板坯不够、轧机排不下等生产勉强排下去销售又发现客户要的牌号跟实际产出对不上。所谓钢铁企业产销一体化整体解决方案核心不是上一套 ERP 就完事而是把销售订单、质量设计、生产计划、合同匹配、库存准发这几件事用同一套物料编码和同一套规则串起来让「接单时算得准、排产时排得下、交付时交得出」。这套方案适合年产能 100 万吨以上的长流程或短流程钢厂的信息化负责人、生产计划员和销售运营岗也适合正在做 MES 与 ERP 集成、想把产销协同从 Excel 搬到系统里的团队。下面按我实际落地过的路径把选型、建模、排产、匹配和踩坑讲清楚。2. 产销一体化的数据底座物料编码、质量设计与合同结构2.1 为什么物料编码不统一后面全是白干钢铁行业的物料编码比离散制造复杂得多。同一块板坯在炼钢叫「炉次号」在热轧叫「轧批号」到冷轧又变成「卷号」销售那边还有「合同号」「订单行号」。如果这几套编码各管各的产销一体化就是空中楼阁。我一般会先做一件事定义一条贯穿全流程的「主物料线索」通常用「材料号 工序状态」来表达。材料号在质量设计阶段就生成后续所有工序都挂在这个号上炉次、轧批、卷号只是它的属性维度不是独立实体。常见做法是建三张主表物料主数据表、质量设计表、合同行表。物料主数据管牌号、规格、标准质量设计管「这个牌号走哪条工艺路线、每道工序要控什么参数」合同行管客户要什么、交期什么时候、允不允许替代。这三张表的主键必须能互相引用否则后面合同匹配时你会发现自己在对着一堆字符串做模糊匹配那才是真正的血泪经验。2.2 质量设计表怎么建从牌号到工艺路线质量设计是产销一体化的「翻译层」把销售语言翻译成生产语言。销售说「我要 DC01 冷轧卷厚度 0.8mm宽度 1250mm」质量设计要输出走哪条产线、炼钢要什么成分、热轧要什么终轧温度、冷轧要什么压下率。下面是一个简化的质量设计表结构和插入示例。-- 质量设计主表一个牌号规格区间对应一条工艺路线 CREATE TABLE qd_route ( route_id VARCHAR(32) PRIMARY KEY, -- 工艺路线ID grade VARCHAR(20) NOT NULL, -- 牌号如 DC01 thickness_min DECIMAL(6,3), -- 厚度下限 mm thickness_max DECIMAL(6,3), -- 厚度上限 mm width_min INT, -- 宽度下限 mm width_max INT, -- 宽度上限 mm steelmaking_code VARCHAR(20), -- 炼钢工艺代码 hot_roll_code VARCHAR(20), -- 热轧工艺代码 cold_roll_code VARCHAR(20), -- 冷轧工艺代码 priority INT DEFAULT 100 -- 匹配优先级越小越优先 ); -- 插入一条 DC01 冷轧卷的工艺路线 INSERT INTO qd_route VALUES (RT_DC01_08_1250, DC01, 0.600, 1.000, 1200, 1300, SM_LD_01, HR_FT_880, CR_01, 10);这段 SQL 的逻辑是当销售订单进来时系统用牌号、厚度、宽度三个条件去qd_route里匹配命中优先级最高的那条路线就得到了炼钢、热轧、冷轧的工艺代码。参数说明上thickness_min/max和width_min/max是闭区间实际匹配时要注意边界值归哪一边我一般规定「下限含、上限不含」避免同一规格命中两条路线。priority是后悔药当规格区间有重叠时靠它决定用哪条。提示质量设计表不要一次建全先覆盖占产量 80% 的牌号和规格剩下的用「默认路线 人工确认」兜底否则前期数据准备能把项目拖死。2.3 合同行表把销售承诺变成可计算的对象合同行表的关键字段不是客户名而是「可承诺量」和「替代规则」。可承诺量 当前库存 在制量 未来可排产量 - 已承诺量。替代规则管的是客户要 1250mm我只有 1200mm能不能替代替代要满足什么条件这些规则不写进系统销售就会一直打电话问生产产销一体化就退化成电话一体化。CREATE TABLE contract_line ( line_id VARCHAR(32) PRIMARY KEY, contract_no VARCHAR(32) NOT NULL, grade VARCHAR(20), thickness DECIMAL(6,3), width INT, qty DECIMAL(12,3), -- 订单量 吨 delivery_date DATE, -- 交期 allow_substitute TINYINT DEFAULT 0, -- 是否允许替代 sub_rule_id VARCHAR(32), -- 替代规则ID status VARCHAR(16) DEFAULT NEW -- NEW/PLANNED/PRODUCING/DELIVERED );allow_substitute和sub_rule_id是产销协同的润滑剂。没有这两个字段计划员只能按合同死排稍微有点库存余量也用不上。status字段是后续排产和准发的状态机基础状态流转必须由系统控制不能让人随便改。3. 用 APS 排产引擎把合同变成炉次和轧批3.1 排产不是排序是带约束的搜索钢铁排产和离散制造最大的区别是「炉次」约束。一炉钢通常 200 到 300 吨同一炉次里不同合同要能一起炼成分要兼容否则要么改判要么回炉。热轧那边还有轧辊周期、换辊次数、宽度跳跃限制。所以排产引擎不能只做交期排序得做带约束的搜索。常见做法是用「合同分组 → 炉次归并 → 轧批排序 → 产线分配」四步走每一步都有明确的约束条件。我一般会先用一个分组算法把可同炉的合同聚在一起判断依据是牌号相近、成分区间重叠、交期接近。分组之后每组合同的总量去凑炉容凑不满的用库存板坯补凑超了的拆到下一炉。这一步的输出是「炉次计划」每个炉次有明确的合同行列表和计划重量。3.2 炉次归并的代码实现与参数下面是一个简化的炉次归并逻辑用 Python 写核心是贪心加约束检查。实际项目里会用更复杂的启发式或求解器但思路一致。# 炉次归并把合同行按可同炉规则聚成炉次 def group_heats(contract_lines, heat_capacity250.0, tolerance0.15): contract_lines: 合同行列表每行含 grade, thickness, width, qty, delivery_date heat_capacity: 炉容 吨 tolerance: 允许超装比例0.15 表示最多超 15% # 按交期和牌号排序交期紧的优先 lines sorted(contract_lines, keylambda x: (x[delivery_date], x[grade])) heats [] current {lines: [], total_qty: 0.0, grades: set()} for line in lines: # 约束1牌号不能差太远这里简化为同牌号或已存在牌号 if current[grades] and line[grade] not in current[grades]: # 尝试开新炉 if current[total_qty] heat_capacity * (1 - tolerance): heats.append(current) current {lines: [], total_qty: 0.0, grades: set()} else: # 当前炉没凑够但牌号不兼容只能强行开新炉 heats.append(current) current {lines: [], total_qty: 0.0, grades: set()} current[lines].append(line) current[total_qty] line[qty] current[grades].add(line[grade]) # 约束2超过炉容上限就封炉 if current[total_qty] heat_capacity * (1 tolerance): heats.append(current) current {lines: [], total_qty: 0.0, grades: set()} if current[lines]: heats.append(current) return heats这段代码的逻辑说明先按交期和牌号排序保证紧急合同先排然后逐行往当前炉次里加加之前检查牌号兼容性和炉容上限。heat_capacity是炉容tolerance是允许超装比例这两个参数直接决定炉次数量和余材量。实际项目中tolerance一般设 0.1 到 0.2设太小会频繁开新炉设太大炼钢厂会有意见。牌号兼容性这里简化成「同牌号」真实场景要用成分区间重叠判断比如碳含量差不超过 0.02%。注意炉次归并的结果一定要回写到合同行的status和heat_id字段否则后续轧批排产和准发环节找不到源头又得靠人工对账。3.3 轧批排序宽度跳跃和轧辊周期的坑热轧排产最容易被忽略的是宽度跳跃限制。轧机从宽料换到窄料容易从窄料换到宽料容易出问题所以排序时要尽量「宽到窄」。另外轧辊有轧制公里数上限排到一定量必须换辊换辊时间要算进交期。我一般会在轧批排序里加两个约束宽度跳跃不超过 200mm单轧程公里数不超过轧辊上限的 90%。这两个参数不设排出来的计划看着漂亮到现场就被操作工打回来。# 轧批排序宽度递减 轧辊公里数约束 def sequence_slabs(heats, width_jump_limit200, roll_km_limit80.0): heats: 炉次列表每个炉次含 lines每行有 width, qty 返回排序后的轧批列表 # 把炉次展开成板坯按宽度降序 slabs [] for h in heats: for line in h[lines]: slabs.append({ heat_id: h.get(heat_id), width: line[width], qty: line[qty], grade: line[grade] }) slabs.sort(keylambda x: -x[width]) sequenced [] current_km 0.0 for slab in slabs: # 模拟轧制公里数这里用 qty 粗略折算 km slab[qty] / 10.0 if current_km km roll_km_limit: # 触发换辊实际项目里要插入换辊时间 current_km 0.0 sequenced.append(slab) current_km km return sequencedwidth_jump_limit控制宽度跳跃roll_km_limit控制单轧程公里数。代码里用qty / 10.0粗略折算公里数真实场景要用「卷重 / 单位长度重量」精确计算。换辊时间要作为独立事件插入排程不能忽略否则交期计算会偏乐观。4. 合同匹配与准发把产出对回订单4.1 匹配规则不是有货就能发产出卷下线后要匹配回合同行才能准发。匹配不是简单的「有货就发」要满足牌号、规格、重量、交期四个条件。常见做法是建一张匹配规则表定义「允差范围」和「优先级」。比如客户要 1250mm实际产出 1245mm允差 ±10mm 内可以匹配重量上合同 30 吨实际产出 28 吨允差 -5% 内可以准发超出部分要么补产要么改判。-- 合同匹配规则表 CREATE TABLE match_rule ( rule_id VARCHAR(32) PRIMARY KEY, grade VARCHAR(20), width_tol_min INT, -- 宽度允差下限 mm width_tol_max INT, -- 宽度允差上限 mm weight_tol_pct DECIMAL(5,2), -- 重量允差百分比 priority INT ); -- 插入一条规则DC01宽度允差 -10 到 10重量允差 -5% INSERT INTO match_rule VALUES (MR_DC01_01, DC01, -10, 10, -5.00, 10);匹配时用产出卷的牌号、宽度、重量去match_rule里找规则命中后判断是否在允差内。priority用于多条规则命中时选哪条。这个表看起来简单但实际项目里经常被忽略导致准发环节要么卡死要么乱发。4.2 准发流程从产出到发货的状态机准发流程要定义清楚状态流转产出下线 → 质量判定 → 匹配合同 → 生成准发单 → 发货 → 合同关闭。每个状态都要有系统校验不能跳步。我见过最离谱的翻车是产出卷还没做质量判定就被匹配到合同并发货了客户收到后发现性能不合格整批退货。所以状态机里「质量判定合格」必须是「匹配合同」的前置条件。# 准发状态机校验 def can_match(coil, contract_line): coil: 产出卷含 grade, width, weight, qc_status contract_line: 合同行 返回 (bool, reason) if coil[qc_status] ! PASS: return False, 质量未判定合格 if coil[grade] ! contract_line[grade]: return False, 牌号不符 # 查匹配规则 rule get_match_rule(contract_line[grade]) if not rule: return False, 无匹配规则 width_diff coil[width] - contract_line[width] if width_diff rule[width_tol_min] or width_diff rule[width_tol_max]: return False, 宽度超允差 weight_diff_pct (coil[weight] - contract_line[qty]) / contract_line[qty] * 100 if weight_diff_pct rule[weight_tol_pct]: return False, 重量低于允差下限 return True, OK这段代码把匹配条件显式化每个失败原因都能追溯。qc_status必须是PASS这是硬约束。宽度和重量的允差判断用规则表驱动不同牌号可以配不同允差。实际项目中get_match_rule要加缓存否则每次匹配都查库产出高峰期数据库扛不住。5. 产销一体化落地避坑五条血泪经验5.1 坑一物料编码没统一就上系统现象系统上线后销售看到的库存和生产看到的库存对不上同一批货两个部门报出两个数字。原因销售用「合同号」管库存生产用「材料号」管库存两套编码没有映射关系。解决上线前先做编码映射表把历史数据里的合同号、炉次号、卷号全部映射到统一材料号映射不上的挂「待确认」状态人工清理完再上线。这一步至少留两周别信「上线后再补」的鬼话。5.2 坑二质量设计表覆盖不全排产时频繁人工干预现象排产引擎跑出来的计划计划员要手工改 30% 以上改完还不如 Excel 排得快。原因质量设计表只覆盖了主力牌号新牌号或小批量牌号匹配不到工艺路线引擎直接报错或走默认路线结果不可用。解决先统计近半年产量按牌号规格区间排序覆盖前 80% 的产量剩余 20% 用「默认路线 人工确认」流程兜底并在系统里记录人工确认的原因后续逐步补全。5.3 坑三炉次归并只看重量不看成分现象炉次计划排出来炼钢厂说「这炉钢成分差太多炼不了」。原因归并算法只按牌号和重量分组没检查成分区间。解决在归并前加一步成分兼容性检查用碳、硅、锰等关键元素的区间重叠判断重叠度低于阈值的不能同炉。阈值一般设 70% 到 80%具体看钢种。5.4 坑四准发匹配没有质量前置校验现象客户收到货后投诉性能不合格追溯发现是未判定合格的卷被匹配发货了。原因准发流程里「质量判定」和「合同匹配」是并行分支没有强制先后顺序。解决把质量判定设为合同匹配的前置状态系统层面校验qc_status不合格或未判定的卷不允许进入匹配环节。这个校验要写在代码里不能只靠流程制度。5.5 坑五排产结果不回写计划和生产两张皮现象排产引擎每天跑出计划但生产现场按自己的节奏干计划形同虚设。原因排产结果没有回写到 MES 或生产工单现场看不到最新计划。解决排产引擎的输出必须通过接口回写到 MES生成生产工单工单状态变更再回传产销系统形成闭环。接口可以先用文件交换稳定后再换消息队列别一上来就追求实时先把闭环跑通。6. 进阶技巧用「可承诺量」做接单前的实时模拟产销一体化做到后面最有价值的不是排产多快而是销售在接单时就能知道「这个单能不能接、什么时候交」。这需要把可承诺量ATP算准并且支持实时模拟。我一般会做一个轻量的 ATP 服务输入是牌号、规格、数量、期望交期输出是「可承诺」「需调整交期」「不可承诺」三种结果并给出建议交期。实现上ATP 当前可用库存 在制量 未来可排产量 - 已承诺量。当前可用库存从库存系统取在制量从 MES 取未来可排产量用排产引擎的粗能力模型估算。关键是「已承诺量」要实时更新每签一个合同就扣减否则 ATP 会虚高。下面是一个简化的 ATP 计算示例。# 可承诺量计算 def calc_atp(grade, width, qty, delivery_date): 返回 (atp_qty, suggested_date) # 1. 可用库存 stock query_stock(grade, width) # 2. 在制量 wip query_wip(grade, width) # 3. 未来可排产量用粗能力模型按周估算 capacity query_capacity(grade, width, delivery_date) # 4. 已承诺量 committed query_committed(grade, width, delivery_date) atp stock wip capacity - committed if atp qty: return atp, delivery_date else: # 建议交期往后顺延直到 ATP 满足 suggested find_next_available(grade, width, qty, delivery_date) return atp, suggestedquery_stock、query_wip、query_capacity、query_committed四个函数分别对接库存、MES、排产引擎和合同系统。find_next_available是顺延逻辑按周粒度往后找找到第一个 ATP 满足的周就返回。这个服务不用追求秒级分钟级更新就够用但数据准确性要求高任何一个环节的数据延迟都会导致 ATP 失真。提示ATP 服务上线后先让销售用一个月但不要直接对接客户等数据准确率稳定在 95% 以上再开放给客户自助查询。我自己的习惯是每做一个产销一体化项目先花两周把物料编码和质量设计表理清楚再动排产引擎。排产引擎可以换编码和规则换起来伤筋动骨。另外别指望一次上线就全自动先做「系统排产 人工确认」跑顺了再逐步减少人工干预。这套方案值不值得做取决于你的合同复杂度——如果每月合同行超过 5000 条手工排产已经明显吃力那就值得投入如果只有几百条先把 Excel 模板优化好可能更划算。希望帮到你。本文还有配套的精品资源点击获取