ABAP Enumerations: Typsichere Aufzählungen

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Enumerations (Aufzählungen) sind typsichere Konstanten, die eine feste Menge von Werten definieren. Sie ersetzen lose CONSTANTS und bieten Compiler-Prüfung, bessere Lesbarkeit und Wartbarkeit.

Syntax

TYPES: BEGIN OF ENUM <enum_name> [ BASE TYPE <basistyp> ] [ STRUCTURE <struktur_name> ],
<wert1> [ VALUE <n> ],
<wert2> [ VALUE <n> ],
...
END OF ENUM <enum_name> [ STRUCTURE <struktur_name> ].

Grundprinzip

  • Enumerations definieren eine geschlossene Wertemenge
  • Jeder Wert bekommt automatisch einen Integer-Wert (0, 1, 2, …)
  • Variablen vom Enum-Typ können nur gültige Werte annehmen
  • Compiler-Prüfung verhindert ungültige Zuweisungen

Beispiele

1. Einfache Enumeration

" Enumeration definieren
TYPES: BEGIN OF ENUM ty_traffic_light,
red,
yellow,
green,
END OF ENUM ty_traffic_light.
" Variable deklarieren
DATA: lv_light TYPE ty_traffic_light.
" Wert zuweisen
lv_light = red.
" In Bedingungen verwenden
CASE lv_light.
WHEN red.
WRITE: / 'Stop!'.
WHEN yellow.
WRITE: / 'Achtung!'.
WHEN green.
WRITE: / 'Fahren!'.
ENDCASE.

2. Vergleich: Enumeration vs. Konstanten

" === ALT: Lose Konstanten (fehleranfällig) ===
CONSTANTS: c_status_new TYPE c VALUE 'N',
c_status_approved TYPE c VALUE 'A',
c_status_rejected TYPE c VALUE 'R'.
DATA: lv_status TYPE c.
lv_status = 'X'. " Ungültiger Wert - kein Compilerfehler!
" === NEU: Enumeration (typsicher) ===
TYPES: BEGIN OF ENUM ty_status,
new,
approved,
rejected,
END OF ENUM ty_status.
DATA: lv_status2 TYPE ty_status.
lv_status2 = approved. " OK
" lv_status2 = 'X'. " SYNTAXFEHLER! Nur Enum-Werte erlaubt

3. Enumeration mit STRUCTURE

" Mit STRUCTURE für qualifizierten Zugriff
TYPES: BEGIN OF ENUM ty_order_status STRUCTURE order_status,
open,
processing,
shipped,
delivered,
cancelled,
END OF ENUM ty_order_status STRUCTURE order_status.
DATA: lv_status TYPE ty_order_status.
" Qualifizierter Zugriff über Struktur
lv_status = order_status-processing.
CASE lv_status.
WHEN order_status-open.
WRITE: / 'Bestellung offen'.
WHEN order_status-processing.
WRITE: / 'In Bearbeitung'.
WHEN order_status-shipped.
WRITE: / 'Versandt'.
WHEN order_status-delivered.
WRITE: / 'Geliefert'.
WHEN order_status-cancelled.
WRITE: / 'Storniert'.
ENDCASE.

4. Explizite Werte

" Standard: Automatische Werte 0, 1, 2, ...
TYPES: BEGIN OF ENUM ty_auto,
val_a, " = 0
val_b, " = 1
val_c, " = 2
END OF ENUM ty_auto.
" Explizite Werte zuweisen
TYPES: BEGIN OF ENUM ty_http_status STRUCTURE http_status BASE TYPE i,
ok VALUE 200,
created VALUE 201,
bad_request VALUE 400,
unauthorized VALUE 401,
not_found VALUE 404,
server_error VALUE 500,
END OF ENUM ty_http_status STRUCTURE http_status.
DATA: lv_http TYPE ty_http_status.
lv_http = http_status-not_found.
WRITE: / 'HTTP Status:', CONV i( lv_http ). " 404

5. BASE TYPE

" String-basierte Enumeration
TYPES: BEGIN OF ENUM ty_color STRUCTURE color BASE TYPE string,
red VALUE `#FF0000`,
green VALUE `#00FF00`,
blue VALUE `#0000FF`,
white VALUE `#FFFFFF`,
black VALUE `#000000`,
END OF ENUM ty_color STRUCTURE color.
DATA: lv_color TYPE ty_color.
lv_color = color-blue.
" Wert extrahieren
DATA(lv_hex) = CONV string( lv_color ).
WRITE: / 'Farbcode:', lv_hex. " #0000FF

6. Enumeration in Klassen

CLASS lcl_order DEFINITION.
PUBLIC SECTION.
" Enumeration als Klassentyp
TYPES: BEGIN OF ENUM ty_status STRUCTURE status,
draft,
submitted,
approved,
rejected,
END OF ENUM ty_status STRUCTURE status.
METHODS: constructor,
set_status IMPORTING iv_status TYPE ty_status,
get_status RETURNING VALUE(rv_status) TYPE ty_status,
approve,
reject.
PRIVATE SECTION.
DATA: mv_status TYPE ty_status.
ENDCLASS.
CLASS lcl_order IMPLEMENTATION.
METHOD constructor.
mv_status = status-draft.
ENDMETHOD.
METHOD set_status.
mv_status = iv_status.
ENDMETHOD.
METHOD get_status.
rv_status = mv_status.
ENDMETHOD.
METHOD approve.
IF mv_status = status-submitted.
mv_status = status-approved.
ENDIF.
ENDMETHOD.
METHOD reject.
IF mv_status = status-submitted.
mv_status = status-rejected.
ENDIF.
ENDMETHOD.
ENDCLASS.
" Verwendung
DATA(lo_order) = NEW lcl_order( ).
lo_order->set_status( lcl_order=>status-submitted ).
lo_order->approve( ).
DATA(lv_current) = lo_order->get_status( ).
IF lv_current = lcl_order=>status-approved.
WRITE: / 'Bestellung genehmigt'.
ENDIF.

7. Enumeration in SWITCH/COND

TYPES: BEGIN OF ENUM ty_weekday STRUCTURE weekday,
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
END OF ENUM ty_weekday STRUCTURE weekday.
DATA: lv_day TYPE ty_weekday VALUE weekday-friday.
" Mit SWITCH
DATA(lv_type) = SWITCH string( lv_day
WHEN weekday-saturday OR weekday-sunday THEN 'Wochenende'
ELSE 'Werktag'
).
" Mit COND
DATA(lv_message) = COND string(
WHEN lv_day = weekday-monday THEN 'Wochenstart'
WHEN lv_day = weekday-friday THEN 'Fast Wochenende!'
WHEN lv_day = weekday-saturday OR lv_day = weekday-sunday THEN 'Frei!'
ELSE 'Normaler Tag'
).
WRITE: / lv_type. " Werktag
WRITE: / lv_message. " Fast Wochenende!

8. Enumeration mit VALUE

TYPES: BEGIN OF ENUM ty_priority STRUCTURE priority,
low,
medium,
high,
critical,
END OF ENUM ty_priority STRUCTURE priority.
TYPES: BEGIN OF ty_task,
id TYPE i,
name TYPE string,
priority TYPE ty_priority,
END OF ty_task.
" Struktur mit Enumeration initialisieren
DATA(ls_task) = VALUE ty_task(
id = 1
name = 'Wichtige Aufgabe'
priority = priority-high
).
" Tabelle mit Enumerations
DATA: lt_tasks TYPE TABLE OF ty_task.
lt_tasks = VALUE #(
( id = 1 name = 'Bug Fix' priority = priority-critical )
( id = 2 name = 'Feature' priority = priority-medium )
( id = 3 name = 'Doku' priority = priority-low )
).
" Filtern nach Priorität
LOOP AT lt_tasks INTO DATA(ls_t) WHERE priority >= priority-high.
WRITE: / ls_t-id, ls_t-name.
ENDLOOP.

9. Enum-Werte iterieren

TYPES: BEGIN OF ENUM ty_size STRUCTURE size,
xs,
s,
m,
l,
xl,
xxl,
END OF ENUM ty_size STRUCTURE size.
" Alle Werte durchlaufen (mit Integer-Konvertierung)
DO.
DATA(lv_size) = CONV ty_size( sy-index - 1 ).
" Prüfen ob gültiger Wert (innerhalb des Bereichs)
IF lv_size > size-xxl.
EXIT.
ENDIF.
WRITE: / 'Größe:', lv_size.
ENDDO.

10. Enumeration in Interfaces

INTERFACE lif_document.
TYPES: BEGIN OF ENUM ty_doc_type STRUCTURE doc_type,
invoice,
credit_memo,
delivery_note,
quotation,
END OF ENUM ty_doc_type STRUCTURE doc_type.
METHODS: get_type RETURNING VALUE(rv_type) TYPE ty_doc_type.
ENDINTERFACE.
CLASS lcl_invoice DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_document.
ENDCLASS.
CLASS lcl_invoice IMPLEMENTATION.
METHOD lif_document~get_type.
rv_type = lif_document=>doc_type-invoice.
ENDMETHOD.
ENDCLASS.

11. Enum zu String konvertieren

TYPES: BEGIN OF ENUM ty_payment STRUCTURE payment,
cash,
credit_card,
bank_transfer,
paypal,
END OF ENUM ty_payment STRUCTURE payment.
DATA: lv_payment TYPE ty_payment VALUE payment-credit_card.
" Enum-Name als String (Reflection)
DATA(lo_type) = CAST cl_abap_enumdescr(
cl_abap_typedescr=>describe_by_data( lv_payment )
).
" Alle Members mit Namen
LOOP AT lo_type->members INTO DATA(ls_member).
WRITE: / ls_member-name, '=', ls_member-value.
ENDLOOP.
" Ausgabe:
" CASH = 0
" CREDIT_CARD = 1
" BANK_TRANSFER = 2
" PAYPAL = 3

12. Praktisches Beispiel: State Machine

CLASS lcl_document_workflow DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ENUM ty_state STRUCTURE state,
draft,
pending_review,
approved,
published,
archived,
END OF ENUM ty_state STRUCTURE state.
METHODS: constructor,
submit RETURNING VALUE(rv_success) TYPE abap_bool,
approve RETURNING VALUE(rv_success) TYPE abap_bool,
publish RETURNING VALUE(rv_success) TYPE abap_bool,
archive RETURNING VALUE(rv_success) TYPE abap_bool,
get_state RETURNING VALUE(rv_state) TYPE ty_state,
get_available_actions RETURNING VALUE(rt_actions) TYPE string_table.
PRIVATE SECTION.
DATA: mv_state TYPE ty_state.
ENDCLASS.
CLASS lcl_document_workflow IMPLEMENTATION.
METHOD constructor.
mv_state = state-draft.
ENDMETHOD.
METHOD submit.
IF mv_state = state-draft.
mv_state = state-pending_review.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD approve.
IF mv_state = state-pending_review.
mv_state = state-approved.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD publish.
IF mv_state = state-approved.
mv_state = state-published.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD archive.
IF mv_state = state-published.
mv_state = state-archived.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD get_state.
rv_state = mv_state.
ENDMETHOD.
METHOD get_available_actions.
rt_actions = SWITCH #( mv_state
WHEN state-draft THEN VALUE #( ( `Submit` ) )
WHEN state-pending_review THEN VALUE #( ( `Approve` ) ( `Reject` ) )
WHEN state-approved THEN VALUE #( ( `Publish` ) )
WHEN state-published THEN VALUE #( ( `Archive` ) )
ELSE VALUE #( )
).
ENDMETHOD.
ENDCLASS.

Enum vs. Domain vs. Konstanten

AspektEnumerationDomainKonstanten
TypsicherheitJa (Compiler)Ja (DDIC)Nein
ScopeLokal oder GlobalGlobal (DDIC)Lokal oder Global
WertprüfungCompile-ZeitLaufzeitKeine
TexteManuellWertetabelleKeine
EinsatzModerne LogikDB-FelderLegacy-Code

Wichtige Hinweise / Best Practice

  • STRUCTURE verwenden für qualifizierten Zugriff (status-approved statt nur approved).
  • Enumerations sind typsicher – ungültige Werte führen zu Syntaxfehlern.
  • BASE TYPE für nicht-Integer-basierte Enumerations (z.B. String).
  • Explizite VALUE nur wenn nötig (z.B. HTTP-Statuscodes, Mapping zu externen Werten).
  • Enumerations ersetzen lose Konstanten für bessere Wartbarkeit.
  • cl_abap_enumdescr für Reflection (Namen auslesen).
  • Kombinieren Sie mit SWITCH und CASE für saubere Verzweigungen.
  • Enumerations können in CLASS und INTERFACE definiert werden.
  • Vergleiche mit =, <>, <, > sind möglich (basierend auf Ordinalwert).
  • Ideal für State Machines, Status-Felder und konfigurierbare Optionen.