2

在我的 AS ABAP 7.50 系统中,我有一个材料长度为 18 的表,我需要通过 CDS 将其公开,就像在 S/4 中材料长度为 40 一样。系统中的材料 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), 40, '0' )
     else cast(matnr as matnr40)
end as material_long,

CDS 本身是否有解决此问题的方法?

源表:

MATNR18 描述
000000000000000142 数字 ID 材料
MATERIAL_2 字母数字 ID

预期结果:

MATNR40 描述
00000000000000000000000000000000000000142 数字 ID 材料
MATERIAL_2 字母数字 ID
4

2 回答 2

2

由于 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 

于 2021-01-12T13:58:26.787 回答
0

当引入自定义实体时,这是 7.55 的处理方式:

  1. 创建自定义实体

    @EndUserText.label: 'Material List'
    @ObjectModel.query.implementedBy: 'ABAP:ZCL_MATERIAL_ZEROED'
    @Search.searchable: false
    define custom entity zcds_mat {
      key matnr  : abap.char( 40 );
          maktx  : abap.char( 40 );
    }
    
  2. 为其创建实现类

     CLASS ZCL_MATERIAL_ZEROED DEFINITION
       PUBLIC
       FINAL
       CREATE PUBLIC .
    
       PUBLIC SECTION.
         INTERFACES if_rap_query_provider.
       PROTECTED SECTION.
       PRIVATE SECTION.
     ENDCLASS.
    
     CLASS ZCL_MATERIAL_ZEROED IMPLEMENTATION.
       METHOD if_rap_query_provider~select.
         DATA: it_result   TYPE  TABLE OF zcustomer_zero. "Internal table to be returned , easier to handle return if internal table is as same type of our data definition
         DATA: lv_param    TYPE string."Local variable to fetch and save parameter value
         TRY.
             TRY.
                 IF io_request->is_data_requested( ). "Fetching incoming data
                   io_request->get_paging( ).
    
                   SELECT matnr maktx FROM makt INTO TABLE @it_result.
    
                   LOOP AT it_result ASSIGNING FIELD-SYMBOL(<fldsym>).
                     <fldsym>-matnr = | { <fldsym>-matnr ALPHA = OUT } |.
                   ENDLOOP.
    
                   io_response->set_total_number_of_records( lines( it_result ) ). "setting the total number of records which will be sent
                   io_response->set_data( it_result  ). "returning the data as internal table
                 ENDIF.
               CATCH cx_a4c_rap_query_provider INTO DATA(lx_exc). "CX_A4C_RAP_QUERY_PROVIDER is now deprecated so use CX_RAP_QUERY_PROVIDER
    
             ENDTRY.
           CATCH cx_rfc_dest_provider_error INTO DATA(lx_dest).
         ENDTRY.
       ENDMETHOD.
     ENDCLASS.
    

在这里,我们通过字符串模板添加前导零

您不能直接使用自定义实体,但可以在OData 服务中使用它,以防万一您有此意图。

于 2022-02-24T13:25:32.050 回答