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 definierenTYPES: BEGIN OF ENUM ty_traffic_light, red, yellow, green, END OF ENUM ty_traffic_light.
" Variable deklarierenDATA: lv_light TYPE ty_traffic_light.
" Wert zuweisenlv_light = red.
" In Bedingungen verwendenCASE 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 erlaubt3. Enumeration mit STRUCTURE
" Mit STRUCTURE für qualifizierten ZugriffTYPES: 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 Strukturlv_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 zuweisenTYPES: 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 ). " 4045. BASE TYPE
" String-basierte EnumerationTYPES: 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 extrahierenDATA(lv_hex) = CONV string( lv_color ).WRITE: / 'Farbcode:', lv_hex. " #0000FF6. 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.
" VerwendungDATA(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 SWITCHDATA(lv_type) = SWITCH string( lv_day WHEN weekday-saturday OR weekday-sunday THEN 'Wochenende' ELSE 'Werktag').
" Mit CONDDATA(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. " WerktagWRITE: / 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 initialisierenDATA(ls_task) = VALUE ty_task( id = 1 name = 'Wichtige Aufgabe' priority = priority-high).
" Tabelle mit EnumerationsDATA: 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ätLOOP 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 NamenLOOP 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 = 312. 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
| Aspekt | Enumeration | Domain | Konstanten |
|---|---|---|---|
| Typsicherheit | Ja (Compiler) | Ja (DDIC) | Nein |
| Scope | Lokal oder Global | Global (DDIC) | Lokal oder Global |
| Wertprüfung | Compile-Zeit | Laufzeit | Keine |
| Texte | Manuell | Wertetabelle | Keine |
| Einsatz | Moderne Logik | DB-Felder | Legacy-Code |
Wichtige Hinweise / Best Practice
- STRUCTURE verwenden für qualifizierten Zugriff (
status-approvedstatt nurapproved). - 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_enumdescrfür Reflection (Namen auslesen).- Kombinieren Sie mit
SWITCHundCASEfür saubere Verzweigungen. - Enumerations können in
CLASSundINTERFACEdefiniert werden. - Vergleiche mit
=,<>,<,>sind möglich (basierend auf Ordinalwert). - Ideal für State Machines, Status-Felder und konfigurierbare Optionen.