Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
12,297

Introduction

For creating value helps based on domain fixed values in ABAP Cloud the recommendation so far was to create custom CDS views based on the released CDS views DDCDS_CUSTOMER_DOMAIN_VALUE  and DDCDS_CUSTOMER_DOMAIN_VALUE_T. 

The drawback of this solution is 

  1. that you have to create dedicated CDS views for each domain and
  2. that the aforementioned CDS views only work for domains that reside in software components owned by customers. 

Based on a question in a forum of the German SAP user group DSAG where the question was raised whether there is no alternative solution I thought again about this requirement. 

Instead of using CDS views it is possible just use one single custom entity which uses RTTI to retrieve the domain fixed values.

Result

When adding the new value help to the projection view as follows:

 

 

 

 

      @Consumption.valueHelpDefinition: 
      [{ entity: { name : 'ZI_DOMAIN_FIX_VAL' , element: 'low' } ,
         additionalBinding: [{ element: 'domain_name',
                               localConstant: 'BEL_API_RETCODE', usage: #FILTER }]
                               , distinctValues: true
                               }]
      Low,

 

 

 

 

We get the following result:

domain_fix_value_help_result.png

Implementation

The challenge to get this to work with just one custom entity is, to provide the name of the domain that is used as a value help via additional binding. 

This can be achieved by using localConstant key word  and in addition it needs the usage parameter set to #FILTER. This way we can specify the name of the domain whose domain fixed values shall be used within the coding.

Be careful !

It doesn't work if the element ("domain_name" in this case) is hidden in the Value Help CDS View (e.g. through "UI.hidden: true").

Custom Entity

The DDL source code of the custom entity looks like this:

 

 

 

 

@EndUserText.label: 'Get domain fix values'
@ObjectModel.resultSet.sizeCategory: #XS
@ObjectModel.query.implementedBy: 'ABAP:ZCL_GET_DOMAIN_FIX_VALUES'
define custom entity ZI_DOMAIN_FIX_VAL
{
      @EndUserText.label     : 'domain name'
      @UI.hidden : true 
  key domain_name : sxco_ad_object_name;
      @UI.hidden  : true
  key pos         : abap.numc( 4 );
      @EndUserText.label     : 'lower_limit'
      low         : abap.char( 10 );
      @EndUserText.label     : 'upper_limit'
      high        : abap.char(10);
      @EndUserText.label     : 'Description'
      description : abap.char(60);


}

 

 

 

 

Query implementation class

And the code of the query implementation class is as follows:

The domain name is retrieved from the filter that is filled via the additional binding.

Once the domain name has been retrieved the domain fixed values are being retrieved using RTTI as described in the following blog post Fetching texts for domain fixed values - SAP Community by Michał Badura.

Another option would be to use the XCO library. 

 

 

 

 

 

CLASS zcl_get_domain_fix_values DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    INTERFACES if_rap_query_provider.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_get_domain_fix_values IMPLEMENTATION.


  METHOD if_rap_query_provider~select.
    DATA business_data TYPE TABLE OF zi_domain_fix_val .
    DATA business_data_line TYPE zi_domain_fix_val .
    DATA(top)     = io_request->get_paging( )->get_page_size( ).
    DATA(skip)    = io_request->get_paging( )->get_offset( ).
    DATA(requested_fields)  = io_request->get_requested_elements( ).
    DATA(sort_order)    = io_request->get_sort_elements( ).

    DATA domain_name  TYPE sxco_ad_object_name  .
    DATA pos TYPE i.

    TRY.
        DATA(filter_condition_string) = io_request->get_filter( )->get_as_sql_string( ).
        DATA(filter_condition_ranges) = io_request->get_filter( )->get_as_ranges(  ).

        READ TABLE filter_condition_ranges WITH KEY name = 'DOMAIN_NAME'
               INTO DATA(filter_condition_domain_name).

        IF filter_condition_domain_name IS NOT INITIAL.
          domain_name = filter_condition_domain_name-range[ 1 ]-low.
        ELSE.
          "do some exception handling
          io_response->set_total_number_of_records( lines( business_data ) ).
          io_response->set_data( business_data ).
          EXIT.

        ENDIF.

        business_data_line-domain_name = domain_name .

        CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_name( domain_name ) )->get_ddic_fixed_values(
          EXPORTING
            p_langu        = sy-langu
          RECEIVING
            p_fixed_values = DATA(fixed_values)
          EXCEPTIONS
            not_found      = 1
            no_ddic_type   = 2
            OTHERS         = 3 ).

        IF sy-subrc > 0.
          "do some exception handling
          io_response->set_total_number_of_records( lines( business_data ) ).
          io_response->set_data( business_data ).
          EXIT.
        ENDIF.

        LOOP AT fixed_values INTO DATA(fixed_value).
          pos += 1.
          business_data_line-pos = pos.
          business_data_line-low = fixed_value-low .
          business_data_line-high = fixed_value-high.
          business_data_line-description = fixed_value-ddtext.
          APPEND business_data_line TO business_data.
        ENDLOOP.

        IF top IS NOT INITIAL.
          DATA(max_index) = top + skip.
        ELSE.
          max_index = 0.
        ENDIF.

        SELECT * FROM business_data AS data_source_fields
           WHERE (filter_condition_string)
           INTO TABLE business_data
           UP TO max_index ROWS.

        IF skip IS NOT INITIAL.
          DELETE business_data TO skip.
        ENDIF.

        io_response->set_total_number_of_records( lines( business_data ) ).
        io_response->set_data( business_data ).

      CATCH cx_root INTO DATA(exception).
        DATA(exception_message) = cl_message_helper=>get_latest_t100_exception( exception )->if_message~get_longtext( ).

        DATA(exception_t100_key) = cl_message_helper=>get_latest_t100_exception( exception )->t100key.

        "do some exception handling

    ENDTRY.
  ENDMETHOD.
ENDCLASS.

 

 

 

 

 

 

 

 

 

 

 

23 Comments