
CDS - Virtuelle Felder
In diesem Artikel geht es um virtuelle Felder in Core Data Services und wie du so komplexe Daten nachliefern kannst.
Inhaltsverzeichnis
Artikel-Update: Seit Release 7.57 (S/4 HANA 2022) ist DEFINE VIEW als obsolet gekennzeichnet, stattdessen solltest du DEFINE VIEW ENTITY verwenden. Diese können an einigen Stellen zu den Beispielen abweichen. Mehr Informationen zu den neuen Views findest du in diesem Artikel.
Heute zeigen wir dir, wie du virtuelle Elemente in CDS Views einfügen kannst und wie du diese mit Daten befüllst. Dabei werden wir auch auf die Besonderheiten eingehen, was du dabei beachten solltest.
Allgemein
Virtuelle Elemente, wie der Name sagt, sind keine persistenten Daten von der Datenbank, sondern werden zum Abruf der Daten erst erzeugt. Damit gehen einige Besonderheiten einher, die du bei der Verwendung beachten solltest:
- Die Befüllung der Daten passiert per SADL Klasse, damit ist keine Anzeige der Daten per Data Preview möglich, das Feld bleibt dort leer.
- Das virtuelle Element ist performancetechnisch ungeeignet für die Selektion und zur Filterung über den Service oder die Fiori Oberfläche.
Virtuelles Element
Dazu legen wir einen Core Data Service an und erzeugen eine virtuelle Spalte "PricePerUnit". Die Spalte benötigt noch eine Annotation "@ObjectModel.virtualElementCalculatedBy", damit bekannt gegeben wird, über welche Klasse der Inhalt generiert wird.
@AbapCatalog.sqlViewName: 'ZBSIDMOPRIPERUNI'
@EndUserText.label: 'Exit in CDS'
define view ZBS_C_DmoPricePerUnit
as select from ZBS_I_DmoPosition
{
key DocumentNumber,
key PositionNumber,
_Material.MaterialName,
PositionQuantity,
PositionPrice,
PositionCurrency,
@ObjectModel.virtualElementCalculatedBy: 'ABAP:ZCL_BS_DEMO_CDS_EXIT'
cast( 0 as abap.curr(15,2) ) as PricePerUnit
}
Klasse
Im Anschluss musst du noch den Exit implementieren, um das Feld mit Daten zu befüllen. Dazu legst du die Klasse mit dem vorher definierten Namen an und implementierst das Interface "if_sadl_exit_calc_element_read".
CLASS zcl_bs_demo_cds_exit DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_sadl_exit_calc_element_read.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_bs_demo_cds_exit IMPLEMENTATION.
METHOD if_sadl_exit_calc_element_read~calculate.
DATA:
lt_view_data TYPE STANDARD TABLE OF ZBS_C_DmoPricePerUnit WITH EMPTY KEY.
lt_view_data = CORRESPONDING #( it_original_data ).
LOOP AT lt_view_data REFERENCE INTO DATA(lr_view_data).
lr_view_data->PricePerUnit = lr_view_data->PositionPrice / lr_view_data->PositionQuantity.
ENDLOOP.
ct_calculated_data = CORRESPONDING #( lt_view_data ).
ENDMETHOD.
METHOD if_sadl_exit_calc_element_read~get_calculation_info.
ENDMETHOD.
ENDCLASS.
Das Interface stellt zwei Methoden zur Verfügung. Im ersten Schritt wird die Methode "GET_CALCULATE_INFO" aufgerufen, wo noch einmal die zu ermittelnden Felder und Informationen übergeben werden. In der Methode "CALCULATE" führst du dann die Berechnung bzw. Befüllung der Felder durch. Der Changing Parameter enthält aber nur die zu berechnenden Elemente.
Anzeige
Schauen wir uns nun die Daten per Data Preview in Eclipse an, dann erhalten wir eine leere Spalte. Der SADL Exit wird bei dieser Form der Anzeige nicht durchlaufen und damit auch nicht die Daten angereichert.
Bauen wir nun eine Anzeige per RAP, um die Daten in einem OData in einer Fiori Elements App zu betrachten, wird der entsprechende Exit aufgerufen, die Daten werden nun auch befüllt und angezeigt. Der CDS View kann auch einfach nur als OData Service publiziert werden, die Anzeige im Browser würde dann ebenso funktionieren. Dafür kann auch die Annotation "@OData.publish: true" verwendet werden:
Fazit
Wenn du einmal komplexe Daten ableiten musst und du es nicht als CDS View abbilden kannst, dann hast du auch die Möglichkeit zusätzliche Daten nachzulesen und komplexe Logiken mit in den View zu integrieren. Dabei musst du allerdings beachten, dass die Logik dann auch nur im Remote Szenario funktioniert.