Application Development and Automation 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: 
Read only

Catch a dynamic structure

Former Member
0 Likes
1,034

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.

8 REPLIES 8
Read only

Sm1tje
Active Contributor
0 Likes
893

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.

Read only

uwe_schieferstein
Active Contributor
0 Likes
893

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

Read only

0 Likes
893

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.

Read only

0 Likes
893

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

Read only

0 Likes
893

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

Read only

0 Likes
893

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.

Read only

0 Likes
893

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

Read only

0 Likes
893

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?