Skip to Content
Technical Articles

Read Material Basic data text (Long Text) WITHOUT using Function module ‘READ_TEXT’ in CDS Views

Overview

This Blog Post discusses the approach to get the long text of a material in a CDS view with virtual elements but without using the function module ‘READ_TEXT’.

( CDS view cannot be joined with function modules directly, but you can use virtual elements to fetch data from function modules). Considering the performance of CDS view,  I used a different approach.

You can find more details about virtual elements in the below link.

https://help.sap.com/viewer/cc0c305d2fab47bd808adcad3ca7ee9d/7.51.7/en-US/a7fc007921d44263b09ccc092392b05f.html.

Business Scenario

Display material and its basic text data ( Material long text) in Fiori application.

Approach:

Basic data text or Long text details are stored in cluster tables STXH / STXL in a binary format but binary objects conversion to character format is not possible in CDS Views or Open SQL.

  • Join CDS with STXL table and get binary data
  • Use CDS exit to convert the binary data to text format
  • Import data from cluster internal table and capture the character format data

the below code in exit class does the magic to convert binary to char format

IMPORT tline TO lt_lines  FROM INTERNAL TABLE lt_cluster.

Sample Code

CDS views

@AbapCatalog.sqlViewName: 'ZMATSTXL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'stxl clusters'
define view zmat_stxl  as select from stxl as LongText
association [1] to zmat_longtext as _Material on $projection.materialNumber = _Material.Material
{ 
  key cast( LongText.tdname as matnr ) as materialNumber,
  key LongText.tdspras                 as language,
      LongText.clustr,
      LongText.clustd,
      _Material
}
where
      LongText.relid    = 'TX'
  and LongText.tdid     = 'GRUN'  
  and LongText.tdobject = 'MATERIAL'
@AbapCatalog.sqlViewName: 'ZMATINTERFACE'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'interface'
define view zmat_interface as select from I_Material 
association [0..*] to zmat_stxl as _LongText         on  $projection.Material = _LongText.materialNumber
and _LongText.language = $session.system_language 
{

 key   Material as Material,
 key   _LongText.language,      
      _LongText.clustr,   
      _LongText.clustd
}

 

Consumption view

@AbapCatalog.sqlViewName: 'ZMATLONGTEXT'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'long text'
define view zmat_longtext
  as select from zmat_interface
  association [0..*] to zmat_stxl as _sxtl on $projection.Material = _sxtl.materialNumber
{
@UI.lineItem: [{position: 10 }]
@UI.selectionField: [{position: 10 }]
  key   Material,
     @ObjectModel.readOnly: true
      @ObjectModel.virtualElement: true
      @ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_LTEXT'
      @UI.lineItem: [{position: 20 }]
        cast( '' as abap.char( 1024 ) ) as materialLongText,
        @Consumption.hidden: true
        _sxtl[1: language = $session.system_language].clustr,

        @Consumption.hidden: true
        _sxtl[1: language = $session.system_language].clustd
}

 

CDS exit class

CLASS zcl_ltext DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .
  PUBLIC SECTION.
   INTERFACES if_sadl_exit_calc_element_read .
  PROTECTED SECTION.
  PRIVATE SECTION.
    TYPES: BEGIN OF lty_cluster,
             clustr TYPE stxl-clustr,
             clustd TYPE stxl-clustd,
           END OF lty_cluster.
    TYPES ltt_cluster TYPE STANDARD TABLE OF lty_cluster WITH DEFAULT KEY.
ENDCLASS.

CLASS ZCL_LTEXT IMPLEMENTATION.
  METHOD if_sadl_exit_calc_element_read~calculate.
    DATA lt_lines TYPE STANDARD TABLE OF tline.
    LOOP AT ct_calculated_data ASSIGNING FIELD-SYMBOL(<ls_calc_data>).
      ASSIGN it_original_data[ sy-tabix ] TO FIELD-SYMBOL(<ls_orig_data>).
      IF <ls_orig_data> IS ASSIGNED
       AND sy-subrc = 0.
        ASSIGN COMPONENT 'CLUSTD' OF STRUCTURE <ls_orig_data> TO FIELD-SYMBOL(<lv_clustd>).
        ASSIGN COMPONENT 'CLUSTR' OF STRUCTURE <ls_orig_data> TO FIELD-SYMBOL(<lv_clustr>).
        DATA(lt_cluster) = VALUE ltt_cluster( ( clustd = <lv_clustd>
                                                clustr = <lv_clustr> ) ).
        IF <lv_clustd> IS ASSIGNED and <lv_clustd> is NOT INITIAL.
          IMPORT tline TO lt_lines
              FROM INTERNAL TABLE lt_cluster.
          DATA(lv_string) = REDUCE #( INIT text TYPE string
                                       FOR <ls_lines> IN lt_lines
                                      NEXT text = COND #( WHEN text IS INITIAL
                                                               THEN <ls_lines>-tdline
                                                          ELSE |{ text }{ <ls_lines>-tdline }| ) ).
          ASSIGN COMPONENT 'MATERIALLONGTEXT' OF STRUCTURE <ls_calc_data> TO FIELD-SYMBOL(<lv_material_long_text>).

          <lv_material_long_text> = lv_string.

        ENDIF.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD if_sadl_exit_calc_element_read~get_calculation_info.
    "CLUSTD and CLUSTR needed for LRAW to STRING conversion
    et_requested_orig_elements = COND #( WHEN iv_entity = 'ZMAT_LONGTEXT'
                                              THEN VALUE #( ( CONV string( 'CLUSTR' ) )
                                                            ( CONV string( 'CLUSTD' ) )
                                                           ) ).
  ENDMETHOD.
ENDCLASS.

READ_TEXT Function module result

 

Fiori Result

 

Conclusion

As I am using CDS joins, for me this is faster than calling function modules in exit class. There are many other approaches to get the long text but I observed performance issues when the CDS used in Fiori Application. This approach would be a solution for this.

Note : You cannot preview long text in CDS or consume this CDS view in ABAP reports as it is a virtual element but this approach is suitable for Fiori applications and you can view data in Gateway client.

References:

https://blogs.sap.com/2020/04/07/read-long-texts-using-read_text-in-cds-views/

https://blogs.sap.com/2020/01/13/using-virtual-elements-with-cds-in-fiori-elements/

 

1 Comment
You must be Logged on to comment or reply to a post.
  • Thanks for sharing!

    At first, I was puzzled by the blog subject. Since it’s 2020 and S/4HANA, CDS views and all that have been around for years, surely SAP should’ve already come up with an alternative to READ_TEXT, no?

    Quick Google search discovered SAP Note 2796654 “CDS View for Long Text not available in S4HANA Cloud”. The note title is a bit misleading since this seems to affect not only Cloud but also on-premise version. From what I see, SAP has not made available any CDS view for long texts (hence this blog).

    The note honestly admits this is “missing functionality” but Resolution section is quite something. First, it suggests to check the CDS view list by LOB to see if there is an alternative. That’s a valid point, so off we go to check the list. But after accepting “terms and conditions” (I hope I didn’t accidentally sign up to be a part of human centipede), I’m getting “403 You’re not authorized”. That went well…

    Next suggestion is “keep checking the roadmap, it’s updated quarterly”. This reminds me when cable companies had a monopoly and they’d send a technician to you “sometime between 9 am and 8 pm on Tuesday”. 🙂

    Finally, “Please use the SAP Customer Influence Program”. Hold up. First of all, you just told us to check the roadmaps. This presumes SAP is aware of the issue and is working on it. So why there is more influence needed? Also, isn’t it clear from the fact that this note became necessary that it’s a desired feature?

    Gotta love these SAP notes. Thank goodness at least we have SAP Community.