This is a test message to test the length of the message box.
Login
ABAP Quick External currency to internal
Created by Software-Heroes

ABAP Quick - External currency to internal

A little tip to convert data from an Excel or CSV file into the correct internal currency format. A simple conversion can quickly lead to errors.

Today a little tip to convert external numbers, for example from an Excel file, into the internal currency format. Here we mainly deal with numbers that are displayed and stored as currency.

Hint: The screenshots shown refer to the output of the german number format for the formatted numbers with currency.

 

Currency format

The problem here is the currency format and how SAP stores such numbers in the system. Here is a simple example to shed light on the "problem" in more detail.

DATA:
  ld_internal_number TYPE bseg-wrbtr,
  ld_output          TYPE char20.

ld_internal_number = CONV #( '123456' ).
out->write( |Number: { ld_internal_number }| ).

WRITE ld_internal_number TO ld_output CURRENCY 'EUR'.
out->write( |EUR: { ld_output }| ).

WRITE ld_internal_number TO ld_output CURRENCY 'JPY'.
out->write( |JPY: { ld_output }| ).

 

We get the following result:

 

You have to know that the EUR currency is defined with two decimal places and the JPY currency has no decimal places. Our external input of 123456 therefore behaves correctly in the number field and as an output in EUR, as we have no shift of the decimal places. If we prepare the same number as JPY, then this number is 100 times too large. This is due to the internal storage and the external processing.

 

Editing

If we work with currencies, we therefore need the correct formatting and preparation of the numbers. We can use the RS_CONV_EX_2_IN function block for this. With the corresponding additional information, he takes the currency into account and correctly fills the internal number field accordingly. The block requires the external format in the corresponding language (see hint).

For our example code, we create a method that wraps the module and use a field from the FI document to prepare the currency. In this case we have to transfer the currency so that the function block knows how to process the number.

METHOD convert_number_to_ext.
  CALL FUNCTION 'RS_CONV_EX_2_IN'
    EXPORTING
      input_external               = CONV char80( id_number )
      table_field                  = VALUE tabfield( tabname = 'BSEG' fieldname = 'WRBTR' )
      currency                     = id_currency
    IMPORTING
      output_internal              = rd_result
    EXCEPTIONS
      input_not_numerical          = 1
      too_many_decimals            = 2
      more_than_one_sign           = 3
      ill_thousand_separator_dist  = 4
      too_many_digits              = 5
      sign_for_unsigned            = 6
      too_large                    = 7
      too_small                    = 8
      invalid_date_format          = 9
      invalid_date                 = 10
      invalid_time_format          = 11
      invalid_time                 = 12
      invalid_hex_digit            = 13
      unexpected_error             = 14
      invalid_fieldname            = 15
      field_and_descr_incompatible = 16
      input_too_long               = 17
      no_decimals                  = 18
      invalid_float                = 19
      conversion_exit_error        = 20
      OTHERS                       = 21.
  IF sy-subrc <> 0.
    rd_result = sy-subrc.
  ENDIF.
ENDMETHOD.

 

To do this, we will use a few examples again and look at the finished preparation of the number. The examples look like this:

out->write( |EUR>123456.78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123456.78` ) }| ).
out->write( |EUR>123456,78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123456,78` ) }| ).
out->write( |EUR>123,456.78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123,456.78` ) }| ).
out->write( |EUR>123.456,78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123.456,78` ) }| ).

out->write( |JPY>123456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123456` ) }| ).
out->write( |JPY>123,456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123,456` ) }| ).
out->write( |JPY>123.456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123.456` ) }| ).

 

We use the German and the English input format for numbers to see whether the logic can cope with different inputs. The output of the routine are now as follows:

 

The function module expects the German formats with commas and thousand points for our scenario. All outputs with a single-digit number are errors that the function block generated because the input format did not match. As you can see, the "real" number in JPY is much smaller in the field after the conversion, because it is saved internally without any decimal places.

 

Example

In addition, like the entire example as an executable class:

CLASS zcl_13bs_tst_convert_ext_num DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PROTECTED SECTION.
  PRIVATE SECTION.
    METHODS:
      convert_number_to_ext
        IMPORTING
                  id_number        TYPE string
                  id_currency      TYPE waers
        RETURNING VALUE(rd_result) TYPE bseg-wrbtr.
ENDCLASS.


CLASS zcl_13bs_tst_convert_ext_num IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    out->write( |EUR>123456.78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123456.78` ) }| ).
    out->write( |EUR>123456,78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123456,78` ) }| ).
    out->write( |EUR>123,456.78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123,456.78` ) }| ).
    out->write( |EUR>123.456,78: { convert_number_to_ext( id_currency = 'EUR' id_number = `123.456,78` ) }| ).

    out->write( |JPY>123456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123456` ) }| ).
    out->write( |JPY>123,456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123,456` ) }| ).
    out->write( |JPY>123.456: { convert_number_to_ext( id_currency = 'JPY' id_number = `123.456` ) }| ).
  ENDMETHOD.


  METHOD convert_number_to_ext.
    CALL FUNCTION 'RS_CONV_EX_2_IN'
      EXPORTING
        input_external               = CONV char80( id_number )
        table_field                  = VALUE tabfield( tabname = 'BSEG' fieldname = 'WRBTR' )
        currency                     = id_currency
      IMPORTING
        output_internal              = rd_result
      EXCEPTIONS
        input_not_numerical          = 1
        too_many_decimals            = 2
        more_than_one_sign           = 3
        ill_thousand_separator_dist  = 4
        too_many_digits              = 5
        sign_for_unsigned            = 6
        too_large                    = 7
        too_small                    = 8
        invalid_date_format          = 9
        invalid_date                 = 10
        invalid_time_format          = 11
        invalid_time                 = 12
        invalid_hex_digit            = 13
        unexpected_error             = 14
        invalid_fieldname            = 15
        field_and_descr_incompatible = 16
        input_too_long               = 17
        no_decimals                  = 18
        invalid_float                = 19
        conversion_exit_error        = 20
        OTHERS                       = 21.
    IF sy-subrc <> 0.
      rd_result = sy-subrc.
    ENDIF.
  ENDMETHOD.
ENDCLASS.

 

Conclusion

The storage of currencies in SAP is very special and should be taken into account when working with internal and external numbers, especially when calculating in addition. With our little tip, the conversion should no longer be a problem.


Included topics:
QuickExternal currencyConversionRS_CONV_EX_2_IN
Comments (0)

ABAP Quick - Processing in a new task

Category - ABAP

This tip is about asynchronous processing in a new process and what to look out for.

01/07/2022

ABAP Quick - Convert JSON to internal

Category - ABAP

In this little tip, we'll go into how you can convert a JSON stream to an internal format and then use it properly.

12/10/2021

ABAP Quick - Creation of test data

Category - ABAP

What challenges do you have when setting up test tables and test data and how can machine processing help you?

06/25/2021

ABAP Unit Quick Guide

Category - ABAP

Our current e-book is now available on Amazon, we would like to briefly show you what you can expect in the book and what it will bring you in the end.

05/28/2021

ABAP Quick - RFC Buffer

Category - ABAP

Here is a little tip from us about what can go wrong with the buffer when reading via RFC and what you should definitely pay attention to.

04/23/2021