Conversion exit is very powerful. It helps to represent data in a different format other than its basic format.
Background
Reader Mohinder asked an question on the previous article SALV ICONs and Tooltips about amount formatting:
As a requirement I need to print $ against a column. I tried by concatenating but didn’t work out since field level properties (Dictionary), sorting/Addition will get affected.
We can certainly achieve to display the Amounts in an Accountant friendly way. Something similar to this:
Conversion Routine
If your first thought is to define a character field on the output, you are wrong. If you create a character field and format the Amount say as per the format above, you will lose some key abilities – Like Total, Sub-total, Sorting etc in an ALV. These are powerful functions and you want to have them for your reports always. So, how to do you solve than? – The answer is Conversion Routines.
For ALV or generically in any case, Conversion Routine is executed just before displaying the data. In ALV, it is executed just before the data packet is sent to GUI control on front end. This flexibility allows all other functions like Total, Subtotal to work as those values are stored without conversion – in native format. Similarly For Forms – SAPScript or SmartForms, as I have covered in this article in past SAPScript / SmartForms Custom Formatting, the data is formatted just before displaying on the form.
Create Conversion Routine
Create the Conversion Routine ZSIGN. Conversion Routine should have two function modules
- CONVERSION_EXIT_ZSIGN_OUTPUT – For displaying the Data from internal values
- CONVERSION_EXIT_ZSIGN_INPUT – For converting the data from external format to interval value
For this demo, I’m not going to create the _INPUT FM as I don’t need it. But you should always create the _INPUT FM as well so, you have all bases covered.
This code snippet converts for Conversion Routine to format values in desired output
CONVERSION_EXIT_ZSIGN_OUTPUT
FUNCTION conversion_exit_zsign_output. *"---------------------------------------------------------------------- *"*"Local Interface: *" IMPORTING *" REFERENCE(INPUT) TYPE DMBTR *" EXPORTING *" REFERENCE(OUTPUT) TYPE CLIKE *"---------------------------------------------------------------------- DATA: lv_dmbtr TYPE bseg-dmbtr. DATA: lv_output TYPE char20. DATA: lv_dmbtr_c TYPE char17. TRY. lv_dmbtr = input. WRITE lv_dmbtr TO lv_dmbtr_c NO-SIGN. CONDENSE lv_dmbtr_c. IF lv_dmbtr LT 0. CONCATENATE '(' lv_dmbtr_c ')' INTO lv_dmbtr_c. ENDIF. * WRITE lv_dmbtr_c TO lv_output RIGHT-JUSTIFIED. * lv_output+0(1) = '$'. CONCATENATE lv_dmbtr_c '$' into lv_output SEPARATED BY ` `. output = lv_output. CATCH cx_root. ENDTRY. ENDFUNCTION.
Few things to note here:
- The INPUT parameter is type as the Amount – DMBTR
- The OUTPUT parameter is type CLIKE as the output would be converted to character like values in the _OUTPUT FM
When you go for _INPUT FM, you need to switch the data type for the INPUT and OUTPUT parameters.
Demo Program to format the Amounts
This is the simple Demo program which I borrowed from the previous Example. You need to specify the Conversion Routine for the column where you need to formatting.
Format Amount in ALV
REPORT ZTEST_NP_SALV_FORMAT_AMOUT. * CLASS lcl_main DEFINITION. PUBLIC SECTION. DATA o_salv TYPE REF TO cl_salv_table . TYPES: BEGIN OF ty_output, status TYPE char10, dmbtr type bseg-dmbtr, END OF ty_output. DATA: t_output TYPE STANDARD TABLE OF ty_output. METHODS: select_data, generate_alv. ENDCLASS. "lcl_main DEFINITION * START-OF-SELECTION. DATA: o_main TYPE REF TO lcl_main. CREATE OBJECT o_main. o_main->select_data( ). o_main->generate_alv( ). * CLASS lcl_main IMPLEMENTATION. METHOD select_data. INCLUDE: <icon>. DATA: ls_output LIKE LINE OF t_output. DO 3 TIMES. ls_output-status = icon_green_light. ls_output-dmbtr = '10000'. APPEND ls_output TO t_output. ls_output-status = icon_yellow_light. ls_output-dmbtr = '-200.00'. APPEND ls_output TO t_output. ls_output-status = icon_red_light. ls_output-dmbtr = '-212.45'. APPEND ls_output TO t_output. ENDDO. ENDMETHOD. "select_Data METHOD generate_alv. DATA: lo_functions TYPE REF TO cl_salv_functions_list. DATA: lo_functional_settings TYPE REF TO cl_salv_functional_settings. DATA: lo_tooltips TYPE REF TO cl_salv_tooltips, lv_value TYPE lvc_value. DATA: lo_columns TYPE REF TO cl_salv_columns. DATA: lo_column TYPE REF TO cl_salv_column_table. INCLUDE: <icon>. * * ALV Object TRY. cl_salv_table=>factory( IMPORTING r_salv_table = o_salv CHANGING t_table = t_output ). CATCH cx_salv_msg. "#EC NO_HANDLER ENDTRY. * Functions lo_functions = o_salv->get_functions( ). lo_functions->set_all( abap_true ). *... set the columns lo_columns = o_salv->get_columns( ). "lo_columns->set_optimize( abap_true ). TRY. lo_column ?= lo_columns->get_column( 'STATUS' ). lo_column->set_icon( if_salv_c_bool_sap=>true ). lo_column->set_long_text( 'Hover for Tooltip' ). lo_column->set_alignment( if_salv_c_alignment=>centered ). lo_column->set_output_length( 20 ). CATCH cx_salv_not_found. "#EC NO_HANDLER ENDTRY. TRY. lo_column ?= lo_columns->get_column( 'DMBTR' ). lo_column->SET_EDIT_MASK( '==ZSIGN' ). "<< CATCH cx_salv_not_found. "#EC NO_HANDLER ENDTRY. *...Tooltips lo_functional_settings = o_salv->get_functional_settings( ). lo_tooltips = lo_functional_settings->get_tooltips( ). TRY. lv_value = icon_green_light. lo_tooltips->add_tooltip( TYPE = cl_salv_tooltip=>c_type_icon VALUE = lv_value tooltip = 'Everything is Processed' ). "#EC NOTEXT CATCH cx_salv_existing. "#EC NO_HANDLER ENDTRY. TRY. lv_value = icon_yellow_light. lo_tooltips->add_tooltip( TYPE = cl_salv_tooltip=>c_type_icon VALUE = lv_value tooltip = 'Partially processed' ). "#EC NOTEXT CATCH cx_salv_existing. "#EC NO_HANDLER ENDTRY. TRY. lv_value = icon_red_light. lo_tooltips->add_tooltip( TYPE = cl_salv_tooltip=>c_type_icon VALUE = lv_value tooltip = 'Nothing Yet processed' ). "#EC NOTEXT CATCH cx_salv_existing. "#EC NO_HANDLER ENDTRY. *... display the table o_salv->display( ). ENDMETHOD. "generate_alv ENDCLASS. "lcl_main IMPLEMENTATION
Output
The output would be like this:
As you can see it deviates a bit from the original requirement. As the fonts on ALV are not “Fixed” fonts, it of the characters has different space. Thus it looks ugly. I couldn’t find any method or style to make the fonts Fixed on ALV Grid yet. When you uncomment the two commented lines and comment the next two from the Conversion routine, you would be able to see these type of output.
Have you used similar approach before?
Very Nice! I haven’t coded a conversion yet and this was a good one. It will come in handy.
Hi Naimesh,
Matches with the requirement. Awesome anwser.
Thanks
Mohinder
Hi Niamesh,
How this can be done for different currency, suppose if i have a report with different currency and i want different functionality based on currency, how can you find which currency you are doing the conversion in the routine.
Thanks
Vijay
Hi,
It can be taken run time too, conversion exit meant for field1(DMBTR). Symbols are not stored against the TCUR, if they are mapped for currency it would have been easier.
It would be interesting to add $,¢,฿,€, against Cuky(currency key) in a table and then to fetch details.
SET_CURRENCY_COLUMN will not solve purpose.
Thanks
Mohinder
Hello Vijay,
The answer to your question is a bit long – Thus created another article on it – Conversion Exit to format Amounts for Specific Currency in ALV.
The idea is like – Have the Currency column before the Amount, have a dummy conversion exit on Currency, Buffer the currency to be used in Amount formatting..
Thanks,
Naimesh Patel
Hi,
A scenario when on document number multiple currencies are used , for countries like Chile/Argentina. Hard Currencies/Local Currencies . Much like T-Code FB03 where LC1,LC2,LC3 fields or BKPF fields HWAER, HWAE2 and HWAE3. I tried with three different conv- routines to populate details.
Document number Amount In local currency1 Amount in Second Currency Amount in Third Currency
456000000 56000 Mex$ 1899$ 1899$
Thanks
Mohinder
Hi namesh,
great tips, very interesting and funcional.
thanks for share your knowledge.
@Mohinder, Thanks for different angle for the solution.
@Billy, I’m glad that you like it.