Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

How to determine current method / interface method that is running?

lars_verbchels
Explorer
0 Kudos
2,293

Hi experts,

I want to determine what method is currently running.

Backgourd:

I have one implementaton of a BAdI method. In this method I want to call other methods of other classes that implement the BAdIs interface. This call must be dynamic.

For that reason I need to know what method of what class/interface is currently running. So that I can call the same method, but in another class.

Thanks for your help.

Best regards

Lars

1 ACCEPTED SOLUTION

uwe_schieferstein
Active Contributor
0 Kudos
404

Hello Lars

Did not read your question carefully enough. Below you see another sample coding which might do the trick.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_GET_CLASS_METHOD
*&
*&---------------------------------------------------------------------*
*& Thread: How to determine current method / interface method that is running?
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="813014"></a>
*&---------------------------------------------------------------------*

REPORT  ZUS_SDN_GET_CLASS_METHOD.

" BAdI ME_PROCESS_PO_CUST
DATA: go_badi        type ref to IF_EX_ME_PROCESS_PO_CUST.


START-OF-SELECTION.


" Simulate instantiation of BAdI and calling of interface method
  create object go_badi type ('ZCL_EX_ME_PROCESS_PO_CUST').
  go_badi->initialize( ).


END-OF-SELECTION.

And here is the coding of the interface method:


METHOD if_ex_me_process_po_cust~initialize.
* define local data
  DATA: lo_badi        TYPE REF TO if_ex_me_process_po_cust,
        lo_typedescr   TYPE REF TO cl_abap_typedescr,
        lo_classdescr  TYPE REF TO cl_abap_classdescr,
        ld_clsname     TYPE string,
        ld_msg         TYPE bapi_msg.

  data: lt_callstack   type ABAP_CALLSTACK,
        ls_callstack   type ABAP_CALLSTACK_LINE.


  CALL METHOD cl_abap_classdescr=>describe_by_object_ref
    EXPORTING
      p_object_ref         = me
    RECEIVING
      p_descr_ref          = lo_typedescr
    EXCEPTIONS
      reference_is_initial = 1
      OTHERS               = 2.
  IF sy-subrc  <> 0.
*   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  CHECK ( lo_typedescr IS BOUND ).
**  lo_classdescr ?= lo_typedescr.


  ld_clsname = lo_typedescr->get_relative_name( ).
  CONCATENATE 'Class' ld_clsname
    INTO ld_msg SEPARATED BY ' = '.
  MESSAGE ld_msg TYPE 'I'.


  CALL FUNCTION 'SYSTEM_CALLSTACK'
*   EXPORTING
*     MAX_LEVEL          = 0
    IMPORTING
      CALLSTACK          = lt_callstack
*     ET_CALLSTACK       =
            .

  read table lt_callstack into ls_callstack index 1. " current block
  message ls_callstack-blockname  type 'I'.


ENDMETHOD.

Obviously, it does not make sense to use this coding in every interface method you are interested in. Instead place the coding into a static method and check which entry of the callstack (probably index = 2) you have to read.

Regards

Uwe

9 REPLIES 9

Former Member
0 Kudos
404

Hi,

Sorry I don't have an answer to your question, but this might solve your problem:

Did you try to set Multiple Use flag of your Enhancement Spot associated to your BAdI? Doing so, you will be able to call the relevant method of all active classes implementing the BAdI interface.

Regards,

Tanguy

0 Kudos
404

Hi Tanguy,

I don't want to use multiple implementations, because the sequence the implementations are called can not be forced. So I want to use only one implementation and then call the other implementations via cunstomizing table.

The other reason is, that consultants often can not program ABAP and are not able to activate or deactivate such implementations. In customizing this is very easy for any consultant.

Best regards

Lars

uwe_schieferstein
Active Contributor
0 Kudos
404

Hello Lars

Here is a simple piece of coding which could be useful to you (assuming you have the RTTI classes available on your system):


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_GET_CLSNAME
*&
*&---------------------------------------------------------------------*
*&
*&
*&---------------------------------------------------------------------*

REPORT  zus_sdn_get_clsname.


DATA: gif_msglist    TYPE REF TO if_reca_message_list,
      go_typedescr   TYPE REF TO cl_abap_typedescr,
      go_classdescr  TYPE REF TO cl_abap_classdescr,
      gd_clsname     TYPE string.


START-OF-SELECTION.

  gif_msglist = cf_reca_message_list=>create( ).

  CALL METHOD cl_abap_classdescr=>describe_by_object_ref
    EXPORTING
      p_object_ref         = gif_msglist
    RECEIVING
      p_descr_ref          = go_typedescr
    EXCEPTIONS
      reference_is_initial = 1
      OTHERS               = 2.
  IF sy-subrc <> 0.
*   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  CHECK ( go_typedescr IS BOUND ).
  go_classdescr ?= go_typedescr.


  gd_clsname = go_typedescr->get_relative_name( ).
  WRITE: / 'Class =', gd_clsname.


END-OF-SELECTION.

Regards

Uwe

0 Kudos
404

Hi Uwe,

I already use cl_abap_classdescr, but it will only return the name of the class. I need the name of the method, that I am currently running. Something like sy-repid, but this variable only contains the class name at this specific time.

Best regards

Lars

0 Kudos
404

Lars,

wouldn't it just be better to deactivate all the other implementations and move everything over to ONE active implementation and then use a customizing table. In this way (customizing) you can also control the order in which the 'implementations' are called.

The other methods will be called anyway, and this way, they will be called twice. I'm not sure if this is what you want.

Sorry if this isn't really the answer you were looking for, but in my opinion it would be 'cleaner' coding.

0 Kudos
404

Hi Micky,

this would perhaps be the usual way. But we have our own namespace for customer developments. And if I transport our "one and only" active implementation to the customer, the implementation can not be changed anymore (only as modification), if some new logic has to be developed.

I am looking for some lines of code, that I can put in any BAdI method. These lines of code should be able to call other methods of inactive BAdI implementations or classes that implement the BAdI's interface. All these calls should be dynamic.

So I have only one active BAdI implementation withing our own namespace active at the customer. All other BAdI methods should be called via customizing tables. This enables the customer to call methods of own Z-implementations of BAdIs or classes also via customizing, without modifying our code.

Best regards

Lars

uwe_schieferstein
Active Contributor
0 Kudos
405

Hello Lars

Did not read your question carefully enough. Below you see another sample coding which might do the trick.


*&---------------------------------------------------------------------*
*& Report  ZUS_SDN_GET_CLASS_METHOD
*&
*&---------------------------------------------------------------------*
*& Thread: How to determine current method / interface method that is running?
*& <a class="jive_macro jive_macro_thread" href="" __jive_macro_name="thread" modifiedtitle="true" __default_attr="813014"></a>
*&---------------------------------------------------------------------*

REPORT  ZUS_SDN_GET_CLASS_METHOD.

" BAdI ME_PROCESS_PO_CUST
DATA: go_badi        type ref to IF_EX_ME_PROCESS_PO_CUST.


START-OF-SELECTION.


" Simulate instantiation of BAdI and calling of interface method
  create object go_badi type ('ZCL_EX_ME_PROCESS_PO_CUST').
  go_badi->initialize( ).


END-OF-SELECTION.

And here is the coding of the interface method:


METHOD if_ex_me_process_po_cust~initialize.
* define local data
  DATA: lo_badi        TYPE REF TO if_ex_me_process_po_cust,
        lo_typedescr   TYPE REF TO cl_abap_typedescr,
        lo_classdescr  TYPE REF TO cl_abap_classdescr,
        ld_clsname     TYPE string,
        ld_msg         TYPE bapi_msg.

  data: lt_callstack   type ABAP_CALLSTACK,
        ls_callstack   type ABAP_CALLSTACK_LINE.


  CALL METHOD cl_abap_classdescr=>describe_by_object_ref
    EXPORTING
      p_object_ref         = me
    RECEIVING
      p_descr_ref          = lo_typedescr
    EXCEPTIONS
      reference_is_initial = 1
      OTHERS               = 2.
  IF sy-subrc  <> 0.
*   MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
*              WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.
  CHECK ( lo_typedescr IS BOUND ).
**  lo_classdescr ?= lo_typedescr.


  ld_clsname = lo_typedescr->get_relative_name( ).
  CONCATENATE 'Class' ld_clsname
    INTO ld_msg SEPARATED BY ' = '.
  MESSAGE ld_msg TYPE 'I'.


  CALL FUNCTION 'SYSTEM_CALLSTACK'
*   EXPORTING
*     MAX_LEVEL          = 0
    IMPORTING
      CALLSTACK          = lt_callstack
*     ET_CALLSTACK       =
            .

  read table lt_callstack into ls_callstack index 1. " current block
  message ls_callstack-blockname  type 'I'.


ENDMETHOD.

Obviously, it does not make sense to use this coding in every interface method you are interested in. Instead place the coding into a static method and check which entry of the callstack (probably index = 2) you have to read.

Regards

Uwe

0 Kudos
404

Hi Uwe,

your idea with the SYSTEM_CALLSTACK function module looks good. I will try this next week and then give you feedback.

Thanks.

Best regards

Lars

0 Kudos
404

Hi Uwe,

I tested the function module SYSTEM_CALLSTACK. With the current call stack I can always determine which method is running.

Great idea !

Thanks.

Best regards

Lars