‎2009 May 28 1:13 PM
Hello All,
Does anyone know how i can catch an exporting parameter from a method, which has type ANY?
Sample code:
CALL METHOD catch_any
IMPORTING
ip_string = lv_string
EXPORTING
es_any = ??????.
In this method the string is converted to a dynamically built up structure. So up front when calling the method i do not know the type of the structure yet. I could use an additional step in which i first set the structure to a dynamic table, return this as a "type ref to data" and set this to a dynamic local structure, but i don't want that. There must be a simple and clean sollution which i'm missing.....
Anyone?
Kind regards,
Martijn de Jong.
‎2009 May 28 2:00 PM
Just to give me additional info, and for not having to code anything myself, could you give me an example of how this string is filled (just one example should do) and what the coding inside the method catch_any is looks like.
I have an idea of what you are trying to do, but I do need some additional info.
‎2009 May 28 2:29 PM
Hello Martijn
Are you aware of class CL_ABAP_CONTAINER_UTILITIES (>= 6.20 available)?
I think its static methods do exactly what you want to achieve: moving data back and forth between an unstructured C-container and a structure.
Regards
Uwe
‎2009 May 28 3:04 PM
Uwe,
I didn't know the class, but having looked at it, the programm's i found which call these methods, all know up front which structure they will receive. It could be a sollution for me to, but i would rather not determine it before calling the method. (e.g. field-symbol is assigned in certain structure before calling the method...)
Underneath the code which does not work yet....
DATA lx_upload_data TYPE string.
Loop at the uploaded data and call the object specific data handling
LOOP AT upload_data INTO lx_upload_data.
TRY.
CALL METHOD extract_data_record
EXPORTING
ip_data = lx_upload_data
IMPORTING
es_extracted_data = <maybe a fieldsymbol here?>.
ENDTRY.
ENDLOOP.
METHOD extract_data_record.
FIELD-SYMBOLS <fs_data> TYPE REF TO data.
FIELD-SYMBOLS <fs_field> TYPE ANY.
DATA dref TYPE REF TO data.
DATA lr_fielddescr TYPE REF TO cl_abap_typedescr.
DATA len_content TYPE i.
DATA len_field TYPE i.
DATA len_src TYPE i.
DATA len_wa TYPE i.
DATA offset TYPE i.
TRY.
CREATE DATA dref TYPE (me->upload_struct_name).
CATCH cx_sy_create_data_error.
ENDTRY.
ASSIGN dref->* TO <fs_data>.
offset = 0.
len_src = 0.
len_src = STRLEN( ip_data ).
DO.
ASSIGN COMPONENT sy-index OF STRUCTURE <fs_data> TO <fs_field>.
CHECK sy-subrc = 0.
DESCRIBE FIELD <fs_field> LENGTH len_field IN CHARACTER MODE.
lr_fielddescr = cl_abap_datadescr=>describe_by_data( <fs_field> ).
len_field = lr_fielddescr->length.
len_field = STRLEN( <fs_field> ).
IF len_src > offset.
<fs_field> = ip_data+offset(len_field).
offset = offset + len_field.
ELSE.
EXIT.
ENDIF.
ENDDO.
es_extracted_data = <fs_data>.
ENDMETHOD.
Maybe some more suggestions?
Kind regards,
Martijn de Jong.
‎2009 May 28 3:10 PM
Hello Martijn
Your program is doing exactly what I suggested:
...
TRY.
CREATE DATA dref TYPE (me->upload_struct_name).
CATCH cx_sy_create_data_error.
ENDTRY.
ASSIGN dref->* TO <fs_data>.
...
" And now you call method:
CALL METHOD cl_abap_container_utilities=>read_container_c
EXPORTING
im_container = ip_data
IMPORTING
ex_value = <fs_data>
EXCEPTIONS
illegal_parameter_type = 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.
Why do you want to re-invent the wheel if SAP has done the job for you?
Regards
Uwe
‎2009 May 28 3:24 PM
Your calling program will also know the strcture, at least at runtime. Create a field-symbol and assign the reference of dynamic structure to this field-symbol.
Like:
*----------------------------------------------------------------------*
CLASS lcl_test DEFINITION.
PUBLIC SECTION.
DATA: t_mara TYPE standard TABLE OF mara.
METHODS:
constructor,
get
IMPORTING
if_matnr TYPE matnr
EXPORTING
ea_mara TYPE any.
ENDCLASS. "lcl_test DEFINITION
START-OF-SELECTION.
DATA: lo_test TYPE REF TO lcl_test,
lr_data TYPE REF TO data.
FIELD-SYMBOLS: <fa_any> TYPE ANY,
<f_field> TYPE ANY.
* At this point I know that I will receive back the structure type MARA
DATA: la_mara TYPE mara.
ASSIGN la_mara TO <fa_any>.
CREATE OBJECT lo_test.
lo_test->get(
EXPORTING
if_matnr = '000000000077000000'
IMPORTING
ea_mara = <fa_any> ).
WRITE: 'Done'.
*----------------------------------------------------------------------*
CLASS lcl_test IMPLEMENTATION.
METHOD constructor.
SELECT * INTO TABLE t_mara
FROM mara
UP TO 10 ROWS.
ENDMETHOD. "constructor
METHOD get.
FIELD-SYMBOLS: <lfs_mara> LIKE LINE OF me->t_mara.
READ TABLE me->t_mara ASSIGNING <lfs_mara> WITH KEY matnr = if_matnr.
ea_mara = <lfs_mara>.
ENDMETHOD. "get
ENDCLASS. "lcl_test IMPLEMENTATION
Regards,
Naimesh Patel
‎2009 Jun 03 8:44 AM
Hi Uwe,
Thanks for your reply. Indeed no need to invent the wheele twice... Still my question remains if there is a way to catch that dynamic structure from the method in which this method (read_container_c) is called, without knowing the upload structure in this calling method?
As in your example code i know the upload structure, but in the actual code, this method is called from another class and method whcih doesn't know the structure.
Hope i made myself clear enough?
Kind regards,
Martijn de Jong.
‎2009 Jun 03 12:40 PM
Hello Martijn
My assumption is that the contents of ME->UPLOAD_STRUCT_NAME changes at runtime and belongs to a DDIC structure (or TYPE-POOLS definition).
If this is correct then the program is fully dynamic:
...
TRY.
CREATE DATA dref TYPE (me->upload_struct_name). " changes during runtime
CATCH cx_sy_create_data_error.
ENDTRY.
ASSIGN dref->* TO <fs_data>.
...
Regards
Uwe
‎2009 Jun 03 12:56 PM
Hello Uwe,
It does, but:
Class A:
method A1.
call method B1
exporting ip_data = ls_data
importing es_new = ls_/fs_???.
endmethod. "A1
Class B:
method B1.
TRY.
CREATE DATA dref TYPE (me->upload_struct_name).
CATCH cx_sy_create_data_error.
ENDTRY.
ASSIGN dref->* TO <fs_data>.
CALL METHOD cl_abap_container_utilities=>read_container_c
EXPORTING
im_container = ip_data
IMPORTING
ex_value = <fs_data>
EXCEPTIONS
illegal_parameter_type = 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.
es_new = <fs_data>.
endmethod. "B1
es_new now contains a dynamically determined structure, but in what kind of local variable do i catch it in method A1?