
ABAP Tools - IDE Actions (Wertehilfe)
Schauen wir uns einmal im Detail an, wie wir eine Wertehilfe für unsere Eingabe für unsere IDE Action in ADT erstellen können. Dabei schauen wir uns mehrere Möglichkeiten und Abhängigkeiten an.
Inhaltsverzeichnis
In diesem Artikel beschäftigen wir uns mit Wertehilfen im Kontext von IDE Actions und werden neben dem Standard, auch eigene Wertehilfen implementieren.
Einleitung
Neben der eigentlichen Eingabe von Werten für unsere IDE Action, ist es auch wichtig, dass wir dem Entwickler die Möglichkeit geben, aus verschiedenen Werten zu wählen, wenn wir eine Eingrenzung vorsehen. Beim letzten Mal hatten wir uns die Dropdown und das ENUM angeschaut, hier stehen die Werte bereits fest und es gibt nur eine Handvoll zur Auswahl. Sind die Werte abhängig von anderen Feldern oder die Auswahl zu groß, dann benötigen wir eine Wertehilfe.
Vorbereitung
Um gleich mit der Arbeit an den Wertehilfen zu beginnen, definieren wir uns drei Felder auf unserer Eingabe. Ziel ist es mit abhängigen Daten zu arbeiten. Dabei wollen wir zuerst eine Klasse aus dem System lesen, die zweite Wertehilfe soll dann alle Methoden auflisten und die Dritte soll die verschiedenen Parameter der Methode wählbar machen. Dazu erweitern wir die Struktur um drei Felder (VH*):
TYPES:
"! <p class="shorttext">Out first action</p>
BEGIN OF input,
"! <p class="shorttext">Choose an output</p>
output_format TYPE output_format,
"! <p class="shorttext">VH: Class</p>
vh_class TYPE string,
"! <p class="shorttext">VH: Method</p>
vh_method TYPE string,
"! <p class="shorttext">VH: Parameter</p>
vh_parameter TYPE string,
END OF input.
Rufen wir die IDE Action nun auf, sehen wir erst einmal drei normale Felder für die Eingabe, aber keine weiteren Möglichkeiten zur Suche von Werten.
Um im nächsten Schritt die Einstellungen vornehmen zu können, benötigen wir in der CREATE_INPUT_CONFIG Methode eine Konfiguration, um die Eigenschaften der Felder anpassen zu können. Dazu erzeugen wir die Konfiguration für unseren Input und übergeben sie zum Abschluss an die Information Factory ans UI. Da Objekt benötigen wir dann in den folgenden Kapiteln des Artikels.
DATA input TYPE input.
DATA(configuration) = ui_information_factory->get_configuration_factory( )->create_for_data( input ).
RETURN ui_information_factory->for_abap_type( abap_type = input
configuration = configuration ).
Standard
Zuerst einmal gibt es für viele Fälle bereits Standardsuchhilfen. Willst du nach Core Data Services oder Klassen suchen, müssen wir keine eigene Logik implementieren, sondern müssen eigentlich nur die Suchhilfe am Feld aktivieren. Dazu lassen wir uns über die Konfiguration eine Instanz zu unserem Feld zurückgeben, hier ist die Groß- und Kleinschreibung egal. Im Anschluss rufen wir die Methode SET_TYPES, um den Typen des Feldes zu bestimmen. In diesem Fall definieren wir das Feld als Klasse.
configuration->get_element( `vh_class` )->set_types( VALUE #( ( `CLAS/OC` ) ) ).
Im Beispiel oben haben wir hardcodierte Werte verwendet, da aktuell der Standard keine Konstanten dafür anbietet, zumindest haben wir bisher keine gefunden. Die verfügbaren Werte findest du per F2 Hilfe auf die Methode SET_TYPES:
Rufen wir nun die IDE Action auf, dann erhalten wir hinter dem Feld den entsprechenden Button, aber auch das Feld an sich reagiert nun auf den Content Assist in Eclipse.
Hinweis: Sollte die Suchhilfe nicht am Feld angezeigt werden, dann musst du noch eine Dummy Implementierung für die eigene Wertehilfe anlegen. Hierbei handelt es sich um einen Fehler, der in einem der kommenden Releases behoben wird.
Eigene
In diesem Kapitel schauen wir uns an, wie wir eine eigene Suchhilfe mit einer Logik und Möglichkeiten implementieren.
Grundlage
Möchten wir eine eigene Suchhilfe implementieren, dann benötigen wir zuerst eine Klasse, die sich um das Handling der Aufrufe kümmert. Dazu legen wir eine neue Klasse an und verwenden dabei das Interface IF_SD_VALUE_HELP_DSNI für die Implementierung. Ist die Klasse angelegt und aktiviert, dann müssen wir die Klasse noch in unserer Input-Klasse registrieren. Dazu implementieren wir die Methode GET_VALUE_HELP_PROVIDER in der Klasse. Solltest du keinen Vorschlag für die Methode erhalten haben, dann musst du die Implementierung manuell vornehmen. Das liegt an der Standardimplementierung per "DEFAULT IGNORE" im Interface. Dabei erzeugen wir eine Instanz unserer Klasse und übergeben sie an den Provider.
METHOD if_aia_sd_action_input~get_value_help_provider.
result = cl_sd_value_help_provider=>create( NEW zcl_bs_demo_ide_first_value( ) ).
ENDMETHOD.
Nun können wir die Suchhilfe an den beiden Feldern definieren, sodass das sie uns beim Aufruf angezeigt werden. Ähnlich wie beim Standard machen wir das über die Konfiguration. Hier lassen wir uns das Element zurückgeben und aktivieren über die Methode SET_VALUES die Eingabehilfe. Damit wird später unsere Value Help Implementierung aufgerufen.
configuration->get_element( 'vh_method' )->set_values( if_sd_config_element=>values_kind-domain_specific_named_items ).
configuration->get_element( 'vh_parameter' )->set_values( if_sd_config_element=>values_kind-domain_specific_named_items ).
Implementierung
Bevor die beiden Wertehilfen implementieren, müssen wir die Grundlage in der Method GET_VALUE_HELP_ITEMS legen. Dazu lesen wir die aktuellen Daten vom Input ein, die wir im nächsten Schritt für die Ableitung benötigen. Dazu erzeugen wir die Struktur und lassen uns diese über das MODEL befüllen.
DATA input TYPE zcl_bs_demo_ide_first_input=>input.
model->get_as_structure( IMPORTING result = input ).
Als nächstes können wir dann die Ableitung über die VALUE_HELP_ID vornehmen, um die richtige Suchhilfe zu starten und die Werte zu ermitteln. Beide Methoden liefern das gleiche Ergebnis in Form einer vordefinierten Struktur. Die Daten und die Anzahl der Zeilen geben wir an den Aufrufer zurück. Die Methode enthält auch einen MAX_ITEM_COUNT, den du bei vielen Datensätzen auch berücksichtigen solltest.
CASE value_help_id.
WHEN 'VH_METHOD'.
items = get_methods( input ).
WHEN 'VH_PARAMETER'.
items = get_parameters( input ).
ENDCASE.
result = VALUE #( items = items
total_item_count = lines( items ) ).
Methoden
Zuerst einmal sollten wir prüfen, ob die Klasse befüllt ist, da wir diese für die Wertehilfe verwenden. Sonst geben wir ein leeres Ergebnis zurück.
IF input-vh_class IS INITIAL.
RETURN.
ENDIF.
Dann verwenden wir die XCO Klasse, um alle öffentlichen Methoden zu lesen. Dabei werden aber nur in der Klasse definierte Methoden gelesen, nicht diese, die aus einem Interface kommen. Dann übernehmen wir den Namen und die Beschreibung in das Ergebnis. Grundsätzlich kann die Beschreibung leer sein, wenn Klassen mit Eclipse angelegt werden und die Texte der ABAP Docs nicht synchronisiert sind.
DATA(class) = xco_cp_abap=>class( CONV #( input-vh_class ) ).
DATA(public_methods) = class->definition->section-public->components->method->all->get( ).
LOOP AT public_methods INTO DATA(method).
INSERT VALUE #( ) INTO TABLE result REFERENCE INTO DATA(result_entry).
result_entry->name = method->name.
result_entry->description = method->content( )->get( )-short_description.
ENDLOOP.
Parameter
Bei den Parametern verhält es sich erst einmal ähnlich, wir prüfen im ersten Schritt die Klasse und die Method, bevor wir die eigentliche Logik starten.
IF input-vh_class IS INITIAL OR input-vh_method IS INITIAL.
RETURN.
ENDIF.
Dann lesen wir die Klasse ein und lassen uns nur die eine Methode zurückgeben. Der Einfachheit halber, geben wir nur die Importing Parameter zurück. Grundsätzlich kannst du mit etwas mehr Logik auch alle Parameter sammeln.
DATA(class) = xco_cp_abap=>class( CONV #( input-vh_class ) ).
DATA(method) = class->definition->section-public->component->method( CONV #( input-vh_method ) ).
LOOP AT method->importing_parameters->all->get( ) INTO DATA(importing).
INSERT VALUE #( ) INTO TABLE result REFERENCE INTO DATA(result_entry).
result_entry->name = importing->name.
result_entry->description = importing->content( )->get( )-typing_definition->get_value( ).
ENDLOOP.
Ergebnis
Hier noch einmal ein Bild, wie sich die Wertehilfen nun verhalten und welche Werte wir zurückbekommen. Dabei verwenden wir einmal den Content Assist und einmal direkt die Wertehilfe mit allen Werten.
Vollständiges Beispiel
Das vollständige Coding aus dem gesamten Beispiel findest du im GitHub Repository. Über den folgenden Commit findest du die Änderungen aus diesem Artikel und kannst so noch später den aktuellen Zustand nachvollziehen.
Fazit
Für die Arbeit mit unserer IDE Action sind Wertehilfen ein zentraler Bestandteil für eine gute Implementierung und ermöglichen dem Entwickler die Auswahl der passenden Einträge. Ebenso kann es die Arbeit mit deinen IDE Actions beschleunigen.



