Application Development Blog Posts
Learn and share on deeper, cross technology development topics such as integration and connectivity, automation, cloud extensibility, developing at scale, and security.
cancel
Showing results for 
Search instead for 
Did you mean: 
saranramu
Explorer

Introduction:


In ABAP, we have several conversion routines available to convert data into external or internal formats. In the new syntax, we can only directly use the ALPHA conversion routine. For other conversion exit function modules, we need to call their respective functions.

In the FOR syntax, it is not possible to directly use other conversion exit function modules. However, the proposed solution will help us to overcome the issue.

Problem Statement:


Normally, when we need to convert fields within an internal table, we call the respective conversion exit function modules inside a LOOP and ENDLOOP block. When utilizing the new syntax to iterate through an internal table, we use the FOR syntax.

In a FOR loop, we can only utilize the ALPHA conversion routine for conversions in both input and output directions. To perform other conversions, we still need to revert to using a LOOP and ENDLOOP construct.
  SELECT vbeln,posnr, matnr, kwmeng, vrkme
FROM vbap
INTO TABLE @DATA(lt_vbap)
WHERE vbeln IN @s_vbeln.
IF sy-subrc = 0.

LOOP AT lt_vbap INTO DATA(ls_vbap).

CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
EXPORTING
input = ls_vbap-matnr
IMPORTING
output = ls_vbap-matnr.

APPEND VALUE #( converted_matnr = ls_vbap-matnr ) TO lt_display.

ENDLOOP.

cl_demo_output=>display( lt_display ).

ENDIF.

 

Proposed Solution:


To avoid LOOP and ENDLOOP for conversions, we have to do the following steps in our program.

Step 1: Create a local class for the conversion routine. Based on our requirements, define one or more methods within the class. These method(s) should have a RETURNING VALUE parameter that stores the output of the method(s).
CLASS lcl_conversion_routine DEFINITION.

PUBLIC SECTION.
METHODS:
matnr_input IMPORTING iv_matnr TYPE matnr
RETURNING VALUE(rv_matnr) TYPE matnr,

matnr_output IMPORTING iv_matnr TYPE matnr
RETURNING VALUE(rv_matnr) TYPE matnr,

menge_output IMPORTING iv_menge TYPE any
iv_meins TYPE meins
RETURNING VALUE(rv_menge) TYPE char17,

meins_output IMPORTING iv_meins TYPE meins
RETURNING VALUE(rv_meins) TYPE meins.
ENDCLASS.

Step 2: In the method implementation, call the respective function modules by passing importing and returning parameters.
CLASS lcl_conversion_routine IMPLEMENTATION.

METHOD matnr_input.

*& Material Conversion External to Internal.
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = iv_matnr
IMPORTING
output = rv_matnr
EXCEPTIONS
length_error = 1
OTHERS = 2 ##FM_SUBRC_OK.

ENDMETHOD.

METHOD matnr_output.

*& Material Conversion Internal to External.
CALL FUNCTION 'CONVERSION_EXIT_MATN1_OUTPUT'
EXPORTING
input = iv_matnr
IMPORTING
output = rv_matnr ##FM_SUBRC_OK.

ENDMETHOD.

METHOD meins_output.

*& Unit of Measure Internal to External Format.
CALL FUNCTION 'CONVERSION_EXIT_CUNIT_OUTPUT'
EXPORTING
input = iv_meins
IMPORTING
output = rv_meins
EXCEPTIONS
unit_not_found = 1
OTHERS = 2 ##FM_SUBRC_OK.

ENDMETHOD.

METHOD menge_output.

*& Quantity Internal to External Format.
WRITE iv_menge TO rv_menge UNIT iv_meins.

ENDMETHOD.

ENDCLASS.

TYPES: BEGIN OF ty_display,
unconverted_matnr TYPE text30,
converted_matnr TYPE text30,
unconverted_menge TYPE text30,
converted_menge TYPE text30,
unconverted_meins TYPE text30,
converted_meins TYPE text30,
END OF ty_display.

DATA: lt_display TYPE TABLE OF ty_display.

Step 3: In this scenario, need to convert the Material, Quantity and Unit of measure to external format. Create an object for the class and call the respective methods to convert field values to external format.
  SELECT vbeln,posnr, matnr, kwmeng, vrkme
FROM vbap
INTO TABLE @DATA(lt_vbap)
WHERE vbeln IN @s_vbeln.
IF sy-subrc = 0.

lt_display = VALUE #( LET lo_conversion = NEW lcl_conversion_routine( ) IN
FOR ls_vbap IN lt_vbap
( unconverted_matnr = ls_vbap-matnr
unconverted_menge = ls_vbap-kwmeng
unconverted_meins = ls_vbap-vrkme
converted_matnr = lo_conversion->matnr_output( iv_matnr = ls_vbap-matnr )
converted_menge = lo_conversion->menge_output( iv_menge = ls_vbap-kwmeng
iv_meins = ls_vbap-vrkme )
converted_meins = lo_conversion->meins_output( iv_meins = ls_vbap-vrkme ) ) ).

lt_display = VALUE #( LET lt_external_values = lt_display
lo_conversion = NEW lcl_conversion_routine( ) IN
BASE lt_display
FOR ls_external_value IN lt_external_values
( unconverted_matnr = ls_external_value-converted_matnr
converted_matnr = lo_conversion->matnr_input( iv_matnr = CONV matnr( ls_external_value-converted_matnr ) ) ) ).

cl_demo_output=>display( lt_display ).

ENDIF.

Output of the program:




Conclusion:


By this way, we can use any conversion routines in the FOR syntax without calling the function modules directly. hope this will helpful.

 

 

 

 

 
10 Comments
Thankyou Saran, It's really helpful👌
Sandra_Rossi
Active Contributor
What about making it fully generic? (conversion exit name as a parameter, only two methods, INPUT and OUTPUT)

 
svj1010
Explorer
very good
saranramu
Explorer
Hi Sandra,

Obviously, we can make it more generic. We need to pass the function module name along with the corresponding input fields as input parameters.
CLASS lcl_conversion_routine DEFINITION.

PUBLIC SECTION.
METHODS conversion IMPORTING iv_conv_exit TYPE rs38l_fnam
iv_input TYPE any
RETURNING VALUE(ev_output) TYPE string.
ENDCLASS.

CLASS lcl_conversion_routine IMPLEMENTATION.
METHOD conversion.
CALL FUNCTION iv_conv_exit " Function Module Name
EXPORTING
input = iv_input " Input
IMPORTING
output = ev_output. " Output
ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

SELECT vbeln,posnr, matnr, kwmeng, vrkme
FROM vbap
INTO TABLE @DATA(lt_vbap)
WHERE vbeln IN @s_vbeln.

lt_display = VALUE #( LET lo_conversion = NEW lcl_conversion_routine( ) IN
FOR ls_vbap IN lt_vbap
( unconverted_matnr = ls_vbap-matnr
converted_matnr = lo_conversion->conversion( iv_conv_exit = 'CONVERSION_EXIT_MATN1_OUTPUT'
iv_input = ls_vbap-matnr ) ) ).


lt_display = VALUE #( LET lt_external_values = lt_display
lo_conversion = NEW lcl_conversion_routine( ) IN
BASE lt_display
FOR ls_external_value IN lt_external_values
( unconverted_matnr = ls_external_value-converted_matnr
converted_matnr = lo_conversion->conversion( iv_conv_exit = 'CONVERSION_EXIT_MATN1_INPUT'
iv_input = ls_external_value-converted_matnr ) ) ).

cl_demo_output=>display( lt_display ).
shrikantpatil
Explorer
0 Kudos
Hi Saran,

In the FOR Syntax, It is possible to use conversion routine. You can refer below block of code.
TYPES: BEGIN OF gty_vbap,
vbeln_in TYPE vbap-vbeln,
vbeln_out TYPE vbap-vbeln,
posnr TYPE vbap-posnr,
matnr_in TYPE vbap-matnr,
matnr_out TYPE vbap-matnr,
meins_out TYPE vbap-vrkme,
END OF gty_vbap,
tt_vbap TYPE STANDARD TABLE OF gty_vbap WITH DEFAULT KEY.

DATA: gt_vbap TYPE STANDARD TABLE OF gty_vbap.

SELECT vbeln,posnr, matnr, kwmeng, vrkme
FROM vbap
INTO TABLE @DATA(lt_vbap)
UP TO 200 ROWS.

IF lt_vbap[] IS NOT INITIAL.
gt_vbap = VALUE tt_vbap( FOR ls_vbap IN lt_vbap
( vbeln_in = |{ ls_vbap-vbeln ALPHA = IN }| "Add leading zeros
vbeln_out = |{ ls_vbap-vbeln ALPHA = OUT }| "Remove leading zeros
posnr = ls_vbap-posnr
matnr_in = |{ ls_vbap-matnr ALPHA = IN }| "Add leading zeros
matnr_out = |{ ls_vbap-matnr ALPHA = OUT }| "Remove leading zeros
meins_out = |{ ls_vbap-vrkme ALPHA = OUT }|
) ).
ENDIF.

Also, its just a suggestion which basically makes your code simple & easy to understand.

Thanks

 
saranramu
Explorer
Hi Shrikant Patil,

The ALPHA IN/OUT conversion routines are only used for removing and adding leading zeros. They are not applicable for other conversion routines such as Material - MATN1, UoM - CUNIT, etc.

To change internal or external formats, we need to use the respective conversion exits. In regular ABAP, we can call the conversion exit directly. However, when using the FOR syntax, we cannot directly call the Function Module. Instead, we require a wrapper method to accomplish the same task.

I hope this is clear to you. Thank you.
shrikantpatil
Explorer
Hi Saran,

Yes, I got your point. It's not gonna work for CUNIT.
Sandra_Rossi
Active Contributor
Thanks. Too much generic for me, I'd keep one method per "direction", but it's personal 😉
DATA(convert_matn1) = zcl_converter=>create( 'MATN1' ).
ASSERT convert_matn1->out( '00000000000000515' ) = '515'.
ASSERT convert_matn1->in( '515' ) = '00000000000000515'.
Jelena
Active Contributor
0 Kudos
Thanks for sharing! If someone really needs to use these conversion routines, it's definitely helpful. I haven't used them in ages though because ALV and SAP Gateway (for OData services) provide great support for these conversions out of the box. It is important to reference correct data types. Too many times I see conversion called unnecessarily where a better reference could solve it. So, good approach but check first if it's actually required. 🙂

It would be neat though to have built-in conversion similar to ALPHA.
here is the class for your code. no need to pass FM name, CONVEXIT name dynamically read using class cl_abap_typedescr=>describe_by_data and ddic_object->get_ddic_object. works for variables declared with DDIC.
CLASS zcl_convexit DEFINITION
PUBLIC
CREATE PRIVATE .

PUBLIC SECTION.
INTERFACES zif_convexit.

ALIASES in
FOR zif_convexit~in.

ALIASES out
FOR zif_convexit~out.

CLASS-METHODS create
IMPORTING
convexit TYPE convexit OPTIONAL
RETURNING
VALUE(r_convexit) TYPE REF TO zcl_convexit.

METHODS constructor
IMPORTING
convexit TYPE convexit .

PROTECTED SECTION.
PRIVATE SECTION.
METHODS get_fnam
IMPORTING
input TYPE any
in_out TYPE char1 DEFAULT 'I'
convexit TYPE convexit OPTIONAL
RETURNING
VALUE(fm_nam) TYPE rs38l_fnam.

CONSTANTS:
BEGIN OF gc,
in TYPE c LENGTH 1 VALUE 'I',
out TYPE c LENGTH 1 VALUE 'O',
END OF gc.
DATA default_convexit TYPE convexit.

ENDCLASS.

CLASS zcl_convexit IMPLEMENTATION.

METHOD constructor.
default_convexit = convexit.
ENDMETHOD.

METHOD create.
r_convexit = NEW zcl_convexit( convexit ).
ENDMETHOD.


METHOD get_fnam.

DATA lv_convexit TYPE convexit.

IF convexit IS SUPPLIED.
lv_convexit = convexit.
ELSEIF default_convexit IS NOT INITIAL .
lv_convexit = default_convexit.
ELSE.

DATA(ddic_object) = cl_abap_typedescr=>describe_by_data( input ).

ddic_object->get_ddic_object(
RECEIVING
p_object = DATA(ddic_tab)
EXCEPTIONS
not_found = 1
no_ddic_type = 2
OTHERS = 3 ).
IF sy-subrc = 0 .
DATA(ls_ddic_tab) = VALUE #( ddic_tab[ 1 ] DEFAULT space ).
lv_convexit = ls_ddic_tab-convexit.
ENDIF.
ENDIF.

IF lv_convexit IS INITIAL.
lv_convexit = 'ALPHA'.
ENDIF.

IF in_out = 'I'.
fm_nam = 'CONVERSION_EXIT_' && lv_convexit && '_INPUT'.
ELSE.
fm_nam = 'CONVERSION_EXIT_' && lv_convexit && '_OUTPUT'.
ENDIF.


CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = fm_nam " Name of Function Module
EXCEPTIONS
function_not_exist = 1 " X
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR fm_nam.
ENDIF.

ENDMETHOD.

METHOD in.

IF quom IS SUPPLIED.
"Quantity. in-progress

ELSEIF curkey IS SUPPLIED.
"Currency. in-progress
ELSE.

DATA(fm_nam) = get_fnam( input = input in_out = gc-in ).

IF fm_nam IS NOT INITIAL.
CALL FUNCTION fm_nam " Function Module Name
EXPORTING
input = input " Input
IMPORTING
output = output. " Output
ELSE.
output = input.
ENDIF.
ENDIF.
ENDMETHOD.

METHOD out.
IF quom IS SUPPLIED.
"Quantity.in-progress

ELSEIF curkey IS SUPPLIED.
"Currency. in-progress
ELSE.
DATA(fm_nam) = get_fnam( input = input in_out = gc-out ).

IF fm_nam IS NOT INITIAL.
CALL FUNCTION fm_nam " Function Module Name
EXPORTING
input = input " Input
IMPORTING
output = output. " Output
ELSE.
output = input.
ENDIF.
ENDIF.

ENDMETHOD.

ENDCLASS.

 
Labels in this area