Enumerations are type-safe constants that define a fixed set of values. They replace loose CONSTANTS and provide compiler checking, better readability and maintainability.
Syntax
TYPES: BEGIN OF ENUM <enum_name> [ BASE TYPE <base_type> ] [ STRUCTURE <structure_name> ], <value1> [ VALUE <n> ], <value2> [ VALUE <n> ], ... END OF ENUM <enum_name> [ STRUCTURE <structure_name> ].Basic Principle
- Enumerations define a closed set of values
- Each value automatically gets an integer value (0, 1, 2, …)
- Variables of enum type can only hold valid values
- Compiler checking prevents invalid assignments
Examples
1. Simple Enumeration
" Define enumerationTYPES: BEGIN OF ENUM ty_traffic_light, red, yellow, green, END OF ENUM ty_traffic_light.
" Declare variableDATA: lv_light TYPE ty_traffic_light.
" Assign valuelv_light = red.
" Use in conditionsCASE lv_light. WHEN red. WRITE: / 'Stop!'. WHEN yellow. WRITE: / 'Caution!'. WHEN green. WRITE: / 'Go!'.ENDCASE.2. Comparison: Enumeration vs. Constants
" === OLD: Loose constants (error-prone) ===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'. " Invalid value - no compiler error!
" === NEW: Enumeration (type-safe) ===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'. " SYNTAX ERROR! Only enum values allowed3. Enumeration with STRUCTURE
" With STRUCTURE for qualified accessTYPES: 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.
" Qualified access via structurelv_status = order_status-processing.
CASE lv_status. WHEN order_status-open. WRITE: / 'Order open'. WHEN order_status-processing. WRITE: / 'In processing'. WHEN order_status-shipped. WRITE: / 'Shipped'. WHEN order_status-delivered. WRITE: / 'Delivered'. WHEN order_status-cancelled. WRITE: / 'Cancelled'.ENDCASE.4. Explicit Values
" Default: Automatic values 0, 1, 2, ...TYPES: BEGIN OF ENUM ty_auto, val_a, " = 0 val_b, " = 1 val_c, " = 2 END OF ENUM ty_auto.
" Assign explicit valuesTYPES: 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-based 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.
" Extract valueDATA(lv_hex) = CONV string( lv_color ).WRITE: / 'Color code:', lv_hex. " #0000FF6. Enumeration in Classes
CLASS lcl_order DEFINITION. PUBLIC SECTION. " Enumeration as class type 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.
" UsageDATA(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: / 'Order approved'.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.
" With SWITCHDATA(lv_type) = SWITCH string( lv_day WHEN weekday-saturday OR weekday-sunday THEN 'Weekend' ELSE 'Weekday').
" With CONDDATA(lv_message) = COND string( WHEN lv_day = weekday-monday THEN 'Start of week' WHEN lv_day = weekday-friday THEN 'Almost weekend!' WHEN lv_day = weekday-saturday OR lv_day = weekday-sunday THEN 'Free!' ELSE 'Normal day').
WRITE: / lv_type. " WeekdayWRITE: / lv_message. " Almost weekend!8. Enumeration with 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.
" Initialize structure with enumerationDATA(ls_task) = VALUE ty_task( id = 1 name = 'Important task' priority = priority-high).
" Table with 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 = 'Docs' priority = priority-low )).
" Filter by priorityLOOP AT lt_tasks INTO DATA(ls_t) WHERE priority >= priority-high. WRITE: / ls_t-id, ls_t-name.ENDLOOP.9. Iterate Enum Values
TYPES: BEGIN OF ENUM ty_size STRUCTURE size, xs, s, m, l, xl, xxl, END OF ENUM ty_size STRUCTURE size.
" Loop through all values (with integer conversion)DO. DATA(lv_size) = CONV ty_size( sy-index - 1 ).
" Check if valid value (within range) IF lv_size > size-xxl. EXIT. ENDIF.
WRITE: / 'Size:', 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. Convert Enum to String
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 as string (Reflection)DATA(lo_type) = CAST cl_abap_enumdescr( cl_abap_typedescr=>describe_by_data( lv_payment )).
" All members with namesLOOP AT lo_type->members INTO DATA(ls_member). WRITE: / ls_member-name, '=', ls_member-value.ENDLOOP.
" Output:" CASH = 0" CREDIT_CARD = 1" BANK_TRANSFER = 2" PAYPAL = 312. Practical Example: 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. Constants
| Aspect | Enumeration | Domain | Constants |
|---|---|---|---|
| Type safety | Yes (Compiler) | Yes (DDIC) | No |
| Scope | Local or Global | Global (DDIC) | Local or Global |
| Value check | Compile-time | Runtime | None |
| Texts | Manual | Value table | None |
| Use case | Modern logic | DB fields | Legacy code |
Important Notes / Best Practice
- Use STRUCTURE for qualified access (
status-approvedinstead of justapproved). - Enumerations are type-safe – invalid values lead to syntax errors.
- BASE TYPE for non-integer-based enumerations (e.g., String).
- Explicit VALUE only when needed (e.g., HTTP status codes, mapping to external values).
- Enumerations replace loose constants for better maintainability.
cl_abap_enumdescrfor reflection (reading names).- Combine with
SWITCHandCASEfor clean branching. - Enumerations can be defined in
CLASSandINTERFACE. - Comparisons with
=,<>,<,>are possible (based on ordinal value). - Ideal for state machines, status fields and configurable options.