ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CS_BOM_EXPL_MAT_V2参数配置详解:BOM展开避坑与实战指南

CS_BOM_EXPL_MAT_V2参数配置详解:BOM展开避坑与实战指南 做SAP ABAP开发绕不开BOM展开。不管是生产订单组件需求计算、成本估算取材料成本还是给MES/APS系统推送制造物料清单最终都会落到CS_BOM_EXPL_MAT_V2这个标准函数上。这个函数功能强参数多文档里交代得又不细很多人第一次调它都是靠网上抄一段代码结果要么展开结果为空要么数量翻倍要么把不该出现的文本项目、文档项目全部带出来。这篇文章直接给你一份我在实际项目里总结的CS_BOM_EXPL_MAT_V2参数配置说明和避坑清单适合正在写报表、接口或增强的ABAP开发也适合供应链顾问在排查数据问题时当参考。1. 先搞清楚函数选型为什么是CS_BOM_EXPL_MAT_V21.1 BOM展开的典型业务场景与输出预期BOM展开在SAP里几乎是无处不在的底层操作。生产订单评审时要按工单数量算出组件需求成本核算时要逐层展开拿到材料成本明细采购缺料分析时要把多级BOM拍平成一张可采购组件清单外部系统对接时还要把SAP的制造BOM推送给MES或PLM。这些场景看起来不一样本质都是同一件事给定一个父物料、一个工厂、一个BOM用途和一个需求数量把该物料下面所有层级的组件、数量、单位、层级关系全部算出来。这里的“展开”不是简单查MAST表和STPO表就完事因为系统还要处理替代BOM、配置物料、有效期、变式、装配报废、单位换算等一系列逻辑。自己写SELECT再拼逻辑工作量巨大且容易漏掉标准逻辑。CS_BOM_EXPL_MAT_V2就是SAP提供的一个标准函数把这些逻辑全部封装好了一次调用返回多层级的BOM展开结果每一行包含组件物料号、需求数量、单位、层级号、项目类别、有效期等关键信息。我个人的体会是凡是涉及生产、物料、成本相关报表或接口的开发这个函数几乎都是标配。你不需要重复造轮子但要把它用对。1.2 V2与V1及CSAP函数的区别不少老项目里还能看到CS_BOM_EXPL_MAT_V1的调用V1是早期的BOM展开函数参数少逻辑相对基础能处理常规的多层展开但对于配置物料KMAT、替代确定、有效期配合这些场景支持得不够好。V2是在V1基础上的增强版新增了CUOBJ配置对象参数、CAPID替代确定应用、更灵活的日期和数量控制绝大多数新开发都建议直接用V2事务码CS12底层也是走V2的展开逻辑。还有一类函数是CSAP系列比如CSAP_MAT_BOM_READ这是SAP为ALE/外部接口封装的BOM读取函数通常用于RFC远程调用。它返回的数据结构和展开逻辑跟V2不完全一样更偏“读取”而非“按需求数量计算”。如果目的是外部系统同步BOM主数据CSAP可能够用如果目的是内部逻辑计算组件需求量尤其是多级、可变式、带配置的物料那CS_BOM_EXPL_MAT_V2是更稳妥的选择。另外BOM展开结果有时会跟实际生产订单组件数量对不上。这里有个容易被忽略的细节生产订单用的BOM展开底层逻辑还有一个事务码是CS11、CS12它们本质是调用相同的标准函数只是在界面层做了展示。你在调试生产订单组件批量计算时打断点进到函数栈里看到的很可能就是CS_BOM_EXPL_MAT_V2的调用只是外层包了一层批导或增强逻辑。2. 参数配置逐项拆解配错一个结果全错2.1 影响BOM选型的核心参数MATNR、WERKS、STLAN、DATUVMATNR是父物料号这个没什么歧义但要注意它必须是BOM表MAST里真实存在的物料。WERKS是工厂这里有个非常容易踩的坑物料主数据的MRP视图里维护了工厂但MAST表里BOM也是按物料加工厂加用途维度存储的。如果调用时不传工厂或者工厂传错函数不会立刻报错而是返回空结果或另一个工厂的BOM。这在实际项目里导致过不少“BOM为什么展开不出来”的排查最后发现是工厂参数没有传对。STLAN是BOM用途这个参数决定了选哪个类型的BOM。标准SAP里常用的STLAN有1生产、2工程设计、3通用、4设备维护。很多物料同时存在多个用途的BOM比如研发阶段维护了2的工程BOM量产阶段又建了1的生产BOM。如果你的报表需要的是生产用量结果用了STLAN2那展开出来的组件清单可能跟产线实际用料完全不一致。所以业务在提需求时一定要确认清楚BOM用途不要想当然。DATUV是有效起始日期系统在决定BOM是否有效时会用这个日期跟BOM抬头表STKO和BOM行项目表STPO里的DATUV字段做比较。如果DATUV不传默认是00000000理论上不限制任何日期但更常见的做法是传SY-DATUM表示按当前日期展开这样历史或未来的BOM就不会被误选。做未来或历史日期模拟时DATUV要改成对应的模拟日期。我遇到过一种情况用户做未来的生产计划工单开始日期是三个月后但当时BOM还没建好于是展开结果为空这其实是符合系统逻辑的不是bug需要在需求层面确认。2.2 影响数量计算的参数EMENG、RTSCH、AUMNG、MEHLSEMENG是需求数量直接参与各层组件数量的计算。举例来说父物料A每生产1个单位需要2个组件B当EMENG传10时B的需求数量就会算成20。很多新手在这里会犯一个经典错误做BOM清单一类报表时本意是查看基础用量比例结果把工单数量10当成EMENG传进去整个数量列全部放大了10倍。如果只想取BOM的标准单耗EMENG传1是最稳妥的。RTSCH是需求类型默认值是1。这个参数会影响替代BOM的确定逻辑按订单需求还是按计划需求在替代选型上会有差异。日常开发中如果业务没有明确要求保持默认值1即可。但如果你在调试时发现BOM展开结果跟CS12界面显示不一致可以顺手检查一下RTSCH是否被改成了别的值。AUMNG是装配报废。BOM行项目里有报废百分比时系统在计算组件数量时会自动把报废量加上去。如果做的是理论用量分析希望剔除报废影响可以把AUMNG传0。这里要特别提醒装配报废跟制造成品率产量报废是两回事AUMNG管的是BOM行项目里的报废不是工序中的废品率不要混在一起。MEHLS是基本计量单位。BOM里组件单位可能跟物料主数据基本单位不一致比如采购单位是KGBOM组件单位是PC系统会根据单位换算关系自动折算。如果不传MEHLS系统使用物料主数据的单位如果物料没有维护换算关系可能会导致数量计算异常或直接报错。在跨单位场景比较多的项目里建议显式传MEHLS避免默认值引起歧义。2.3 影响替代逻辑与配置件展开的参数CAPID、XBLAN、CUOBJCAPID是我认为这个函数里最容易被误解的参数。很多人从字面上看“CAPID”以为它是BOM用途继承了一点老代码里的错误写法直接传1或2结果发现展开结果不对甚至报错。实际上CAPID是“替代确定的应用”Alternative Determination Application它定义的是系统在多个替代BOM之间如何做选择标准默认值是PP01生产。STLAN才是BOM用途。这两个参数的关系需要理清楚STLAN决定选哪一类BOMCAPID决定在同一类BOM存在多个替代时取哪一个。XBLAN是替代BOM标识。当一个物料存在替代组时MAST表里会有多个STLAL行。不指定XBLAN时系统按CAPID定义的规则自动选一个通常是按优先级、有效期和数量综合判断指定XBLAN时可以强制展开某一个特定替代。做工程变更对比、或者业务明确要求“只展开替代2”时XBLAN就派上用场了。CUOBJ是配置对象。可配置物料KMAT在BOM展开时如果不传CUOBJ系统只会返回配置占位行比如项目类别C行并不会告诉你具体选了哪些可选件。要得到实际配置结果必须先调用配置求解函数生成CUOBJ实例再把这个CUOBJ传给CS_BOM_EXPL_MAT_V2。很多项目在做可配置产品BOM展开时卡住八成是这个参数没有处理好。2.4 影响返回行项目过滤的参数EXP_OTHERS、SANFR、SANIN、SANOU这四个参数决定展开结果里是否包含非库存类行项目。EXP_OTHERS控制是否展开“其他项目”的下一层默认是XSANFR、SANIN、SANOU则分别控制自由文本项目、文档项目、非库存项目是否计入结果。默认情况下这些类型的行项目都可能在STB表里出现如果你做的是MRP相关或者成本相关计算这些项目往往是干扰项。我做过一个缺料分析报表当时没有设置这些参数展开结果里混进来一批文档项SANINX和文本项SANFRX后续按物料汇总时闹了一个乌龙。后来统一把EXP_OTHERS、SANFR、SANIN、SANOU全部传空只留库存项目参与计算数据一下就干净了。当然如果业务场景本身需要这些特殊项目比如做工程BOM对比时要保留文档项目那就按需传入。这几个参数在不同SAP版本上的默认值会有差异正确的做法是在调用时显式指定不要依赖默认值。3. 返回结果表结构解读拿到STB之后怎么做3.1 STB表关键字段与层级判定CS_BOM_EXPL_MAT_V2的返回结果主要在STB表里结构类型是STPOX。常用字段包括POSNR项目号、IDNRK组件物料号、MENGE展开后的需求量、MEINS单位、STUFE层级号、POSTP项目类别、DATUV有效期、LKENZ删除标记、POTX1组件描述。其中STUFE字段是判断父子层级的关键顶层物料是0第一层组件是1第二层组件是2依此类推。拿到STB后很多报表还需要还原BOM树形结构。我在项目里一般不自作聪明写递归解析而是先按STUFE排序再把IDNRK和上一层的IDNRK做对照。这里有个细节STB表里同一层级的行有多个组件数量已经是按顶层需求数量累乘过的绝对值不要再用“当层数量乘以上层数量”去算否则会重复放大。这种错误我在代码Review里见到过好几次。如果要在报表里展示BOM树POSNR只是BOM行项目号不直接等于父子关系还需要结合STUFE和上一个层级来构造层级路径。一个简单做法是按STUFE升序、POSNR升序遍历维护一个当前路径栈遇到STUFE等于当前栈深度加1的节点就入栈这样比递归查表要高效很多。3.2 与MAT、TOPMAT配合使用MAT表返回的是展开过程中涉及的物料主数据信息类型是MBAT里面包含物料号、基本单位、物料组、物料类型等。大多数业务场景下STB表已经够用MAT表可以用来做单位换算或补充物料维度信息。TOPMAT则返回顶层物料的相关信息调用时可以通过IMPORTING参数直接取到顶层物料号不需要自己再从STB表第一条里解析。我的建议是写一个统一的BOM展开封装函数对外只暴露MATNR、WERKS、STLAN、EMENG等业务参数内部把CAPID、DATUV、MEHLS、EXP_OTHERS等固定参数集中维护返回结构统一用STB表。这样业务方不需要理解每个技术参数后续调整替代选择逻辑或过滤规则时也只改一处不容易出现同一个函数在多个报表里参数写法五花八门的情况。3.3 一个可直接复用的标准调用封装下面给出一段我常用的封装代码按“只取库存组件”的场景做了参数配置可以直接复制到程序里改一改用FORM frm_bom_explode USING iv_matnr TYPE matnr iv_werks TYPE werks iv_stlan TYPE stlan iv_emeng TYPE emeng CHANGING ct_stb TYPE STANDARD TABLE OF stpox. DATA: lt_mat TYPE STANDARD TABLE OF mbat, lv_topmat TYPE matnr. FIELD-SYMBOLS: ls_stb LIKE LINE OF ct_stb. CLEAR: ct_stb[], lt_mat[], lv_topmat. CALL FUNCTION CS_BOM_EXPL_MAT_V2 EXPORTING capid PP01 datuv sy-datum emeng iv_emeng werks iv_werks stlan iv_stlan matnr iv_matnr mktvs 1 exp_others sanfr sanin sanou IMPORTING topmat lv_topmat TABLES stb ct_stb mat lt_mat EXCEPTIONS error 1 matnr_empty 2 OTHERS 3. IF sy-subrc 0. 这里建议记录错误日志方便后续排查 RETURN. ENDIF. 去掉删除标记项避免把已删除的BOM行算进去 DELETE ct_stb WHERE lkenz X. ENDFORM.注意几点函数签名中的TABLES参数在调用时直接写“stb 内表”的语法不能在EXPORTING里传异常分支的返回码在不同SAP版本上定义可能略有差异建议在自己的系统里通过F1帮助或调试界面确认一下封装里我习惯直接把LKENZX的行删掉这是从业务报表角度考虑的如果是要做原始BOM数据接口删之前要想清楚。4. 实战中的坑与排查技巧4.1 为什么展开结果为空结果为空是最高频的问题。排查顺序我一般是先看MAST表直接跑一个SELECT把物料、工厂、BOM用途、有效期条件都带上确认系统里到底有没有BOM。如果MAST有记录再看STKO表的LKENZ删除标记和STAST状态字段如果BOM被标记删除函数不会返回任何行。还有一种隐蔽情况是BOM行全部是文本项或文档项而你的过滤参数把这类项目排除了结果看起来就像是“没有数据”。CAPID传错也会导致空结果。因为替代确定规则里如果找不到匹配的BOM系统会返回空。我遇到过同事把CAPID写成1在有些系统上这个值对应的应用根本不是“生产”展开结果时好时坏。排查时先回退到标准值PP01把变量一个个排除比盲目乱猜参数快得多。4.2 为什么组件数量成倍或不对数量问题通常出在EMENG和单位上。最典型的是把EMENG当成“数量”传了一个业务单据里带小数的值比如工单数量是12.5BOM组件单耗是0.02展开出来组件需求就是0.25看起来好像没问题但如果后续在汇总时又乘了一遍工单数量数字就会翻倍。另外多级BOM展开时系统会自动把每一层的用量乘到顶层需求上所以STB里第二层组件的数量已经是“最终需求量”如果业务报表还要按层级乘系数就会出现数量异常。AUMNG有值的时候展开数量会比BOM原始用量大这是系统按报废规则自动计算的结果。如果业务方拿着展开结果跟CS03里维护的BOM单项数量核对发现有差异先检查是不是AUMNG造成的。单位换算也是一个隐蔽因素比如BOM维护用的单位是TO物料基本单位是KGMEHLS不传的情况下系统可能按主数据默认值换算出现数量完全对不上的情况。4.3 为什么多出或缺失组件组件多出来最常见的原因是替代BOM干扰和特殊项目被包含进来了。如果展开结果里多出了一些“不该出现”的组件物料第一步先看STB里的POSTP字段L是库存项目N是非库存项目R是变式项目I是文档项目T是文本项目。确认多出来的项目类别后就能判断是不是EXP_OTHERS、SANFR、SANIN、SANOU的配置问题。组件缺失则优先检查BOM行项目有效期和删除标记。在SAP里即使整个BOM是有效的个别行项目也可能因为有效期问题在指定日期不被展开。比如某组件DATUV维护成未来日期你在今天做展开这行就不会出现在结果里。还有一种常见情况是配置物料没有传CUOBJ导致配置相关组件没有展开返回的只是配置占位行。4.4 循环BOM与幽灵物料的处理循环BOM就是物料在BOM里直接或间接引用自己比如A的BOM里有BB的BOM里又有A。这种情况在系统设计上不应该出现但历史数据迁移或手工维护失误时会存在。CS_BOM_EXPL_MAT_V2内部有循环检测机制检测到循环后会中断展开并且通常会返回STOP标记。如果程序不检查STOP参数只看到返回部分数据就继续处理很容易漏算组件。我的建议是封装函数里先判断STOP是否有值如果有值就写错误日志并终止处理不要硬着头皮继续展开。幽灵物料指的是BOM里存在但在物料主数据里状态异常比如被删除或未完成创建的物料这类物料展开不会报错但后续查询MARA/MARC时会发现查不到描述或工厂视图。做接口推送时这类物料最容易导致下游系统解析失败。实际项目中可以在封装内部对IDNRK循环查询一把MARA把不存在或删除状态的物料标记出来提前暴露问题。5. 常见问题排查速查表与调优建议5.1 问题-原因-解决方案对照表下面这张表是我在实际项目里沉淀下来的排查顺序遇到问题按表对一下多数情况能快速定位现象可能原因排查方案展开结果为空MAST无BOM、WERKS错、STLAN错、DATUV不在有效期内SELECT MAST确认物料工厂用途检查STKO删除标记展开结果为空CAPID传错或替代规则不匹配先改回PP01验证再检查替代组配置组件数量放大EMENG传了业务单据数而不是1对比CS12按基础单耗时EMENG传1组件数量含报废AUMNG取到了默认值理论用量场景显式传AUMNG0多出文本/文档项EXP_OTHERS、SANFR等未显式配置显式传空只保留库存项目缺少组件行项目有效期未覆盖DATUV查STPO表对应行DATUV缺少配置组件CUOBJ未传调配置求解函数生成实例后再展开程序卡死或循环BOM存在循环引用检查STOP标记并拦截异常数据单位对不上MEHLS未传单位换算异常显式传MEHLS排查单位换算配置5.2 性能优化与后续扩展建议CS_BOM_EXPL_MAT_V2的单次调用性能还可以但在大批量场景下仍要小心。比如物料主数据批导程序里LOOP几百上千个物料每个都做多层展开整体耗时可能非常难看。优化的手段主要有几个方向一是把展开结果做本地缓存同一个物料在短时间内重复展开时直接走缓存表能省掉大量重复计算二是如果业务只需要一层BOM不要用V2做多层展开然后再过滤直接考虑单层函数或自定义查询表三是大数据量的批处理作业尽量在后台执行避免在前台报表中实时展开超大型BOM。还有一个容易忽略的点函数内部逻辑在同一系统版本下是相对稳定的但不同SP级别或版本之间返回结果在某些边界场景可能有差异。上线前最好在目标环境跑一遍关键物料的回归用例把展开结果和CS12界面比对确认一致后再推广到所有程序。这个函数涉及的增强点也有不少比如BOM展开时自动过滤禁用物料、按物料类型排除包装材料、按用户权限过滤工厂数据等。如果标准函数不满足业务要求优先考虑在调用外层做增强尽量不去改标准函数本身。后续如果有精力可以把组件类别分析和替代BOM对比做成一个独立的公共功能让多个报表共用一套BOM展开逻辑这样维护成本会低很多。最后再分享一个我的个人习惯所有调用CS_BOM_EXPL_MAT_V2的程序我都在代码里保留完整的调用参数注释说明每个参数是在什么业务背景下这样设置的。因为这种函数不像自定义函数有清晰的注释文档三个月后回头改代码时经常要想半天当时为什么要传这个值。给每个参数留一句注释后面的人包括你自己都能少掉几根头发。
返回列表