ABAP - Enumeration
Aufzählungen werden in der Entwicklung zur Einschränkung von Möglichkeiten auf einer Variable verwendet und funktionieren mittlerweile auch in ABAP und Schnittstellen von Methoden.
Inhaltsverzeichnis
Das Thema Aufzählung ist in der Entwicklung bereits seit langer Zeit bekannt, wurde bisher aber in ABAP nicht unterstützt. Wenn du in einem CHAR1 Feld nur fest definierte Werte zulassen wolltest, musstest du den Inhalt selbst prüfen. Auch Festwerte innerhalb einer Domäne waren nur für die F4 Hilfe bestimmt, hatten aber keinen Einfluss bei Aufrufen von Methoden, sodass andere Entwickler die Schnittstelle auch falsch aufrufen konnten.
Grundlage
Die Aufzählung wird innerhalb von Programmcode wie ein Typ definiert und hat einen Anfang und ein Ende, wie die Definition einer Struktur. Als Beispiel für dich die Basisausprägung einer Aufzählung.
TYPES:
BEGIN OF ENUM te_status,
c_success,
c_warning,
c_error,
END OF ENUM te_status.
Am meisten Sinn macht es, Aufzählungen in Klassen zu definieren und als öffentlichen Typ zur Verfügung zu stellen. Die Verwendung funktioniert deshalb, wie der Zugriff auf eine Konstante. Dies erkennst du auch ganz leicht, dass die Werte mit der ungarischen Notation versehen sind. Für den Aufruf eines Wertes und die Definition in einer Schnittstelle, stellen wir dir ebenfalls ein Beispiel zur Verfügung.
" Methodendefinition
METHODS:
validate_status_for_process
IMPORTING
id_status TYPE te_status.
" Abfrage
IF id_status = zcl_test_enum=>c_success.
ENDIF
In der Grundausprägung der Aufzählung werden die Elemente der Reihe nach durchnummeriert, beginnend ab Null, so wie es auch in anderen Programmiersprachen gemacht wird, der Grunddatentyp ist Integer.
Strukturierung
Sobald es mehrere Aufzählungen in einer Klasse sind, wird die Übersicht der einzelnen Gruppen stark abnehmen und über die Code-Vervollständigung wirst du auf den ersten Blick keine eindeutige Zuordnung treffen können, da alle ENUMs mit "c_" angezeigt werden. Hierfür kannst du aber den Zusatz STRUCTURE verwenden, mit dem du die Aufzählungen direkt über die Struktur ansprechen kannst.
" Definition
TYPES:
BEGIN OF ENUM te_strcutured STRUCTURE cs_music,
free,
classic,
punk,
hiphop,
END OF ENUM te_strcutured STRUCTURE cs_music.
" Abfrage
IF id_music = cs_music-classic.
ENDIF.
Im oberen Beispiel hat sich nun die ungarische Notation auf die Struktur verschoben und wird für die einzelnen Werte nicht mehr benötigt. Der Zugriff auf die einzelnen Werte erfolgt über den Strukturnamen, für den Typ verwendest du weiterhin den Namen der Aufzählung.
Typisierung
Solltest du für die Verwendung einmal einen abweichenden Typen benötigen, kannst du deiner Aufzählung auch einen Typen geben. Per Value kannst du dann den einzelnen Werte entsprechende Zielwerte zuweisen, es muss aber mindestens einen Wert geben, der als INITIAL gekennzeichnet wird. Hier wird dich aber auch entsprechend deine IDE darauf hinweisen.
TYPES:
BEGIN OF ENUM te_typed BASE TYPE char1,
c_hot VALUE IS INITIAL,
c_cold VALUE 'A',
c_well VALUE 'B',
END OF ENUM te_typed.
Ausgabe
Wie sieht nun eigentlich die Ausgabe für ein Enumeration aus, wenn wir es in dies Console oder als String ausgeben? Vom Datentyp her, würde man eigentlich einen Integer erwarten, doch wenn du einen Wert ohne Konvertierung ausgibst, dann wird der Name des Wertes ausgegeben. Dazu das folgende Beispiel:
out->write( |{ cs_music-classic }| ).
out->write( |{ c_cold }| ).
out->write( |{ cs_numbers-two }| ).
Das Ergebnis in der Console sieht dann wie folgt aus, die Namen der einzelnen Werte wurden entsprechend ausgeschrieben:
Schnittstellen
Was funktioniert nun beim Aufruf der Methode alles? Diese Frage wirst du dir schon sicherlich gestellt haben. In dem folgenden Beispiel zeigen wir dir die verschiedenen Möglichkeiten, wie die Methode mit verschiedenen Werten versorgt werden kann:
" in Ordnung
validate_status_for_process( c_warning ).
validate_status_for_process( CONV #( 1 ) ).
" Fehler
validate_status_for_process( 'C_WARNING' ).
validate_status_for_process( 1 ).
validate_status_for_process( CONV #( 'C_WARNING' ) ).
Was funktioniert ist die Verwendung des Wertes und dem dahinterliegenden Wert, wenn du beim Aufruf mit einer Konvertierung arbeitest. Alle anderen drei Beispiele funktionieren nicht, da entwder keine Konvertierung angewandt wurde oder der falsche Wert verwendet wird. Auch der Wert, der bei der Ausgabe gezeigt wird, funktioniert nicht als Übergabewert.
Hinweis: An dieser Stelle ist die Prüfung sehr restriktiv und eine Kompilierung des Quellcodes nicht möglich.
Beispielklasse
Hier noch einmal das gesamte Beispiel, damit du eine funktionierende Klasse in deinem System hast und etwas mit den Aufrufen und der Definition spielen kannst.
CLASS zcl_test_enum DEFINITION PUBLIC FINAL CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
TYPES:
BEGIN OF ENUM te_status,
c_success,
c_warning,
c_error,
END OF ENUM te_status,
BEGIN OF ENUM te_structured STRUCTURE cs_music,
free,
classic,
punk,
hiphop,
END OF ENUM te_structured STRUCTURE cs_music,
BEGIN OF ENUM te_typed BASE TYPE char1,
c_hot VALUE IS INITIAL,
c_cold VALUE 'A',
c_well VALUE 'B',
END OF ENUM te_typed,
BEGIN OF ENUM te_mixed STRUCTURE cs_numbers BASE TYPE numc1,
zero VALUE IS INITIAL,
one VALUE 1,
two VALUE 2,
END OF ENUM te_mixed STRUCTURE cs_numbers.
PROTECTED SECTION.
PRIVATE SECTION.
METHODS:
validate_status_for_process
IMPORTING
id_status TYPE te_status.
ENDCLASS.
CLASS zcl_test_enum IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
out->write( |{ cs_music-classic }| ).
out->write( |{ c_cold }| ).
out->write( |{ cs_numbers-two }| ).
validate_status_for_process( c_warning ).
validate_status_for_process( CONV #( 1 ) ).
validate_status_for_process( 'C_WARNING' ).
validate_status_for_process( 1 ).
validate_status_for_process( CONV #( 'C_WARNING' ) ).
ENDMETHOD.
METHOD validate_status_for_process.
IF id_status = c_success.
ENDIF
ENDMETHOD.
ENDCLASS.
Fazit
Aufzählungen können an vielen Stellen im Coding sinnvoll verwendet werden und bieten eine gewisse Stabilität beim Aufruf der Methode, da du selbst nicht die Korrektheit aller Werte prüfen musst. Wenn du die Werte für die Kommunkation in einem OData-Servie verwenden willst, solltest du vorsichtig sein, hinsichtlich der Konvertierung. Typisierung und Strukturierung einer Enumeration können auch gemeinsam genutzt werden.