In den nächsten 3:30 Minuten werden wir einen neuen Report für den Rapid Report Generator anlegen. Mit Filter. – Wir werden uns die wirklich notwendigen Schritte und Einstellungen ansehen.
Die Rapid Report Administration wird mit der Transaktion /CADAXO/UI38_ADMIN aufgerufen. Das ist zugleich auch die einzige Transaktion, die man sich merken sollte – alle anderen Einstellungen erreicht man über diese zentrale Stelle. Für die Interessierten unter uns – UI38 ist unser interner Projektname. In Anlehnung an SE38 bzw. TM38.
00:10 – Anlegen eines neuen Reports
Aktuell können bereits Reports mit 4 verschiedenen Datenquellen angelegt werden: SELECT, STDALV, SAPQUERY und ABPACLASS. In unserem Beispiel legen wir einen SELECT Report auf die berühmt (berüchtigte) SFLIGHT an:
1
Anlegen eines neuen Reports über das KontextmenüReports oder über den Button Report.
2
Als Reportname wählen wir hier Z_DEMO_SFLIGHT und als Report Type selektieren wir SELECT.
3
Im Detailscreen des neuen Reports müssen zumindest die GOLD markierten Einstellungen vorgenommen werden.
3.1
Die Ergebnisstruktur in Result Structure kann (muss aber nicht) gleich wie die Struktur in Data Type sein. Die Übertragung erfolgt via CORRESPONDING (=Namensgleiche Felder). Nur aktive Reports können in der Fiori App verwendet werden.
3.2
Die Ergebnislisten können in 3 verschiedenen Ausgabeformen dargestellt werden (Responsive, Grid, Analytical). Wir wählen RESPONSIVE, da diese auf allen Devices optimal gerendert wird.
3.3
Reportname vergeben – Jeder Report benötigt einen Titel. Titel können natürlich auch mehrsprachig gepflegt werden.
3.4
Wichtig – Sichern nicht vergessen
01:00 – Test des Reports im RRG-Launchpad
Sofern man als Anwender genügend Berechtigungen besitzt, sollte der neue Report bereits im RRG-Launchpad zur Verfügung stehen. Mit F5 machen wir einen Refresh im Browser.
Wir können den Report bereits auswählen und sogar starten.
Nicht schlecht. Gerade einmal eine Minute und wir haben schon einen RRG Report im Launchpad. Jetzt wollen wir noch ein paar wichtige Ergänzungen vornehmen.
01:30 – Filterbare Felder definieren
Mit Hilfe der Feldeinstellungen können viele verschiedene Anpassungen für den Report und speziell für die Ergebnisliste vorgenommen werden. An dieser Stelle beschränken wir uns auf ein paar filterrelevante Einstellungen. Zwei Felder sollen filterbar werden.
1
Feld CARRID 1.Filterable aktivieren 2.Mandatory aktivieren 3. Filter Position auf 1
2
Feld CONNID 1.Filterable aktivieren 2.Filter Position auf 2 3.Filter Exclude aktivieren
3
Sichern nicht vergessen
Durch diese Einstellungen sollten für die Felder Airline (CARRID) und Flight Number (CONNID) nun ein Filter zur Verfügung stehen. Airline ist wie gewünscht ein Pflichtfeld und Flight Number ist initial ausgeblendet, kann aber zur Laufzeit durch den Anwender eingeblendet werden. Mal sehen ob das Ergebnis passt, also zurück in den RRG Report. Refresh mit F5 nicht vergessen.
02:30 – Test der Filter im RRG-Launchpad
Oha – siehe da, es kann schon nach Airline gefiltert werden. Und wie eingestellt ist es ein Pflichtfeld. Zum Test geben wir AA (American Airlines) ein und starten den Report mit Start bzw. Go – falls der Report in Englisch aufgerufen wurde.
Perfekt! Der initial ausgeblendet Filter für die Flight Number kann über Filter anpassen bzw. Adapt Filter eingeblendet und verwendet werden.
03:00 – Zurücklehnen und staunen
Es sind jetzt ca. 3:00 Minuten vergangen und wir haben einen fix fertigen Report welcher ungeschaut produktiv gesetzt werden kann. Anstatt der SFLIGHT kann hier jede beliebige Tabelle, DB View, CDS View oder AMDP Tablefunktion verwendet werden.
03:30 – Zusätzliche Einstellungsmöglichkeiten
Das Grundgerüst ist geschafft. Jetzt kann der Report durch die verschiedensten Einstellungsmöglichkeiten an die gewünschten Bedürfnisse angepasst werden:
Vielen Dank für Ihre Teilnahme an unserem Webinar!
Wir sind ja mit Selbstlob sehr zurückhaltend – aber die Erklärung von Domi zu Table Expressions & Table Functions zählt mit zu den besten Erklärungen die ich bisher zu dem Thema gesehen habe!
Natürlich sind auch Sörens Erklärungen zu Field Symbols bzw. Reference hervorzuheben und mein Part zu CORRESPONDING ist bis auf ein paar Versprecher auch ganz gut.
Unterlagen/Links zum Webinar „Modernize your ABAP“
Präsentationsunterlagen in PDF – Diesmal gab es keine Slides
Ein SAP-System besteht traditionell aus einer sehr, sehr großen Anzahl von SAPGui basierten Reports. Die Bandbreite reicht hier von einfachen List-Reports bis hin zu komplexen interaktiven Reports, quer über alle SAP-Module hinweg. Diese Reports sind entweder durch die SAP zur Verfügung gestellt oder wurden durch SAP-Kunden ergänzt.
Es gibt mehrere Ideen und Möglichkeiten diese traditionellen Reports im SAP Fiori Launchpad zu verwenden. In diesem Blog zeige ich, wie wir das mit Hilfe einer SAP-Transaktion via SAPGui for HTML realisieren können.
Ich beschränke mich hier auf die notwendigen Schritte und Einstellungen. Gute Beschreibungstexte, schöne Icons und auch spezielle Launchpad/Rollen Einstellungen überlasse ich eurer Fantasie.
In diesem Bespiel wollen wir den Demo Report BCALV_FULLSCREEN_DEMO im Launchpad anzeigen, daher verwende ich fast durchwegs auch diesen Namen in IDs oder sonstigen Bezeichnungen. So sieht der Report im SAP Gui aus:
Anlage Transaktionscode
Wenn noch nicht vorhanden, legen wir zuerst einmal einen Transaktionscode für den Report an:
Anlage semantisches Objekt
Für das spätere Mapping im Fiori Catalog verwenden wir ein semantisches Objekt. Die Anlage solcher semantischen Objekte erfolgt mit der Transaktion /UI2/SEMOBJ.
Das semantische Objekt sollte mit Z oder Y beginnen, die restlichen Angaben können frei gewählt werden.
Anlage des neuen Fiori Katalogs
Ich verzichte in dieser Demo auf die Erstellung einer Fiori Gruppe da dies für das Beispiel nicht notwendig oder hilfreich ist. Aber wir benötigen zumindest einen Katalog. Es kann natürlich auch ein bestehender Katalog verwendet werden.
Falls jemand fragt, ob diese umständliche Anwendung tatsächlich das zentrale Tool für diese Definitionen ist – ja, leider!
Im Launchpad Customizing erstellen wir nun in der Katalogübersicht einen neuen Katalog:
Anlegen Target Mapping
Für die zuvor angelegte Transaktion legen wir nun das Targetmapping an. Wir verknüpfen hier nun die Transaktion mit dem semantischen Objekt. Folgende Angaben sind zu machen:
– Semantic Object: Z_BCALV_FULLSCREEN_DEMO
– Action: display (z.B. es kann auch eine andere Action gewählt werden)
– Application Type: Transaction
– Transaction: Z_BCALV_FULLS_DEMO
Anlegen Tile
Jetzt folgt der letzte Schritt im Launchpad Customizing. Die Anlage eines Tiles mit der Verknüpfung zum semantischen Objekt. Notwendige Angaben sind:
– Title: sinnvoller Name
– Use semantic object navgation: true
– Semantic Object: Z_BCALV_FULLSCREEN_DEMO
– Action: display (bzw. die gewählte action)
Rollenpflege (PFCG)
Der Katalog muss einer Rolle und die Rolle dem User zugeordnet werden. Diese Einstellungen sind auch nicht Ziel dieses Blogs. Der Part wird normalerweise durch einen Basis- bzw. Berechtigungsadministrator vorgenommen werden. In wenigen Worten:
Anlage/Pflege Rolle
Anlage Transaction SAP Fiori Tile Catalog
Catalog wählen
User zuordnen. Ggf. Gruppe zuordnen.
Report aufrufen
Wenn der Report nur via Katalog dem User zugeordnet wurde, sollte dieser über den App Finder auffindbar sein. Wenn auch eine Gruppe verwendet wurde, sollte der Report beim User bereits beim Einstieg ins Launchpad sichtbar sein.
Report Ergebnigs im Launchpad
Wenn alles korrekt vorgenommen wurde, sollte der Report nun erfolgreich gestartet werden können und das Ergebnis sollte wie folgt aussehen:
Fazit
Eine SAP-Transaktion und somit auch ein Report kann relativ einfach ins SAP Fiori Launchpad eingebunden werden. Der Aufwand ist überschaubar und das Ergebnis kann sich sehen lassen.
Natürlich unterliegt diese Lösung einigen Einschränkungen, die bedacht werden sollten:
– Darstellung in neuem Browser Tab, keine „saubere“ Integration im Launchpad
– Kein Fiori Design
– Key User Extensibility wird nicht unterstützt
– Nicht Responsive – Nicht optimierte Darstellung für Tablets oder Mobile Phones
Alternative – Rapid Report Generator
Wir haben mit dem Rapid Report Generator ein Tool entwickelt, welches bei der Integration von klassischen SAP Reports im SAP Fiori Launchpad bzw. im SAP Fiori Design behilflich ist. Der Rapid Report Generator verwendet ebenfalls den Original Report, rendert die Inhalte jedoch via SAP Fiori Smart Controls zu 100% im SAP Fiori Design und bietet alle SAP Fiori Vorteile.
In diesem Blogbeitrag beschreibe ich, wie man eine SE11 Standard Suchhilfe in eine SAP Fiori Elements Anwendung auf Basis von Custom Entitys einbinden kann. SE11 Suchhilfen gibt es schon ewig und sind aus einem SAP-System nicht wegzudenken. In einem aktuellen S/4 System sind nach wie vor über 30.000 SE11 Suchhilfen vorhanden. Zudem wurden im Laufe der Jahre durch die SAP-Kunden viele Suchhilfen dazu entwickelt. Und daher macht es durchaus Sinn, diese auch in SAP Fiori Elements oder UI5 Anwendungen zu verwenden.
Zum Zeitpunkt dieses Blogs ist mir keine Möglichkeit im SAP Standard bekannt (abgesehen vom Ansatz mit dem SAP Gateway), die SE11 Original-Suchhilfen einfach und schnell in vorhandene SAP Fiori Elements Anwendungen zu integrieren. Aber ehrlich gesagt rechne ich damit, dass dies irgendwann in Zukunft durch spezielle Annotations möglich sein wird. Sollte sich daran was ändern, werde ich diesen Blog natürlich erweitern. Aber bis es so weit ist, müssen wir uns mit ein paar Workarounds helfen.
Prinzipiell müssen wir einmal Sammelsuchhilfen und elementare Suchhilfen unterschieden. Sammelsuchhilfen bestehen aus einer oder mehreren elementaren Suchhilfen. Der hier gezeigte Ansatz verfolgt nur die Integration von elementaren Suchhilfen. Aber natürlich können einzelne Suchhilfen wieder über Annotations zu Sammelsuchhilfen zusammengefügt werden. An dieser Stelle verweise ich auf den Blog Fiori Element: Collective / Multiple value help on selection field von Mohit Bansal. Er zeigt in seinem Blog, wie man mehrere CDS Views als Suchhilfen einbinden kann.
Elementare Suchhilfen welche als Selektionsmethode eine Datenbanktabelle oder einen DB-View verwenden und keinen speziellen Suchhilfe-Exit implementiert haben, können auch mit Hilfe eines klassischen CDS View nachgebildet werden. Dann erspart man sich die zusätzliche ABAP Implementierung. Eine gute Beschreibung dazu findet man in in diesem Blog Fiori Elements-Value help on a selection field within a value help dialog ebenfalls von Mohit Bansal.
Elementare Suchhilfen verwenden jedoch sehr oft Suchhilfe-Exits, dann reicht der Ansatz über klassische CDS Views nicht aus. Mit Hilfe der Custom Entitys können wir unser Vorhaben umsetzen. In dem nachfolgenden Beispiel wird die Suchilfe BUPAP des SAP Business Partners verwendet. Die Suchhilfe besteht lediglich aus einem Suchhilfe Exit.
Step 1 – ABAP Klasse
Zuerst brauchen wir eine ABAP Klasse, welche dann später in der Custom Entity verwendet wird. Die ABAP Klasse muss das Interface if_rap_query_provider implementieren.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CLASSzcl_cq_value_help_bupap DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLICSECTION.
INTERFACES if_rap_query_provider.
PROTECTEDSECTION.
PRIVATESECTION.
ENDCLASS.
CLASSzcl_cq_value_help_bupap IMPLEMENTATION.
METHOD if_rap_query_provider~select.
ENDMETHOD.
ENDCLASS.
Step 2 – Custom Entity
Nun legen wir noch die Custom Entity ZCE_VALUE_HELP_BUPAP an.
1
2
3
4
5
6
7
8
9
10
11
@EndUserText.label:'Value Help for BUPAP'
@ObjectModel:{
query:{
implementedBy:'ABAP:zcl_cq_value_help_bupap'
}
}
definerootcustomentityzce_value_help_bupap
{
}
Mit der Annotation ObjectModel.Query.implementedBy wird die zuvor angelegte ABAP Klasse hinterlegt. Nun müssen wir noch auf Basis der Parameter der Suchhilfe, die Custom Entity aufbauen. Die SE11 Suchhilfe sieht wie folgt aus:
Exakt diesen Aufbau bilden wir nun auch in der Custom Entity ab.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@EndUserText.label:'Value Help for BUPAP'
@ObjectModel:{
query:{
implementedBy:'ABAP:zcl_cq_value_help_bupap'
}
}
definerootcustomentityzce_value_help_bupap
{
key partner:bu_partner;
mc_name1:bu_mcname1;
mc_name2:bu_mcname2;
bu_sort1:bu_sort1;
bu_sort2:bu_sort2;
type:bu_type;
valdt:bu_valdt_s;
}
Eine Custom Entity benötigt zwingend ein KEY-Feld. In dem Fall verwenden wir natürlich PARTNER welches auch der Value ist, welcher durch die Suchhilfe zurückgeliefert wird.
Step 3 – Implementierung der Query-Methode
Jetzt wird es spannend, wir implementieren die Suche in der ABAP Query Methode. Glücklicherweise gibt es die Klasse cl_dsh_type_ahead_processor, die uns hier enorm weiterhilft und vieles abnimmt. Mit Hilfe der Klasse prozessieren wir die Suchhilfe.
Dieser Schritt ist jetzt nicht zwingend notwendig. Hier geht es nur darum, dass wir die neue Custom Entity testen wollen.
Service Definition
1
2
3
4
@EndUserText.label:'SD für Value Help BUPAP'
defineserviceZSD_VALUE_HELP_BUPAP{
expose zce_value_help_bupap;
}
Service Bindung
Sobald die Service Bindung angelegt ist, können wir die Custom Entity und die Implementierung der Suche mit der Preview-Funktion testen.
Die Filter- und Result-Felder müssen vorerst noch manuell ausgewählt werden, aber dann sollte bereits ein Ergebnis sichtbar sein.
Wenn alles korrekt implementiert wurde, sollten auch die Filter und die Sortierung funktionieren.
Step 5 – Verwendung der Custom Entity in einem CDS View
Jetzt verknüpfen wir die neue Custom Entity Value Help mit einer bestehenden SAP Fiori Elements Anwendung. Angenommen wir haben eine auf RAP basierende Anwendung zur Darstellung von Business Partner.
Folgende Annotation ist nun beim Feld mit der Partnernummer anzugeben.
Danach sollte bei der Anwendung für das Feld PartnerID folgende Suchhilfe zur Verfügung stehen.
Fazit
Es ist vielleicht keine perfekte Lösung, wie gesagt, ich warte auf eine Lösung im SAP Standard. Aber mit Hilfe der Custom Entitys kann man SE11 Suchhilfen einfach und rasch in Fiori Elements oder UI5 Smart Controls verwenden.
Um einem Anwender eine nahtlose Integration zwischen verschiedenen Fiori Anwendungen im Launchpad zu bieten, ist eine App to App Navigation zwischen den Fiori Anwendungen sehr wichtig. Wie ihr gleich sehen werdet, ist das bei neu erstellten UI5 Fiori Anwendungen oder mit Hilfe von CDS gar nicht so schwierig.
Semantisches Objekt, Aktion und Parameter
Ein semantisches Objekt ist in der Regel ein Business Objekt wie z.B. BusinessPartner oder PurchaseOrder. Die Action ist das, was man mit dem Objekt machen kann. Z.B. Approve, Change oder Change. Optional könne Parameter angegeben werden welche eine Objektinstanz (Partner ID oder Product-ID) spezifizieren. Je nach Anwendung wird dann direkt die gewünschte Objektinstanz aufgemacht. Soweit die notwendige Theorie.
UI5 – Service CrossApplicationNavigation
Grundsätzlich wird dafür das Service CrossApplicationNavigation verwendet. Einen Zugriff auf das Service bekommt man wie folgt:
UI5 – Direkte Navigation mit semantischem Objekt, Aktion und Parameter
Mit der Methode toExternal wird die Navigation direkt ausgelöst. In target sind das semantische Objekt und optional die Aktion anzugeben. Und in params kann man ebenfalls optional eine Objektinstanz angeben.
Im Nachfolgenden Beispiel wird das semantische Objekt EPMPurchaseOrder mit der Aktion approve und dem optionalen Parameter PurchaseOrder = 300001993 verwendet.
Wenn zu einem semantischen Objekt mehrere Anwendungen definiert sind und keine Aktion mitgegeben wurde, bekommt der Anwender ein Popup mit einer Auswahlmöglichkeit der Target-Anwendungen.
Nachfolgendes Beispiel zeigt, wie man zur Launchpad Startpage navigiert.
1
2
3
this.oCrossAppNav.toExternal({
target:{shellHash:"#"}
});
UI5 – Erzeugung Link ohne direkte Navigation
Es kann auch die Methode hrefForExternal verwendet werden. Prinzipiell hat die Methode die gleichen Eigenschaften wie toExternal – jedoch wird nicht direkt in die Anwendung navigiert. Stattdessen erhält man einen generierten Link.
Eine App to App Navigation kann auch durch CDS Annotation @Consumption.semanticObject definiert werden. Dadurch wird dann in Fiori Elements Anwendungen oder in UI5 Anwendungen welche Smart Controls einsetzen automatisch die App to App Navigation angeboten.
Vielen Dank für Ihre Teilnahme an unserem Webinar!
Das spannende Thema RAP wird uns alle noch viele Jahre beschäftigen. In unseren nächsten Webinaren werden wir uns erst einmal wieder anderen ABAP Themen beschäftigen. Wir sind noch nicht sicher, ob unser nächstes Webinare im November stattfinden wird. Unsere ganze Aufmerksamkeit gilt nämlich nun der ABAPConf welche am 9. Dezember 2021 über die Bühne gehen wird. Ein Tag an dem sich alles um ABAP dreht! Einfach hier auf Eventbrite registrieren, damit ihr in der Sache am Laufenden bleibt! Für das Event selber ist keine Registrierung notwendig.
Unterlagen/Links zum Webinar „ABAP RESTful Application Programming Model (RAP) – 3. Teil“
Findet vielleicht im noch im November oder erst im nächsten Jahr statt. Aber dafür gibt es mit der ABAPconf einen perfekten Ersatz! Wir würden uns freuen, wenn wir Euch bei der ABAPConf wieder sehen würden.
Vielen Dank für Ihre Teilnahme an unserem Webinar!
Wie angekündigt, werden wir uns auch im nächsten Webinar mit RAP beschäftigen. Dann etwas mehr im Detail. – Anmeldelink befindet sich ganz unten in diesem Blog.
Unterlagen/Links zum Webinar „ABAP RESTful Application Programming Model (RAP)“
Frage: Ist das ABAP RESTful Programming Model, zu dem es ja auch Literatur von SAP Press gibt, das selbe wie RAP?
Antwort: Ja genau RAP = RESTful Applicatino Programming Model
Frage: Wie kann ich verhindern, dass bei Projections auf einen Root-View, die Compositionen verlorenen gehen?
Antwort: Bei der Projection muss man die Composition umbiegen auf die Projection des „Kindes“
Frage: OData V4 geht auf onPrem mit 2020 SPS01.
Antwort: Jop!
Frage: Die neuen, nicht mehr DDIC basierten, View-Entities kann man leider nicht mit den SE16* Transaktionen auswerten. Wisst ihr da einen Workaround? Ist gerade für Troubleshooting auf Nicht-Entwicklungssystemen und Mandanten immer ganz praktisch, da man dort oft keinen ADT Zugriff hat. Zudem ist es für Nicht-Entwickler auch nützlich im die Views, bzw. die Daten zu validieren.
Frage: Welche Eclipse Version habt Ihr im Einsatz?
Antwort: Eclipse 2020-12 mit ABAP 3.16 -> immer the Latest and greatest! – Ergänzung Föß: Ich aktualisiere Eclipse immer alle 3 Monate, sobald eine neue Version rauskommt. ADT Update checke und update ich ggf. täglich.
Frage: Was ist der unterschied von define root view und definde root view entity?
Antwort: ROOT VIEW ist noch DDIC basiert (DDIC View)
Frage: Gibt es hier ein Thema Locking auf den DB-Tabellen?
Antwort: Locking geht natürlich auch: Sperrobjekte, Optimistisches Locking im eTag (das kommt beim nächsten Mal ganz sicher), Draft
Frage: Domi hat das managed Szenario oder?
Antwort: Domi verwendet das Managed Szenario, aber dem EML ist es egal was drunter läuft – ob managed oder un-managed
Frage: Starkes Webinar. Vielen Dank für den Vortrag. Macht das ganze viel sympatischer wenn es live (coding) durchgeführt wird!
Antwort: Danke dir!
Frage: Danke. Wollte nur wissen, ob man die neueste Version nutzen kann, nicht das es Probleme gibt.
Antwort: Immer die neueste von ADT und Eclipse – man sollte aber 1 bis 2 Wochen warten mit dem Eclipse update, bis auch die SAP 100%ig nachgezogen hat 🙂
Frage: Eine Verständnisfrage, in den Beispielen der SAP sieht man immer die Implementierung auf Basis „selbst“ erstellter Tabellen. Aber wie funktioniert das ganze Model, wenn ich auf APIs (OneOrder, BP usw) zugreifen muss. Ich will ja nicht unbedingt Daten lesen und schreiben mit direktem Tabellen Zugriff.
Antwort: Dieses Thema versuchen wir beim nächsten oder übernächsten Webinar aufzugreifen.
CDS View Entities / CDS Root View Entities
Wir haben im Webinar immer mit CDS ROOT VIEW ENTITIES gearbeitet. CDS View Entites sind ab aber erst ABAP 7.55 verfügbar und es handelt sich dabei um eine verbesserte / erweiterte Möglichkeit der CDS DDIC-based Views. CDS View Entities sind sozusagen der Nachfolger der CDS DDIC-based Views.
Unterschiede:
Keine zusätzlicher DB View notwendig (@AbapCatalog.sqlViewName … ) – daher aber auch kein SE16 …
Schnellere Aktivierung
Vereinfachte Syntax
Verbesserter / strikterer Syntaxcheck um potentielle Fehler bereits bei der Aktivierung zu erkennen
Wenn man Anwendungen mit Fiori Elements erstellt, wird man sehr bald mit der Aufgabenstellung konfrontiert, zusätzliche Buttons zu ergänzen. Dies ist mit gewissen Einschränkungen allein durch Erweiterungen im ABAP Backend möglich.
In diesem Beispiel zeige ich, wie man die Buttons in einem List Report mit einer ABAP RESTful Implementierung verwenden kann. Eine Verwendung mit BOPF ist sehr ähnlich und Buttons können auch an anderer Stelle ergänzt werden. Vielleicht schreib ich dazu noch extra einen Blog.
Ich hab dieses Demo auf einem ABAP 1909 Trial und UI5 1.71 System umgesetzt. Es handelt sich um ein unmanaged Szenario, sollte aber ohne großartige Anpassungen auch mit einem managed Szenario funktioineren.
Ausgangssituation
Ich verwende immer sehr vereinfachte, reduzierte Beispiele. Umfangreiches oder schwer nachvollziehbares Coding soll nicht vom eigentlichen Thema ablenken. Obwohl ich ein großer Anhänger von Clean Code und Modern ABAP bin, versuche ich trotzdem in solchen Beispielen so einfach wie möglich zu arbeiten. Wir haben hier jedenfalls eine Liste von internen Bestellungen und deren Status. Im Detail besteht die Anwendung aus folgenden Objekten. Wenn man eine Anwendung halbwegs sauber aufsetzt, hat man leider so viele Entwicklungsobjekte.
ZFOE_DB_ORDER – Order Datenbanktabelle
ZFOE_I_ORDER – Order Interface View
ZFOE_P_ORDER – Order Projection View
ZFOE_P_ORDER – Metadata Extension für Projection View
Hier bitte darauf achten, dass die Annotation @Metadata.allowExtensions auf true ist. Dies ist notwendig, um eine Metadata Extension anzulegen.
Metadata Extension: ZFOE_P_ORDER (UI Annotations)
Die Metadata Extension wird verwendet um die UI Annotations besser strukturieren und von den anderen DDLs besser trennen zu können. In dem Beispiel hätten wir die Annotations natürlich auch direkt im Projection View aufnehmen können. Beim Layer ist hier #CORE anzugeben. Die Ausgabeposition der 4 Felder wird hier mit den Annotations @UI.lineItem.position angegeben.
Behavior Definition für ZFOE_I_ORDER
Wir wollen später im Demo lediglich ein update ermöglichen. Daher ist hier update aktiviert. Alles andere kann derzeit deaktiviert bleiben.
Behavior Klasse ZBP_FOE_I_ORDER
In aktuellen Systemen kann die Klasse einfach über Quick Fix angelegt werden. In älteren Systemen kann das ggf. auch manuell erfolgen.
Behavior Definition für ZFOE_P_ORDER
Service Definition ZFOE_SD_ORDER
Service Bindung ZFOE_SB_ORDER
Und hier noch eine Implementierung um 3 Testdaten in die Tabelle zu schreiben. Das geht super einfach mit dem Interface IF_OO_ADT_CLASSRUN welche in irgendeiner Helperklasse implementiert sein sollte.
So viel zu der Ausgangssituation. Wenn man die Fiori Elements Anwendung nun mit Preview startet, sollte in etwa folgende Liste dargestellt werden:
Button ergänzen
Nun wollen wir uns der eigentlichen Aufgabenstellung widmen und zwei Buttons (Ist die Mehrzahl von Button überhaupt Buttons?) ergänzen. Ein Button soll die Order genehmigen, der zweite Button soll die Order ablehnen. So eine Art Miniworkflow.
Behavior Definitionen & Implementation
Als Erstes müssen wir mal in den Behavior Definitionen von ZFOE_I_ORDER und ZFOE_P_ORDER die beiden neuen Button als Action aufnehmen. Ich hab mich für die Namen but_accept und but_decline entschieden.
In der Behavior Definition ZFOE_I_ORDER geht das ganz einfach durch action gefolgt von einem eindeutigen Namen. In der Behavior Definition von ZFOE_P_ORDER reicht die Angabe von use und dem Namen der Action.
Natürlich brauchen wir auch später auch eine Methode in unserer Klasse. Über einen Quick Fix auf die action im Interface View kann diese automatisch angelegt werden. Vorerst lassen wir aber die Methoden einfach leer.
Damit die neuen Buttons auch im Userinterface angezeigt werden, müssen wir zwei Annotations in der Metadata Extension ZFOE_P_ORDER ergänzen. Dies ist durch eine Erweiterung der lineItem Annotation möglich. Mit type: #FOR_ACTION defineren wir dass es sich um eine Action handelt und in dataAction ist die zuvor angelegt Action anzugeben. Damit wir auch einen Text am Button sehen, sollten wir ein label angeben.
Wenn wir uns jetzt die Fiori Anwendung nochmals aktualisieren, sollten die beiden Buttons bereits vorhanden sein:
Wau – das ging ja schnell. Jetzt passiert aber noch nichts wenn man einen der Button klickt. Dafür brauchen wir noch eine Implementierung in den beiden Action-Methoden. Nachfolgendes Coding macht die Änderungen auf der Datenbank. Hinweis: Bitte Verbesserungen am Coding selber machen, für die Demo Zwecke ist die Implementierung vollkommen ausreichend.
Ein neuerlicher Test der Anwendung zeigt uns, dass das Setzen der Statusinformationen bereits funktioniert.
Die Lösung ist bis hierhin schon richtig gut, aber es geht natürlich noch etwas besser. Beispielsweise sollen die beiden Button nur aktiv sein, wenn der Status New ist. Ein bereits gesetzter Status soll nicht mehr verändert werden können.
Button dynamisch aktiv oder inaktiv
Mit den so genannten Instance Features können wir einen Button dynamisch aktiv bzw. inaktiv setzen. Um dies zu erreichen, müssen wir zuerst einmal die Behavior Definition des Interfaces Views etwas anpassen. Der Zusatz ( features: instance ) muss nach action ergänzt werden.
Über die Quick Fix Funktion auf ZFOE_I_ORDER wird auch gleich die neue Methode GET_INSTANCE_FEATURES angelegt. Im nachfolgenden Beispiel lesen wir zuerst mit EML die Entity und setzen in der Export Tabelle den Button auf aktiv oder inaktiv.
Da wir oben mit EML die Entity lesen, sollten wir auch die read Methode implementieren.
Ein erneuter Test sollte nun zeigen, dass die Buttons nur bei Zeilen mit Status „New“ aktiv sind:
Wer es bis hier geschafft hat: Respekt! Ihr habt Euch nun einen Kaffee oder ein Bier verdient.
Button mit Popup
Die zwei Buttons sind ja eigentlich fertig, aber wie wäre es, wenn der Anwender zusätzlich einen Kommentar ergänzen könnte. Geht das einfach? Ja, auch das kann mit Fiori Elements umgesetzt werden.
Zuerst müssen wir eine abstrakte Entität definieren. Die gewünschten Attribute im Popup sind als Felder der Entität anzugeben. Nähere Informationen zu abstract entities bitte bei Bedarf selber nachlesen.
Diese abstrakte Entität müssen wir nun noch in der action der Behavior Definition des Interface Views eintragen. Mit dem prefix parameter.
Der eingegeben Kommentar soll natürlich auch irgendwie verarbeitet werden. Dafür ist die Implementierung der Action but_decline zu erweitern. Der eingegebene Kommentar befindet sich in der Inbound Struktur keys, Substruktur %param
Jetzt noch ein kurzes Stoßgebet und mit etwas Glück funktioniert alles wie gewünscht. Bei Decline erscheint nun ein Popup und die dort eingegeben Message wird zusätzlich zum Status geändert.
Was (noch) nicht möglich ist und was ich vermisse
Alles nur aus Sicht, dass ich keine Anpassung im Frontend (UI5) machen will. Durch individuelle Erweiterungen am Frontend ist natürlich vieles möglicht.
Farben und Icons
Leider können keine Icons oder Farben (Criticality) verwendet werden. Soweit ich gesehen habe ändert sich dies auch in der aktuellsten UI5 Version nicht. Manchmal sind Icons oder Farben einfach hilfreich um wichtige von weniger wichtigen Buttons zu unterscheiden. Ich hoffe, dass SAP dies bald via Annotations ermöglicht.
Es gibt aber die Möglichkeit Emojis oder ASCII-Codes zu verwenden. Damit bekommt man schon Symbole rein. – Im Sinne des Fiori Designs wäre es aber natürlich wichtig die SAP Standard Icons zu untersützten.
Beispiel mit Emojis
Multiline
Action Popups für Multiline List-Reports funktionieren erst ab UI5 1.76. Aufpassen beim Testen. Wenn man z.B. über Visual Studio Code testet, wird meist die aktuellste UI5 Version verwendet. Die Preview Funktion via ADT erzeugt nur eine Anwendung mit Single-Line-Selektion. Bitte immer vorab prüfen, nicht dass dann beim Deployen ins Backend das große Erwachen kommt.
Bisher wurden für Zeitstempel-Felder die Datenelemente TIMESTAMP und TIMESTAMPL verwendet. Hinter diesen Datenelementen verbergen sich gewöhnliche ABAP Typen. Mit 7.54 enthält ABAP nun den eingebauten ABAP-Typ utclong. Ein auf 100 Nanosekunden genauer UTC Zeitstempel.
Es sind Werte von 0001-01-01T00:00:00,0000000 bis 9999-12-31T23:59:59,9999999 möglich. Die interne Darstellung der gültigen Werte ist 1 – 3.155.380.704.000.000.000, was uns aber eher nicht interessieren sollte.
ABAP Zeitstempelfunktionen
Damit wir diese neuen Zeitstempelfelder sinnvoll verwenden können, hat SAP zum Glück auch ein paar neue Funktionen zur Verfügung gestellt:
utclong_current( ) erzeugt einen aktuellen Zeitstempel
utclong_add( … ) addiert Tage, Stunden, Minuten oder Sekunden zu einem Zeitstempel
utclong_diff( … ) berechnet die Differenz von zwei Zeitstempel
ABAP SQL Zeitstempelfunktionen ab 7.55
Auch bei ABAP SQL SELECT Abfragen können die utclong Zeitstempel verwendet werden. Folgende SQL Funktionen stehen zusätzlich zur Verfügung:
utcl_current( ) erzeugt einen aktuellen Zeitstempel
utcl_add_seconds( … ) addiert x Sekunden zu einem Zeitstempel
utcl_seconds_between( … ) berechnet die Differenz von zwei Zeitstempel in Sekunden
ABAP Zeitstempelkonvertierungsfunktionen ab 7.55
Für die Konvertierungen zwischen einem ABAP Dictionary Type TIMESTAMPL und den neuen utclong Zeitstempel, wurden folgende Funktionen zur Verfügung gestellt:
tstmpl_to_utcl( … ) konvertiert einen ABAP Dictionary Type TIMESTAMPL in einen utclong Zeitstempel
tstmpl_from_utcl( … ) konvertiert einen utclong Zeitstempel in einen ABAP Dictionary Type TIMESTAMPL
Systemklasse CL_ABAP_UTCLONG
Diese Systemklasse bietet ein paar weitere hilfreiche Funktionen und Konstanten. In den Konstanten CL_ABAP_UTCLONG=>MIN und CL_ABAP_UTCLONG=>MAX sind die jeweiligen Minimal und Maximalwerte für ein utclong Feld definiert.
Die Klasse verfügt über folgende Methoden:
diff ermittelt die Differenz von zwei Zeitstempel – ähnlich wie Funktion utclong_diff
read_iso_format Konvertiert einen ISO 8601 Zeitstempel in einen utclong Zeitstempel
write_iso_format_with_offset Konvertiert einen utclong Zeitstempel in einen ISO 8601 Zeitstempel
from_system_timestamp Konveriert ein Datum und Uhrzeit in einen utclong Zeitstempel
to_system_timestamp Konvertiert einen utclong Zeitstempel in ein Datum und Uhrzeit
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Dauer
Beschreibung
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.