Technology Blog Posts by Members
cancel
Showing results for 
Search instead for 
Did you mean: 
kranthinbv
Explorer
32,867
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/a7fc007921d44263b09ccc0923....

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/

 
11 Comments