缺料分析二次开发:带出用料清单自定义字段的实战方案
做物料需求计划缺料分析的人应该都有过这种经历系统把缺料计算跑完界面上清清楚楚列着哪个物料编码缺了多少、可用量还剩多少可当你顺着这张表往前追想看它到底缺在哪张生产订单、对应的是哪一版用料清单、清单上有没有什么备注或替换料标记结果发现——这些信息压根没带过来只能关掉分析界面回去一张张翻单据。这个痛点我在项目上踩过无数次后来干脆做了一个专门解决这个问题的二次开发把用料清单上的自定义字段一起带进缺料分析结果里。这篇文章就把这个二开的思路、设计和实现过程完整拆一遍给正在被同样问题困扰的朋友做个参考。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.SetProductionBOM() .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天否则出了问题想查历史记录都查不到。做这个二开最深的体会是字段携带看着是个小功能真正做起来涉及数据模型、单据关联、权限体系、性能优化方方面面任何一个环节考虑不到位上线后都会变成计划员的日常抱怨。但反过来只要前期把字段来源、取数规则和权限控制想明白实现起来其实并不复杂代码量也不大却能实打实地把缺料分析的可用性提升一个档次。如果你们公司也面临同样的问题不妨按这个思路先梳理一下自己的用料清单字段看看哪些值得带进分析结果然后从最刚需的那两三个字段开始试点逐步扩展会比一次性铺开稳妥得多。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →