This is a test message to test the length of the message box.
Login
ABAP Tipp Externe Währung nach Intern
Erstellt von Software-Heroes

ABAP Tipp - Externe Währung nach Intern

Ein kleiner Tipp um Daten aus einer Excel oder CSV-Datei in das korrekte interne Währungsformat zu konvertieren. Eine einfach Konvertierung kann schnell zu Fehlern führen.

Werbung

Heute einmal ein kleiner Tipp um externe Zahlen, die zum Beispiel aus einer Excel Datei kommen, in das interne Währungsformat zu bringen. Hierbei gehen wir vor allem auf Zahlen ein, die als Währung dargestellt und gespeichert werden.

Hinweis: Die gezeigten Screenshots beziehen sich auf die Ausgabe des deutschen Zahlenformats für die formatierten Zahlen mit Währung.

 

Währungsformat

Das Problem ist hier das Währungsformat und wie SAP solche Zahlen im System ablegt. Dazu einmal ein einfaches Beispiel um das "Problem" genauer zu beleuchten.

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 }| ).

 

Dabei erhalten wir das folgende Ergebnis:

 

Dabei musst du wissen, dass die Währung EUR mit zwei Nachkommastellen definiert ist und die Währung JPY keine Nachkommestellen besitzt. Unser externer Input von 123456 verhält sich deshalb im Zahlenfeld und als Ausgabe in EUR korrekt, da wir keine Verschiebung der Nachkommastellen haben. Bereiten wir die gleiche Zahl aber als JPY auf, dann ist diese Zahl um den Faktor 100 zu groß. Dies liegt an der internen Speicherung und der externen Aufbereitung.

 

Aufbereitung

Arbeiten wir mit Währungen benötigen wir daher die korrekte Formatierung und Aufbereitung der Zahlen. Dazu können wir den Funktionsbaustein RS_CONV_EX_2_IN verwenden. Mit entsprechenden Zusatzinformationen berücksicht er die Währung und befüllt das interne Zahlenfeld entsprechend korrekt. Dabei benötigt der Baustein das externe Format in der entsprechenden Sprache (siehe Hinweis).

Für unseren Beispielcode erzeugen wir eine Methode die den Baustein verschalt und verwenden Dabei ein Feld aus dem FI Beleg, um die Aufbereitung nach Währung zu machen. In diesem Fall müssen wir die Währung übergeben, damit der Funktionsbaustein weiß, wie er die Zahl aufbereiten soll.

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.

 

Dazu verwenden wir wieder einige Beispiele und schauen uns die fertige Aufbereitung der Zahl an. Die Beispiele sehen wir folgt aus:

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` ) }| ).

 

Dabei verwenden wir einmal das deutsche und einmal das englische Eingabeformat für Zahlen, um zu sehen, ob die Logik mit verschiedenen Eingaben zurecht kommt. Die Ausgabe der Routine sind nun wie folgt aus:

 

Der Funktionsbaustein erwartet für unser Szenario die deutschen Formate mit Komma und Tausender Punkt. Alle Ausgaben mit einer einstelligen Zahl sind Fehler die der Funktionsbaustein erzeugt hat, weil das Eingabeformat nicht gepasst hat. Wie du sehen kannst ist die "echte" Zahl in JPY nach der Konvertierung viel kleiner im Feld, da Intern ohne Nachkommastellen gespeichert wird.

 

Beispiel

Dazu wie immer noch das gesamte Beispiel als ausführbare Klasse:

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.

 

Fazit

Die Speicherung von Währungen in SAP ist sehr speziell und sollte beachtet werden, wenn mit internen und externen Zahlen gearbeitet wird, vor allem wenn dazu noch gerechnet wird. Mit unserem kleinen Tipp sollte die Konvertierung kein Problem mehr sein.


Enthaltene Themen:
TippExterne WährungKonvertierungRS_CONV_EX_2_IN
Kommentare (0)

ABAP Tipp - CLEAR right

Kategorie - ABAP

Richtig löschen? In diesem Artikel wollen wir uns einmal anschauen, wann es Sinn macht zu löschen und wie du effektiv vorgehen kannst.

12.05.2023

ABAP Tipp - Performance Kettensätze

Kategorie - ABAP

Schauen wir uns hier einmal die Performance beim Bilden von Kettensätzen mit DATA und FIELD-SYMBOL an. Welche Variante wird bei der Performance vorn liegen?

28.04.2023

ABAP Tipp - Adobe Formulare zu groß

Kategorie - ABAP

In diesem kleinen Tipp wollen wir uns anschauen, wieso im schlechtesten Fall Adobe Formulare größer werden, als sie eigentlich sein sollten.

18.11.2022

ABAP - ALV in 2022 noch relevant?

Kategorie - ABAP

Heute mal die scherzhafte Frage, benötigen wir im Jahr 2022 noch Reports die ALV Ausgaben erzeugen? Der Frage wollen wir in diesem Artikel einmal nachgehen.

01.07.2022

ABAP im Wandel

Kategorie - ABAP

Die Programmiersprache ABAP ist bereits seit Jahren im Wandel und modernisiert sich in verschiedenen Konzepten. In diesem Artikel schauen wir uns das einmal im Detail an.

24.06.2022