
RAP - Suchhilfe und Schlüssel optimieren
In diesem Artikel optimieren wir unsere Suchhilfen im Custom Pattern, verwenden das Additional Binding und machen unsere RAP Anwendung fit für den Endanwender.
Inhaltsverzeichnis
In diesem Artikel legen wir unseren Fokus auf die Suchhilfe in unserer Anwendung und optimieren die Eingabe für den Endanwender, um diesen die beste Erfahrung zu geben.
Einleitung
Wir erweitern unser Custom Pattern um Suchhilfen und optimieren die Eingabe für den Endanwender. In den meisten Fällen möchte der eigentliche Fachanwender keine technischen Werte mehr haben. Ihn interessiert nicht, ob dort die Belegart XY verwendet wird oder das Kennzeichen 1. Hinter den technischen Bezeichner liegen dann meist Fachlichkeiten, wie die Belegart für Gutschrift oder das Zahlungskennzeichen für Inland. In diesem Sinne wollen wir die Anwendung heute optimieren und alle technischen Werte vor dem Anwender verstecken.
Vorbereitung
Dazu wollen wir in unserer RAP Anwendung zwei neue Suchhilfen zur Verfügung stellen und zwar für Team und Anwendung. Dazu müssen wir im ersten Schritt eine Grundlage in Form von Tabellen schaffen und diese dann mit Daten versorgen.
Tabelle
Legen wir uns also erste einmal die Tabellen an. Dabei verwenden wir Datenelemente die wir bereits für die Custom Entity Erweiterung verwendet haben. Dazu legen wir zuerst einmal das Team an.
@EndUserText.label : 'Teams'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dcp_team {
key client : abap.clnt not null;
key team : zbs_demo_dcp_team not null;
description : zbs_demo_dcp_text;
}
Im nächsten Schritt legen wir die Anwendung an, wobei eine Anwendung erst einmal einem Team zugeordnet ist. Hier haben wir also eine Beziehung zu den anderen Daten.
@EndUserText.label : 'Application'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zbs_dcp_appl {
key client : abap.clnt not null;
key application : zbs_demo_dcp_appl not null;
team : zbs_demo_dcp_team;
description : zbs_demo_dcp_text;
}
Daten
Im nächsten Schritt befüllen wir die Tabellen mit Daten, die wir dann über unsere Suchhilfe erhalten wollen. In diesem Fall schreiben wir uns eine kleine Klasse, die die Tabellen mit Daten befüllt. In der "echten" Welt könntest du eine Business Configuration zur Verfügung stellen, in der Fachanwender die Daten pflegen und transportieren können oder eine eigene RAP Anwendung mit mehr Funktionen.
CLASS zcl_bs_dcp_data_init DEFINITION
PUBLIC FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_bs_dcp_data_init IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA teams TYPE SORTED TABLE OF zbs_dcp_team WITH UNIQUE KEY team.
DATA applications TYPE SORTED TABLE OF zbs_dcp_appl WITH UNIQUE KEY application.
teams = VALUE #( ( team = 'BASE_DEV' description = 'Central Development' )
( team = 'FI_DEV' description = 'Development Financial' )
( team = 'HR_CUST' description = 'HR Customizing' ) ).
DELETE FROM zbs_dcp_team.
INSERT zbs_dcp_team FROM TABLE @teams.
applications = VALUE #( ( application = 'GENERAL' team = 'BASE_DEV' description = 'General Developments' )
( application = 'REVIEW' team = 'BASE_DEV' description = 'Review Tool' )
( application = 'CALC' team = 'FI_DEV' description = 'Tax Calculation' )
( application = 'ENGINE' team = 'FI_DEV' description = 'Calculation engine' )
( application = 'ACC_DEF' team = 'FI_DEV' description = 'Account definition' ) ).
DELETE FROM zbs_dcp_appl.
INSERT zbs_dcp_appl FROM TABLE @applications.
ENDMETHOD.
ENDCLASS.
Hinweis: Grundsätzlich kannst du UUIDs bei der Anlage verwenden, allerdings kannst du diese später nicht in Berechtigungsobjekte aufnehmen, um den User zu berechtigen. Daher vergeben wir teilweise sprechende technische Kürzel als Schlüssel.
Suchhilfe
Im zweiten Schritt legen wir uns direkt die beiden Suchhilfe Views an und verzichten auf einen Basis-View für die Normalisierung der Felder. Dazu erst einmal den View für das Team in dem wir auch noch ein Suchfeld über beide Spalten anlegen.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'VH for Team'
@Search.searchable: true
define view entity ZBS_I_DCPTeamVH
as select from zbs_dcp_team
{
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 1.0
key team as Team,
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
description as Description
}
Weitere Infos zu den Suchfeldern erhältst du in diesem Artikel. Den zweiten View gestalten wir ähnlich, definieren hier allerdings noch zusätzlich eine Suchhilfe über das Team Feld.
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'VH for Application'
@Search.searchable: true
define view entity ZBS_I_DCPApplicationVH
as select from zbs_dcp_appl
{
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 1.0
key application as Application,
@Consumption.valueHelpDefinition: [{ entity: { name: 'ZBS_I_DCPTeamVH', element : 'Team' } }]
team as Team,
@Search.defaultSearchElement: true
@Search.fuzzinessThreshold: 0.8
description as Description
}
Schlüssel ausblenden
Um den Schlüssel nun ausblenden zu können, benötigen wir drei Dinge. Zuerst einmal muss er Text in der Entität zur Verfügung stehen oder per Assoziation angebunden sein. Als Zweites hinterlegen wir am Schlüssel den dazugehörigen Text und als letzten Schritt bestimmen wir die Anzeige des Schlüsselfeldes.
Text
Dazu legen wir zwei Felder in der Custom Entity an, die den Datentyp aus unseren Tabellen erhalten. Die Felder können am Ende der Custom Entity definiert sein.
@UI.hidden: true
TeamDescription : zbs_demo_dcp_text;
@UI.hidden: true
ApplDescription : zbs_demo_dcp_text;
Dann lesen wir die Daten in unserer Query Implementierung und befüllen die Felder in der Methode GET_REMOTE_DATA. Dazu implementieren wir eine sehr einfache Leseroutine in der Schleife.
SELECT SINGLE FROM ZBS_I_DCPTeamVH
FIELDS Description
WHERE Team = @line->team
INTO @line->TeamDescription.
SELECT SINGLE FROM ZBS_I_DCPApplicationVH
FIELDS Description
WHERE Application = @line->application
INTO @line->ApplDescription.
Hinweis: Grundsätzlich solltest du daran denken, die Felder aus der Selektion auszuschließen, da sonst keine Daten mehr angezeigt werden. Deshalb müssen wir auch die DELETE_FIELDS um die beiden Felder ergänzen.
Annotation
Im letzten Schritt ergänzen wir die Felder noch um die entsprechenden Annotationen. Mit "ObjectModel.text.element" definieren wir den Text am Schlüsselfeld und mit "UI.textArrangement" können wir den Schlüssel mit dem Text anzeigen oder diesen sogar komplett ausblenden. Damit sieht ihn der Anwender nicht mehr, er wird allerdings in unserer Anwendung weiterhin verwendet.
@ObjectModel.text.element: [ 'TeamDescription' ]
@UI.textArrangement: #TEXT_ONLY
team : zbs_demo_dcp_team;
@ObjectModel.text.element: [ 'ApplDescription' ]
@UI.textArrangement: #TEXT_ONLY
application : zbs_demo_dcp_appl;
Die eigentlichen Textfelder können wir mit "UI.hidden" ausblenden, diese müssen wir nicht als zusätzlichen Text anzeigen. Dafür erhalten wir nun sauber formatierte Felder.
Änderung
Wechseln wir allerdings in den Ändern-Modus, dann sieht der User wieder die technischen Inhalte und nicht mehr die lesbaren Werte.
Damit wir auch dieses Verhalten ändern, müssen wir die beiden Suchhilfen an sich anpassen und die gleichen Änderungen durchführen, wie bei der Einbindung mit den Annotationen. Die fertigen Views findest du im GitHub Repository, wenn du dir die Anpassungen im Detail anschauen möchtest, die Listung sparen wir uns für den Moment.
Additional Binding
Wir haben nun eine Suchhilfe, die theoretisch einen Wert der aktuellen Entität verwenden könnte, um die Suchmenge einzuschränken oder der sogar automatisch befüllt werden könnte. In diesem Fall können wir das "Additional Binding" verwenden, damit dieses Feld in der Suchhilfe berücksichtigt wird. Dazu ergänzen wir die Suchhilfe um eine zusätzliche Eigenschaft.
@Consumption.valueHelpDefinition: [ { entity: { name: 'ZBS_I_DCPApplicationVH', element: 'Application' },
additionalBinding: [ { element: 'Team', localElement: 'team', usage: #FILTER } ] } ]
Das zusätzliche Binding verbindet ein Feld in der Suchhilfe mit einem lokalen Element oder einem konstanten Wert. Dabei können wir die Einstellung "USAGE" noch weiter verfeinern und die Funktionsweise an unsere Bedürfnisse anpassen. Das Feld hat die folgenden Eigenschaften:
- #FILTER - Die zusätzlichen Felder werden zu Einschränkung des Suchergebnisses verwendet.
- #RESULT - Die Felder aus der Suche überschreiben auch die anderen Felder in der Entität, wenn ein Suchergebnis gewählt wird.
- #FILTER_AND_RESULT - Eine Kombination aus den beiden Einstellungen zuvor.
In diesem Beispiel verwenden wir die Variante #FILTER, um das Feld in unseren Filter mit zu berücksichtigen und die Werte direkt einzuschränken. Dazu schauen wir uns die verfügbaren Anwendungen an (5), wählen dann ein Produkt und im zweiten Schritt sehen wir nur noch zwei Anwendungen, da der zusätzliche Filter greift.
Semantischer Schlüssel
Als Bonus passen wir noch den semantischen Schlüssel der Anwendung an, sodass die Navigation auf technischer Ebene weiterhin funktioniert, der Anwender aber nur noch die Beschreibung in der Anwendung sieht. Hierbei handelt es sich aber um ein Beispiel, da die Anwendung wahrscheinlich eher durch den Entwickler bedient wird und er den Namen der Software Komponente für die Arbeit benötigt. Dafür haben wir den semantischen Schlüssel für die Navigation:
@ObjectModel.semanticKey: [ 'staging', 'sc_name' ]
Wenn wir an unserem Schlüsselfeld nun ebenfalls das Textfeld definieren und den Text ausblenden, können wir somit das Aussehen beeinflussen.
@UI.textArrangement: #TEXT_ONLY
@ObjectModel.text.element: [ 'descr' ]
key sc_name : abap.char(18);
@UI.hidden: true
descr : abap.char(60);
In der Anwendung würde sich nun das folgende Ergebnis ergeben. Der technische Schlüssel ist nicht mehr sichtbar und die Beschreibung ist wie der Schlüssel Fett hervorgehoben und besser ersichtlich.
Vollständiges Beispiel
Wie immer findest du alle Anpassungen an der Anwendung in unserem GitHub Repository zum Thema RAP. Über den Commit kannst du die gemachten Änderungen nachvollziehen und bekommst so einen einfachen Überblick über das Thema.
Fazit
Mit einigen wenigen Annotationen können wir die Suchhilfen und die UI verbessern und so dem Anwender die Arbeit mit unserer Anwendung vereinfachen. Mit den heutigen Tipps sollte die nächste Anwendung um einiges besser werden.