Unter der Linie sind Referenzen zu Quellen, z.B.
SAP RAP (Restful ABAP Programming Model) ist ein Framework, das zur Entwicklung von modernen, cloudbasierten ABAP-Anwendungen in der SAP Cloud Platform genutzt wird. Es basiert auf dem Konzept von RESTful Services und zielt darauf ab, die Entwicklung von End-to-End-Anwendungen zu vereinfachen. Hier sind die wesentlichen Komponenten kurz erklärt:
Importance Annotation
hidden: #('Hidden')
Wenn sich Feldannotationen auf Facetten beziehen, dann erfolgt die Verknüpfung über die qualifier und targetQualifier. Damit kann ein Feld mehrfach, ggf. auch unterschiedlich dargestellt werden. Bei Feldgruppen werden die Annotationen eigentlich immer verwendet.
Bei Tabellen funktioniert das auch. Ohne @UI.lineItem.qualifier wird ein Feld im List Report dargestellt. Wenn auf einer Object Page eine andere Darstellung sein soll, dann muss man qualifier und targetQualifier setzen.
Records
...
association [0..*] to Items as _Items on ...
@UI.facet: [{
id: 'idItem',
label : 'Ref',
type : #LINEITEM_REFERENCE,
targetQualifier: 'onObjectPage'
targetElement: '_Items'
}]
...
Items
@UI.lineItem: [
{ position: 10}
{ position: 10, qualifier: 'onObjectPage'}
],
summary
Manche Annotationen, vornehmlich die aus dem Bereich UI und Search können auch in einer separaten Datei, der so genannten Metadata Extension(MDE), ausgelagert werden. Dies geschieht am einfachsten über einen Refactoring Assistent:
Das Kontextmenü mit der rechten Maustaste im CDS öffnen und dort Source Code ➔ Extract Metadata Extension.
Die Metadata Extension selber hat in Zeile 1 eine wichtige Annotation: @Metadata.layer: #CUSTOMER Da es mehrere MDEs geben kann, können die sich überlagern. Beim SAP Kunden steht hier immer #CUSTOMER, womit dieser MDE alle anderen übersteuern kann.
Der CDS-View, der durch eine MDE annotiert wird, benötigt die Annotation @Metadata.allowExtensions: true
Manche Annotationen, vornehmlich die aus dem Bereich UI und Search können auch in einer separaten Datei, der so genannten Metadata Extension(MDE), ausgelagert werden. Dies geschieht am einfachsten über einen Refactoring Assistent:
Das Kontextmenü mit der rechten Maustaste im CDS öffnen und dort Source Code ➔ Extract Metadata Extension.
Die Metadata Extension selber hat in Zeile 1 eine wichtige Annotation: @Metadata.layer: #CUSTOMER Da es mehrere MDEs geben kann, können die sich überlagern. Beim SAP Kunden steht hier immer #CUSTOMER, womit dieser MDE alle anderen übersteuern kann.
Der CDS-View, der durch eine MDE annotiert wird, benötigt die Annotation @Metadata.allowExtensions: true
Auf View Ebene, also vor der eigentlichen Definintion des Views. Diese Annotationen beziehen sich auf den ganzen View und werden nicht nach oben propagiert. Die Standard-Annotationen aus den Templates werden hier nicht gezeigt.
...
@UI: {
headerInfo: {
typeName: 'Aufgabe',
typeNamePlural: 'Aufgaben',
typeImageUrl: 'sap-icon://activity-items',
title: {
type : #STANDARD , value : 'Summary'
}
}
}
...
DEFINE ROOT VIEW ENTITY ZBC_C_TASKS
AS SELECT FROM zbc_tasks {
...
Die Annotation @UI.lineItem definiert, dass das Feld als Spalte in einer Tabelle angezeigt wird. Meist wird mindestens die position angegeben.
@UI.lineItem: [ { position: 30 ,
label: 'Beauftragter' ,
importance: #HIGH
} ]
Assignee,
@ObjectModel.text.element stellt die Verbindung zwischen dem Bezeichner-Element und seinen beschreibenden sprachunabhängigen Texten her.
@ObjectModel.text.element: [ 'Name' ]
key user_id as UserId,
Die Filterfelder eines List Report können vom Benutzer über den Button Filter anpassen selber eingestellt werden. Wenn die Annotation @UI.selectionField verwendet wird, können diese voreingestellt werden. Auch hier muss mindestens die position angegeben werden. Alle anderen Annotationen sind optional.
@UI.selectionField: [ { position: 10,
label: 'Aufgabenstatus',
exclude: true } ]
Status,
Für eine unscharfe Suche über mehrere Felder kann die @Search Annotation verwendet werden. Auf View-Ebene, also vor DEFINE VIEW ENTITY, kommt
@Search.searchable: true
Für jedes Feld, das Durchsuchbar sein soll, kommen dazu noch die folgenden Annotationen:
@Search:{ defaultSearchElement: true,
fuzzinessThreshold: 0.7 }
Der fuzzinessThreshold gibt an, wie unscharf gesucht werden soll. Die SAP empfiehlt als Startwert 0.7.
Auf der Object Page wird eine Instanz eines Objektes dargestellt. Der Header-Bereich wird durch die Header Annotationen gestaltet. Die Objekt-Daten werden in sogenannten Facetten angezeigt:
Die Bereiche, die auf der Object Page dargestellt werden sollen, müssen mit der Annotation @UI.facet definiert werden. Obwohl sich die Definition auf alle Spalten beziehen, werden sie nicht in den View-Annotationen sondern auf Feldebene definiert. Der Grund hierfür ist, dass sie sonst nicht propagiert werden. Normalerweise werden Facetten vor dem ersten Feld definiert.
Wenn sich Feldannotationen auf Facetten beziehen, dann erfolgt die Verknüpfung über die qualifier und targetQualifier. Damit kann ein Feld mehrfach, ggf. auch unterschiedlich dargestellt werden. Bei Feldgruppen werden die Annotationen eigentlich immer verwendet.
Bei Tabellen funktioniert das auch. Ohne @UI.lineItem.qualifier wird ein Feld im List Report dargestellt. Wenn auf einer Object Page eine andere Darstellung sein soll, dann muss man qualifier und targetQualifier setzen.
Records
...
association [0..*] to Items as _Items on ...
@UI.facet: [{
id: 'idItem',
label : 'Ref',
type : #LINEITEM_REFERENCE,
targetQualifier: 'onObjectPage'
targetElement: '_Items'
}]
...
Items
@UI.lineItem: [
{ position: 10}
{ position: 10, qualifier: 'onObjectPage'}
],
summary
Felder in diesem Bereich sollen das Objekt, gemeinsam mit den Informationen aus dem Header, eindeutig identifizieren.
@UI.facet: [ {
id: 'idIdentification',
type: #IDENTIFICATION_REFERENCE,
label: 'Aufgabe',
position: 10
} ]
TaskKey;
Felder, die in dieser Facette angezeigt werden sollen, benötigen die Annotation @UI.identification:
@UI.identification:[ { position: 20,
label: 'Bearbeiter' } ]}
Firstname
Feldgruppenfacetten zeigen eine Gruppe von Feldern mit ihren Beschriftungen an.
@UI.facet: [{
id: 'idHeader',
label : 'Aufgabe',
type : #FIELDGROUP_REFERENCE,
targetQualifier: 'AddressQ'
}]
...
Felder, die in dieser Gruppe angezeigt werden sollen, benötigen die Annotation @UI.fieldGroup:
@UI.fieldGroup: [{ qualifier: 'AddressQ',
position: 10,
label: 'Name'
}]
Firstname;
Diese Facette wird verwendet, um assoziierte Objekte als Tabelle anzuzeigen. Der Name der Assoziation ist in targetElement anzugeben. In der zugehörigen CDS-Entität muss die Annotation @UI.lineItem für die anzuzeigenden Felder angegeben werden.
@UI.facet: [{
id: 'idItem',
label : 'Ref',
type : #LINEITEM_REFERENCE,
targetElement: '_Items'
}]
...
weitere
Weitere Facetten findet Ihr in unserem Cheat Sheet Fiori Elements (tbd).
Die folgenden Annotationen können an unterschiedlichen Stellen eingesetzt werden. Zum Beispiel bei @UI.lineItem ,@UI.fieldGroup, @UI.identification.
hidden - Das Feld wird nicht angezeigt und kann auch mit Personalisierung nicht hinzugefügt werdenposition - Gibt die Reihenfolge der Felder in der Facette/Tabelle anlabel - FeldlabelDie Felder können auch vom Benutzer per Personalisierung ausgeblendet werden.
@UI.hidden: true
TaskKey;
Eine Suchhilfe ermöglicht das Auswählen von Werten. Dazu wird ein anderer CDS-View als entity.nameangegeben und das entsprechende Feld, das übernommen werden soll, als entity.element. Mit additionalBinding können zusätzliche Bindungen zum Filtern definiert werden.
@Consumption.valueHelpDefinition: [
{
entity: { name: 'ZI_StatusVH',
element: 'Status' }
// zusätzlich das Projekt als Filterbedingung:
additionalBinding: [{ localElement: 'Project',
element: 'Project' }]
}
]
Status;
Static Actions in SAP RAP führen geschäftslogische Operationen durch, die unabhängig von einer bestimmten Instanz eines Geschäftsobjekts sind und daher nicht auf spezifische Objekteigenschaften zugreifen müssen.
static action someAction;
//factory erzeugt eine neue Instanz der Entität
static factory action otherAction [1];
Funktionen haben nur lesenden Zugriff auf die Daten. Sie ändern die Daten des Geschäftsobjekts nicht. Sie können jedoch berechnete Werte oder Informationen über den Status des Objekts zurückgeben.
Die Syntax ist die gleiche wie unter Aktionen. Es muss nur das Wort action durch function ersetzt werden.
Mit Hilfe von Triggern können Änderungen am Business Objekt unmittelbar vor dem Speichern vorgenommen werden. Erfordert eine Implementierung im Behavior Pool.
//kurz vor dem Speichern
determination setDetermination on save { create; }
//unmittelbar nach einer Änderung oder Löschen
determination setDetermination on modify { update; delete; }
//Auslösebedingung auf Feldebene
determination setDetermination2 on modify { field SomeField, SecondField }
//Bedingungen können kombiniert werden (löst beim löschen und beim Ändern des Feldes SomeField aus)
determination setDetermination3 on modify { delete; field SomeField }
Dadurch wird sichergestellt, dass die definierte Validierungslogik bei der Erstellung oder Aktualisierung der Daten zum Zeitpunkt der Speicherung angewendet wird. Erfordert eine Implementierung im Behavior Pool.
validation checkSomething on save { create; update; delete; }
Mehrere Auslösebedingungen können kombiniert werden, Auslösebedingungen können auch auf Feldebene definiert werden.
validation validateSomething on save { create; field some_field, other_field; }
Felder, Standard-Operationen und Aktionen können durch Features beeinflusst werden. Dazu ist eine Implementierung im Behavior Pool erforderlich. Es können inszanzbasierte ( features:instance ) oder globale features ( features:global) verwendet werden.
...
{
...
//Felder
field ( features : instance )SomeField;
//Operationen
create ( features : global );
//Assoziationen
association _Child { create (features : global); }
//Aktionen
action ( features : instance ) someAction;
static action ( features : global ) otherAction;
}
Projektionsansichten stellen eine eingeschränkte Sicht auf die Entitäten dar. Sie können auch mit Informationen angereichert werden, die nicht zum Kern des Datenmodells gehören. Sie basieren immer auf genau einem existierenden CDS-View oder einem CDS-DDIC-basierten View.
Wenn eine Projektion eine Kind-Beziehung hat, kann diese mit redirected to composition child definiert werden.
Wenn eine Projektion eine Beziehung zu einer übergeordneten Entität hat, kann diese über redirected to parent definiert werden.
@EndUserText.label: 'Projection View Consumption'
@AccessControl.authorizationCheck: #NOT_REQUIRED
define root view entity ZC_USERS as projection on zr_users_TP
{
key UserId,
Firstname,
Lastname,
Name,
...
LocalLastChanged,
/* Associations */
_TasksToDo
//_TasksToDo : redirected to composition child zr_tasks_tp //Association als Komposition (composition)
//_TasksToDo : redirected to parent zr_tasks_tp //Association zum Parent (association to parent)
}

wird in den Behaviorpool-Klassen implementiert. Hierzu wird EML verwendet. EML ist Teil der ABAP-Sprache.
Buch S. 230 ff.
EML ermöglicht den Zugriff auf Geschäftsobjekte (auch von außen) und die Implementierung von deren Verhalten.
ermöglicht den Zugriff auf ein Objekt ohne Zugriffs- und Berechtigungskontrolle
Lesezugriff auf Entitäten. READ ENTITIES greift auf den Transaktionspuffer des aktuellen Business Objekts zu, um z.B. Feldinhalte zu lesen.
DATA: lt_entities TYPE TABLE OF your_entity_type.
READ ENTITIES OF your_entity in LOCAL MODE
ENTITY entity_name
FIELDS ( field1 field2 field3 )
WITH CORRESPONDING #( VALUE #( ( %key = '0001' ) ( %key = '0002' ) ) )
INTO TABLE @lt_entities
FAILED FAILED_SUB.
IF failed IS INITIAL.
" Verarbeitung der gelesenen Daten
ELSE.
" Fehlerbehandlung
ENDIF.
schreibender Zugriff auf die Eintitäten.
" Daten vorbereiten
DATA(lt_changes) = VALUE your_entity_type(
( %key = '0001' field1 = 'new value 1' field2 = 'new value 2' )
( %key = '0002' field1 = 'new value 3' field2 = 'new value 4' ) ).
MODIFY ENTITIES OF your_entity
ENTITY entity_name
CREATE FIELDS ( field1 field2 )
WITH CORRESPONDING #( lt_changes )
MAPPED mapped
FAILED failed
REPORTED reported.
IF failed IS INITIAL.
" Verarbeitung der Erfolgsfälle
ELSE.
" Fehlerbehandlung
ENDIF.
MODIFY ENTITIES OF /DMO/I_Travel_D
ENTITY TRAVEL
DELETE FROM VALUE #( ( TravelUUID = lv_travel_id
%is_draft = if_abap_behv->mk-off_))
FAILED DATA(failed)
REPORTED DATA(reported)