ABAP - Enumeration
Enumerations are used in development to restrict the possibilities for a variable and now also work in ABAP and method interfaces.
Table of contents
The topic of enumeration has been known in development for a long time, but was not previously supported in ABAP. If you only wanted to allow fixed values in a CHAR1 field, you had to check the content yourself. Fixed values within a domain were only intended for the F4 help, but had no influence on calling methods, so that other developers could call the interface incorrectly.
Basics
The enumeration is defined within the program code like a type and has a beginning and an end, like the definition of a structure. As an example for you, the basic version of a enumeration.
TYPES:
BEGIN OF ENUM te_status,
c_success,
c_warning,
c_error,
END OF ENUM te_status.
It makes the most sense to define enumerations in classes and make them available as a public type. The use therefore works like the access to a constant. You can also easily see that the values are provided with the Hungarian notation. We also provide you with an example for calling up a value and defining it in an interface.
" Method definition
METHODS:
validate_status_for_process
IMPORTING
id_status TYPE te_status.
" Compare
IF id_status = zcl_test_enum=>c_success.
ENDIF
In the basic version of the enumeration, the elements are numbered consecutively, starting from zero, as is also done in other programming languages, the basic data type is integer.
Structure
As soon as there are several enumerations in a class, the overview of the individual groups will decrease significantly and you will not be able to make a clear assignment at first glance via the code completion, since all ENUMs are displayed with "c_". For this you can use the addition STRUCTURE, with which you can address the enumeration values directly via the structure.
" Definition
TYPES:
BEGIN OF ENUM te_strcutured STRUCTURE cs_music,
free,
classic,
punk,
hiphop,
END OF ENUM te_strcutured STRUCTURE cs_music.
" Compare
IF id_music = cs_music-classic.
ENDIF.
In the example above, the Hungarian notation has now shifted to the structure and is no longer required for the individual values. The individual values are accessed via the structure name, for the type you continue to use the name of the enumeration.
Typing
Should you ever need a different type for use, you can also give your enumeration a type. You can then use VALUE to assign corresponding target values to the individual values, but there must be at least one value that is marked as INITIAL. Your IDE will also point this out to you here.
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.
Output
What does the output for an enumeration actually look like if we output it in this console or as a string? In terms of data type, you would actually expect an integer, but if you output a value without conversion, then the name of the value is printed. The following example shows this:
out->write( |{ cs_music-classic }| ).
out->write( |{ c_cold }| ).
out->write( |{ cs_numbers-two }| ).
The result in the console then looks like this, the names of the individual values have been printed out accordingly:
Interface
What works now when calling the method? You must have asked yourself this question by now. In the following example we show you the different options how the method can be supplied with different values:
" Works fine
validate_status_for_process( c_warning ).
validate_status_for_process( CONV #( 1 ) ).
" Error
validate_status_for_process( 'C_WARNING' ).
validate_status_for_process( 1 ).
validate_status_for_process( CONV #( 'C_WARNING' ) ).
What works is the use of the value and the value behind it if you are working with a conversion when you call it. All of the other three examples do not work because either no conversion was applied or the wrong value is used. The value shown in the output also does not work as a transfer value.
Hint: At this point the check is very restrictive and it is not possible to compile the source code.
Full example
Here's the entire example again so that you have a working class in your system and can play around with the calls and definition.
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.
Conclusion
Enumerations can be used sensibly in many places in the coding and offer a certain stability when calling the method, since you do not have to check the correctness of all values yourself. If you want to use the values for communication in an OData service, you should be careful about the conversion. Typing and structuring an enumeration can also be used jointly.