This is a test message to test the length of the message box.
Login
ABAP RAP Report Pattern
Erstellt von Software-Heroes

RAP - Report Pattern

328

Wie ist das Report Pattern in RAP aufgebaut und was kannst du damit machen? Mehr dazu in diesem ABAP Artikel.

Werbung


In diesem Artikel werden wir auf das Report Pattern eingehen und wie du es für dich am besten nutzen kannst. Dabei gehen wir auf die unterschiedlichen Schichten und Möglichkeiten ein.

 

Einleitung

Das ABAP RESTful Programming Model ist das neue Modell in ABAP, um Cloud Ready und Clean Core Anwendungen zu erstellen. Mit RAP lassen sich neben Anwendungen, auch Schnittstellen für den internen und externen Gebrauch zur Verfügung stellen. Mit den neusten Features ist RAP sehr flexibel was den Aufbau und die Nutzung angeht, weshalb wir die Anwendungen in verschiedene Pattern aufteilen möchten.

 

Aufbau

Das "Report Pattern" zeichnet sich dadurch aus, dass es dem klassischen Report sehr nah ist. Die Datenquelle der RAP Anwendung ist ein Standard Core Data Service. Dabei verwenden wir zum Speichern der Daten einen "Unmanaged Save", sind aber frei in der Anbindung von zusätzlichen Entitäten und Informationen. Bevor wir mit dem Aufbau starten, hier noch die allgemeine Legende:

 

Dazu die folgenden Merkmale zur Abgrenzung:

  • Datenquelle ist ein Core Data Service (Standard, Custom)
  • Daten sollen angezeigt, aber nicht geändert werden
  • Zusätzliche Daten per Assoziation (zusätzliche Entität, zusätzliche Felder)
  • Unmanaged Save zum Speichern der Informationen

 

 

Beispiel

In den folgenden Abschnitten erstellen wir eine Reporting Anwendung und erweitern diese Stück für Stück um verschiedene Anforderungen. Die Anwendung soll uns die aktuellen Währungen im System anzeigen. Dazu möchten wir noch eigene Informationen speichern, wie eine Dokumentation zur Währung, ein Bild und zusätzliche Informationen, in welchen Ländern unser Unternehmen die Währung verwendet.

 

Daten

Im ersten Schritt bauen wir dazu unser zusätzliches Datenmodell auf und erstellen die verschiedenen Layer des RAP Objekts (Interface und Consumption).

 

Tabellen

Im ersten Schritt legen wir eine Tabelle für Zusatzinformationen, an die wir an der Währung speichern wollen. Da wir nicht direkt die Währungstabelle und den Core Data Service erweitern wollen, legen wir die Tabelle im Kundennamensraum an.

@EndUserText.label : 'Additional Currency Informations'
define table zbs_drp_addcurr {
  key client    : abap.clnt not null;
  key currency  : waers not null;
  ccomment      : abap.char(60);
  documentation : abap.string(0);
  picture_url   : abap.string(0);
  last_editor   : abap.char(12);
}

 

Dazu benötigen wir noch eine Entität unter der Währung, wo wir Zusatzinformationen zu den Ländern hinterlegen wollen. Die Tabelle sieht deshalb wie folgt aus:

@EndUserText.label : 'Country Assignment'
define table zbs_drp_country {
  key client   : abap.clnt not null;
  key currency : waers not null;
  key country  : land1 not null;
  ranking      : abap.int2;
}

 

Basis

Da wir später mit Core Data Services arbeiten wollen, legen wir über den beiden Tabellen einen Basis Layer an, der die Tabelle als einfachen Views zur Verfügung stellt. Hier haben wir auch noch einmal die Möglichkeit, die Felder für unser Datenmodell zu normalisieren.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Additional Informations'
define view entity ZBS_B_DRPAdditionalCurrency
  as select from zbs_drp_addcurr
{
  key currency      as Currency,
      ccomment      as CurrencyComment,
      documentation as Documentation,
      picture_url   as PictureURL,
      last_editor   as LastEditor
}

 

Der Basis View für die Länder Entität sieht nun wie folgt aus:

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Country Assignment'
define view entity ZBS_B_DRPCurrencyCountry
  as select from zbs_drp_country
{
  key currency as Currency,
  key country  as Country,
      ranking  as CountryRanking
}

 

Hinweis: Der Basis-Layer ist optional, dient in diesem Fall aber dazu, die Felder der Tabelle sauber für die weitere Verarbeitung zur Verfügung zu stellen.

 

Interface

Im Interface Layer modellieren wir nun die Daten, die wir in unserem Modell für die Anzeige später benötigen und stellen schon einmal alle Felder für den Consumption Layer zur Verfügung. Im Root View stellen wir die Beziehung zu den Ländern her und übernehmen alle Zusatzdaten, die wir später für die Erweiterung benötigen.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Currency Overview'
define root view entity ZBS_R_DRPCurrency
  as select from I_Currency
  composition of many ZBS_I_DRPCurrencyCountry          as _Country
  association of one to one ZBS_B_DRPAdditionalCurrency as _Data on _Data.Currency = $projection.Currency
  association of one to one I_BusinessUserVH            as _User on _User.UserID = $projection.lasteditor
{
  key Currency,
      Decimals,
      CurrencyISOCode,
      AlternativeCurrencyKey,
      _Text[ Language = $session.system_language ].CurrencyName,
      _Text[ Language = $session.system_language ].CurrencyShortName,      
      _Data.CurrencyComment,
      _Data.Documentation,
      _Data.PictureURL,
      _Data.LastEditor,
      _Country,
      _User
}

 

Der View für die Länderzuordnung stellt die Beziehung zu der Root Entität her und stellt bereits alle Informationen, wie zum Beispiel den Namen, für den Consumption View zur Verfügung.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Country Assignment'
define view entity ZBS_I_DRPCurrencyCountry
  as select from ZBS_B_DRPCurrencyCountry
  association        to parent ZBS_R_DRPCurrency as _Currency on _Currency.Currency = $projection.Currency
  association of one to one I_Country            as _Country  on _Country.Country = $projection.Country
{
  key Currency,
  key Country,
      _Country._Text[ Language = $session.system_language ].CountryName,
      CountryRanking,
      _Currency
}

 

Projektion

Im nächsten Schritt erzeugen wir die Projektionsschicht für die Währung. Hier wirst du bereits auch eine allgemeine Suche finden über den Schlüssel und die Textfelder (@Search). Zusätzlich lesen wir Felder, die Wir nur im Consumption Layer anzeigen wollen, wie den Namen des letzten Änderers.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption for Currency'
@Metadata.allowExtensions: true
@Search.searchable: true
define root view entity ZBS_C_DRPCurrency
  provider contract transactional_query
  as projection on ZBS_R_DRPCurrency
{
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 1.0
      @Search.ranking: #HIGH
  key Currency,
      Decimals,
      CurrencyISOCode,
      AlternativeCurrencyKey,
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.7
      @Search.ranking: #MEDIUM
      CurrencyName,
      @Search.defaultSearchElement: true
      @Search.fuzzinessThreshold: 0.8
      @Search.ranking: #MEDIUM
      CurrencyShortName,
      CurrencyComment,
      Documentation,
      PictureURL,
      LastEditor,
      _User.PersonFullName as EditorName,
      _Country : redirected to composition child ZBS_C_DRPCurrencyCountry
}

 

Für die Zuordnung der Länder binden wir bereits die Standardsuchhilfe an. Du solltest auch sicherstellen, dass für den nächsten Schritt die Annotation "@Metadata.allowExtensions: true" gesetzt ist, um die Metadaten zu erzeugen und damit dem UI ein Aussehen zu geben.

@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Consumption for Country Assignment'
@Metadata.allowExtensions: true
define view entity ZBS_C_DRPCurrencyCountry
  as projection on ZBS_I_DRPCurrencyCountry
{
  key Currency,
      @Consumption.valueHelpDefinition: [{ entity: { name: 'I_CountryVH', element: 'Country' } }]
  key Country,
      CountryName,
      CountryRanking,
      _Currency : redirected to parent ZBS_C_DRPCurrency
}

 

Service und UI

Damit wir nun aus den Daten den ersten Service und eine erste UI zu sehen bekommen, können wir nun unser RAP Objekt nach außen freigeben. Im ersten Schritt geben wir dazu den Service mit einem Binding nach außen frei, im zweiten Schritt erzeugen wir Metadaten, um die Elemente auf dem Bild zuzuordnen.

 

Service 

Dazu legen wir auf unserem Consumption View über das Kontextmenü eine Service Definition an. In diesem Fall können wir auch die "LeadingEntity" definieren, die Annotation sorgt für eine Markierung im Service Binding.

@EndUserText.label: 'Currency Service'
@ObjectModel.leadingEntity.name: 'ZBS_C_DRPCurrency'
define service ZBS_DEMO_DRP_CURRENCY {
  expose ZBS_C_DRPCurrency        as Currency;
  expose ZBS_C_DRPCurrencyCountry as Country;
}

 

Zum Abschluss legen wir noch ein Service Binding an. In diesem Fall generieren wir einen OData v4 Service als UI, da wir hier unsere App erzeugen wollen.

 

Zum Abschluss nicht vergessen auf den "Publish" Button zu drücken, damit der Service angelegt wird und von außen aufgerufen werden kann.

 

Metadaten

Solltest du bereits den Preview deiner Anwendung aufgerufen haben, erhältst du dort ein leeres Bild, aber immerhin mit einer Liste. Über das Zahnrad und die Anpassung der Filter kannst du dir bereits Elemente einblenden und somit die ersten Daten ansehen. Damit wir aber als Default gleich unser aufgeräumtes UI finden, erzeugen wir noch Metadata Extensions für unsere Consumption Views.

@Metadata.layer: #CUSTOMER
@UI: {
  headerInfo: {
    typeName: 'Currency',
    typeNamePlural: 'Currencies',
    title: { value: 'Currency' },
    description: { value: 'CurrencyName' },
    imageUrl: 'PictureURL'
  }
}
annotate entity ZBS_C_DRPCurrency with
{
  @UI.facet      : [
    {
      id         : 'idTechFields',
      label      : 'Technical Details',
      position   : 10,
      type       : #IDENTIFICATION_REFERENCE,
      targetQualifier: 'TECH'
    },
    {
      id         : 'idAddFields',
      label      : 'Additional Info',
      position   : 20,
      type       : #IDENTIFICATION_REFERENCE,
      targetQualifier: 'ADD'
    },
    {
      id         : 'idDocumentation',
      label      : 'Documentation',
      position   : 30,
      type       : #IDENTIFICATION_REFERENCE,
      targetQualifier: 'DOCU'
    },
    {
      id         : 'idChanges',
      label      : 'Changes',
      position   : 40,
      type       : #IDENTIFICATION_REFERENCE,
      targetQualifier: 'CHANGE'
    },
    {
      id         : 'idCountryTable',
      label      : 'Country Assignment',
      position   : 50,
      type       : #LINEITEM_REFERENCE,
      targetElement: '_Country'
    }
  ]

  @UI:{
    lineItem: [{ position: 10 }],
    selectionField: [{ position: 10 }]
  }
  Currency;

  @UI:{
    lineItem: [{ position: 20 }]
  }
  CurrencyName;

  @UI:{
    lineItem: [{ position: 30 }]
  }
  CurrencyShortName;

  @UI:{
    identification: [{ position: 10, qualifier: 'TECH' }]
  }
  CurrencyISOCode;

  @UI:{
    identification: [{ position: 20, qualifier: 'TECH' }]
  }
  Decimals;

  @UI:{
    identification: [{ position: 30, qualifier: 'TECH' }]
  }
  AlternativeCurrencyKey;

  @UI:{
    identification: [{ position: 40, qualifier: 'ADD' }]
  }
  @UI.multiLineText: true
  @EndUserText.label: 'Comment'
  CurrencyComment;

  @UI:{
    identification: [{ position: 50, qualifier: 'DOCU' }]
  }
  @UI.multiLineText: true
  @EndUserText.label: 'Informations'  
  Documentation;

  @UI:{
    identification: [{ position: 60, qualifier: 'ADD' }]
  }
  @EndUserText.label: 'Currency Image'  
  PictureURL;

  @UI:{
    identification: [{ position: 70, qualifier: 'CHANGE' }]
  }
  @EndUserText.label: 'Last Changer (ID)'  
  LastEditor;

  @UI:{
    lineItem: [{ position: 40 }],
    identification: [{ position: 80, qualifier: 'CHANGE' }]
  }
  @EndUserText.label: 'Last Changer'
  EditorName;
}

 

Hier vergeben wir Texte für unsere eingebauten Typen, platzieren die Elemente auf dem Bild, bilden Gruppen und Filter. Die Zuordnung der Länder ist recht überschaubar, da wir die Informationen nur im Detailbild anzeigen wollen und die Objektseite nicht benötigen. Die Währung können wir ausblenden, da die Information nur doppelt wäre.

@Metadata.layer: #CUSTOMER
annotate entity ZBS_C_DRPCurrencyCountry with
{
  @UI.hidden: true
  Currency;

  @UI:{
    lineItem: [{ position: 10 }]
  }
  Country;

  @UI:{
    lineItem: [{ position: 20 }]
  }
  CountryName;
  
  @UI:{
    lineItem: [{ position: 30 }]
  }
  CountryRanking;
}

 

Preview

Da die Anwendung nun auch ein Bild hat, können wir einen ersten Preview der Anwendung wagen. Die Liste für die Auswertung steht nun soweit zur Verfügung. Auf der Einstiegsseite erhalten wir alle nötigen Informationen zur Währung.

 

Die Detailseite ist nun auch entsprechend aufgeräumt und bietet zusätzliche Informationen zur Währung, die aus unserer eigenen Tabelle kommen. Damit haben wir den Standard um zusätzliche Felder "erweitert", die wir nun auch im nächsten Abschnitt änderbar machen wollen.

 

Verhalten

Damit die App nun interaktiv und änderbar wird, müssen wir noch ein Verhalten implementieren. Bisher handelt es sich um eine reine Anzeige-App, womit der Anwender aber auch bereits arbeiten kann, um an die nötigen Informationen zu kommen.

 

Draft

Wenn wir die Standardoperationen verwenden wollen, müssen wir zusätzlich noch für den OData v4 Service das Draft Handling aktivieren. Dazu müssen wir in unserer Haupttabelle noch die folgenden Felder ergänzen:

local_last_changed : abp_locinst_lastchange_tstmpl;
last_changed       : abp_lastchange_tstmpl;

 

Die Felder müssen wir dann bis auf Interface Ebene veröffentlichen, damit wir sie in der Verhaltensdefinition nutzen können. Dazu benötigen wir für jeden View noch eine Draft Tabelle, die dann alle Felder des Views puffert. Für die Währung wäre das damit:

@EndUserText.label : 'Draft für Currency'
define table zbs_drp_currd {
  key client             : abap.clnt not null;
  key currency           : waers not null;
  decimals               : abap.int1;
  currencyisocode        : abap.char(3);
  alternativecurrencykey : abap.char(3);
  currencyname           : abap.char(40);
  currencyshortname      : abap.char(15);
  currencycomment        : abap.char(60);
  documentation          : abap.string(0);
  pictureurl             : abap.string(0);
  lasteditor             : abap.char(12);
  locallastchanged       : abp_locinst_lastchange_tstmpl;
  lastchanged            : abp_lastchange_tstmpl;
  "%admin"               : include sych_bdl_draft_admin_inc;
}

 

Für die Länderzuordnung würde die Draft Tabelle entsprechend so aussehen.

@EndUserText.label : 'Draft for Country'
define table zbs_drp_cound {
  key client     : abap.clnt not null;
  key currency   : waers not null;
  key country    : land1 not null;
  countryname    : abap.char(50);
  countryranking : abap.int2;
  "%admin"       : include sych_bdl_draft_admin_inc;
}

 

Verhaltensdefinition

Nun können wir das entsprechende Verhalten implementieren. Da wir die normale UPDATE Aktion von RAP verwenden wollen, müssen wir Draft implementieren. Dazu setzen wir CREATE und DELETE auf Internal, da wir diese Aktionen dem Anwender nicht anbieten wollen, zumindest für die Root Entität. Dabei verwenden wir einen Unmanaged Save, um das Speichern der Daten selbst zu übernehmen. Managed hilft uns dabei, die Daten im Draft und im Transaktionalen Puffer zu verwalten, damit müssen wir uns nicht darum kümmern. Die definierten Timestamps benötigen wir für die ETAGs. Alle Felder, die aus dem Standard kommen, setzen wir auf READONLY, damit der Anwender nicht denkt, dass er diese auch ändern könnte über die Anwendung.

managed implementation in class zbp_bs_drp_currency unique;
strict ( 2 );
with draft;

define behavior for ZBS_R_DRPCurrency alias Currency
with unmanaged save
draft table zbs_drp_currd
etag master LocalLastChanged
lock master total etag LastChanged
authorization master ( instance )
{
  internal create;
  update;
  internal delete;

  draft action Edit;
  draft action Activate optimized;
  draft action Discard;
  draft action Resume;
  draft determine action Prepare;

  field ( readonly )
  Currency,
  Decimals,
  CurrencyISOCode,
  AlternativeCurrencyKey,
  CurrencyName,
  CurrencyShortName,
  LastEditor;

  mapping for zbs_drp_addcurr
    {
      Currency         = currency;
      CurrencyComment  = ccomment;
      Documentation    = documentation;
      PictureURL       = picture_url;
      LastEditor       = last_editor;
      LocalLastChanged = local_last_changed;
      LastChanged      = last_changed;
    }

  association _Country { create; with draft; }
}

define behavior for ZBS_I_DRPCurrencyCountry alias Country
with unmanaged save
draft table zbs_drp_cound
lock dependent by _Currency
authorization dependent by _Currency
{
  update;
  delete;

  field ( readonly )
  Currency,
  CountryName;

  field ( readonly : update )
  Country;

  mapping for zbs_drp_country
    {
      Currency       = currency;
      Country        = country;
      CountryRanking = ranking;
    }

  association _Currency { with draft; }
}

 

In der Projektion geben wir nun die Aktionen und Möglichkeiten nach Außen, die der Anwender zum Arbeiten mit unserem Objekt benötigt. Die Draft Aktionen (Edit, Activate, Discard, Resume und Prepare) sind dabei verpflichtend, damit der Draft verwendet werden kann.

projection;
strict ( 2 );
use draft;

define behavior for ZBS_C_DRPCurrency alias Currency
{
  use update;

  use action Edit;
  use action Activate;
  use action Discard;
  use action Resume;
  use action Prepare;

  use association _Country { create; with draft; }
}

define behavior for ZBS_C_DRPCurrencyCountry alias Country
{
  use update;
  use delete;

  use association _Currency { with draft; }
}

 

Verhaltensimplementierung

In der Verhaltensimplementierung kümmern wir uns nun um das Speichern der geänderten Datensätze in der Methode SAVE_MODIFIED. Dabei kommt uns zugute, dass wir in der Verhaltensdefinition das Mapping konfiguriert haben. Mit dem Mapping können wir beim CORRESPONDING den Zusatz MAPPING FROM ENTITY nutzen, um so die normalisierten Felder der Entität auf die Datenbankstruktur zu mappen. Du solltest allerdings auch beim UPDATE mit der %CONTROL Struktur arbeiten, da sonst Felder auf der Datenbank ausversehen gelöscht werden können.

CLASS lhc_Currency DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
      IMPORTING keys REQUEST requested_authorizations FOR Currency RESULT result.

ENDCLASS.


CLASS lhc_Currency IMPLEMENTATION.
  METHOD get_instance_authorizations.
  ENDMETHOD.
ENDCLASS.


CLASS lsc_ZBS_R_DRPCURRENCY DEFINITION INHERITING FROM cl_abap_behavior_saver.
  PROTECTED SECTION.
    METHODS
      save_modified REDEFINITION.

    METHODS
      cleanup_finalize REDEFINITION.

ENDCLASS.


CLASS lsc_ZBS_R_DRPCURRENCY IMPLEMENTATION.
  METHOD save_modified.
    LOOP AT update-currency INTO DATA(ls_new_currency).
      ls_new_currency-LastEditor = cl_abap_context_info=>get_user_technical_name( ).

      INSERT zbs_drp_addcurr FROM @ls_new_currency MAPPING FROM ENTITY.
      IF sy-subrc <> 0.
        UPDATE zbs_drp_addcurr FROM @ls_new_currency INDICATORS SET STRUCTURE %control MAPPING FROM ENTITY.
      ENDIF.
    ENDLOOP.

    LOOP AT create-country INTO DATA(ls_create_country).
      INSERT zbs_drp_country FROM @ls_create_country MAPPING FROM ENTITY.
    ENDLOOP.

    LOOP AT update-country INTO DATA(ls_update_country).
      UPDATE zbs_drp_country FROM @ls_update_country INDICATORS SET STRUCTURE %control MAPPING FROM ENTITY.
    ENDLOOP.

    LOOP AT delete-country INTO DATA(ls_delete_country).
      DELETE zbs_drp_country FROM @( CORRESPONDING zbs_drp_country( ls_delete_country MAPPING FROM ENTITY ) ).
    ENDLOOP.
  ENDMETHOD.


  METHOD cleanup_finalize.
  ENDMETHOD.
ENDCLASS.

 

Bei der Währung müssen wir uns nur um den UPDATE Fall kümmern, da die Datensätze von der Datenbank kommen. Dafür müssen wir allerdings den MODIFY verwenden, da wir nicht wissen, ob der Datensatz bereits gespeichert wurde.

 

Zusammenfassung

Das "Report Pattern" kann in mehreren Schritten implementiert werden, je nach Anforderung an den Report. Als Grundlage benötigst du eigentlich immer:

  • Datenmodell
  • Service
  • Metadaten
  • Berechtigung (Access Control)

 

Damit kannst du die Daten bereits im UI anzeigen und der User kann damit interagieren. Dies würde auch einem reinen Anzeige-ALV entsprechen. Zum Schluss solltest du ebenfalls nicht vergessen, die verschiedenen Core Data Services mit Berechtigungen (Access Control) auszustatten. Da unsere Standard Entitäten keine Berechtigungsprüfungen haben, haben wir ebenfalls keine implementiert. Möchtest du noch Änderungen vornehmen, benötigst du weitere Bestandteile:

  • Draft (wenn benötigt)
  • Verhaltensdefinition
  • Verhaltensimplementierung

 

Die letzten Bestandteile entsprechen schon sehr stark einem Report mit ändernden Funktionalitäten. Hier erhältst du auch Mehrwerte zur Erweiterung der Standard-Entitäten, ohne diese zwingend modifizieren zu müssen. Das Endergebnis sieht nun wie folgt aus.

 

In der App ist auch noch das Feature versteckt, dass wir über das Feld "Bild URL", das Bild im Header der Objektseite dynamisch anpassen können. Zusätzlich können wir über den "Edit" Button alle unsere eigenen Felder anpassen und auf der Datenbank speichern.

 

Vollständiges Beispiel

Da das Beispiel recht komplex ist und viele Objekte enthält, findest du alle erstellten Objekte in einem Commit in unserem GitHub Repository zum Thema ABAP RESTful Programming Model. Oder du schaust dir das Paket ZBS_DEMO_RAP_PATTERN_REPORT im Repository an für die vollständige Anwendung. Damit kannst du die verschiedenen Objekte noch einmal abgleichen, die wir nach der Änderung nicht vollständig aufgelistet haben.

 

Fazit

Mit dem Report Pattern kannst du einfach Anzeigereports umsetzen, aber auch komplexe Änderungstransaktionen erstellen, um Kundenerweiterungen zu erzeugen, die Zusatzdaten verarbeiten.


Enthaltene Themen:
RAPBTPPatternReport
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 - Popup Defaultwerte

Kategorie - ABAP

Wie kannst du im Popup einer Aktion in RAP dem User Defaultwerte zur Verfügung stellen? In diesem Artikel erweitern wir unsere Anwendung.

21.01.2025

RAP - Popup Pflichtfelder

Kategorie - ABAP

Wie kannst du eigentlich Pflichtfelder für ein Popup in RAP definieren? In diesem Artikel werden wir etwas genauer auf die Details eingehen.

14.01.2025

RAP - Deep Table Action

Kategorie - ABAP

Ist die Übergabe von Tabellen an Aktionen in RAP aktuell möglich? Dieser Artikel soll einen besseren Einblick in das Thema gewähren.

07.01.2025

ABAP Cloud - Programmiermodell

Kategorie - ABAP

Welches Programmiermodell kommt mit ABAP Cloud zum Einsatz und was können wir aus dem Vorgänger lernen? Mehr Details im Artikel.

03.01.2025

RAP - Side Effects

Kategorie - ABAP

Wie kannst du Teile der Fiori UI aktualisieren, ohne einen kompletten Refresh zu machen? Mit Side Effects ist das in ABAP und RAP ganz leicht möglich.

27.12.2024