SAP B1金属包装批次追溯与按单生产实践
2026/9/17 19:11:21 网站建设 项目流程

简介:该资源为面向金属包装制造企业的SAP ERP解决方案文档,适合包装行业信息化负责人、ERP实施顾问及企业管理者参考。文档围绕印涂铁、饮料罐、食品罐、气雾罐、化工罐及钢桶等金属包装产品线,梳理行业向大珠江三角、长三角、环渤海三角集聚及向中西部转移的发展态势,并归纳出库存精细化、生产批次、成本核算、质检记录、物流追溯、车间精细化管理、条码出入库等信息化诉求。内容重点展开华智基于SAP Business One的行业整体方案,覆盖财务、进销存、生产、质检等模块,具体讲解库位与安全库存管理、按销售订单排产与一单一清、批次垛号质检与隔离复检复判、全链条产品追溯、工单报工与班组交接,以及二维码扫描物料流转等落地做法,并附济南联合制罐等成功案例与实施服务商背景。资源为1个PDF文件,压缩包约136KB,篇幅精炼、结构清晰,便于快速把握方案框架与功能要点。目前已有66人学习关注。

1. 金属包装厂上 SAP,为什么先要解决批次和追溯

金属包装这个行业的特殊性在于:一个马口铁三片罐从印涂铁到成品,中间要经过印刷、涂布、制罐、封口、检验五六道工序,原料是按卷、按张进的,成品是按垛、按单出的。客户投诉一个罐子漏了,你要在两天内说清楚这批料是哪家的、哪台机做的、同批次还发给了谁。这件事靠Excel和纸质流转卡基本做不到,所以金属包装企业上 ERP 的第一诉求往往不是财务,而是原料批次和成品追溯。

SAP Business One 在这类中型金属包装厂里出现频率很高,原因不复杂:单厂、多品种、按单生产、需要条码和批次,SAP B1 的批次管理、库位管理、生产工单和 UDO 开发能力刚好卡在这个需求区间。这篇围绕华智那套金属包装行业解决方案的功能框架,拆开讲库存库位、按单生产、质检隔离、追溯链和条码出入库具体怎么落到配置和代码上。

2. SAP B1 批次与库位管理的配置与查询逻辑

金属包装的库存难点不在总量,在"这批料还能不能用"。马口铁有保质期和涂层有效期,印涂铁有批次色差,同一个物料号下可能压着三批不同入库日期的料,PMC 排产时必须知道哪批先出。SAP B1 里解决这个问题靠的是物料主数据上的批次管理和库位管理两个开关,加上批次属性。

2.1 物料主数据上的三个关键开关

在 SAP B1 的物料主数据「库存数据」页签下,有三个设置决定了后续能不能按批次查库位:

字段取值对金属包装的影响
管理批次按批次 / 按序号印涂铁、罐身料按批次;高值模具可用序号
管理库位启用分区、货架、垛位三级库位
序列号管理按批次 / 按序号成品垛号追溯用序号更细,但录入成本高

管理批次一旦开,后续所有收货、发货、库存转储都必须带批次号,中途不能改回。常见坑是新上线时图省事只开了部分物料,结果半年后客户要求成品追溯,才发现罐身料没有批次,追溯链断在中间。

2.2 用 SQL 查实存数、占用数和可用数

SAP B1 标准的库存状态报表只能看实存数,生产占用数和可用数要自己拼。金属包装厂 PMC 每天要看的核心就是这三个数。下面这段查询直接读 B1 的 OITM、OITW、OIBT 三张表:

-- 查询某物料在各仓库的实存、占用、可用数量(SAP B1,SQL Server) SELECT T0.ItemCode AS 物料编码, T0.ItemName AS 物料名称, T1.WhsCode AS 仓库, T1.OnHand AS 实存数, -- OITW.OnHand,实际在库 ISNULL(T2.LockedQty, 0) AS 占用数, -- 生产工单已发未领部分 T1.OnHand - ISNULL(T2.LockedQty, 0) AS 可用数, T1.IsCommited AS 承诺标识 FROM OITM T0 INNER JOIN OITW T1 ON T0.ItemCode = T1.ItemCode LEFT JOIN ( -- 汇总未关闭生产工单的预留量 SELECT W.ItemCode, W.WhsCode, SUM(W.PlannedQty - W.IssuedQty) AS LockedQty FROM WOR1 W INNER JOIN OWOR O ON W.DocEntry = O.DocEntry WHERE O.Status = 'R' -- R=已下达,尚未关闭 AND W.PlannedQty > W.IssuedQty GROUP BY W.ItemCode, W.WhsCode ) T2 ON T0.ItemCode = T2.ItemCode AND T1.WhsCode = T2.WhsCode WHERE T0.ItemCode = '[%0]' -- 查询窗口传入的物料编码 ORDER BY T1.WhsCode;

逻辑说明:OITW 是物料-仓库维度的库存表,OnHand 是实存。占用数这里用未关闭生产工单的"计划数减已发数"来近似,语义是"已经被工单预定但还没领出去的料"。WHsCode 关联保证占用数落在仓库维度上,不会跨仓乱扣。参数[%0]是 B1 查询接口的占位符,在格式化搜索或用户自定义查询里直接传给界面。

注意:OITW.OnHand 是包含未过账单据调整后的值,如果厂里习惯先做收货草稿再集中过账,这个数会和实物对不上,需要额外扣减草稿单据量。

2.3 库位管理减少寻址时间

库位管理的直接收益是让仓管员不用满仓库找料。B1 的库位结构是仓库-分区-货架-垛位,金属包装厂常见划法是按产品线分区:印涂铁一个区、罐身料一个区、盖料一个区、成品按客户分垛位。配置上要先启用「库位」主数据,再在库存转储和发货环节强制选择来源库位。

启用后有一件事必须提前定:库位是只在收货时分配,还是每次转储都要求人工确认。前者的数据准确度差,后者增加仓管工作量。金属包装厂料重、搬运靠叉车,我一般建议收货和上架两步走,上架必须扫描库位条码确认,这样账面库位和实物基本同步。

3. 按单生产:从销售订单到生产工单的排产映射

金属包装是典型的按单生产,客户下单时带一堆特殊要求:托盘盖板要几层、隔层纸用不用、运输方式走海运还是陆运、罐身印刷图案用哪个版本。这些要求如果只写在邮件里,生产线上就是一问三不知。SAP B1 里要做的是把这些要求结构化地挂到销售订单,再通过 MRP 带到生产工单。

3.1 销售订单特殊要求的承载方式

B1 的销售订单行有自由文本字段,可以用,但检索困难。更稳的做法是建 UDO(用户自定义对象)挂销售订单,字段包括托盘盖板层数、隔层纸类型、印刷版本号、运输方式。下面是 UDO 表的结构示意:

-- 销售订单特殊包装要求 UDO 表(SAP B1 用户自定义表) CREATE TABLE [@PACK_REQ] ( DocEntry INT IDENTITY(1,1) PRIMARY KEY, -- B1 系统主键 DocNum NVARCHAR(20), -- 单据号 OrderDocEntry INT, -- 关联销售订单 DocEntry OrderLineNum INT, -- 关联订单行号 PalletBoard NVARCHAR(10), -- 托盘盖板层数 InterPaper NVARCHAR(20), -- 隔层纸类型 PrintVersion NVARCHAR(30), -- 印刷版本号 ShipMode NVARCHAR(10) -- 运输方式 );

逻辑说明:OrderDocEntry 加 OrderLineNum 的组合指回 ORDR/RDR1,保证要求挂在具体行上而不是整单。B1 的 UDO 建表规则是表名以 @ 开头,主键用 DocEntry,其余字段名可以自己定。ShipMode 用下拉值集控制,避免手输"海运""海運""Sea"三种写法。

参数说明:PalletBoard 建为字符型而不是整型,因为产线现场经常写"2层+1垫板"这类非纯数字信息,整型反而限制录入。

3.2 MRP 运行与工单下达

销售订单确认后,通过 MRP(物料需求计划)生成生产工单和采购建议。金属包装厂的 MRP 参数有两个地方要对:

  • 生产周期:印涂铁类半成品设 2 到 3 天,制罐工序设 1 天,排产时 B1 按这个倒推开工日期
  • 最小订货量:马口铁采购有最小起订吨数,不设这个数,MRP 会生成一堆几百公斤的采购建议,采购根本没法下单

MRP 跑完后检查建议工单的开工日期是否落在工作日,节假日日历要在 B1 的「生产日历」里维护,否则排出来的计划全是错的。

3.3 工单发料与一单一清

按单发料的关键是工单和领料单强制关联。B1 里做「生产发料」时选工单,物料和数量自动带出,仓管只扫批次。一单一清意味着这张工单的料只能发到这张工单上,不能挪给别的单。实际执行中会有人为了赶交期互相挪料,导致成本串单,解决办法是在发料环节加批次校验,非本工单预留批次不给过账。

4. 质检、隔离与成品追溯链的落地做法

金属包装的质量管理有两个特点:一是检验项多(涂层厚度、附着力、罐身抗压、焊缝完整性),二是出问题要能整批隔离。SAP B1 的质检模块本身较弱,行业里通常是用批次状态加 UDO 检验记录表补出来的。

4.1 批次状态控制与质检记录

B1 的批次可以设状态,常用的有"可用""质检中""锁定""报废"。收货后批次默认进"质检中",检验合格才转"可用"。质检记录如果用 UDO 存,字段至少要有批次号、检验项、实测值、标准上下限、判定结果、检验员。查询某批次全部检验记录:

-- 按批次查历史质检记录 SELECT Q.BatchNum AS 批次号, Q.CheckItem AS 检验项, Q.MeasuredVal AS 实测值, Q.LowerLimit AS 下限, Q.UpperLimit AS 上限, CASE WHEN Q.MeasuredVal BETWEEN Q.LowerLimit AND Q.UpperLimit THEN '合格' ELSE '不合格' END AS 判定, Q.Inspector AS 检验员, Q.InspDate AS 检验日期 FROM [@QC_RECORD] Q WHERE Q.BatchNum = '[%0]' ORDER BY Q.InspDate DESC;

逻辑说明:判定结果用 CASE 现场计算而不存字段,是为了避免检验员手工改判定结果。如果厂里要求判定留痕(谁改过、什么时候改的),就要改成存字段并加变更日志 UDO。

参数说明:LowerLimit 和 UpperLimit 用数值型,检验项本身的名称放 CheckItem,这样同一张表能装涂层厚度、抗压强度等不同量纲的项,不用为每个检验项单独建表。

4.2 隔离-复检-复判的完整追踪

发现质量问题后,流程是:选批次 → 状态改为"锁定" → 生成隔离单 → 二次质检 → 复判(报废或返修或放行)。这条链路要完整记录,B1 里用一张隔离单 UDO 加状态流转字段实现。核心字段是隔离单号、原批次、隔离原因、复检结果、复判结论、复判人、复判时间。

注意:批次锁定后,B1 默认不允许对该批次发货和发料,但已经生成未过账的发货单不受影响,需要在发货过账前做一次批次状态校验,否则锁了还能发出去。

4.3 从成品垛号反查原料批次

这是金属包装追溯最核心的一条查询。成品出库时记了垛号(或序号),要能反查到:这垛产品用了哪些原料批次、这些原料还做给了哪些客户、这些原料批次的其他成品发给了谁。前向追溯一段 SQL 能搞定,后向要多跳一次。

-- 从成品批次反查原料批次(前向追溯) SELECT DISTINCT F.BatchNum AS 成品批次, F.ItemCode AS 成品编码, R.ItemCode AS 原料编码, R.BatchNum AS 原料批次, R.WhsCode AS 原料仓库, I.DocDate AS 发料日期 FROM OBTN F -- 成品批次主表 INNER JOIN OWOR O ON F.BatchNum = O.BatchNum INNER JOIN WOR1 W ON O.DocEntry = W.DocEntry INNER JOIN OBTN R ON W.ItemCode = R.ItemCode INNER JOIN OIGE I ON R.ItemCode = I.ItemCode AND R.BatchNum = I.BatchNum WHERE F.BatchNum = '[%0]';

逻辑说明:OBTN 是 B1 的批次主表,成品批次通过生产工单 OWOR 关联到工单用料 WOR1,再关联回原料批次 OBTN。这里用 DISTINCT 是因为一个原料批次可能多次发到同一工单,不去重会出现重复行。实际生产环境还要加上仓库和日期过滤,链路长的时候这条查询会很慢,建议对 OBTN.BatchNum 和 WOR1.ItemCode 建索引。

参数说明:[%0]传成品批次号。如果厂里成品用序号管理而不是批次,把 OBTN 换成 OSRN,关联字段相应调整。

5. 条码扫描出入库与报表验证的几个实用技巧

条码这块是金属包装 ERP 落地最容易翻车的地方。原料卷材上贴的标签要能扫、要能扛住车间环境,成品垛标签要能整垛扫也能单件扫,还要考虑托盘换垛后标签怎么处理。SAP B1 本身不带条码模块,行业里用的是 HuaZhi WMS 这类外挂条码系统,通过 B1 的 DI API 或 Service Layer 回写单据。

5.1 用 DI API 回写库存收货单

扫码入库的本质是:扫物料码和批次码,组装成一张 B1 的收货单(库存收货或采购收货),通过接口过账。下面是用 DI API 创建收货单的最小代码:

# SAP B1 DI API 创建库存收货单(Python 通过 comtypes 调用) import comtypes.client as cc company = cc.CreateObject("SAPbobsCOM.Company") company.Server = "sap-server" company.CompanyDB = "METAL_PACK" company.UserName = "manager" company.Password = "******" company.DbServerType = 10 # 10 = dst_MSSQL2019 company.Connect() doc = company.GetBusinessObject(59) # 59 = oInventoryGenEntry doc.CardCode = "V001" # 供应商 doc.TaxDate = "2025-06-01" # 过账日期 line = doc.Lines line.SetCurrentLine(0) line.ItemCode = "RM-TINPLATE-01" # 物料编码 line.Quantity = 1250.5 # 数量 line.WhsCode = "RAW01" # 仓库 line.BatchNumbers.BatchNumber = "B20250601001" # 批次号 line.BatchNumbers.Quantity = 1250.5 line.BatchNumbers.Add() ret = doc.Add() if ret != 0: print("失败原因:", company.GetLastErrorDescription()) else: print("过账单号:", company.GetNewObjectKey())

逻辑说明:GetBusinessObject(59)里的 59 是 B1 库存收货单的对象类型码,这个码不能记错,记错会拿到完全不同的业务对象。批次信息不是设在行上,而是设在行的 BatchNumbers 子集合里,一个行可以有多批次,所以要 Add 多次。Add 返回非 0 表示失败,必须调 GetLastErrorDescription 看原因,常见的是批次不存在、库位没启用、过账期间已关闭。

参数说明:CardCode 在库存收货里可空,采购收货里必填。TaxDate 和 DocDate 的区别是 TaxDate 是税务日期,DocDate 默认取系统日期,跨月过账时这两个值很容易出错,建议都显式赋值。

5.2 扫码出入库的三个操作要点

  • 批次码和物料码分离:物料码贴在卷材芯上,批次码贴在外包装,收货时两个都扫,避免混批
  • 库位码必须在转储时扫:上架环节不扫库位,库位管理的账面数据一周就烂掉
  • 成品垛标签留一个可整垛扫描的汇总码:整垛出货时扫一次,避免上万个罐子逐件扫

5.3 用报表验证追溯链是否闭合

上线后验证追溯能不能跑通,最直接的办法是抽查。选一个客户投诉过的成品批次,走一遍:成品批次 → 生产工单 → 原料批次 → 原料入库日期 → 供应商 → 同原料批次发给了哪些客户。这条链路每跳都应该在 B1 里查得到,任何一跳是空的,说明数据没录进去。我一般建议上线后跑一个月,随机抽 20 个成品批次做全链路追溯,把断链的地方统计出来,基本就能看出是哪个环节的操作规范没执行到位。

提示:追溯查询在上线初期挂得慢很正常,批次表数据量上来后,OBTN 和生产工单表的关联查询要走索引,否则一个查询能跑几分钟。

5.4 生产报工与工序进度

车间精细化管理的落点是生产工单的报工。B1 里通过「生产收货」记录完工数量,每道工序建立一个工艺路线行。金属包装厂的常见做法是每道工序打完一张报工标签,扫标签触发报工,工单进度实时更新。报工数量必须和实际完工数对齐,报多了会导致成本分摊偏高,报少了成本偏低,月底财务会发现工单成本异常。

工序间的报工频率也要平衡:印刷、涂布这类前置工序可以按卷报,制罐、封口这类按垛报,检验按批报,全按件报的话车间根本跟不上。工单进度报表建议做成按工序分段的甘特图,PMC 一眼能看出卡在哪道工序。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询