问题描述
在我的 AS ABAP 7.50 系统中,我有一个表格,其中材料长度为 18,我需要通过 CDS 将其公开,就像材料长度为 40 一样,就像在 S/4 中一样。系统中的材料 ID 可以是数字(带前导零)或字母数字。材质字段需要强制转换为MATNR40,如果ID为数字,则需要将前导零相加至40个字符。
首先,我尝试了 `lpad。但当然,它还为字母数字值添加了前导零:
lpad( cast(matnr as matnr40),40,'0' ) as material_long,
然后我添加了一个 case
,但我无法使条件按预期工作。正如康斯坦丁在评论中确认的那样,我尝试在这里使用正则表达式是不可能的:
case when matnr like '%[^0-9.]%'
then lpad( cast(matnr as matnr40),'0' )
else cast(matnr as matnr40)
end as material_long,
CDS 本身是否有针对此问题的解决方案?
源表:
MATNR18 | 说明 |
---|---|
000000000000000142 | 数字ID材料 |
材料_2 | 字母数字 ID |
预期结果:
MATNR40 | 说明 |
---|---|
0000000000000000000000000000000000000142 | 数字ID材料 |
材料_2 | 字母数字 ID |
解决方法
由于 CDS 语法的功能有限,我看到的唯一方法是嵌套 10 个 REPLACE
函数来删除数字并将结果与初始字符串进行比较。如果它是初始的,那么你只有数字,所以你可以用零 LPAD
它们。如果不是 - 使用原始值。
这是我的代码:
@AbapCatalog.sqlViewName: 'Z_V_TEST'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Test'
define view Z_TEST as select from /bi0/mmaterial {
cast(
case replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(material,'0',''),'1','2','3','4','5','6','7','8','9','')
when ''
then lpad(material,40,'0')
else material
end as abap.char(40)
) as MATERIAL_ALPHA,material
}
结果是:
REPORT Z_TEST.
select *
from Z_V_TEST
where material in ('LAMP','000000000000454445')
into table @data(lt_res)
.
cl_demo_output=>display( lt_res ).
MATERIAL_ALPHA | MATERIAL
-----------------------------------------+-------------------
0000000000000000000000000000000000454445 | 000000000000454445
LAMP | LAMP