Question

Is it possible to create an Enumeration (enum) in ABAP such as in Java ?

As far as I know, we can define a domain with fixed values, but they are only used for screens.

Was it helpful?

Solution

Before release 7.51, there was no native support for enums in ABAP, but you can simulate the same behavior with a few simple steps:

  1. Create your "enum" class;
  2. Set the instance constructor to private;
  3. Add the static attributes of TYPE REF TO <your_class> for each "enum object";
  4. Create a CLASS_CONSTRUCTOR and instantiate each "enum object" with the desired properties.

For instance, if you have a status enum, you may have a CL_STATUS class with CL_STATUS=>APPROVED and CL_STATUS=>REJECTED enum objects.

Example:

REPORT z_test.

CLASS cl_status DEFINITION
      CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-DATA: approved TYPE REF TO cl_status,
                rejected TYPE REF TO cl_status.
    CLASS-METHODS class_constructor.
ENDCLASS.
CLASS cl_status IMPLEMENTATION.
  METHOD class_constructor.
    approved = NEW cl_status( ).
    rejected = NEW cl_status( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  DATA status TYPE REF TO cl_status.
  status = cl_status=>approved.
  CASE status.
    WHEN cl_status=>approved.
      MESSAGE 'approved' TYPE 'I'.
    WHEN cl_status=>rejected.
      MESSAGE 'rejected' TYPE 'I'.
  ENDCASE.

OTHER TIPS

From ABAP release 7.51 it is also possible to use enumerated objects in ABAP.

See also this blog for more info.

Simple example:

TYPES:
  BEGIN OF ENUM ty_enum_status STRUCTURE status,
    approved,
    rejected,
  END OF ENUM ty_enum_status STRUCTURE status.

DATA my_status TYPE ty_enum_status.
my_status = status-approved.

Example for tables:

TYPES:
  BEGIN OF ENUM ty_enum_mealtype STRUCTURE mealtype BASE TYPE smeal-mealtype,
    unknown    VALUE IS INITIAL,
    vegetarian VALUE 'VE',
    fish       VALUE 'FI',
    flesh      VALUE 'FL',
  END OF ENUM ty_enum_mealtype STRUCTURE mealtype.

SELECT SINGLE * FROM smeal
  WHERE carrid     = 'LH'
    AND mealnumber = 1
  INTO @DATA(smeal).

" For comparing an enumerated component with a data object of the base type,
" it requires a conversion to the enumerated type
DATA(enum_mealtype) = SWITCH #( CONV ty_enum_mealtype( smeal-mealtype )
  WHEN mealtype-vegetarian THEN mealtype-fish
  WHEN mealtype-fish       THEN mealtype-flesh
  WHEN mealtype-flesh      THEN mealtype-vegetarian ).

" Conversion between ENUM type and string type - This takes the first characters 
" of the name of the enumerated component
ASSERT CONV string( enum_mealtype ) = SWITCH #( enum_mealtype
  WHEN mealtype-unknown    THEN `UNKNOWN`
  WHEN mealtype-vegetarian THEN `VEGETARIAN`
  WHEN mealtype-fish       THEN `FISH`
  WHEN mealtype-flesh      THEN `FLESH` ).

" Assigning an enumerated variable to a data object of the base type
smeal-mealtype = CONV smeal-mealtype( enum_mealtype ).

" Conversion between ENUM type and base type
ASSERT CONV smeal-mealtype( enum_mealtype ) = SWITCH #( enum_mealtype
  WHEN mealtype-unknown    THEN '  '
  WHEN mealtype-vegetarian THEN 'VE'
  WHEN mealtype-fish       THEN 'FI'
  WHEN mealtype-flesh      THEN 'FL' ).

" Use CONV for assigning an enumerated component to a data object of the base type
smeal-mealtype = CONV #( mealtype-vegetarian ).
ASSERT smeal-mealtype = 'VE'.

" If you don't use CONV, you'll get the first characters of the name of the 
" enumerated component
smeal-mealtype = mealtype-unknown.
ASSERT smeal-mealtype = 'UN'.

A somewhat closer approach is to use the following;

constants: begin of status,
             approved TYPE i value 1,
             rejected TYPE i value 2,
           end of status.

So now, you use this constant throughout your program:

DATA my_status TYPE i.
my_status = status-approved.
CASE my_status.
  WHEN status-approved.
    MESSAGE 'approved' TYPE 'I'.
  WHEN status-rejected.
    MESSAGE 'rejected' TYPE 'I'.
ENDCASE.

If you want them global, create them as class attributes in a global class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top