I’m affraid there might be a standard function module already available to achieve the same what I’m going to write myself, but I believe it is good to know that the number format can be different when different user settings is used in SAP.
If you forget about this during your development you might start fighting serious problems in the future.
Therefore I’ve written two short code snippets for numbers conversion for INPUT (save to database) and OUTPUT (display to the user)
DATA: l_value(8) type c.
CLASS lcl_utils DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
class_constructor,
convert_number_input
CHANGING c_value TYPE any,
convert_number_output
IMPORTING
i_length TYPE i
i_decimals TYPE i
CHANGING c_value TYPE any.
PRIVATE SECTION.
CLASS-DATA:
m_dcpfm TYPE xudcpfm.
ENDCLASS. "lcl_utils DEFINITION
CLASS lcl_utils IMPLEMENTATION.
METHOD class_constructor.
* Read number format from user settings
SELECT SINGLE dcpfm
INTO m_dcpfm
FROM usr01
WHERE bname = sy-uname.
ENDMETHOD.
METHOD convert_number_input.
CASE m_dcpfm.
WHEN ''.
REPLACE ALL OCCURRENCES OF '.' IN c_value WITH ''.
TRANSLATE c_value USING ',.'.
WHEN 'X'.
REPLACE ALL OCCURRENCES OF ',' IN c_value WITH ''.
WHEN 'Y'.
CONDENSE c_value NO-GAPS.
TRANSLATE c_value USING ',.' .
ENDCASE.
ENDMETHOD.
METHOD convert_number_output.
DATA:
lr_data TYPE REF TO data,
lr_var_description TYPE REF TO cl_abap_elemdescr.
FIELD-SYMBOLS:
<fs_data> TYPE ANY.
lr_var_description = cl_abap_elemdescr=>get_p(
p_length = i_length
p_decimals = i_decimals
).
CREATE DATA lr_data TYPE HANDLE lr_var_description.
CHECK lr_data IS BOUND.
ASSIGN lr_data->* TO <fs_data>.
<fs_data> = c_value.
WRITE <fs_data> to c_value.
ENDMETHOD. "CONVERT_NUMBER_OUTPUT
ENDCLASS. "lcl_utils IMPLEMENTATION
START-OF-SELECTION.
l_value = '4.5689'.
WRITE: 'Original: ', l_value.
lcl_utils=>convert_number_output(
EXPORTING
i_length = 8
i_decimals = 2
CHANGING
c_value = l_value
).
WRITE:/ 'Output with length=8 decimals=2: ', l_value.
lcl_utils=>convert_number_input(
CHANGING
c_value = l_value
).
WRITE:/ 'Input: ', l_value.
Thanks a lot for all your help, I’m learning a lot !
I guess the next two standard FM do pretty much the same.
– CONVERSION_EXIT_ALPHA_INPUT
– CONVERSION_EXIT_ALPHA_OUPUT.
Hope it helps.
Hi Kanoe,
I’m affraid you’re not 100% correct 🙂 I tested and it seems the mentioned function modules are not working as expected.
1. Let’s assume I have USR01 settings with display number format = ‘ ‘ (space), which means 123.456,89
2. In database or in your variable you have your number stored as string or 255 char in internal database format (with dot as decimal point with no spaces and no commas) with value ‘12.345’ (this means 12 + 0.345)
3. If you run CONVERSION_EXIT_ALPHA_OUTPUT the result will be…12.345 (this is NOT what I expected)
4. If you run my piece of code lcl_utils=>convert_number_output…the result will be 12,345 (comma is correctly considered as decimal point according to my user settings USR01-DCPFM=’ ‘)
5. The same is experienced in oposite way: FM CONVERSION_EXIT_ALPHA_INPUT with input 12,345 returns…12,345 – this is NOT what I expected
6. My piece of code lcl_utils=>convert_number_input with input 12,345 returns 12.345 (which is correct internal database number format
But I also might be wrong so please let me know if there is something I missed or understood incorrectly.