Skip to Content
avatar image
Former Member

Understanding Dynamic Tables (RTTS)

Hi guys,

While i was playing with dynamic tables and i can't figure how to get the exact data type from data elements.

I'll explain better in code 😊

* Declare Data. ( dynamic fields )

DATA:  gt_fields TYPE STANDARD TABLE OF char30,

            gs_fields TYPE char30,

             gt_comp     TYPE cl_abap_structdescr=>component_table,

            gs_comp     LIKE LINE OF gt_comp,

             go_element  TYPE REF TO cl_abap_elemdescr,

            go_struct   TYPE REF TO cl_abap_structdescr.

LOOP AT gt_fields INTO gs_fields.

*   Element descripiton

     go_element ?= cl_abap_elemdescr=>describe_by_name( gs_fields ).

*   Field name

     MOVE gs_fields TO gs_comp-name.

*   Field type

     gs_comp-type =  cl_abap_elemdescr=>get_c( go_element->length ).

     APPEND gs_comp TO gt_comp.

ENDLOOP.

This code is good and i can manage to build a dynamic table from this.

But:

1) gs_fields ( where i store the name of the fields ) can only be chart type ( get_c () ). if i send a field which type is integer i get dump and is normal.

2) when i display with alv i don't get any description in my column header.

I managed to get a better result but not as i wanted. ( i want a completely dynamic table )

-> Define a type in my program. add fields. ( ex: matnr type mara-matnr, mara-mtart etc )

-> Get components from existing type:

   go_struct ?= cl_abap_typedescr=>describe_by_name( 'TY_MY_TYPE' ).

   gt_comp  = lo_struct->get_components( ).

I tried different options but none was good. I think is still something regarding how i fill my go_element i think. Do you have any ideas?

Thank you,

Alex F.


cap1.PNG (4.2 kB)
Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

2 Answers

  • Best Answer
    avatar image
    Former Member
    Jun 22, 2012 at 03:24 PM

    Hi Alexandru Fediuc,

    the best thing is to use existing data elements to create the dynamic table.

    So you may extend your table that it carries a fieldname and a datatype (data element or DDIC structure and component) for each field to be created.

    See here the (tested) sample program:

    FORM dyndata .

      TYPES:

        BEGIN OF ty_dyndata,

        fieldname              TYPE fieldname,

        data_type              TYPE string,

        END OF ty_dyndata,

        ty_t_dyndata           TYPE STANDARD TABLE OF ty_dyndata.

      DATA:

        lt_dyndata             TYPE ty_t_dyndata,

        lo_salv_table          TYPE REF TO cl_salv_table,

        lo_structdescr         TYPE REF TO cl_abap_structdescr,

        lo_typedescr           TYPE REF TO cl_abap_typedescr,

        lo_tabledescr          TYPE REF TO cl_abap_tabledescr,

        lr_data                TYPE REF TO data,

        lr_dyntable            TYPE REF TO data,

        lt_component           TYPE cl_abap_structdescr=>component_table.

      FIELD-SYMBOLS:

        <dyndata>              TYPE ty_dyndata,

        <component>            TYPE LINE OF cl_abap_structdescr=>component_table,

        <dyntable>             TYPE table.

    * example with 2 fields

      APPEND INITIAL LINE TO lt_dyndata ASSIGNING <dyndata>.

      <dyndata>-fieldname = 'ORDER'.

      <dyndata>-data_type = 'VBAK-VBELN'.

      APPEND INITIAL LINE TO lt_dyndata ASSIGNING <dyndata>.

      <dyndata>-fieldname = 'ITEM'.

      <dyndata>-data_type = 'VBAP-POSNR'.

      APPEND INITIAL LINE TO lt_dyndata ASSIGNING <dyndata>.

      <dyndata>-fieldname = 'COMPANY'.

      <dyndata>-data_type = 'BUKRS'.

      APPEND INITIAL LINE TO lt_dyndata ASSIGNING <dyndata>.

      <dyndata>-fieldname = 'COUNT'.

      <dyndata>-data_type = 'I'.

    * creation of dynamic table

      LOOP AT lt_dyndata ASSIGNING <dyndata>.

        TRY.

            CREATE DATA lr_data TYPE (<dyndata>-data_type).

            APPEND INITIAL LINE TO lt_component ASSIGNING <component>.

            <component>-type ?= cl_abap_datadescr=>describe_by_data_ref( lr_data ).

            <component>-name = <dyndata>-fieldname.

          CATCH cx_root.

    * error handling

    * ... cannot create data of type <dyndata>-data_type

        ENDTRY.

      ENDLOOP.

    * new description object for structured type

      lo_structdescr = cl_abap_structdescr=>create( lt_component ).

    * create table description for structure decription

      lo_tabledescr = cl_abap_tabledescr=>create(

                      p_line_type  = lo_structdescr

                      p_table_kind = cl_abap_tabledescr=>tablekind_std

                      p_unique     = abap_false ).

    * create dynamic data object (table)

      CREATE DATA lr_dyntable TYPE HANDLE lo_tabledescr.

    * use table

      ASSIGN lr_dyntable->* TO <dyntable>.

    * append a couple of records

      DO 10 TIMES.

        APPEND INITIAL LINE TO <dyntable>.

      ENDDO.

    * create SALV object

      TRY.

          cl_salv_table=>factory(

            IMPORTING

              r_salv_table   = lo_salv_table

            CHANGING

              t_table        = <dyntable>

                 ).

        CATCH cx_salv_msg .

      ENDTRY.

    * display table

      lo_salv_table->display( ).

    ENDFORM.                    " DYNDATA

    As you may have noticed, I used field-symbols quite frequently. For a reason: INTO <work area> is NEVER faster than the use of field-symbols, field-symbols save memory and they can be used much more flexible.

    We have column headers for data created based on structure fields (VBAK-VBELN) and data elements (BUKRS), not for direct type (I).

    Also, the ALV consistency check reports a warning for this field:

    BTW: The ALV consistency check can be invoked by holding CTRL and SHIFT keys, pointing in an empty area of the grid and double-right-click the mouse. (If someone can tell me how to catch a double-right-click and the CTRL-SHIFT key press, he or she is invited for dinner😎)

    The description in column header is taken from field catalog. If you use SALV object model, the object model will create the field catalog it self. It works better if the data element refers to a dictionary DOMAIN, direct data type in data element causes inconsistencies.

    Hope you can make use of this,

    Regards,

    Clemens


    salv.jpg (17.4 kB)
    consistency.jpg (55.7 kB)
    Add comment
    10|10000 characters needed characters exceeded

    • Former Member Former Member

      Thanks for the comment. Yes you are right, that's what I found out later that you can always use cl_abap_datadescr=>describe_by_name, it works identical. But if you look into the code of describe_by_name, you will see that it is more complex than describe_by_data_ref.

      I did not take measures regarding speed in comparison. Usually dynamic table creation is used only once per execution, the difference can't be noticed. Even for a mass run, I have serious doubts that this action will be significant at all - compared to the rest of using the table.

      Thank you for the hint for catching the double-right-click. I tried some time ago, even used pretty much time debugging - no success whatsoever.

      Regards

      Clemens

  • avatar image
    Former Member
    Jun 22, 2012 at 09:48 AM

    Hi,

    Please refer the blog for you queries

    http://scn.sap.com/people/arunkumar.prabakaran/blog

    Here a FM is used to generate dynamic internal table with different data type

    Add comment
    10|10000 characters needed characters exceeded

    • Former Member Former Member

      Hi,

      well at least the search function still works :-)

      Arunkumar Prabakaran

      Dynamic Internal Table Population Code :

      I would recommend not to use the code presented here. The used METHOD cl_alv_table_create=>create_dynamic_table

      is from pre-RTTS times and uses obsolete coding technique including limited use (generate subroutine) and unwanted database commit.

      Though, the code may be changed and adapted to RTTS easily.

      Regards

      Clemens