点击蓝字 关注我们
一
前言
之前曾经写过一篇文章 怎么去掉商品编码的前置0
详见链接 无峰,公众号:ABAP开发技巧SAP小技巧之 商品编码去掉前置0
当时的应用场景是去掉数据库表中的前置0. 同时系统商品编码使用外部给号方式.
这样可以保留0开头的商品编码与非0开头的商品编码同时存在
比如 0123 与 123 可以作为两个不同的商品编码存在.
但是如果期望商品编码使用内部给号方式,同时又不想保留数据表中的前置0.
那就是本文补充讨论的范畴了.
本文主要讨论怎么在使用SAP ECC/S4系统内部获取商品编码的同时去除表中前置0
二
标准配置
配置表 TMCNV(维护视图V_TMCNV)
标准配置的帮助中已经详细说明. 勾选<辞典编撰>后,系统将严格按照外部给的号码显示并存储商品编码.
但是如果是内部给号,则会添加前置0.
三
标准帮助文本
如下文字来自系统标准配置的帮助文档.
如果还没有在系统中使用数字物料编号,因为它们在设置或重置此标识后不再是可说明的,那么才有可能设置或重置(取消)此标识。
-
如果未设置此标识,那么数字物料编号用前导零填充并右对齐存储(例1)。
包含至少一个非数字符的物料编号左对齐存储(例2)。
例1
定义的长度: 8 个字符
内部/外部分配的编号:,,123
存储的编号: 000000000000000123
例 2
定义的长度: 8个字符
外部分配的编号: 1A3
存储的编号: 1A3
如果未设置此标识, 那么物料编号存储如下:
如果物料编号(数字的或不完全数字的)外部地分配输入的时候左对齐存储。
示例
定义的长度: 8个字符
外部分配地编号: 123
存储的编号: 123
注释
也存储可能已输入的前导零。这使得在编号123和0123中进行区分成为可能。
如果物料编号(仅数字的)内部地分配 ,那么它用前导零填充到定义的长度并左对齐存储。
示例
定义的长度: 8 个字符
内部分配的编号: 123
存储的编号: 00000123
四
系统的缺陷
对于内部给号的,无法取消商品编码的前置0. 勾选词典编撰后,反而会导致前台也显示前置0. 反而让事情变得更加糟糕.
五
期望
假设项目中期望商品编码长度8位, 同时需要内部给号,并且期望数据库中保存的编号不带有前置0.
六
解决方案
那么怎么解决这个问题呢?
01
方案一
可以尝试通过标准的配置尝试解决. 配置表 TMCNV中配置编号长度 8 , 同时勾选<词典编撰>
通过MM41测试获取商品编码, 可以正常获取,并且保存的商品编码也是没有前置0.
但是尝试一般商品时, 系统报错,这个报错的原因是标准商品编码体系对变式商品会按一般商品编码补充3位数字作为变式商品编码, 因为限制了总商品长度为8,系统就会检查一般商品不能超过5位,给变式商品留出空间.
02
方案一总结
标准配置方案可以解决单一商品的给号长度问题, 但是因为一般商品产生变式商品会补充3位数字, 系统检查了单一商品的编号不能超过5位(8-3). 所以方案一不适合与同时使用单一商品和一般商品的项目.
方案一的另外一个局限是物料编号长度限制为8后, 之前超过8位的物料编号也就不能再使用了. 同时也限制了其它类型的商品不能超过8位.
同时方案一也不适用于不同商品类型编码长度不一致的情况
说明
商品编码通过号码组可以同时设置一个内部号码范围, 一个外部号码范围分配给商品类型. 这就意味着, 同一个商品类型,同时允许内部给号和外部给号,比如下图的Z004同时分配了两个间隔 20(内部给号) 21(外部给号)(分配的结果存放在表T134-NUMKI (内部给号范围) T134-NUMKE(外部给号范围)
03
方案二
商品号码范围正常配置. 按可能的最大长度定义物料编码长度. 可以保留默认配置18
勾选 <词典编撰>
创建一个自定义的号码范围ZBC_MATNR及物料类型与号码间隔的对应关系表,用来维护一个自定义的内部号码获取
标准配置的给号间隔. 标准的外部给号间隔需要保留前置0
自定义号码对象的间隔,注意需要确保自定义号码间隔和标准号码范围外部给号间隔一致
因为自定义间隔无法去掉前置0 , 需要修改NRIV表, 去掉前置0.并且确保自定义间隔和外部给号间隔号码范围一致(忽略前置0的情况下一致,系统检查外部给号时会附加前置0后执行检查)
在MM41的屏幕字段 SAPLMGMW(100)
在MODULE LESEN_MAT_ANKER 开头添加代码(因为MODULE不能使用隐式增强,只能通过源代码修改的方式添加代码) 判断 变量RMMW1-MATNR 为空时, 同时商品类型 RMMW1-MTART 非空,通过配置表获取一个间隔,读取一个号码赋值到RMMW1-MATNR即可.
这样,这就解决了前台MM41创建商品编码的给号增强(系统配置外部给号, 实际通过自定义号码范围内部给号). 基于商品长度配置中 <词典编撰> 字段的帮助说明. 对于系统来说,实际是外部给号. 就会确保商品的显示及底表都不带有前置0 .
如果开发尝试使用BAPI或IDOC创建商品. 只需要通过读取配置表获取间隔, 调用函数NUMBER_GET_NEXT获取一个号码作为外部号码写入BAPI或IDOC的商品编号字段即可.
代码很简单,如下图(需要创建一个配置表ZTMARA_NR)
七
方案对比
方案一比较简单, 只需要配置即可. 但是限制了使用的范围(不能创建变式商品, 同时所有商品号码都是相同长度)
方案二较复杂,因为本质是外部给号(对系统来说是外部给号, 对用户来说是内部给号),没有违背系统的标准逻辑. 可以完解决了系统标准商品编码内部给号无法去掉前置0的问题.
八
总结
商品编码的前置0 在很多项目上都会一定程度的困扰开发,尤其是接口开发. 很多时候需要做商品编码的内外转换. 在一些底层代码逻辑随时需要考虑商品编码的实际长度18与业务使用长度的差异.
通过本文的方案可以确保商品编码表里如一(显示及存储的编号一致). 给后续开发带来一些便利.
THE
END
约定
如果你对这篇文章感兴趣,请帮忙点赞,在看,分享.