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: 

Field symbols/Data ref - dynamic structure determination

Former Member
0 Kudos

I am creating a class which is used to create idocs within in the system. I want this object to be dynamic so that the same can be reused. As a part of this class, one of the method would create the segments for the idocs. My idea was to pass the segment name to this method and it should dynamically determine the components of the structure. I was hoping to get this done simply via field symbols and data references instead of using the RTTS process.

The last statement obviously throws an error stating " The data object "<FS_SEGMENT>" has no structure and therefore no component called "COMP_CODE" which makes absolute sense but how do I overcome this without using RTTS?

Thanks,

Vikram.M

13 REPLIES 13

Juwin
Active Contributor
0 Kudos

Please check the ASSIGN COMPONENT OF... syntax. You will need one more ASSIGN statement.

Thanks,

Juwin

Former Member
0 Kudos

That wouldn't be completely dynamic. What is the the component order or the component name changes?

Thanks,

Vikram.M

Juwin
Active Contributor
0 Kudos

Do you think writing <fs_segment>-comp_code in the program is completely dynamic?

Thanks,

Juwin

Sandra_Rossi
Active Contributor
0 Kudos

We don't know what you exactly expect, so it's difficult to answer to you. By the way, please read the ABAP documentation, you'll see that you may use ASSIGN COMPONENT <position> OF STRUCTURE ...

Former Member
0 Kudos

Ah. I see what you are saying.

Nevertheless, using ASSIGN COMPONENT might not be the one I need since based on the structure I might need 'N' number of components to be filled which would mean many assign statements and more than 1 field symbol.

What I had in my mind was to create on field symbol which can point to any structure and its components visible. Suggestions?

Thanks,

Vikram.M

Former Member
0 Kudos

Sandra,

What I had in my mind was to create on field symbol which can point to any structure and its components visible. Suggestions?


Thanks,

Vikram.M

Juwin
Active Contributor
0 Kudos

There also ASSIGN COMPONENT will help you. You may need help from CL_STRUCTDESCR to get the fieldnames though, Or traverse through all the fields using a DO loop.

Thanks,

Juwin

Sandra_Rossi
Active Contributor
0 Kudos

Let's say we loop at fields of the dynamic structure as follows:

DO.

  ASSIGN COMPONENT sy-index OF STRUCTURE <fs_segment> TO <fs_field>.

  IF sy-subrc <> 0. EXIT. ENDIF.

  ... operate on <fs_field>

ENDDO.

Please explain what you want to achieve exactly...

Former Member
0 Kudos

Hi,

    Assign component using index is one way of doing it provided that you will keep the component order fixed for the structures. If you are not going to maintain the order then at least you will be knowing name of the component you want to access. Now if you want to know whether such a component exists in the structure you can use CL_STRUCTDESCR as Juwin said. Please see below code for reference.

DATA   : l_ref_structdesc TYPE REF TO             cl_abap_structdescr,

             lv_value         TYPE                    string,

             lv_field_name    TYPE                    string,

             lv_fullcondition TYPE string.

FIELD-SYMBOLS :

     <fs_where_wa>  TYPE                    any,

     <fs_component> TYPE                    abap_compdescr,

     <fs_field>     TYPE                    any.

LOOP AT im_wherein ASSIGNING <fs_where_wa>.

   CLEAR lv_field_name.

    l_ref_structdesc ?= cl_abap_structdescr=>describe_by_data( <fs_where_wa> ).

    IF l_ref_structdesc IS BOUND.

       LOOP AT l_ref_structdesc->components ASSIGNING <fs_component>.

         ASSIGN COMPONENT <fs_component>-name OF STRUCTURE <fs_where_wa> TO <fs_field>.

         IF <fs_field> IS  NOT INITIAL.

            lv_value <fs_field>.

         IF lv_field_name IS INITIAL.

             CONCATENATE: lv_field_name <fs_component> -      name '=' INTO lv_field_name SEPARATED BY space, '''' lv_value '''' INTO lv_value,

             lv_field_name lv_value INTO lv_field_name SEPARATED BY space.

           ELSE.

             CONCATENATE: lv_field_name 'AND' INTO lv_field_name SEPARATED BY space, lv_field_name <fs_component>-name '=' INTO lv_field_name

             SEPARATED BY space, '''' lv_value '''' INTO lv_value,

             lv_field_name lv_value INTO lv_field_name SEPARATED BY space.

           ENDIF.

         ENDIF.

       ENDLOOP.

     ENDIF.

   ENDLOOP.

Here lv_field_name will have name and the values of each field of that structure appended as a string ( Get whatever components you require from the structure.)

Now that you know whether a component you want access in a structure exists or not  , you can do assign component using that component name.

Hope it helps .

Junas Pious.

Former Member
0 Kudos

Sandra/Juwin,

Apologies for the delayed response.

when you look at the below code:


PERFORM crt USING 'E1EDL20'.                         


FORM crt USING name TYPE c.

   DATA: dref      TYPE REF TO data.

   FIELD-SYMBOLS : <fs> TYPE any .

   CREATE DATA dref TYPE (name).

   ASSIGN dref->* TO <fs>.

   <fs>-ebeln = '1'.

ENDFORM

This will throw  an error stating the field symbol does not have a structure and therefore no component called VBELN.

What I want to achieve is to have 1 routine that can accept any segment name as input along with a structure with input for the segment fields. This way I do not have to define many work areas for each input segment inside the routine.


Thanks,

Vikram.M

Juwin
Active Contributor
0 Kudos

You still haven't used ASSIGN COMPONENT OF... syntax. You need use this to attain the required result. Pass the component name as parameter and use that parameter in the statement.

Thanks

Former Member
0 Kudos

In this case, I would have to call the routine for a every field, yes?

Juwin
Active Contributor
0 Kudos

Depends on how you code. You could use a Loop as mentioned already in other replies.

Thanks