02-03-2009 2:09 PM
Hi,
I implemented the MB_MIGO_BADI and, in the method if_ex_mb_migo_badi~pbo_detail, i need to access the PT_GOITEM table (that is an attribut of class LCL_MIGO_KERNEL).
In ABAP debugger, this table can be access with this line :
(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL->PT_GOITEM[]
But i can't find a solution to access this table in my program.
The only thing i can access is the class LCL_MIGO_KERNEL, using this code :
DATA lv_class TYPE string.
lv_class = '(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL'.
ASSIGN (lv_class) TO <fs_kernel>.
I tried to add the PT_GOITEM to lv_class but in this case, the assign return a sy-subrc = 4.
Is anybody knows a solution to access to this table ?
Edited by: Olivier Abbeloos on Feb 3, 2009 3:09 PM
Edited by: Olivier Abbeloos on Feb 3, 2009 3:10 PM
02-03-2009 2:50 PM
Try to get an access of the table PT_GOITEM, instead of the entire object KERNEL.
Like:
DATA lv_tab TYPE string.
FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE.
lv_tab = '(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL->PT_GOITEM'.
ASSIGN (lv_tab) TO <fs_tab>.
Regards,
Naimesh Patel
02-03-2009 2:50 PM
Try to get an access of the table PT_GOITEM, instead of the entire object KERNEL.
Like:
DATA lv_tab TYPE string.
FIELD-SYMBOLS: <fs_tab> TYPE ANY TABLE.
lv_tab = '(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL->PT_GOITEM'.
ASSIGN (lv_tab) TO <fs_tab>.
Regards,
Naimesh Patel
02-03-2009 3:00 PM
I tried this method and also with PT_GOITEM[], but i always have a SY-SUBRC = 4 after the ASSIGN statement.
02-03-2009 3:10 PM
Yes, it is not allowing to access the PT_GOITEM as it is a PRIVATE attribute. Previously, I have tried with the Public attribute and it allowed me to gain an access to that attribute with help of field-symbol.
Regards,
Naimesh Patel
02-03-2009 3:27 PM
Ok thanks for this explication.
But do you know a way to access to these private datas ?
02-03-2009 4:17 PM
I finaly found the GET_LINE method from LCL_MIGO_KERNEL, that is in the public section.
But i can't call this method.
Here is my code :
DATA vl_class TYPE string.
DATA l_oref TYPE REF TO object.
vl_class = `\PROGRAM=SAPLMIGO\CLASS=LCL_MIGO_GLOBALS`.
CREATE OBJECT l_oref TYPE (vl_class). " At this point, l_OREF contain object LCL_MIGO_GLOBALS
CALL METHOD l_oref=>kernel->line_get
EXPORTING
i_line = i_line_id " The line ID from the PBO_DETAIL parameter
IMPORTING
es_goitem = s_goitem.
So i can't activate my program (because of the call method) and i don't know why because i found the kind of syntaxe in program AD_MPN_PUR2_SAPLMIGO (line 62)
Do you know why my code don't work??
02-03-2009 8:17 PM
Hello Olivier
You are very close to the final solution. The trick is to make a casting of the local class instance to the root(!) object => see my Wiki posting [Accessing the Inacessible - Local Classes within Global Classes|https://wiki.sdn.sap.com/wiki/display/ABAP/AccessingtheInacessible-LocalClasseswithinGlobalClasses]
Below you see a possible implementation of the BAdI method:
METHOD if_ex_mb_migo_badi~pbo_detail.
* define local data
DATA: lo_obj TYPE REF TO object.
DATA: ld_class TYPE string,
ld_method TYPE string.
FIELD-SYMBOLS:
<lo_kernel> TYPE ANY.
DATA:
ls_goitem TYPE goitem,
lt_goitems TYPE STANDARD TABLE OF goitem,
ld_line TYPE sytabix,
ld_tabix TYPE sytabix,
lx_dep_tables TYPE abap_bool.
break uwsc.
ld_class = '(SAPLMIGO)LCL_MIGO_GLOBALS=>KERNEL'.
ASSIGN (ld_class) TO <lo_kernel>.
" Reference: SDN Wiki entry
" 'Accessing the Inacessible - Local Classes within Global Classes'
" <a href="https://wiki.sdn.sap.com/wiki/display/ABAP/Accessing+" TARGET="test_blank">https://wiki.sdn.sap.com/wiki/display/ABAP/Accessing+</a>
" the+Inacessible+-+Local+Classes+within+Global+Classes
lo_obj ?= <lo_kernel>.
ld_method = 'LINE_GET'.
ld_line = 1.
REFRESH: lt_goitems.
DO.
ld_line = syst-index.
CLEAR: ls_goitem.
" NOTE: Public methods can be accessed using this approach
" even if the instance is of TYPE REF TO object !!!
CALL METHOD lo_obj->(ld_method)
EXPORTING
i_line = ld_line
* i_tabix TYPE sytabix OPTIONAL
* i_dependent_tables = abap_false
IMPORTING
* et_goserial TYPE ty_t_goserial
* et_gofreight TYPE ty_t_gofreight
es_goitem = ls_goitem.
" NOTE: Assumes that method default_line_get( ) [see below]
" returns an empty structure.
IF ( ls_goitem IS INITIAL ).
EXIT.
ELSE.
APPEND ls_goitem TO lt_goitems.
ENDIF.
ENDDO.
break uwsc.
ENDMETHOD.
" NOTE: Implementation of lcl_migo_kernel->LINE_GET method:
**METHOD line_get.
** DATA: l_tabix TYPE sytabix.
** FIELD-SYMBOLS: <ls_goserial_kernel> TYPE ty_s_goserial_kernel,
** <ls_gofreight> TYPE ty_s_gofreight.
**
** DATA cl_change TYPE REF TO /sappspro/cl_numbers.
** DATA lf_active TYPE boolean.
**
*** Line mapping
** l_tabix = i_tabix.
** IF l_tabix IS INITIAL.
** CALL METHOD line_mapping
** EXPORTING
** i_line = i_line
** IMPORTING
** e_tabix = l_tabix.
** ENDIF.
*** Read line
** READ TABLE pt_goitem INTO es_goitem INDEX l_tabix.
** IF sy-subrc <> 0.
*** Requested non existing line: Send a line containing only default
*** values (so that the defaults are already filled in the viewers).
** CLEAR: es_goitem,
** et_goserial,
** et_gofreight.
** es_goitem = default_line_get( ).
** EXIT.
** ENDIF.
**
*** convert field ebeln to external format and put it in longnum
** CLEAR: lf_active.
** CREATE OBJECT cl_change.
**
** CALL METHOD cl_change->is_active
** RECEIVING
** rv_active = lf_active.
**
** IF lf_active = 'X'.
** TRY.
** goitem-longnum = /sappspro/cl_numbers=>lookup( goitem-ebeln ).
** CATCH /sappspro/cx_number_not_found.
*** number does not exist.
** ENDTRY.
** ENDIF.
**
*** Reading data for dependent tables
** IF i_dependent_tables = abap_true.
*** Serial number table for current item
** CLEAR et_goserial.
** READ TABLE pt_goserial_kernel ASSIGNING <ls_goserial_kernel>
** WITH TABLE KEY global_counter = es_goitem-global_counter.
** IF sy-subrc = 0.
** et_goserial = <ls_goserial_kernel>-t_goserial.
** ENDIF.
*** Freight vendor table for current item
** IF NOT es_goitem-ebeln IS INITIAL AND
** NOT es_goitem-ebelp IS INITIAL.
** CLEAR et_gofreight.
** LOOP AT pt_gofreight_kernel ASSIGNING <ls_gofreight>
** WHERE ebeln = es_goitem-ebeln
** AND ebelp = es_goitem-ebelp.
** APPEND <ls_gofreight> TO et_gofreight.
** ENDLOOP.
** ENDIF.
** ENDIF. " if dependent_tables = abap_true
**ENDMETHOD. "line_get
Regards
Uwe
02-03-2009 8:27 PM
Cool Uwe..!
I was also close to gain the access of the object LCL_MIGO_GLOBALS=>KERNEL. I only mistake I was doing is, I was trying to get the reference of the LCL_MIGO_GLOBALS=>KERNEL directly to the Object, instead of the field-symbol and object reference.
Regards,
Naimesh Patel
02-03-2009 8:35 PM
Hello Naimesh
The first time I published this approach in thread .
It took me about 2 hours (I guess) before I found the final solution. At the end I thought "Casting to the root object is completely nuts so let's give it try".
Looking through the other forum links mentioned in the Wiki posting it seems that this approach is a fundamental one which can be summarized like this:
"Every public attribute or method can be accessed from a root object instance using field symbols."
While this finding has little meaning for global classes it has a hug impact for accessing the many-fold local classes that are (still) in use.
Best Regards
Uwe
02-03-2009 8:43 PM
Honour to whom honour is due:
Your blog about [Overcome the Restrictions of SALV Model|/people/naimesh.patel/blog/2008/11/24/power-of-abap-objects-overcome-the-restrictions-of-salv-model] is just brilliant.
Regards
Uwe
02-03-2009 8:46 PM
Thanks for inventing (& sharing) the great tip to access LIVE objects.
I'm glad that you like my blog.
Regards,
Naimesh Patel
02-04-2009 9:45 AM
Thanks UWE. it finally works with your solution
And thx Naimesh to
Edited by: Olivier Abbeloos on Feb 4, 2009 10:46 AM
06-19-2012 7:34 AM
Hi Uwe,
Im just picking up oo concepts in abap and your code really was a good start for me as I'm trying to change the serial number via goitem structure. We have activated the serial number profile and for certain scenarios i would want to replace back an existing serial number during gr post. Unfortunately, I am not able to do any changes to ls_serial as nor replace the populated serial number before posting.
Any tips on this?
Neesha.
06-19-2012 7:34 AM
Hi Uwe,
Im just picking up oo concepts in abap and your code really was a good start for me as I'm trying to change the serial number via goitem structure. We have activated the serial number profile and for certain scenarios i would want to replace back an existing serial number during gr post. Unfortunately, I am not able to do any changes to ls_serial as nor replace the populated serial number before posting.
Any guide on this?
Neesha.