缺料分析二次开发:带出用料清单自定义字段的实战方案
2026/9/7 18:28:31 网站建设 项目流程

做物料需求计划缺料分析的人应该都有过这种经历:系统把缺料计算跑完,界面上清清楚楚列着哪个物料编码缺了多少、可用量还剩多少,可当你顺着这张表往前追,想看它到底缺在哪张生产订单、对应的是哪一版用料清单、清单上有没有什么备注或替换料标记,结果发现——这些信息压根没带过来,只能关掉分析界面,回去一张张翻单据。这个痛点我在项目上踩过无数次,后来干脆做了一个专门解决这个问题的二次开发,把用料清单上的自定义字段一起带进缺料分析结果里。这篇文章就把这个二开的思路、设计和实现过程完整拆一遍,给正在被同样问题困扰的朋友做个参考。

1. 为什么缺料分析要带用料清单字段

1.1 标准缺料分析看不到“缺料背后的料”

缺料分析的任务,按理说就是把“缺什么、缺多少、什么时候缺、谁造成的”一次性讲清楚。但大多数ERP的标准缺料分析,输出结果往往只有几个核心字段:物料编码、物料名称、需求数量、可用数量、预计缺料数量、需求单据编号、需求单据类型。

问题就出在“需求单据编号”这层。缺料分析把需求追溯到生产订单或计划订单后,就停住了,不会继续往下拆。可真正做物料计划和采购计划的人,缺的不只是“某个料缺了多少”,还要知道这个需求来自哪张生产订单的用料清单,用料清单上有没有特殊工艺要求,用的物料是不是一版已经失效的清单,有没有被跳过或用虚拟件代替。这些信息,标准界面里基本不会展示。

我举一个实际场景:一张总装生产订单的用料清单上,某个原材料料号其实已经被工程变更单替换过,新的替代料号在清单里以“替换料”的形式存在,标准缺料分析不会把这个替换关系带出来。计划员看到的仍然是旧料号缺料,于是照旧下采购申请,结果仓库来料之后发现根本没消耗位置,既占用资金又积压库存。这种问题靠人工翻单能发现,但翻单本身需要打开用料清单,还得知道去哪个页签看,效率低不说,碰上一天几十条缺料记录,根本翻不过来。

1.2 二开字段能解决什么问题

把用料清单上的自定义字段携带到缺料分析里,本质上是给分析结果补上了“第二层上下文”。第一层上下文是物料维度,第二层就是用料清单维度。新增字段以后,计划员在分析界面上直接就能看到:

  • 需求来源单据对应的用料清单版本号
  • 用料清单表头的备注、审批状态、变更状态
  • 清单行上的替换料标记、虚拟件标记、厂牌要求
  • 工艺路线或物料主数据里指定的计划员、采购负责人

这些字段一旦出现在分析界面,计划员就不用再跳出去翻明细单据,缺料原因判断和采购决策可以直接在分析界面完成。更重要的是,这些字段还能作为后续自动化逻辑的输入条件,比如判断“某条缺料对应的用料清单已经失效”时,自动跳过采购建议,或者把需求转向替代料,这是标准功能做不到的。

2. 动手前先理清这几个基础概念

2.1 缺料分析的核心计算逻辑

要理解二开字段的价值,先要搞明白缺料分析本身是怎么算的。常见的底层逻辑并不复杂,大致是三条量相减:

需求量减可用量减在途在制量,得出缺料量。

需求量主要来自销售订单、生产订单、计划订单、预测单这些需求来源。可用量是当前库存、采购在途、生产在制中可以拿来用的部分。缺料量就是两者之间的差额。系统一般还会再做一次“时序平衡”,把供应和需求按日期对碰,算出来的结果比简单相减更准确。

这里强调一个细节:很多缺料分析报表里,同一个物料会出现多行,因为不同需求单据的日期、数量不同,系统会按供需日期把缺口拆开。所以字段携带时,必须跟着“需求单据”走,而不是跟着“物料”走。如果只按物料编码取用料清单,取到的可能永远是最新版本,而不是需求单据真正引用的那一版,这就会造成带错字段。

2.2 物料清单和用料清单不能混为一谈

物料清单是产品结构标准,描述一个产品由哪些物料、多少数量构成,通常由研发或工程部门维护。用料清单则是生产订单关联的实际用料明细,它是物料清单在生产执行阶段的实例化结果,包含了版本快照、实际替代方案、工艺路线信息、现场调整等。

缺料分析在追溯需求时,追溯的是生产订单对应的用料清单,不是设计阶段的物料清单。这就带来一个问题:二开字段如果直接去取物料清单字段,很可能取不到,因为生产订单引用的是用料清单主键,跟设计物料清单主键不是一回事。

我当年第一次做这个二开时就踩过这个坑。字段配在物料清单上,分析结果怎么都带不出来,查到最后发现需求单据关联的表是用料清单表,根本不是物料清单表。两个表名字看着像,里面的FID、FEntryID对应关系完全不一样,只按物料编码关联当然取不到。搞清楚这个区别,后面设计字段来源才不会再跑偏。

2.3 携带用料清单的二开字段到底指什么

简单说,这个二开要做的事就是三步:确定需要在缺料分析界面显示的字段、找到这些字段在用料清单里的存储位置、写规则把它们带出来并显示在分析结果中。

“携带”这个词用的是ERP系统里的习惯说法,意思是当一条数据在主表被查询时,把关联子表或关联基础资料上的值带过来展示。关键点在于“自定义”三个字。系统自带的字段一般已经有现成关系,不需要处理;自定义字段是实施或开发阶段新增的,比如字段名称、可见性、数据来源这些,系统并不会自动把它和缺料分析关联起来,需要人工维护规则。

字段类型也需要提前想清楚。自定义字段通常分几类:文本型、数值型、日期型、基础资料型,还有的是带选项列表的下拉型。不同类型的字段在携带时有不同的处理方式,基础资料型字段不只是取值,还要带出对应的编码和名称,甚至需要考虑显示格式。这些细节在方案设计阶段就要敲定,不能等到开发完再去适配。

3. 字段设计与方案选型

3.1 选对落地方式:视图、表单属性还是插件

实现“携带字段”的方式,不同系统有不同路径,但大体上可以归成三类。

第一类是数据库视图和存储过程方式。在后台新建一个视图,把缺料分析结果和用料清单自定义字段关联起来,报表或者查询直接读视图。这种方式性能好,适合数据量大、查询频率高的场景,但存在两个问题:一是视图里的字段不受系统权限体系管控,容易出现越权查看;二是系统升级时如果改了表结构,视图容易失效,维护成本高。

第二类是标准配置和表单计算字段方式。在缺料分析配置界面里,把用料清单的现有字段直接注册成显示字段,或者配置一个计算字段去引用。这种方式不用写代码,实施顾问就能完成,适合字段来源关系简单、都是标准字段的场景。缺点也很明显,遇到复杂的取数规则,比如要根据用料清单的版本状态动态取不同值,配置就做不到了。

第三类是插件或事件处理方式。在查询结果集构建或行数据加载事件里写代码,按当前行的需求单据编号获取用料清单信息,填入新增字段。这种方式灵活性最高,能处理各种复杂逻辑,但需要开发资源,而且必须注意性能,不能让每一行的取值都触发一次数据库查询。

我个人的建议是:能用配置解决的就不用插件,纯配置解决不了的再上插件,插件里也要尽量批量取数。顺序是先做字段分析,列出所有要携带的字段和来源,确认哪些是标准字段,哪些是自定义字段,然后对标准字段走配置,对自定义字段走插件。不要一上来就写代码,那样既慢又难维护。

3.2 字段清单与取数规则参考

下面这份字段清单是实际项目里比较常用的一组,可以根据自己系统的字段名微调。

字段用途建议字段类型取数来源
单据标识需求单据编号文本缺料分析标准字段
需求追溯用料清单编号文本用料清单表头
版本控制用料清单版本号文本用料清单表头
状态判断用料清单审批状态下拉用料清单表头
变更追踪变更单号文本用料清单表头
备注信息清单备注文本用料清单表头
替代信息替代料标记复选框用料清单明细行
计划归属计划员基础资料物料主数据或工艺路线
采购归属采购负责人基础资料物料主数据
供应参数采购提前期数值物料主数据

取数规则方面,有一条需要特别注意:表头和明细行的差异。缺料分析结果本身是物料级别的行,一个需求单据可能对应多行用料清单明细,比如一个最终产品有几十个物料。这种情况下,从用料清单明细行带字段到缺料分析行,要按当前缺料分析的“物料编码+需求单据编号”去匹配用料清单的“物料编码+单据编号”,保证一一对应。如果同一张单里一个物料重复出现,还要额外考虑行号匹配,否则可能取到第一行就拿不到第二行。

3.3 组织、期间和权限维度别忘掉

缺料分析通常是按组织、仓库、计划期间来过滤的,二开字段接入后,也要保证字段值的可见范围和组织权限一致,否则就会出现一种怪现象:分析界面上能看到这个物料缺料,但看不到它对应的用料清单字段,因为当前用户对用料清单没有查询权限。

我建议在方案里明确三件事:第一,新增字段在缺料分析结果集中是否始终可见,还是按用户角色控制;第二,取值时要不要判断用户的数据权限范围;第三,如果基础资料上的字段被禁用或删除,分析界面上的列应该隐藏还是显示为空。这些规则不提前定,上线后大概率会收到权限投诉或者数据准确性的质询。

4. 实操实现:从配置到插件

4.1 第一步:在基础资料和用料清单上添加字段

如果目标字段在系统里还不存在,第一步是把它加到对应的主数据或单据上。比如要在用料清单表头增加“计划员”字段,先在基础资料或单据扩展里注册,设置字段名称、标识、类型、默认值,再分配权限。

字段标识的命名要规范。我见过不少项目把字段标识写成拼音缩写,后来报表取数时根本猜不出含义。推荐统一用“F_U_模块_字段名”这种格式,比如F_U_BOM_Planner,看到标识就知道是哪个模块的自定义字段。数据类型也要慎重,计划员如果用基础资料类型,后来想改成文本都得做数据迁移,不如一开始就定准。

添加字段之后,一定要做一次权限分配。很多ERP的自定义字段默认只有创建者可见,其他用户登录后看不到,更不用说被报表和插件读取。这块操作看着不起眼,实际上新字段上线后“看不见”的问题,有一半都出在这。

4.2 第二步:在缺料分析查询中注册显示字段

字段加好后,进入缺料分析的查询配置界面,把新增字段注册到显示字段列表里。这一步一般不需要写代码,在界面上操作:

  • 打开缺料分析的列设置或字段选择器
  • 在可用字段里找到刚新增的用料清单相关字段
  • 拖到已选字段列表,设置列标题、宽度、排序
  • 保存配置,刷新分析界面

如果是标准字段,操作到这一步就已经能显示了。因为在系统的数据模型里,缺料分析结果和用料清单之间本来就有内在关联,字段注册后系统会自动取值。这里要提醒的是,注册显示字段不意味着自动带上值,很多时候系统只是把列的框架显示出来,值还需要通过后续的取数逻辑填充。不要把两步混为一谈,否则调试时会找不到原因。

4.3 第三步:为自定义字段写取数逻辑

到了自定义字段,就需要写取数逻辑了。最常见的做法是写服务端插件,在缺料分析结果集构建完成、即将返回给界面之前,对结果集循环补充字段值。

以用料清单版本号为例,伪代码逻辑大致是:

// 收集所有需求单据编号 var orderIds = resultRows.Select(r => r.OrderId).Distinct().ToList(); // 批量查询用料清单,避免逐行查询 var bomList = DbContext.Set<ProductionBOM>() .Where(b => orderIds.Contains(b.OrderId)) .Select(b => new { b.OrderId, b.Version, b.Remark }) .ToList(); // 构建字典,按订单号快速查找 var bomMap = bomList.ToDictionary(b => b.OrderId); // 给每一行结果填充自定义字段 foreach (var row in resultRows) { if (bomMap.TryGetValue(row.OrderId, out var bom)) { row.U_BOMVersion = bom.Version; row.U_BOMRemark = bom.Remark; } }

这里有两个关键点。第一,一定要批量查询,不能每行结果都开一次数据库查询,数据量几百行时可能感觉不出来,到了几千行时性能会明显下降,报表转圈能转上几分钟。第二,要按订单编号建立字典再匹配,不要在循环里反复查字典的替代写法,那样虽然逻辑上正确,但代码可读性和效率都差很多。

如果是简单的按物料编码取值,还可以直接在查询SQL里写子查询或者关联,这要看系统的开放程度。能用SQL解决的尽量用SQL,插件能少写就少写,减少将来维护成本。但SQL关联会带来新的问题:如果用料清单有多条记录,关联会产生数据翻倍,必须在SQL里聚合或者去重。建议根据具体场景选方案,千万不要一种方案套到底。

4.4 第四步:性能优化与上线前验证

字段带上以后,接下来重点就是性能和正确性验证。

性能上,先看两个指标:单次缺料分析从打开到出结果的耗时,以及大数据量下不卡死。我一般的做法是,先在测试环境塞一批数据,模拟一个月订单量,跑一次分析,记录耗时。如果耗时翻倍以上,优先检查是不是取数逻辑里出现了逐行查询,然后看索引是否命中。用料清单表的需求单据编号字段必须建索引,这是最常见的性能瓶颈点,不加索引时全表扫描,数据量大了必卡。

正确性验证方面,我会做三层校验:

第一层,拿三笔已知订单做样本,手工核对分析界面上的字段值和用料清单里的实际值是否一致。 第二层,故意构造一笔“用料清单已删除、但生产订单未删除”的数据,看字段显示是否合理,页面会不会报错。 第三层,验证权限,用普通用户账号和系统管理员账号分别登录,确认字段可见性符合预期。

我的经验是第二层最容易出问题。很多插件只处理了正常取数路径,遇到用料清单被删、订单还在的情况,就直接抛异常或者返回空值,严重时整个分析界面都打不开。这块一定要在代码里做好空值保护,取不到值时返回空字符串,不要中断主流程。

5. 常见问题与排查技巧实录

5.1 高频问题清单

这类二开上线后,计划员反馈最多的问题基本集中在下面几类,我整理成了一张速查表:

问题现象可能原因处理建议
字段列有显示但值全是空白取数逻辑没有执行或字段标识写错先确认字段标识与代码中的标识一致,再查日志
只有部分单据能带出字段部分用料清单没有保存自定义字段值补数据历史值,或在取数时加默认值
带出的版本号不是订单指示的版本按物料编码取值时取到了最新版本改为按需求单据编号匹配用料清单
分析页面打开非常慢取数循环中的逐行查询或者缺索引改批量查询,给关联字段加索引
普通用户看不到字段字段权限未分配检查角色权限和字段可见性配置
插件报错导致分析界面打不开空值未处理或异常被上抛增加空值判断,把异常吞掉并记录日志

5.2 实战排查思路

遇到问题时,我建议按三步走定位问题原因,不要一上来就翻代码。

第一步,先看数据库里的数据。直接用SQL查用料清单表,确认这个需求单号对应的自定义字段是否有值。如果表里就没值,那就是数据问题,不是代码问题,让业务人员补数据即可。

第二步,看取数日志。如果表里有值但分析界面看不到,八成是取数逻辑没有走通。打开调试模式或者查看系统操作日志,看那一行结果执行取数时是否抛了异常。这一步能快速区分是查询语句写错还是权限不够。

第三步,复现最小集。把所有过滤条件清掉,只保留一张订单的数据,跑一次分析,逐步加条件,定位是哪一步触发了问题。这个方法对权限类、过滤条件类问题特别有效,我调试时基本每次都这么干。

5.3 几个必须知道的避坑点

最后分享几个实战中踩出来的坑,都是文档里不会写的。

第一,用料清单版本变更以后,历史生产订单不会自动跟着变。二开字段如果按“最新用料清单版本”带值,历史订单的版本信息就会对不上。所以取数时必须按照生产订单上保存的那个版本号去取,不能图省事按物料编码找最新版本。

第二,替代料和虚拟件会在用料清单里产生额外隐藏行。这些隐藏行有时在界面上不显示,但数据库里真实存在。如果取数逻辑没做过滤,一个物料可能匹配到多个用料清单行,字段值就会重复甚至错乱。取数时一定要带上“是否有效、是否显示”这类过滤条件。

第三,缓存字段的更新时机。部分系统对基础资料自定义字段有缓存机制,刚修改的字段值不会立刻反映到分析界面,有时要等几分钟甚至重启缓存才能生效。上线初期业务人员如果反馈“改了没反应”,不要急着怀疑代码,先验证一下缓存刷新机制。

第四,记录日志的位置要留够。插件里最好在关键分支写日志,包括进入事件、取数条数、异常信息。生产环境不能随便调试,日志就是排障的唯一依据。日志保存周期建议不少于30天,否则出了问题想查历史记录都查不到。

做这个二开最深的体会是:字段携带看着是个小功能,真正做起来涉及数据模型、单据关联、权限体系、性能优化方方面面,任何一个环节考虑不到位,上线后都会变成计划员的日常抱怨。但反过来,只要前期把字段来源、取数规则和权限控制想明白,实现起来其实并不复杂,代码量也不大,却能实打实地把缺料分析的可用性提升一个档次。如果你们公司也面临同样的问题,不妨按这个思路先梳理一下自己的用料清单字段,看看哪些值得带进分析结果,然后从最刚需的那两三个字段开始试点,逐步扩展,会比一次性铺开稳妥得多。

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

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

立即咨询