Avoiding the Pitfalls of Type Conversions

Objectives

After completing this lesson, you will be able to:

  • Avoid the pitfalls of type conversions

Successful Assignments

In ABAP, you are allowed to perform value assignments between variables of different data types. When you do so, ABAP attempts to convert the value of the source field into the type of the target field. Whether the conversion is successful depends on whether the value of the source field is compatible with the data type of the target field.

In the first example here, we are attempting to assign the value of a string to an integer field. Since the value of the string 12345 is a valid integer, the assignment is successful. The second assignment is also successful.

Try It Out - Successful Assignments

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code into the editor between the METHOD if_oo_adt_classrun~main. and ENDMETHOD. statements:
    Code snippet
    
    DATA var_string TYPE string.
    DATA var_int TYPE i.
    DATA var_date TYPE d.
    data var_pack type p length 3 decimals 2.
    
    
    var_string = `12345`.
    var_int = var_string.
    
    
    out->write( 'Conversion successful' ).
    
    
    var_string = `20230101`.
    var_date = var_string.
    
    
    out->write( |String value: { var_string }| ).
    out->write( |Date Value: { var_date date = user }| ).
    Expand
  3. Activate the class by pressing Ctrl + F3.
  4. Play around with the code to familiarize yourself with the topic.

Unsuccessful Assignments

Type conversions in value assignments are not always successful. Sometimes the source value is incompatible with the type of the target field. The two assignments shown here both lead to exceptions which, if left uncaught, lead in turn to runtime errors.

When we try to assign the string value ABCDE to an integer field, the system recognizes that the contents of the string cannot be represented as a number and triggers the exception CX_SY_CONVERSION_NO_NUMBER. In the second example, we try to assign the value 1000 to a packed number with length 3 and 2 decimal places. The variable consequently has 5 digits, of which two are decimal places and hence a maximum value of 999.99. The assignment therefore causes an arithmetic overflow and the system responds with the exception CX_SY_CONVERSION_OVERFLOW .

Truncation and Rounding

Some assignments lead to loss of data or accuracy. If, for example, you assign the value of a character field to a shorter field, the value will be truncated. In the example, we attempted to assign 5 characters to a character field with length 3. In this case, the fourth and fifth characters are lost.

If you assign a value to a numeric field and the number of decimal places in the target field is insufficient, the system will use arithmetic rounding. In the two examples here, one quarter can be represented accurately as 0.25, but one eighth - 0.125 - is rounded up to 0.13.

Try It Out - Truncation and Rounding

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code into the editor between the METHOD if_oo_adt_classrun~main. and ENDMETHOD. statements:
    Code snippet
    
    DATA long_char TYPE c LENGTH 10.
    DATA short_char TYPE c LENGTH 5.
    
    
    DATA result TYPE p LENGTH 3 DECIMALS 2.
    
    
    long_char = 'ABCDEFGHIJ'.
    short_char = long_char.
    
    
    out->write( long_char ).
    out->write( short_char ).
    
    
    result = 1 / 8.
    out->write( |1 / 8 is rounded to { result NUMBER = USER }| ).
    
    
    Expand
  3. Activate the class by pressing Ctrl + F3.
  4. Play around with the code to familiarize yourself with the topic.

Unexpected Results of Assignments

Sometimes the result of an assignment between two different data types can seem unexpected. For example, if you assign a date field to an integer field, the value is the number of days since 01.01.0001. Similarly, if you assign a time field to an integer, the result is the number of seconds since midnight.

If you assign a character field or string to a variable with type N, the system discards any characters that are not digits, arranges the remaining digits right-justified in the field, and fills the remaining spaces with leading zeroes.

A date field is, from a technical point of view, a character field. You can therefore assign values to date fields in ABAP that do not correspond to a valid date (note that this cannot happen when the user enters dates via the UI, as the UI layer validates the date).

Pitfalls of Inline Declarations

When you use inline declarations in arithmetic expressions, the system derives the type of the new variable from the right-hand side of the expression. Since the numeric literals 5 and 10 are integers, the variables result1 and result2 are created as integers as well. While the result of the multiplication is correct, the result of the division is rounded up to 1.

Try It Out - Unexpected Results of Assignments

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code into the editor between the METHOD if_oo_adt_classrun~main. and ENDMETHOD. statements:
    Code snippet
    
    DATA var_date TYPE d.
    DATA var_int TYPE i.
    DATA var_string TYPE string.
    DATA var_n TYPE n LENGTH 4.
    
    var_date = cl_abap_context_info=>get_system_date( ).
    var_int = var_date.
    
    out->write( |Date as date| ).
    out->write( var_date ).
    out->write( |Date assigned to integer| ).
    out->write( var_int ).
    
    var_string = `R2D2`.
    var_n = var_string.
    
    out->write( |String| ).
    out->write( var_string ).
    out->write( |String assigned to type N| ).
    out->write( var_n ).
    Expand
  3. Activate the class by pressing Ctrl + F3.
  4. Play around with the code to familiarize yourself with the topic.

Conversions of Forced Type

Watch this video to learn how to force type conversions explicitly and implicitly.

Try It Out - Conversions of Forced Type

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code into the editor between the METHOD if_oo_adt_classrun~main. and ENDMETHOD. statements:
    Code snippet
    
    * result has type C.
    * and is displayed unformatted in the console
    DATA(result1) = '20230101'.
    out->write( result1 ).
    
    
    * result2 is forced to have type D
    * and is displayed with date formatting in the console
    DATA(result2) = CONV d( '20230101' ).
    out->write( result2 ).
    
    
    
    
    * The method do_something( ) has an importing parameter of type string.
    * Attempting to pass var results in a syntax error
    * The CONV #( ) expression converts var into the expected type
    * Note that CONV #( ) can lead to conversion exceptions
    
    
    * lcl_class=>do_something( var ).
    Expand
  3. Activate the class by pressing Ctrl + F3.
  4. Play around with the code to familiarize yourself with the topic.

Prevention of Truncation and Rounding

Watch this video to learn how to prevent truncation and rounding.

Try It Out - Prevention of Truncation and Rounding

  1. Create a new class that implements the interface IF_OO_ADT_CLASSRUN.
  2. Copy the following code into the editor between the METHOD if_oo_adt_classrun~main. and ENDMETHOD. statements:
    Code snippet
    
    DATA var_date TYPE d.
    DATA var_pack TYPE p LENGTH 3 DECIMALS 2.
    DATA var_string TYPE string.
    DATA var_char TYPE c LENGTH 3.
    
    
    var_pack = 1 / 8.
    out->write( |1/8 = { var_pack NUMBER = USER }| ).
    
    
    TRY.
    var_pack = EXACT #( 1 / 8 ).
    CATCH cx_sy_conversion_error.
    out->write( |1/8 has to be rounded. EXACT triggered an exception| ).
    ENDTRY.
    
    
    var_string = 'ABCDE'.
    var_Char = var_string.
    out->write( var_char ).
    
    
    TRY.
    var_char = EXACT #( var_string ).
    CATCH cx_sy_conversion_error.
    out->write( 'String has to be truncated. EXACT triggered an exception' ).
    ENDTRY.
    
    
    var_date = 'ABCDEFGH'.
    out->write( var_Date ).
    
    
    TRY.
    var_date = EXACT #( 'ABCDEFGH' ).
    CATCH cx_sy_conversion_error.
    out->write( |ABCDEFGH is not a valid date. EXACT triggered an exception| ).
    ENDTRY.
    
    
    var_date = '20221232'.
    out->write( var_date ).
    
    
    TRY.
    var_date = EXACT #( '20221232' ).
    CATCH cx_sy_conversion_error.
    out->write( |2022-12-32 is not a valid date. EXACT triggered an exception| ).
    ENDTRY.
    
    
    Expand
  3. Activate the class by pressing Ctrl + F3.
  4. Play around with the code to familiarize yourself with the topic.

Log in to track your progress & complete quizzes