Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call dynamic method without naming parameters

Tags:

abap

I'm calling a method of a class dynamically like this, and it works:

CALL METHOD (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method)
  EXPORTING
    iv_dats      = <lv_value>
  RECEIVING
    rv_timestamp = <ls_import_params>-attr_value.

The problem is that I'm naming the two parameters iv_dats and rv_timestamp.
Not every method has these parameter names so I'm looking for a way to call them without naming the parameters.
I tried like this, but I get many syntax errors.

<ls_import_params>-attr_value = (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method)(<lv_value>).

Is there a correct syntax for my goal to omit the parameter names?

like image 211
Cold_Class Avatar asked Oct 24 '25 15:10

Cold_Class


1 Answers

Unfortunately, you have to name the returning parameter and other parameters too.

The full dynamic calling is explained here in the ABAP documentation

For your example code, that will give this code :

DATA(ptab) = VALUE abap_parmbind_tab( 
    ( name  = 'IV_DATS' 
      kind  = cl_abap_objectdescr=>exporting 
      value = REF #( <lv_value> ) )
    ( name  = 'RV_TIMESTAMP'
      kind  = cl_abap_objectdescr=>receiving
      value = REF #( <ls_import_params>-attr_value ) ) ). 

DATA(etab) = VALUE abap_excpbind_tab( ).

CALL METHOD (gc_zcl_mapping_methods)=>(<ls_import_params>-attr_logic_method) 
    PARAMETER-TABLE ptab 
    EXCEPTION-TABLE etab. 

You may get the name of the returning parameter by using RTTI (here, I suppose that the class is global), you may also adapt it to get other parameter names:

DATA(rtti_class) = CAST cl_abap_objectdescr( 
    cl_abap_typedescr=>describe_by_name( '\CLASS=' && gc_zcl_mapping_methods ) ).

DATA(method) = rtti_class->methods[ name = <ls_import_params>-attr_logic_method ].

DATA(returning_parameter) = method-parameters[ parm_kind = cl_abap_objectdescr=>returning ].

DATA(returning_parameter_name) = returning_parameter-name.

I let you add the handling of exceptions.


ADDENDUM : Minimal, Complete, and Verifiable Example :

Let's say this static call is to be done dynamically :

DATA(result) = VALUE sychar01( ).
DATA(ltxttab) = VALUE rslinltab( ( kind = 'E' numb = 1 param = 'MSGID' value = 'MESSAGEGY9' )
                                 ( kind = 'E' numb = 1 param = 'PRAGMA' value = '##DUMMY' ) ).

cl_abap_syntax_message=>long_text_exists(
  EXPORTING
    p_kind            = 'E'
    p_number          = 1
    p_ltxttab         = ltxttab
  RECEIVING
    p_result          = result
  EXCEPTIONS
    message_not_found = 1 ).

Dynamic version (also, the RECEIVING parameter is being determined dynamically at runtime, but usually it's not needed because its name is known at compile time) :

DATA(rtti_class) = CAST cl_abap_objectdescr(
    cl_abap_typedescr=>describe_by_name( '\CLASS=' && 'CL_ABAP_SYNTAX_MESSAGE' ) ).
DATA(method) = rtti_class->methods[ name = 'LONG_TEXT_EXISTS' ].
DATA(returning_parameter) = method-parameters[ parm_kind = cl_abap_objectdescr=>returning ].
DATA(returning_parameter_name) = returning_parameter-name.
ASSERT returning_parameter_name = 'P_RESULT'. " <=== just for the demo

DATA(ptab) = VALUE abap_parmbind_tab(
    ( name  = 'P_KIND'
      kind  = cl_abap_objectdescr=>exporting
      value = REF #( 'E' ) )
    ( name  = 'P_NUMBER'
      kind  = cl_abap_objectdescr=>exporting
      value = REF #( 1 ) )
    ( name  = 'P_LTXTTAB'
      kind  = cl_abap_objectdescr=>exporting
      value = REF #( ltxttab ) )
    ( name  = returning_parameter_name
      kind  = cl_abap_objectdescr=>receiving
      value = REF #( result ) ) ).

DATA(etab) = VALUE abap_excpbind_tab(
    ( name = 'MESSAGE_NOT_FOUND' value = 1 ) ).

CALL METHOD ('CL_ABAP_SYNTAX_MESSAGE')=>('LONG_TEXT_EXISTS')
  PARAMETER-TABLE ptab
  EXCEPTION-TABLE etab.
like image 56
Sandra Rossi Avatar answered Oct 26 '25 18:10

Sandra Rossi