This is a test message to test the length of the message box.
Login
ABAP RAP Entity Manipulation Language
Erstellt von Software-Heroes

RAP - Entity Manipulation Language (EML)

682

In diesem Artikel beschäftigen wir uns mit einem neuen Sprachkonstrukt zum Zugriff auf unser RAP Business Objekt.

Werbung


Wie greift man leicht von außen auf ein Business Objekt zu und was bringt es mit sich mit? In diesem Artikel erfährst du mehr über das neue Sprachkonstrukt EML und was dahintersteht. Wir versuchen dir die Grundbegriffe und die ersten Möglichkeiten zu zeigen, die EML dir zur Verfügung stellt.

 

EML

Die Entity Manipulation Language ist ein neues SQL-artiges Sprachkonstukt, welches dir Zugriffe auf RAP Business Objekte und deren Daten ermöglicht. Dabei werden alle Validierungen, Ermittlungen und sonstige Einstellungen berücksichtigt, sodass du die gleichen Funktionen hast, wie mit der Fiori App. Beim Verwenden erhältst du auch vollen Support auf Aktionen und die Draft Funktionen, wenn diese im Objekt konfiguriert sind.

 

Lesen

In diesem Abschnitt gehen wir auf das Lesen von Daten aus einem Objekt ein, dabei musst du beachten, dass es sich um keinen SELECT handelt, sondern eher um einen READ. Wir müssen also vorher auf einem Weg die passenden Schlüssel lesen, es gibt aktuell noch keine Query Funktion für Business Objekte.

Schauen wir uns dazu zwei unterschiedliche Formen des Zugriffs an, die sich im Detail etwas unterscheiden. Im ersten Beispiel lesen wir alle Daten zu einem Datensatz und befüllen die Selektionstabelle vor dem Zugriff:

DATA:
  lt_selection TYPE TABLE FOR READ IMPORT ZBS_I_RAPPartner.

lt_selection = VALUE #(
  ( PartnerNumber = '1000000001' )
  ( PartnerNumber = '1000000003' )
).

READ ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
  ALL FIELDS WITH lt_selection
  RESULT DATA(lt_partner_long)
  FAILED DATA(ls_failed)
  REPORTED DATA(ls_reported).

out->write( lt_partner_long ).

 

Dazu definieren wir zu Beginn eine Tabelle für den Zugriff, die die passenden Partnernummern enthält, die wir Lesen wollen. Im Anschluss rufen wir READ ENTITIES auf, um uns für die Selektion das Ergebnis zurückgeben zu lassen. Das zweite Beispiel ist etwas kürzer, da wir die Selektion direkt übergeben. In diesem Beispiel lesen wir nur einige Felder der Entität aus:

READ ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
  FIELDS ( PartnerName Street City ) WITH VALUE #(
    ( PartnerNumber = '1000000001' )
    ( PartnerNumber = '1000000003' )
  )
  RESULT DATA(lt_partner_short)
  FAILED ls_failed
  REPORTED ls_reported.

out->write( lt_partner_short ).

 

Nachdem die Selektion durchgeführt wurde und die Ausgabe in die Console erfolgt ist, erhältst du das folgende Ergebnis. Das obere Ergebnis ist die Langform, unten die Kurzform. Die erzeugten Ergebnistabelle repräsentieren immer die gesamte Entität:

 

Was hat es nun also mit den einzelnen Bestandteilen des Statements auf sich, hier kurz erklärt:

  • READ ENTITIES - Angabe des RAP Business Objekt, entspricht meist dem Root Knoten des Objekts.
  • ENTITY - Angabe der zu lesenden Entität aus dem RAP Objekt, hier kommt vor allem der Alias der Entität zum Tragen.
  • FIELDS - Angabe der zu lesenden Felder als Tabelle, Ausdruck der Felder oder aller Felder.
  • WITH - Übergabe der Schlüssel an die Lesefunktion, Tabelle wird mit "TABLE FOR READ IMPORT" definiert.
  • RESULT - Tabelle mit den gelesenen Daten, kann per Inline-Deklaration angelegt werden und besitzt den Typ "TABLE FOR READ RESULT".
  • FAILED - Schlüssel der fehlerhaften Einträge, wenn das Lesen nicht geklappt hat.
  • REPORTED - Enthält Fehlermeldungen, wenn es beim Lesen zu Problemen kam.

 

Anlegen

Im nächsten Schritt wollen wir einmal einen neuen Datensatz anlegen, dazu gibt es das Statement MODIFY ENTITIES, welches alle wichtigen Operationen (Create, Update, Delete, Action) enthält. In unserem Beispiel befüllen wir wieder eine Tabelle, dieses mal vom Typ "TABLE FOR CREATE", da wir ja einen neuen Datensatz anlegen wollen. Dazu das folgende Beispiel:

DATA:
  lt_creation  TYPE TABLE FOR CREATE ZBS_I_RAPPartner.

lt_creation = VALUE #(
  (
    %cid = 'DummyKey1'
    PartnerNumber = '1000000007'
    PartnerName = 'Amazon'
    Country = 'US'
    %control-PartnerNumber = if_abap_behv=>mk-on
    %control-PartnerName = if_abap_behv=>mk-on
    %control-Country = if_abap_behv=>mk-on
  )
).

MODIFY ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
  CREATE FROM lt_creation
  FAILED ls_failed
  MAPPED DATA(ls_mapped)
  REPORTED ls_reported.

TRY.
    out->write( ls_mapped-partner[ 1 ]-PartnerNumber ).
    COMMIT ENTITIES.

  CATCH cx_sy_itab_line_not_found.
    out->write( ls_failed-partner[ 1 ]-%cid ).
ENDTRY.

 

Was dir bei der Befüllung der Tabelle auffällt ist, dass wir nicht nur die Datenfelder übernehmen, sondern auch die CID und CONTROL Felder befüllen. Diese Felder sind wichtig, damit die Daten im Objekt sauber übernommen werden:

  • %CID - Dummy ID die einen Datensatz innerhalb von Create, Update und Delete identifiziert. Kann frei vergeben werden, soll aber eindeutig sein.
  • %CONTROL - Angabe welche Felder bei der Operation berücksichtigt werden. Sind die Felder in der Struktur nicht aktiv, werden keine Daten übernommen und der neue Datensatz ist leer.
  • MAPPED - Rückgabe der geänderten Schlüssel und Zuordnung von CID zu Tabellenschlüssel. Vor allem dann wichtig, wenn die Schlüssel innerhalb des Business Objekts generiert werden.

 

Zum Abschluss wird der neue Schlüssel ins Log ausgegeben und ein COMMIT ENTITIES abgesetzt, dies entspricht in etwa dem COMMIT WORK im ABAP, wird aber speziell für die RAP Operationen eingesetzt.

 

Aktualisieren

Im letzten Schritt haben wir einen relativ unvollständigen Datensatz auf der Datenbank erzeugt, den wir nun mit einigen Daten anreichern wollen. Dazu für die Ausgangslage noch den aktuellen Datensatz auf der Datenbank:

 

Wir definieren dazu eine Tabelle vom Typen "TABLE FOR UPDATE", passend zur Aktion und befüllen die benötigten Felder. Für den Update müssen wir keine CID angeben, da der Schlüssel bereits bekannt ist. Allerdings sollten wir auch den passenden Schlüssel angeben. Weiterhin ist wieder die CONTROL Struktur wichtig. Das ergibt den folgenden Code:

DATA:
  lt_update    TYPE TABLE FOR UPDATE ZBS_I_RAPPartner.

lt_update = VALUE #(
  (
    PartnerNumber = '1000000007'
    PartnerName = 'Amazon Fake'
    City = 'Seattle'
    PaymentCurrency = 'USD'
    %control-PaymentCurrency = if_abap_behv=>mk-on
    %control-City = if_abap_behv=>mk-on
  )
).

MODIFY ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
  UPDATE FROM lt_update
  FAILED ls_failed
  MAPPED ls_mapped
  REPORTED ls_reported.

IF ls_failed-partner IS INITIAL.
  out->write( 'Updated' ).
  COMMIT ENTITIES.
ENDIF.

 

Wie du oben im Beispiel siehst, übergeben wir auch einen neuen Namen für den Partner, befüllen aber nicht die CONTROL Struktur. Wir gehen also davon aus, dass das Feld Name nicht aktualisiert wird und den originalen Wert behält. Nach Ausführung des Codes erhalten wir das folgende Ergebnis und unsere Vermutung bewahrheitet sich:

 

IF_ABAP_BEHV

In unseren Beispielen hatten wir bereits Konstanten aus dem Interface IF_ABAP_BEHV verwendet. Das Interface stellt verschiedene Konstanten für die Nutzung rund um die Verhaltensimplementierung zur Verfügung und gibt über ABAP Docs auch Hinweise, wo diese Konstanten genutzt werden können. Hier im Beispiel der verwendeten MK Konstanten:

 

Verwendung

Wo benötigt man eigentlich überall EML? Vor allem setzt man es beim externen Zugriff auf das Business Objekt ein, so wie aktuell unsere Beispiele aufgebaut sind. Später wird es viele RAP Objekte geben, die als BAPI im System fungieren, dann muss man sie über diesen Weg ansprechen. Weiterhin setzt man RAP auch innerhalb des Business Objekts ein, wenn man Validierungen, Ermittlungen oder Aktionen implementiert, da man dort immer wieder auf Daten des BOs zugreifen und diese verändern muss.

 

Komplettes Beispiel

Wie immer am Ende noch den kompletten Quellcode des Beispiels, das Ganze findest du auch per Commit im entsprechenden GitHub Repository von uns:

CLASS zcl_bs_demo_simple_eml DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.

CLASS zcl_bs_demo_simple_eml IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA:
      lt_selection TYPE TABLE FOR READ IMPORT ZBS_I_RAPPartner,
      lt_creation  TYPE TABLE FOR CREATE ZBS_I_RAPPartner,
      lt_update    TYPE TABLE FOR UPDATE ZBS_I_RAPPartner.

    " Long form for selection (ALL FIELDS)
    lt_selection = VALUE #(
      ( PartnerNumber = '1000000001' )
      ( PartnerNumber = '1000000003' )
    ).

    READ ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
      ALL FIELDS WITH lt_selection
      RESULT DATA(lt_partner_long)
      FAILED DATA(ls_failed)
      REPORTED DATA(ls_reported).

    out->write( lt_partner_long ).

    " Short form for selection (SOME FIELDS)
    READ ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
      FIELDS ( PartnerName Street City ) WITH VALUE #(
        ( PartnerNumber = '1000000001' )
        ( PartnerNumber = '1000000003' )
      )
      RESULT DATA(lt_partner_short)
      FAILED ls_failed
      REPORTED ls_reported.

    out->write( lt_partner_short ).

    " Create new partner
    lt_creation = VALUE #(
      (
        %cid = 'DummyKey1'
        PartnerNumber = '1000000007'
        PartnerName = 'Amazon'
        Country = 'US'
        %control-PartnerNumber = if_abap_behv=>mk-on
        %control-PartnerName = if_abap_behv=>mk-on
        %control-Country = if_abap_behv=>mk-on
      )
    ).

    MODIFY ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
      CREATE FROM lt_creation
      FAILED ls_failed
      MAPPED DATA(ls_mapped)
      REPORTED ls_reported.

    TRY.
        out->write( ls_mapped-partner[ 1 ]-PartnerNumber ).
        COMMIT ENTITIES.

      CATCH cx_sy_itab_line_not_found.
        out->write( ls_failed-partner[ 1 ]-%cid ).
    ENDTRY.

    " Update partner
    lt_update = VALUE #(
      (
        PartnerNumber = '1000000007'
        PartnerName = 'Amazon Fake'
        City = 'Seattle'
        PaymentCurrency = 'USD'
        %control-PaymentCurrency = if_abap_behv=>mk-on
        %control-City = if_abap_behv=>mk-on
      )
    ).

    MODIFY ENTITIES OF ZBS_I_RAPPartner ENTITY Partner
      UPDATE FROM lt_update
      FAILED ls_failed
      MAPPED ls_mapped
      REPORTED ls_reported.

    IF ls_failed-partner IS INITIAL.
      out->write( 'Updated' ).
      COMMIT ENTITIES.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

 

Fazit

Mit EML gilt es erst einmal einige neue Sprachkonstrukte zu lernen und wie diese genau funktionieren. Auch die neuen Tabellentypen können am Anfang erst einmal überfordern und einige Inhalte machen erst einmal keinen Sinn. Doch wenn du erst einmal in der Sprache drin bist, macht es Spaß damit zu arbeiten. In einem späteren Artikel werden wir noch tiefer in das Thema EML einsteigen, hier erst einmal nur die Grundlagen für die folgenden Artikel.


Enthaltene Themen:
RAPBTPEML
Kommentare (0)



Und weiter ...

Bist du zufrieden mit dem Inhalt des Artikels? Wir posten jeden Freitag neuen Content im Bereich ABAP und unregelmäßig in allen anderen Bereichen. Schaue bei unseren Tools und Apps vorbei, diese stellen wir kostenlos zur Verfügung.


RAP - Übersetzungs-App (Beispiel)

Kategorie - ABAP

Schauen wir uns einmal ein praktisches Beispiel für die Entwicklung einer RAP Anwendung im ABAP Environment an und wie du mit wenig Aufwand eine App erstellst.

02.08.2024

RAP - Custom Entity Wertehilfe (Deep Dive)

Kategorie - ABAP

Mit der Custom Entity hast du in RAP die meisten Freiheiten in der Entwicklung von ABAP Cloud Anwendungen, doch wie sieht es mit potentiellen Fehlern aus?

12.07.2024

RAP - Deep Action in OData v4

Kategorie - ABAP

In diesem Artikel schauen wir uns einmal Aktionen mit tiefen Strukturen an, wie wir sie erzeugen und Daten an einen API Endpunkt übergeben können.

24.05.2024

BTP - Anbindung On-Premise (Consumption Model v2)

Kategorie - ABAP

In diesem Artikel wollen wir noch einmal einen Update zur Anbindung von On-Premise Systemen geben und wie dies mit einem Communication Arrangement durchgeführt wird.

15.12.2023

RAP - App Count anzeigen (Kachel)

Kategorie - ABAP

In diesem Beispiel geht es um die Anzeige eines Zählers auf der Kachel einer Fiori Elements Anwendung und wie sich so etwas umsetzen lässt.

06.10.2023