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: 

Get a reference of a local class at another program

Former Member
0 Kudos

Hello experts! Sorry if this has been asked before, but I couldn't find exactly what I'm searching for.

Within function-pool MIGO (main program of transaction MIGO), there's a local class LCL_MIGO_KERNEL. This class has the private attribute PT_CHANGE_TAKEIT (which is an internal table).

During the execution of MIGO, for a certain criteria, I would like to clear the contents of PT_CHANGE_TAKEIT. Since it's a private attibute, I have managed to create a new public method that just clears it. This method was defined and inplemented within ENHANCEMENT SPOTS available all over SAPLMIGO. My method is ZZ_CLEAR_PT_CHANGE_TAKEIT. So far so good.

Now, I have to call this method. I have found no other ENHANCEMENT SPOTS in SAPLMIGO at a place where I would me able to make the call (eg, don't know if the criteria fits yet).

Inside BADI MB_MIGO_BADI, method LINE_MODIFY, I have just what I need to know if I should clear PT_CHANGE_TAKEIT.

However, inside here I don't have access to the instance of class LCL_MIGO_KERNEL (the instance itself is (SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL)

So far I have managed to get a pointer to the instance with:


  FIELD-SYMBOLS: <lfs_kernel> TYPE ANY.

  ASSIGN ('(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL')
    TO <lfs_kernel>.

So I have the instance of the class, but how can I call my method ZZ_CLEAR_PT_CHANGE_TAKEIT?

The command call method <lfs_kernel>->zz_clear_pt_change_takeit.

can't be done because ""<LFS_KERNEL>" is not a reference variable" as the sintax check tells me.

I have tried stuff like


  CREATE DATA dref TYPE REF TO
             ('\FUNCTION-POOL=MIGO\CLASS=LCL_MIGO_KERNEL').

  ASSIGN dref->* TO <ref>.

but nothing works so far.

I know if LCL_MIGO_KERNEL was a class from SE24 (not a local one), I could just create a field-symbol of that type instead of type ANY and it would work.

Does anyone have an idea how that can be done?

Thank you very much!

1 ACCEPTED SOLUTION

Former Member
0 Kudos

I have managed to do what I needed by calling my method from other ENHANCEMENT SPOTS within SAPLMIGO and some extra coding on MB_MIGO_BADI, but unfortunately I couldn't do what I originaly wanted which was to call a method of a local class from another program, something that could be handy in other situations.

If it's not lack of knowledge by myself and it really can't be done, I think the ABAP OO framework fell just short of having that flexibility, since I can get the field-symbol to point to the instance of the class, but just can't call the method because of syntax issues.

Thanks!

8 REPLIES 8

Former Member
0 Kudos

I have managed to do what I needed by calling my method from other ENHANCEMENT SPOTS within SAPLMIGO and some extra coding on MB_MIGO_BADI, but unfortunately I couldn't do what I originaly wanted which was to call a method of a local class from another program, something that could be handy in other situations.

If it's not lack of knowledge by myself and it really can't be done, I think the ABAP OO framework fell just short of having that flexibility, since I can get the field-symbol to point to the instance of the class, but just can't call the method because of syntax issues.

Thanks!

0 Kudos

I have managed to do what I needed by calling my method from other ENHANCEMENT SPOTS within SAPLMIGO and some extra coding on MB_MIGO_BADI, but unfortunately I couldn't do what I originaly wanted which was to call a method of a local class from another program, something that could be handy in other situations.

If it's not lack of knowledge by myself and it really can't be done, I think the ABAP OO framework fell just short of having that flexibility, since I can get the field-symbol to point to the instance of the class, but just can't call the method because of syntax issues.

Thanks!

Well it seems you already solved, but I got curious and knew how this could be done, so I wanted to prove it and here it is:


* This would be inside the Function group

CLASS lcl_kernel DEFINITION.
  PUBLIC SECTION.
    METHODS:
      zz_clear_pt_change_takeit.
ENDCLASS.                    "lcl_kernel DEFINITION

CLASS lcl_kernel IMPLEMENTATION.
  METHOD zz_clear_pt_change_takeit.
    WRITE 'Dummy! I do nothing!'.
  ENDMETHOD.                    "zz_clear_pt_change_takeit
ENDCLASS.                    "lcl_kernel IMPLEMENTATION

START-OF-SELECTION.

* This is just to create the reference. It corresponds to
* (SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL in your example

  DATA: kernel  TYPE REF TO lcl_kernel.
  CREATE OBJECT kernel.


*----------------- Now your program (which supposedly does not have
*----------------- access to kernel or even lcl_kernel def)
*----------------- would begin

  FIELD-SYMBOLS: <lfs_kernel> TYPE ANY.
  DATA: generic_ref           TYPE REF TO object.

  ASSIGN ('KERNEL')
    TO <lfs_kernel>.
  generic_ref = <lfs_kernel>.

  TRY.
      CALL METHOD generic_ref->('ZZ_CLEAR_PT_CHANGE_TAKEIT').
    CATCH cx_sy_dyn_call_illegal_method .
  ENDTRY.

Apart from that, I wouldn't access a local class this way. There's a reason for blocking the access, one of them being that SAP could change local classes without notice thus breaking your program.

0 Kudos

Thank you very much! I tested this on my scenario and it worked fine!

I tried using almost that same code you sent me but with DATA: generic_ref TYPE REF TO any .

but the syntax check did not allow ANY and I knew if there was a generic class type it would work for me. Even tried TYPE REF TO class, but class is a dictionary structure not related do ABAP OO. I didn't know or remember about the generic type object.

Apart from that, I wouldn't access a local class this way. There's a reason for blocking the access, one of them being that SAP could change local classes without notice thus breaking your program.

Sure, but I just didn't find another way to do what the user wanted - not check subcontracting components for GI when checking the main material for GR - so I had to do it.

Thanks again!

0 Kudos

Y el 05/09, quien gana?

0 Kudos

In fact I haven't tried but now I realize that most probably you can define <lfs_kernel> as TYPE REF TO object itself and then call the method with it directly, avoiding the copy to generic_ref.

The other key part of this workaround is the method call which has to be made dynamically (name between quotes) because the object reference doesn't know at compile time the type of object it will actually hold, so it doesn't recognize the method. However at runtime the object held by the reference is actually of LCL_KERNEL class (it could be downcasted if the class definition was accesible).

Offtopic: No me gusta el futbol pero gana Argentina!

0 Kudos

Unintentional double post.

Former Member
0 Kudos

My reply was duplicated (I'm sure I clicked Post message only once). It seems that SDN is having some issues with the Security Certificate.

Edited by: Sérgio Oliveira on Aug 27, 2009 5:07 PM

0 Kudos

It is quite old but it is in google search so -> You can try this:

DATA lv_migo_class TYPE string VALUE '(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL'.
DATA lv_migo_method TYPE string VALUE 'HEADER_GET'.

  DATA ls_header TYPE gohead. 
  DATA lt_ptab TYPE abap_parmbind_tab.
  DATA lt_etab TYPE abap_excpbind_tab.
  DATA: exc_ref TYPE REF TO cx_sy_dyn_call_error.
  FIELD-SYMBOLS <fo> TYPE   any.
  data lr_o TYPE REF TO object.
    lt_ptab = VALUE #( ( name = 'E_GOHEAD'
                         kind = cl_abap_objectdescr=>importing
                         value = REF #( ls_header ) )
                     ).
    TRY.
        ASSIGN (lv_migo_class) to <fo>.
        lr_o ?= <fo>.
        CALL METHOD lr_o->(lv_migo_method)
          PARAMETER-TABLE
          lt_ptab
          EXCEPTION-TABLE
          lt_etab.
        CASE sy-subrc.
          WHEN 1.
        ENDCASE.
      CATCH cx_sy_dyn_call_error INTO exc_ref.
*        MESSAGE exc_ref->get_text( ) TYPE 'I'.
    ENDTRY.