CDS - Typen und Enums
Was wird im ABAP Dictionary die Datenelemente ablösen und wie kannst du schon heute die Typen für die Core Data Services verwenden? Mehr hier.
Inhaltsverzeichnis
In diesem Artikel wirst du mehr zu den neuen Typen erfahren, wie du sie erstellst und bereits heute im System nutzen kannst. Dabei werden wir auf die verschiedenen Besonderheiten eingehen.
Einleitung
Die Table Entities werden nächstes Jahr ihren Weg in die Cloud Produkte (ABAP Environment und S/4HANA Public Cloud) finden und damit eine Möglichkeit zur Verfügung stellen, die alten Dictionary Tabellen abzulösen. Das Problem des heutigen Dictionary sind die Begrenzungen der Namenslänge und der fehlende Support für Groß- und Kleinschreibung von Feldern und Tabellen, dass soll sich mit der neuen Art von Tabelle ändern. In diesem Artikel vergleichen wir die heutigen Datenelemente mit den neuen Typen und deren Möglichkeit.
Anlage
Wie kannst du den neuen Typen definieren? In diesem Abschnitt werden wir auf die beiden aktuellen Typen eingehen und diese im System anlegen.
Type (Simple)
Legen wir dazu erst einmal einen einfachen Typen an. Dazu auf das Paket mit Rechts-Klick gehen und über "New -> Other ABAP Repository Object" den Wizard starten. Dort suchen wir nach "Type", dieser sollte sich unter "Core Data Services" befinden.
Nun vergeben wir einen Namen und eine Beschreibung für den Typen. Hier können wir auch in CamelCase arbeiten, dies wird in den Typen übernommen.
Nach Auswahl des Transports, können wir das entsprechende Template wählen, in diesem Fall reicht uns "defineType" zur Anlage des Typs. Mit Finish bestätigen wir die Anlage.
Der Typ ist nun angelegt und hat bereits ein Label erhalten. Hinter dem Doppelpunkt können wir einen elementaren Datentype vergeben, ein Datenelement aus dem DDIC oder einen anderen Typen, den wir definiert haben.
@EndUserText.quickInfo: 'Inv. status'
@EndUserText.label: 'Invoice status'
@EndUserText.heading: 'Invoice status'
define type ZBS_DemoCDSInvoiceStatus : abap.char( 1 )
Im oberen Teil siehst du bereits die verschiedenen Annotationen für die Texte im Datenelement. Diese sind am Ende normal übersetzbar über die App "Maintain Translations".
Type (Enum)
Als zweites Beispiel wollen wir den Typen "ZBS_DemoCDSInvoiceStatusEnum" anlegen, der ein Enumeration darstellt. Dazu legen wir wie oben über den Wizard einen neuen Typen an und wählen im letzten Schritt das andere Template. Nun können wir die einzelnen Werte des Enums definieren und einen Wert zuordnen. Der Wert Initial muss immer definiert werden.
@EndUserText.quickInfo: 'Inv. status'
@EndUserText.label: 'Invoice status as Enum'
@EndUserText.heading: 'Invoice status'
define type ZBS_DemoCDSInvoiceStatusEnum : abap.char(1) enum
{
@EndUserText.label: 'Initial'
Empty = initial;
@EndUserText.label: 'Created'
Created = 'C';
@EndUserText.label: 'Payed'
Payed = 'P';
@EndUserText.label: 'Closed'
Closed = 'O';
}
Du kannst auch jedem Wert ein Label zuordnen, um einen Text zu erhalten. Wollen wir den Typen aus dem ersten Schritt verwenden, erhalten wir allerdings eine Fehlermeldung, wir sollten den eingebauten Typen verwenden.
Verwendung
Grundsätzlich kannst du die Typen in Core Data Services verwenden, wenn du die Felder auf den neuen Datentyp castest. Damit übernimmt er die Eigenschaften und Label unseres Typen und wir können das Element wiederverwenden. Aktuell können beide Typen nicht für klassische DDIC Tabellen verwendet werden, sollen später aber einmal für die Table Entities als Typen fungieren. Aktuell ist die Nutzung daher auf CDS Views und Objekte, wie Klassen, beschränkt.
Klasse (Type)
Um den Typen im Coding zu verwenden, definieren wir eine Variable oder arbeiten mit Inline Deklaration. In diesem Beispiel legen wir per DATA die Variable an und weisen einen Wert zu. Es erfolgt keine Abfrage, ob der übergebene Wert korrekt ist.
DATA ld_simple TYPE ZBS_DemoCDSInvoiceStatus.
ld_simple = 'C'.
Geben wir den Wert in die Konsole aus, wird auch ein entsprechender Werte "C" geschrieben, so wie wir ihn der Variable übergeben haben.
out->write( `Simple type:` ).
out->write( ld_simple ).
Klasse (Enum)
Bei der Enumeration sieht es eigentlich so ähnlich aus, wie können den Datentypen zuweisen und verwenden. Wollen wir einen Wert zuweisen, können wir das am einfachsten über die definierten Werte machen. Dazu verwenden wir den Typen mit einem Bindestich (-), wie bei Strukturen, und können über STRG + 1 den passenden Wert wählen.
DATA ld_enum TYPE ZBS_DemoCDSInvoiceStatusEnum.
ld_enum = ZBS_DemoCDSInvoiceStatusEnum-created.
Geben wir dann die Variable in die Konsole aus, erhalten wir in diesem Fall den Wert "CREATED" und nicht "C". Schauen wir uns noch einen Sonderfall an:
ld_enum = 'C'.
Versuchen wir direkt einen Wert zuzuordnen, dann können wir den Code nicht aktivieren und erhalten im Compiler eine Fehlermeldung.
Hier können wir aber mit einem CONV arbeiten und einen Wert übergeben. Es wird intern das richtige Enum zugeordnet. Damit kannst du auch verschiedene Verarbeitungen oder Schnittstellen absichern, sodass nur korrekte Werte an den Typ übergeben werden.
ld_enum = CONV #( 'C' ).
Versuchst du allerdings einen falschen und nicht verfügbaren Wert zu übergeben, wird die Ausnahme CX_SY_CONVERSION_NO_ENUM_VALUE ausgelöst und muss abgefangen werden oder die Logik wird mit einem Dump beendet.
Core Data Service
Schauen wir uns im letzten Schritt noch die aktuelle Verwendung in einem Core Data Service an. Dazu erstellen wir einen neuen Core Data Service auf der Rechnungstabelle unseres Datenmodells.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Invoice with Types'
@Metadata.ignorePropagatedAnnotations: true
define view entity ZBS_I_DmoInvoiceWithType
as select from zbs_dmo_invoice
{
key document as Document,
doc_date as DocumentDate,
doc_time as DocumentTime,
partner as PartnerNumber,
cast( 'C' as ZBS_DemoCDSInvoiceStatus preserving type ) as StatusSimpleType,
ZBS_DemoCDSInvoiceStatusEnum.#Payed as StatusEnumType
}
In dem Core Data Service haben
- CAST - Die Spalte "StatusSimpleType" erstellen wir per Cast unseres Elements auf unseren neuen Zieltypen.
- Enum Wert - Für die Spalte "StatusEnumType" verwenden wir direkt ein Enum, dazu geben wir den Typen an und greifen per Punkt (.) auf die verschiedenen Werte zu. Jedes Enum beginnt mit einem Hashtag (#).
Schauen wir uns dann die Daten an, erhalten wir über den EnumType das sprechendste Ergebnis zurück. Die beiden neuen Spalten sind nun in der Tabelle verfügbar und sichtbar. Da wir hier nur Konstanten zuweisen, soll dies einmal ein Beispiel sein.
Vergleich
In diesem Abschnitt wollen wir die neuen Typen mit dem klassischen DDIC vergleichen. Dazu haben wir zwei Gegenüberstellungen vorbereitet. Im ersten Fall vergleichen wir die verschiedenen Texte aus dem Datenelement. Dabei kannst du die verschiedenen Texte im Typen definieren.
Im zweiten Schritt vergleichen wir den Typen und die Werte mit der Domäne. Der Datentyp kommt vom Basistypen und die Festwerte können mit der Enumeration verglichen werden. Im Gegensatz zu den Festwerten, werden die Werte eines Enums aber hart geprüft und es können keine anderen Werte eingetragen werden.
Hinweis: Weitere Informationen zu den Texten findest du auch im SAP Community Blog zu dem Thema.
Ressourcen
Du bist auf der Suche nach den Ressourcen dieses Blogs? Für die Core Data Service Serie haben wir ein GitHub Repository angelegt, alle Sourcen von heute findest du im folgenden Commit.
Fazit
Du kannst die neuen Typen bereits heute in der Entwicklung einsetzen, allerdings noch nicht bis auf Datenbankebene. Wenn 2025 dann die ersten Table Entities erscheinen, wirst du die neuen Typen lieben lernen.
Quellen:
SAP Community - Simple Types