
BTP - Table Entity und Includes
Table Entity für den Draft im RAP Objekt? Dazu prüfen wir auch Includes und Aspects und bauen unser RAP Objekt auf die neuen Entitäten um.
Inhaltsverzeichnis
In diesem Artikel schauen wir uns die Table Entity als Draft an, prüfen aber zuvor wie wir Includes innerhalb der Tabellen verwenden können.
Einleitung
In einem älteren Artikel haben wir uns das CDS Pattern angeschaut und wie wir damit Anwendungen auf Basis von Table Entities bauen können. Die Table Entities damals hatten aber noch ein paar Nachteile, zum Beispiel konnten wir sie nicht im Bereich des Drafts einsetzen. Mit dem Release 2605 wurde der Draft erweitert. Damit ist es nun möglich, eine Table Entity auch als Draft-Tabelle einzusetzen. Dazu schauen wir uns die verschiedenen Schritte einmal genauer an.
Aspekt
Dabei spielt der Aspekt eine wichtige Rolle, wenn es um Includes in Table Entities geht. Bisher war es leider nicht möglich, Felder über Strukturen in Table Entities einzubinden. Dies hat sich mit dem letzten Release ebenfalls geändert. Der Aspekt ist normalerweise eine Art Struktur, wo wir bestimmte Felder und Berechnungen aus einem Core Data Service auslagern und wiederverwenden können. Dabei müssen wir später bei der Einbindung ein sogenanntes Binding durchführen und die entsprechenden Felder gegen den Aspekt binden, um so zum Beispiel die Berechnungen wiederzuverwenden. Daher war die eigentliche Verwendung des Aspekts vor allem bezogen auf die Auslagerung von Funktionen und weniger auf die Wiederverwendung als Strukturen mit entsprechenden Feldern. Dazu legen wir einen neuen Aspekt an. Dieser erhält auch eine eigene Ordnerstruktur innerhalb der ADTs, ist also nicht im Bereich der Core Data Services zu finden.
In unserem Beispiel erzeugen wir einen neuen Aspekt für die Adminfelder eines RAP-Objektes, die wir für den Draft benötigen. Dabei definieren wir neben den Feldern und Typen auch entsprechende Annotationen, die wir später wiederverwenden wollen. In diesem einfachen Fall bekommt der Aspekt einen sprechenden Namen, ansonsten müssen wir keine Besonderheiten beachten. Wir haben auch keine Funktionen, die wir auslagern wollen.
@EndUserText.label: 'RAP Admin Fields'
define aspect ZBS_DMORapAdminFields {
@Semantics.user.createdBy: true
LocalCreatedBy : abp_creation_user;
@Semantics.systemDateTime.createdAt: true
LocalCreatedAt : abp_creation_tstmpl;
@Semantics.user.localInstanceLastChangedBy: true
LocalLastChangedBy : abp_locinst_lastchange_user;
@Semantics.systemDateTime.localInstanceLastChangedAt: true
LocalLastChangedAt : abp_locinst_lastchange_tstmpl;
@Semantics.systemDateTime.lastChangedAt: true
LastChangedAt : abp_lastchange_tstmpl;
}
Include
Wie sieht es nun eigentlich mit Includes aus? Includes wurden in den klassischen Tabellen vor allem dafür verwendet, um Strukturen wiederverwendbar zu machen und die gleichen Felder in mehreren Tabellen zum Beispiel zu verwenden, indem wir diese inkludiert haben. Eine ähnliche Funktion gibt es nun auch für die Table Entities.
Table Entity
Dazu legen wir uns eine neue Table Entity an, diese ist relativ überschaubar gehalten. Wir haben eine Invoice-ID und einen Invoice-Status und wollen dazu die Admin-Felder ergänzen.
@ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'TE with Include'
define table entity ZBS_TableEntityWithInc
{
key InvoiceId : abap.raw( 16 );
InvoiceStatus : ZBS_DemoCDSInvoiceStatus;
}
Erweiterung
Für die Erweiterung übernehmen wir nun die Felder, die aus dem Aspekt kommen. Dazu verwenden wir wieder das Keyword INCLUDE, gefolgt von dem Aspektnamen. Um dann auf die verschiedenen Felder zugreifen zu können, verwenden wir den Punkt, gefolgt von einem Stern, um alle Felder anzusprechen. Hier hätten wir auch die Möglichkeit, einzelne Felder jeweils zu nehmen. Über den Zusatz SIGNATURE ONLY wollen wir nur die Signatur des Aspekts übernehmen, nicht aber die Funktionalität, wie zum Beispiel Formeln, die in einem normalen Aspekt möglich wären.
@ClientHandling.type: #CLIENT_DEPENDENT
@AbapCatalog.deliveryClass: #APPLICATION_DATA
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'TE with Include'
define table entity ZBS_TableEntityWithInc
{
key InvoiceId : abap.raw( 16 );
InvoiceStatus : ZBS_DemoCDSInvoiceStatus;
include ZBS_DMORapAdminFields.* signature only;
}
Schauen wir uns die Table Entity über die Element Info an, dann sehen wir, dass alle Felder aus dem Include eingebunden wurden und in der Tabelle auch verfügbar sind. Somit funktioniert es ähnlich wie bei den klassischen Tabellen. Wir sehen zwar, dass ein Include vorhanden ist, aber nicht das die Felder nun im Nachgang verfügbar sind. Über die Element Info auf den Namen bekommen wir ein vollständiges Bild der Table Entity.
Verwendung
Für die Verwendung wollen wir einmal Daten in die Tabelle einfügen. Dabei wollen wir nicht nur die Hauptfelder befüllen, sondern auch eines der inkludierten Felder. Nachdem wir die Daten eingefügt haben, lesen wir sie direkt aus der Tabelle und geben sie in die Konsole aus.
INSERT ZBS_TableEntityWithInc FROM @( VALUE #( InvoiceId = xco_cp=>uuid( )->value
InvoiceStatus = 'T'
LocalCreatedBy = cl_abap_context_info=>get_user_alias( ) ) ).
SELECT FROM ZBS_TableEntityWithInc
FIELDS *
INTO TABLE @DATA(table_data).
out->write( table_data ).
Dies haben wir nun mehrere Male durchgeführt. Und wie wir im Ergebnis in der Konsole sehen, wurden mehrere Datensätze von der Table Entity gelesen. Die Werte sind vorbefüllt und auch das Zusatzfeld wurde mit dem Erstellungs-User befüllt. Grundsätzlich greift damit das Include ganz normal wie bei einer Tabelle und erweitert diese.
Draft
Wie sieht es nun eigentlich bei der Verwendung als Draft-Tabelle aus? Mit der Grundlage über die Aspekte können wir nun die Erweiterung vornehmen und die Draft-Tabelle auf eine Table Entity umstellen.
Hilfsfelder
Dazu gibt es das Include-Objekt SYCH_BDL_DRAFT_ADMIN_INC, welches wir über die Suche in den ABAP Development Tools (STRG + SHIFT + A) finden. Suchen wir nach dem Include-Namen, erhalten wir aktuell zwei Objekte in einem neuen System: einmal das klassische Include, welches automatisch in den Draft-Tabellen eingebunden wird, und das neue Include, welches den gleichen Namen hat, aber als Aspekt verfügbar ist. Dieses Element benötigen wir, um es dann in unseren Draft-Tabellen einzubinden.
Löschen
Aktuell handelt es sich vor allem um einen manuellen Prozess Daher löschen wir im ersten Schritt die Drahttabellen aus dem System. Solltest du natürlich aufpassen, dass Kandidaten mehr vorhanden sind beziehungsweise kann er mir mit einer Anwendung arbeitet Wenn du dies tust Grundsätzlich können wir ein Projekt Explorer beide Objekte markieren und per Rechtsklick aus dem System löschen, auch wenn er eine Warnung erfolgt, dass die Objekte noch genutzt werden, nämlich in der. Verhaltensdefinition können wir diese aus dem System entfernen
Anlage
Die Draft-Tabelle müssen wir nun manuell im System anlegen, dazu legen wir eine neue Table Entity an und vergeben einen sprechenden Namen, der zum Beispiel auch das Wort Draft enthält. Hier solltest du aber vorsichtig sein: Aktuell gibt es keine Prüfung für die Länge des Namens, der eingegeben wird. So hatten wir zum Beispiel den Namen "ZBS_T_CDSPatternInvoiceDraft" verwendet, um unsere Draft-Entity anzulegen. Der Name einer Table Entity kann aber nur 25 Zeichen lang sein. Dies erfahren wir leider erst nach Anlage des Objektes und mit einer Fehlermeldung durch den Compiler. Deshalb haben wir das Objekt gelöscht, den Namen geändert und einen kürzeren Namen gewählt.
define table entity ZBS_T_CDSPatternInvDraft
{
key DocumentNumber : abap.char(8);
key DraftUUID : sdraft_uuid;
DocumentDate : abap.datn;
DocumentTime : abap.timn;
PartnerNumber : abap.char(10);
@Semantics.user.createdBy: true
LocalCreatedBy : abp_creation_user;
@Semantics.systemDateTime.createdAt: true
LocalCreatedAt : abp_creation_tstmpl;
@Semantics.user.localInstanceLastChangedBy: true
LocalLastChangedBy : abp_locinst_lastchange_user;
@Semantics.systemDateTime.localInstanceLastChangedAt: true
LocalLastChangedAt : abp_locinst_lastchange_tstmpl;
@Semantics.systemDateTime.lastChangedAt: true
LastChangedAt : abp_lastchange_tstmpl;
include SYCH_BDL_DRAFT_ADMIN_INC.* signature only;
}
Über den Include hängen wir dann unsere Struktur ans Ende der Table Entity. Prüfen wir dann wiederum die Table Entity mit der Element Info, dann sehen wir, dass auch alle Draft-Felder am Ende angehangen wurden.
Damit ist unsere Draft-Tabelle vorbereitet und wir legen noch eine zweite Tabelle an für die zweite Entität beziehungsweise Tabelle, die wir aus dem System gelöscht haben. Zum Abschluss tauschen wir in der Verhaltendefinition die Tabelle durch die neuen Entitäten aus und aktivieren das Objekt.
Includes
Aktuell werden Aspekte unterstützt, wenn du normal mit den Table Entities arbeitest. Allerdings gibt es noch keine Unterstützung innerhalb des RAP-Objektes. Hier hatten wir zum Beispiel unser wiederverwendbares Include für die administrativen Felder eingefügt, was grundsätzlich auf Table-Entity-Basis funktioniert. Allerdings unterstützt das SADL-Framework aktuell noch keine Includes innerhalb unserer Tabelle. Hier erhalten wir auch eine Fehlermeldung im Service Binding und können den Service nicht mehr ausführen, da er einen Fehler enthält.
Vollständiges Beispiel
Das vollständige Beispiel findest du über verschiedene Repositories aufgeteilt. Das Beispiel für den Aspekt findest du bei den Core Data Services mit diesem Commit. Die Anpassungen an der RAP Anwendnung sind im RAP Repository und in diesem Commit.
Fazit
Die ersten zaghaften Versuche für Includes für die neuen Tabellen sind da, können leider noch nicht im kompletten Prozess verwendet werden. Grundsätzlich sieht die Handhabung aber schon einmal gut aus und fühlt sich zumindest nach klassischen Includes an. Damit ist es in Zukunft möglich, administrative Felder und andere Felder, die man in mehreren Entitäten verwenden will, auszulagern und separat über Includes wieder einzubinden. Damit sparst du dir das Kopieren und Einfügen von Feldern und Inhalten.
Weitere Informationen:
SAP Help - Include Aspect






