Skip to Content

It is a common pattern. A data object, say an attribute of a class, should assume only values from a given set. Before Release 7.51 that might have looked as follows:

CLASS cx_wrong_size DEFINITION INHERITING FROM cx_static_check.
 ENDCLASS.
 
 CLASS shirt DEFINITION.
   PUBLIC SECTION.
     TYPES tsize TYPE i.
     CONSTANTS:
       size_s  TYPE tsize VALUE 0,
       size_m  TYPE tsize VALUE 1,
       size_l  TYPE tsize VALUE 2,
       size_xl TYPE tsize VALUE 3.
     METHODS
       constructor IMPORTING size TYPE tsize
                   RAISING   cx_wrong_size.
     ...
   PRIVATE SECTION.
     DATA
       size TYPE tsize.
 ENDCLASS.
 
 CLASS shirt IMPLEMENTATION.
   METHOD constructor.
     IF size <> size_s AND
        size <> size_m AND
        size <> size_l AND
        size <> size_xl.
       RAISE EXCEPTION TYPE cx_wrong_size.
     ENDIF.
     me->size = COND #(
       WHEN size <> size_s AND
                    size <> size_m AND
                    size <> size_l AND
                    size <> size_xl THEN THROW cx_wrong_size( )
       ELSE size ).
   ENDMETHOD.
 ENDCLASS.

Here, the size attribute of a shirt class should have only values that are defined as a set of constants in the class. Other values lead to an exception. A user can create an object of the shirt class as follows:

TRY.
    DATA(shirt) = NEW shirt( shirt=>size_xl ).
  CATCH cx_wrong_size.
    ...
ENDTRY.

You see the overhead? Why not let the runtime environment do the value check for you? There is a concept for this called enumeration or enumerated type.

With Release 7.51, ABAP will support the concept of enumerations too. Let’s rewrite the example using such a new enumerated type:

CLASS shirt DEFINITION.
  PUBLIC SECTION.
    TYPES:
      BEGIN OF ENUM tsize,
        size_s,
        size_m,
        size_l,
        size_xl,
      END OF ENUM tsize.
    METHODS
      constructor IMPORTING size TYPE tsize.
    ...
  PRIVATE SECTION.
    DATA
      size TYPE tsize.
ENDCLASS.

CLASS shirt IMPLEMENTATION.
  METHOD constructor.
    me->size = size.
  ENDMETHOD.
ENDCLASS.

A new variant of the TYPES statement, BEGIN OF ENUMEND OF ENUM, serves as a bracket around a set of constants. The standard base type of the constants is i and the enumerated values are counted up starting with 0.

The usage looks as before:

  DATA(shirt) = NEW shirt( shirt=>size_xl ).

But hey, there’s no need for exception handling any more. If you try to pass an illegal value you get a syntax error!

  DATA(shirt) = NEW shirt( 333 ).

Enumerations are a mixture of types and constants. With BEGIN OF ENUM enum – END OF ENUM enum you declare an elementary type enum that can be used behind the TYPE addition. In between, you declare a set of constants, the so called enumeration constants, that define the enumerated values that are allowed for enumerated objects that have the type enum.  At this position TYPES in fact works as the CONSTANTS statement.

The ABAP runtime environment takes care, that only allowed enumerated values can be assigned to enumerated objects:

TYPES:
  BEGIN OF ENUM tsize,
    size_s,
    size_m,
    size_l,
    size_xl,
  END OF ENUM tsize.

DATA size TYPE tsize.
size = size_xl. "Allowed

DATA dobj LIKE size.
dobj = size. "Allowed

dobj = 333. "Syntax or runtime error

You can assign enumerated objects only to enumerated objects of the same enumerated type and you can compare enumerated objects only with enumerated objects of the same enumerated type. Of course, this includes the enumeration constants itself.

Normally, you are not interested in the contents of an enumerated object at all. The semantics of an enumerated object is defined by the enumeration constant that defines its value. Nevertheless, you can define enumerated types with other base types than i and with other enumerated values (where one value must be initial):

TYPES:
  basetype TYPE c LENGTH 2,
  BEGIN OF ENUM tsize BASE TYPE basetype,
    size_i  VALUE IS INITIAL,
    size_s  VALUE `S`,
    size_m  VALUE `M`,
    size_l  VALUE `L`,
    size_xl VALUE `XL`,
  END OF ENUM tsize.

DATA size TYPE tsize.
size = size_xl. "Allowed

DATA dobj LIKE size.
dobj = size. "Allowed

This enables you to easily transform your existing “enumerated values” to the new concept. If you are lucky, you might be able to this without having to adjust their usage (in fact, I was able to do so for one of my classes).

If you have more than one enumerated type within one context, you might want to organize the respective enumerated values in structures:

TYPES:
  BEGIN OF ENUM tsize STRUCTURE size,
    s,
    m,
    l,
    xl,
  END OF ENUM tsize STRUCTURE size.

DATA dobj TYPE tsize.
dobj = size-xl. "Allowed

With that, you declare a constant enumeration structure size. The components of the structure are the enumeration constants of the enumerated type.

The main usage of enumerated objects is comparing them with the respective enumeration constants in order to branch to some according functionality.

TYPES:
  BEGIN OF ENUM tsize STRUCTURE size,
    s,
    m,
    l,
    xl,
  END OF ENUM tsize STRUCTURE size.

DATA dobj TYPE tsize.

...

CASE dobj.
  WHEN size-s.
    ...
  WHEN size-m.
    ...
  WHEN size-l.
    ...
  WHEN size-xl.
    ...
ENDCASE.

Besides that, there are a few other allowed usages:

You can assign an enumerated object to text fields of type c or text strings of type string. The result is the name of the enumeration constant that defines the current value.

TYPES:
  BEGIN OF ENUM tsize,
    size_s,
    size_m,
    size_l,
    size_xl,
  END OF ENUM tsize.

DATA text TYPE string.
text = size_xl.
cl_demo_output=>display( text ). "Output is SIZE_XL

You can also write

DATA(text) = CONV string( size_xl ).

You can access the current value with the CONV operator by specifying the base type.

TYPES:
  BEGIN OF ENUM tsize,
    size_s,
    size_m,
    size_l,
    size_xl,
  END OF ENUM tsize.

DATA(value) = CONV i( size_xl ) .
cl_demo_output=>display( value ). "Output is 3

The other way around, a valid enumerated value can be converted to an enumerated object (which is not possible in a normal assignment):

TYPES:
  BEGIN OF ENUM tsize,
    size_s,
    size_m,
    size_l,
    size_xl,
  END OF ENUM tsize.

DATA(num) = 3.

TRY.
    DATA(dobj) = CONV tsize( num ) .
    cl_demo_output=>display( dobj ). "Output is SIZE_XL
  CATCH cx_sy_conversion_no_enum_value.
    ...
ENDTRY.

There is also a new class CL_ABAP_ENUMDESCR in RTTI.

TYPES:
  BEGIN OF ENUM tsize,
    size_s,
    size_m,
    size_l,
    size_xl,
  END OF ENUM tsize.

DATA(size) = VALUE tsize( ).

DATA(enum_descr) = CAST cl_abap_enumdescr(
  cl_abap_typedescr=>describe_by_data( size ) ).

cl_demo_output=>new(
  )->write_data( enum_descr->kind            "E, for elementary
  )->write_data( enum_descr->type_kind       "k, new for enumerated type
  )->write_data( enum_descr->base_type_kind  "I, the base type
  )->write_data( enum_descr->members         "Table of constants and values
  )->display( ).

And that’s basically all.

Lean back and let the ABAP runtime environment do the work for you. It takes care that enumerated objects can only be used at appropriate operand positions and that they can only contain their prescribed values. An illegal enumerated value in an enumerated object should never occur (OK, there’s one known gap …).

To report this post you need to login first.

43 Comments

You must be Logged on to comment or reply to a post.

  1. Custodio de Oliveira

    Thanks Horst, I think I can see a few good uses for this.

    TYPES:
      BEGIN OF ENUM tsize,
        size_s,
        size_m,
        size_l,
        size_xl,
      END OF ENUM tsize.
    
    DATA(value) = CONV i( size_xl ) .
    cl_demo_output=>display( value ). "Output is 3

    Why is the output 3? Isn’t ABAP an one based language?

    Cheers,
    Custodio

    (1) 
    1. Horst Keller Post author

      Hi Custodio,

      As I said above,

      “the enumerated values are counted up starting with 0.”

      ABAP follows the general design pattern for enumerations here.

      Horst

      (4) 
  2. Thomas Wuercher

    Hi Horst,

    that’s a big step towards input check simplification and data consistency. What I’m still missing is that one killer feature – integration with domain values from ABAP DDIC when typing with data elements. But I know: this will never happen.

    Regards,
    Thomas

    (6) 
    1. Horst Keller Post author

      “What I’m still missing is that one killer feature – integration with domain values from ABAP DDIC when typing with data elements.”

      You are so right. That was the first question, that crossed my mind, when I’ve seen the enumerations for the first time. In fact, the design is there, it’s only a question of ressources and priorities. Hopefully it will happen.

      (8) 
  3. Peter Inotai

    Hi Horst,
    Sorry, I have some stupid question: what is actually release 7.51?
    When I check Netweaver in the marketplace it seems it has 7.45 kernel, so not really sure if it’s a like a patch for a NW 7.50 system or something new?
    Are there other bigger changes in this release or smaller ones?
    Thanks,
    Peter

    (1) 
    1. Horst Keller Post author

      RTC of 7.51, the successor of 7.50  was planned for today, but postponed a few days.

      -> Yes I am a bit too early, but the temptation to blog in the new community was just too big …
      (and well, Karl Kessler mentioned it too)

      Therefore, pls. just wait a couple of days until official announcement and you’ll see further blogs with other nice stuff.

      (3) 
      1. Peter Inotai

        Thanks a lot for the clarification.
        Peter
        PS: Currently I feel a little bit lost in the new platform, however now I’m happy that there is syntax highlighting for ABAP code. Rendering takes some time, but hopefully it will be improved.

        (0) 
  4. Christian Guenter

     

    Hi Horst,

     

    nice feature, I’m really looking forward to use it.

    By the way, a few days ago i saw a feature in another programming language which I think would be really usefull in ABAP. I’d like to know your opinion.
    Has anybody already thought about inline constant declarations (other terms might be: assign once variable | read-only variable | constant expression | runtime constant)? Which means to use arbitrary expressions on the RHS of a constant declaration and of course that the value of the constant is evaluated during runtime.
    The idea behind this is to remove as much mutable state as possible from our programs and prevent a whole class of subtle bugs. The whole idea of eliminating mutable state from our code is borrowed from functional programming where it is a fundamental paradigm.
    Let me explain the idea with a short code snippet.
    " This is how the syntax of inline constant declaration could look like. The
    " expression on the right side is evaluated during runtime and assigned to the constant.
    " It could be abitrary complex (constructor) expressions and the compiler derives the type
    " in the same it does for other expressions
    CONSTANT(co_title) = |This is an immutable title. My name is { sy-uname }|.
    
    " Any subsequent static assignments result in syntax errors, e.g.
    co_title = |New title|. " SYNTAX ERROR
    " or this one
    instance->method( changing c_text = co_title ). " SYNTAX ERROR
    
    " dynamic assignments result in runtime error
    assign ('CO_TITLE') to field-symbol(<title>).
    <title> = |New title|. "RUNTIME ERROR
    

    By the way that’s what you can do in lots of other programming languages. E.g. C++, and as far as I know the ABAP kernel is programmed in C/C++, well…

    Just an idea, what do you think?

    Regards Christian
    (4) 
    1. Raphael Pacheco
      Cool if this statement comes, having a mutable constant would be really amazing. 🙂

      If I may add, I think it would be cool to put a freezing condition for the constant creation, it is also used in some languages (Like Ruby)

      Br,

      Raphael Pacheco.

       

      (1) 
    2. Horst Keller Post author

      Hi Christian,

      Believe it or not, but the Kernel developers had it already on their minds. Working title “static single assignment”. But for the time being its tentative.

      Best

      Horst

      (4) 
  5. Alexander K

    Hello, Horst.
    Thanks for this blog, it is very interesting information.
    I would like to ask, do you use Eclipse for development or GUI.
    And what kind of development environment for ABAP you can recommends? Maybe Eclipse is the future of ABAP development.
     

    (0) 
    1. Matthew Billingham

      I believe the future of ABAP is in the web based IDE (whose name escapes me).

      I use a mixture of Eclipse and SAPGui in my daily work, but generally prefer SAPGUI, because I find it is actually better suited to software design (as opposed to coding)..

      (0) 
      1. Thomas Fiedler

        Hi Matthew,
        currently we have no plans to integrate ABAP into the Web IDE as there are no plans to integrate ABAP into HCP.

        Eclipse is the development platform of choice for ABAP development. SAP GUI based ABAP workbench is obsolete but still supported for compatibility reasons. Modern concepts like CDS are only supported in eclipse. So the clear recommendation from SAP site is to use Eclipse.

        Kind Regards,
        Thomas.

        (2) 
        1. Matthew Billingham

          Yes, I know you’d like us all to use Eclipse, but I find it more awkward to use – and I really have given it a fair go – I use Eclipse all the time for Java development.

          It may be SAP’s choice, but it ain’t mine. Yet.

          (2) 
    2. Horst Keller Post author

      “I would like to ask, do you use Eclipse for development or GUI.”

      Exactly as Matthew, “I use a mixture of Eclipse and SAPGui in my daily work, but generally prefer SAPGUI”.

      “Maybe Eclipse is the future of ABAP development.”

      Let’s hear Thomas Fiedler about that …

      (2) 
  6. Matthew Billingham

    Converting  semantic error that has to be coded for to a syntax error, is a very good thing. This gives a quick and easily convertible ENUM implementation, but was consideration made (is it being made) to a more class based ENUM implementation – as in Java – with constructors and other methods (like toString) being possible?

    (0) 
    1. Tapio Reisinger

      I found a nice implementation of enumeration classes or better how to simulate them.

      http://stackoverflow.com/questions/20637925/is-it-possible-to-create-an-enumeration-enum-in-abap

      I don’t think it’s too much overhead. You can create nice check and validation methods than, if you need them.

      class CL_CSP_REPOSTING_FUNC definition
        public
        final
        create private .
      
      public section.
      
        class-data STANDARD type ref to CL_CSP_REPOSTING_FUNC read-only .
        class-data ACTUAL type ref to CL_CSP_REPOSTING_FUNC read-only .
        class-data GROUP type ref to CL_CSP_REPOSTING_FUNC read-only .
        data ID type STRING read-only .
      
        class-methods CLASS_CONSTRUCTOR .
      protected section.
      private section.
      
        methods CONSTRUCTOR
          importing
            !I_ID type STRING .
      ENDCLASS.
      
      CLASS CL_CSP_REPOSTING_FUNC IMPLEMENTATION.
      * <SIGNATURE>---------------------------------------------------------------------------------------+
      * | Static Public Method CL_CSP_REPOSTING_FUNC=>CLASS_CONSTRUCTOR
      * +-------------------------------------------------------------------------------------------------+
      * +--------------------------------------------------------------------------------------</SIGNATURE>
        method class_constructor.
      
          cl_csp_reposting_func=>standard = new #('STANDARD').
          cl_csp_reposting_func=>actual = new #('ACTUAL').
          cl_csp_reposting_func=>group = new #('GROUP').
      
        endmethod.
      
      * <SIGNATURE>---------------------------------------------------------------------------------------+
      * | Instance Private Method CL_CSP_REPOSTING_FUNC->CONSTRUCTOR
      * +-------------------------------------------------------------------------------------------------+
      * | [--->] I_ID                           TYPE        STRING
      * +--------------------------------------------------------------------------------------</SIGNATURE>
        method constructor.
      
          me->id = i_id.
      
        endmethod.
      ENDCLASS.
      (3) 
  7. Sandra Rossi

    Hello Horst,
     

    I’m a little perplexed when you say that “The usage looks as before: DATA(shirt) = NEW shirt( shirt=>size_xl ).”
     

    If I read your next examples about assignments to data objects, I guess it should behave the same for parameters, but you don’t mention it explicitly. So, I mean the following should compile too (size_xl instead of shirt=>size_xl): DATA(shirt) = NEW shirt( size_xl ).
     
    Thanks for the clarification.
    Sandra

    (0) 
    1. Horst Keller Post author

       

      Hi Sandra,

      It is simply a question of visibilty. In the first example, the enumeration constants are declared as static components of a class. As always, you have to put class=> before them in order to access them from outside the class. Your DATA(shirt) = NEW shirt( size_xl ). would work inside the class only.

      The following examples for simplicity declare und use enumerated types within the same context (program, class, method, …) and therefore no prefix class=> is needed.

      Best

      Horst

      (1) 
      1. Sandra Rossi

        Oh, really too bad, I’m disappointed ! 🙂

        But, as the type of the parameter is an enumeration, the compiler should be able to locate it automatically in the class pool, and I hope the ABAP team can improve it in next releases.

        Example: the parameter types are all enumerations from the ZCALENDAR class:

        thanksgiving = zcalendar=>get_date( year = ‘2016’ month = november day = thursday month_week = fourth ).

        (0) 
        1. Horst Keller Post author

          “compiler should be able to locate it automatically in the class pool”

          How???

          TYPES:
            BEGIN OF ENUM my_enum,
              c1, c2, c3,
            END OF ENUM my_enum.
          
          CLASS cls DEFINITION.
            PUBLIC SECTION.
              TYPES:
                BEGIN OF ENUM my_enum,
                  c1, c2, c3,
                END OF ENUM my_enum.
          ENDCLASS.
          
          START-OF-SELECTION.
          "You can address c1 and cls=>c1 here!

          Two different types. How should the compiler know which one you mean?

          But OK, I get the idea, you want a short form

          CLASS cls DEFINITION.
            PUBLIC SECTION.
              TYPES:
                BEGIN OF ENUM my_enum,
                  c1, c2, c3,
                END OF ENUM my_enum.
              METHODS m1 IMPORTING p TYPE my_enum.
          ENDCLASS.
          
          CLASS cls IMPLEMENTATION.
            METHOD m1.
            ENDMETHOD.
          ENDCLASS.
          
          START-OF-SELECTION.
          
            NEW cls( )->m1( cls=>c1 ).
            NEW cls( )->m1( c1 ).      "<--- Short form

          If  a parameter is typed with an enum of the same class, always put implicitly cls=> in front of the actual parameter. Let’s see, what the ABAP team says …

          (1) 
  8. Sandra Rossi

    As a data object of type enumeration can only be assigned a member of this enumeration, the compiler should also do the same with a parameter of type enumeration. It means that the compiler should not locate the types as usual based on names and scope, i.e. the type can only be the type of the parameter.

    REPORT ztest.
    TYPES: BEGIN OF ENUM week_day BASE TYPE i,    " \PR:ZTEST\TY:WEEK_DAY
             thursday VALUE 5,
           END OF ENUM week_day.
    CLASS zcalendar DEFINITION.
      PUBLIC SECTION.
        TYPES: BEGIN OF ENUM week_day BASE TYPE i," \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
                 thursday VALUE 5,
               END OF ENUM week_day.
        CLASS-METHODS get_date
          IMPORTING day TYPE week_day             " \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
          RETURNING VALUE(date) TYPE d.
    ENDCLASS.
    CLASS zcalendar IMPLEMENTATION.
      METHOD get_date.
      ENDMETHOD.
    ENDCLASS.
    START-OF-SELECTION.
      DATA(weekday) = VALUE week_day( thursday ).       " \PR:ZTEST\TY:WEEK_DAY
    
      DATA(wd2) = VALUE zcalendar=>week_day( thursday )." \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
    
      DATA(thanksgiving) = zcalendar=>get_date( 
                             day = thursday             " \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
                             ).
    (0) 
    1. Horst Keller Post author

      Your example in “correct” Syntax:

      REPORT.
      
      TYPES: BEGIN OF ENUM week_day BASE TYPE i,    " \PR:ZTEST\TY:WEEK_DAY
               monday VALUE IS INITIAL,
               tuesday VALUE 1,
               wednesday value 2,
               thursday VALUE 3,
               friday VALUE 4,
             END OF ENUM week_day.
      
      CLASS zcalendar DEFINITION.
        PUBLIC SECTION.
        TYPES: BEGIN OF ENUM week_day BASE TYPE i,    " \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
               monday VALUE IS INITIAL,
               tuesday VALUE 1,
               wednesday value 2,
               thursday VALUE 3,
               friday VALUE 4,
             END OF ENUM week_day.
          CLASS-METHODS get_date
            IMPORTING day TYPE week_day             " \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
            RETURNING VALUE(date) TYPE d.
      ENDCLASS.
      
      CLASS zcalendar IMPLEMENTATION.
        METHOD get_date.
        ENDMETHOD.
      ENDCLASS.
      
      START-OF-SELECTION.
        DATA(weekday) = thursday .       " \PR:ZTEST\TY:WEEK_DAY
      
        DATA(wd2) = zcalendar=>thursday ." \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
      
        DATA(thanksgiving) = zcalendar=>get_date( 
                               day = thursday             " \PR:ZTEST\TY:ZCALENDAR\TY:WEEK_DAY
                               ). "<--- Syntax error

      For the time being, the last line gives a syntax error, because the program global constant thursday is not compatible to the class constant thursday. You have to write

      DATA(thanksgiving) = zcalendar=>get_date( 
                               day =  zcalendar=>thursday                                    ).

      or

          DATA(thanksgiving) = zcalendar=>get_date(
                               day = wd2                                      ).

      You want an automatic  zcalendar=> in front of thursday.

      Now let me give you a counter-example (not very realistic, but how should the compiler know?)

      CLASS cls DEFINITION.
        PUBLIC SECTION.
          TYPES:
            BEGIN OF ENUM my_enum,
              c1, c2, c3,
            END OF ENUM my_enum.
          METHODS m1 IMPORTING p TYPE my_enum.
      ENDCLASS.
      
      CLASS cls IMPLEMENTATION.
        METHOD m1.
        ENDMETHOD.
      ENDCLASS.
      
      START-OF-SELECTION.
      
        DATA(c2) = cls=>c1.   "<--- Program variable c2 of type cls=>my_enum with value cls=>c1
      
        NEW cls( )->m1( c2 ). "<---  What should the compiler take, cls=>c1 or cls=>c2 ?

       

       

       

      (1) 
      1. Sandra Rossi

        Agreed. I understand the dilemma now 🙂

        But the compiler is able to take decisions if several symbols have the same names (local versus global scopes or class visibility).

        Couldn’t it decide that it may select the enumeration if there’s no local data object with that name (I guess the rule should be “local data object has priority over enumeration” so that to keep ascending compatibility) ?

        (0) 
        1. Horst Keller Post author

           

          Well, yes it could. But it would open another trap (what is “local”?). Introducing “local” variables later on that by chance  have the same name as an enumeration constant could lead to syntax or even runtime errors.

          The problem of specifying (long) class names in front of static components is not restricted to enumerations anyhow. A general solution could be to introduce explicit aliases for class/Interface names (or to work with objects).

          (0) 
          1. Sandra Rossi

            As I’d really like the enumeration members to be extended to parameter arguments, I’m trying to propose some possible rules here. Anyway, it seems not to be in the plans, so let’s forget it… Thank you very much for your time and argumented clarifications! 🙂

            (0) 
  9. Prashant Sharma

    Hi Horst,
    Its really amazing stuff. But I’m facing below error while using it in ADT.
    SAP_ABA 75A  Cross-Application Component

    Regards,
    Prashant Sharma.

    (0) 
  10. Stefan Faust

    Hello Horst,

    awesome blog with great explanation of the concept. Just went through your latest blogs and learned so many new things! Thanks so much!

     

    I just wanted to add, that maybe it’s worth to mention that the conversion back into the enum type is also possible with CX_SY_CONVERSION_NO_ENUM_VALUE being raised in case the input has no suitable enum value assigned. I found the need for this in case a component needs to work with externally defined configuration input (e.g. DB table, JSON/Text Files etc.) and the enum type.

    TYPES:
      BEGIN OF ENUM tsize,
        size_s,
        size_m,
        size_l,
        size_xl,
      END OF ENUM tsize.
    
    DATA(valueInt) = 3.
    
    TRY.
        DATA(valueEnum) = CONV tsize( valueInt ).
        " work with enum typed data
      CATCH cx_sy_conversion_no_enum_value.
        " do something meaningful
    ENDTRY.

    Best regards,

    Stefan

     

    (1) 
    1. Horst Keller Post author

       

      Yep, that’s documented under Enumerated Objects as follows:

       

      … a valid enumerated value can be converted to an enumerated object:

      ... CONV enum_type( dobj ) ... 
      

      The argument dobj is converted to the base type of the enumerated type  enum_type and CONV returns an enumerated object with this value. Any invalid values raises an exception.

      And in full under CONV – Conversion of Enumerated Types

      I also added it to the blog now, thx for pointing it out.

      Horst

       

      (1) 
  11. Paul Hardy

    I’ve just had a thought.

     

    If the ideal end state is a syntax error if a variable – for example – is typed as TRVOG which has a domain, and in my program I try to assign an invalid value e.g. “H” which is not in the domain.

     

    Even in 7.51 this has not yet been implemented, but was mentioned above as a “killer feature”. Indeed I have seen problems caused by spelling mistakes, assigning nonsense values to variables, then passing them into BAPIS, and the whole thing falls over. it happened to me last week

    While we are blue skying, why not have such a check on domains with value tables as well?

     

    I am going to add to my (incredibly long) “things to look into” list, the idea of creating some sort of code inspector check, to look for precisely this sort of thing. The overhead might well be too high.

     

    I understand the aversion to putting literals in code. The “fat finger” syndrome will almost always end in tears…..

     

    (0) 
    1. Horst Keller Post author

      Problem:

      The simple names

      “false” and “true”

      are not allowed.

      Simple names are already used.

      You need something clumsy as:

      TYPES: 
      BEGIN OF ENUM abap_boolean,
       abap_fls,
       abap_tru,
      END OF enum abap_boolean.

      or as:

      TYPES: 
      BEGIN OF ENUM abap_boolean STRUCTURE abap_boolean_struc,
       false,
       true,
      END OF enum abap_boolean STRUCTURE abap_boolean_struc.

        

       

       

      (1) 
      1. Fabian Lupa

        I just now got what the structure addition does…

        How about this?

        TYPES:
          BEGIN OF ENUM abap_boole BASE TYPE abap_bool STRUCTURE abap_bools
            false VALUE abap_false,
            true  VALUE abap_true,
          END OF ENUM abap_boole STRUCTURE abap_bools.
        
        (...)
        
        METHODS:
          do_stuff IMPORTING ie_sure TYPE abap_boole.
        
        (...)
        
        do_stuff( abap_bools=>true ).
        do_stuff( abap_bools=>false ).
        
        " Do these work without CONV #() ?
        do_stuff( abap_true ).
        do_stuff( abap_false ).
        do_stuff( 'X' ).
        do_stuff( space ).
        do_stuff( abap_undefined ). " Syntax error
        do_stuff( 'E' ). " Syntax error
        (0) 

Leave a Reply