Skip to Content

Hi there community,

This will be a short blog post, for 2 reasons. First reason, I have some time to kill, but not that much! Second reason, I’m just writing this so I have a place to quickly find some information I keep searching over and over again.

This blog post will be about something that should be VERY clear for any seasoned developer, but unfortunately many times I see things done in a way that is going to fail very often. We are talking about currencies, units, and their external/internal formats and representation.

Writing a value or quantity to the screen or a form

When it comes to units, this is not so critical. The most popular option I have seen for this is WRITE variable TO output_field DECIMALS number_of_decimals. So, if you’re displaying kilos, or square meters, or something like that, most of the times it will work decently. The next thing I see very often is a suppressing of the decimal places if the unit is pieces. Or if the decimal part of the number is zero. So quickly you get a lot of “ifs”, you get added complexity, and as soon as there is a new unit you didn’t think about, this fails.

When it comes to values (as in, money value), this is terrible. I think I have never seen this developed properly in my life. It seems that most people fail to understand that not all currencies were created equal. Most of them have 2 decimals, yes, but some have 3. And some, like my “ex-mother-currency”, have none! Most of the times I don’t even see a WRITE statement, I just see a MOVE TO. And then you get no thousand separator, and the decimal separator is always a point, regardless of where you are. There is also usually a fair amount of logic in the form to make up for this, that is completely unnecessary.

So what should you do?

You should learn more about the WRITE statement. The WRITE statement has very powerful additions CURRENCY and UNIT.

This will make use of the proper representation of the unit or currency you are displaying, and you have no extra work. What more could you ask?

Also, if for any reason there’s a unit or currency in your system that doesn’t seem to have the right format, you can use transaction codes CUNI and OY04 to maintain this output format.

Reading a number from an external format (like an excel sheet or text file)

This is also something that I see terribly implemented almost everywhere. The most popular way of converting a number from an external format (i.e. 1.123,12 for Europe), is to use the REPLACE statement abundantly. Followed by a condense… This works fine as long as this code will always be executed in the same “locale”, but that’s not always the case. And if it’s not, what do you do? As many IF statements as you can think of? Wrong.

So what should you do?

You should use function module MOVE_CHAR_TO_NUM. This function module reads the setting of the user, and will convert the number accordingly. So, assuming the person is uploading numbers that follow the format said person is using in SAP, this will always work.

As mentioned by Shai Sinai below, you can also check out function module RS_CONV_EX_2_IN for this. It looks like you can also provide the currency/table field you are trying to read with this function module, and it will let you know if what the user entered (or equivalent) makes sense.

There are situations where this might still not work. For example, if it’s some sort of background job being executed by a batch user, and this job is supposed to deal with different formats, this will be a hard task to achieve. You will need proper design to deal with this situation.

Conclusion

Now you don’t have an excuse any more to use those silly SAP Script additions, to suppress zeros, to condense, to hide the decimals, etc. Just use the WRITE statement with the correct options.

When it comes to reading a number, if it’s from an excel or a csv file, you are better off using my awesome file reader anyway.

If you have any further suggestions or comments let me know, I can update this blog post.

Cheers,

Bruno

To report this post you need to login first.

10 Comments

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

  1. Nikolay Evstigneev

    Hi Bruno,

    International thinking is always a good idea even if your company operates within single country. How about hardcoding text strings in program without refering to as text elements? If you login in different language, you’ll have to guess almost every step.

    Our company is not international and I had more problems with different settings of Excel while batch uploading of data. So I wrote several small methods to get Excel decimal and thousand separators and in case something goes wrong – to get system separators. Then I can parse “text” numbers as I need.

    (0) 
    1. Bruno Esperança Post author

      Hi Nikolay,

      Yes indeed, don’t even get me started with the language topic 😀

      That topic could start a whole new blog post itself. When I get some more time to kill, maybe I’ll update this post with my ideas regarding that topic as well, or if you want to go ahead and do that, I can point this blog post to yours 😉

      Those methods to get the Excel/system separators sounds very interesting!! Would you care to share it? 🙂

      Cheers,

      Bruno

      (0) 
      1. Nikolay Evstigneev

        Easily. To be honest, the idea of it isn’t mine, it is a result of work of one well-known among our local SAP users guy.

        METHOD get_system_decimal_separator.

           DATA: hkey_current_user TYPE i VALUE 1.

           CLEAR rv_separator.

           CALL FUNCTION ‘GUI_GET_REGVALUE’
             EXPORTING
               root           = hkey_current_user
               key            = ‘Control Panel\International’
               value_name     = ‘sDecimal’
             CHANGING
               string         = rv_separator
             EXCEPTIONS
               registry_error = 1.

           CHECK sysubrc = 1.

           RAISE registry_error.

        ENDMETHOD.


        METHOD get_excel_decimal_separator.

           DATA: lo_app   TYPE ole2_object.
           DATA: lv_usesystemseparators(10).

           CREATE OBJECT lo_app ‘Excel.Application’.
           IF sysubrc = 0.
             GET PROPERTY OF lo_app
               ‘UseSystemSeparators’ = lv_usesystemseparators.
             CALL FUNCTION ‘FLUSH’.

             IF sysubrc <> 0 OR
              ( sysubrc = 0 AND lv_usesystemseparators <> 0 ).

               zcl_utility_print=>get_system_decimal_separator(
                 RECEIVING
                   rv_separator   = rv_separator
                 EXCEPTIONS
                   OTHERS         = 1 ).
             ELSE.
               GET PROPERTY OF lo_app
                 ‘DecimalSeparator’ = rv_separator.
               CALL FUNCTION ‘FLUSH’.
             ENDIF.
           ENDIF.

           FREE OBJECT lo_app.
           CALL FUNCTION ‘FLUSH’.

           IF sy-subrc <> 0.
             RAISE read_error.
           ENDIF.

        ENDMETHOD.

        (0) 
  2. Nick Young

    Hi Bruno,

    I have to say I share your frustration on writing values and quantities, particularly around currency.  I think the problem often starts when developers are creating their own tables or append fields, how often do we see currency fields defined with a Reference Field off
    in some random unrelated table?  If I’m storing or displaying a value of 200, is it 200 USD or 200 INR?  Even without the consideration of decimal places, a monetary value is meaningless without its currency code.

    And as the topic of language came up, it would be amiss of me not to plug my own
    blog on the subject Don’t get lost in translation.

    Regards,

    Nick

    (0) 
    1. Bruno Esperança Post author

      Hi Nick!

      If someone ever thinks of creating an amount/quantity field without the corresponding reference field to unit or currency, seems to me that person should seriously consider changing jobs… 🙂

      I will check your blog post on translations when I have some time, thanks!!

      Cheers,
      Bruno

      (0) 
  3. Joachim Rees

    I’m just writing this so I have a place to quickly find some information I keep searching over and over again.

    a very good reason to write a blog!

    Thanks for sharing!

    Joachim

     

    (1) 

Leave a Reply