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: 

Understanding Dynamic Tables (RTTS)

Former Member
0 Kudos

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 )

DATAgt_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.


1 ACCEPTED SOLUTION

Clemenss
Active Contributor
0 Kudos

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

6 REPLIES 6

former_member184497
Participant
0 Kudos

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

0 Kudos

Sorry, but the link is empty.

0 Kudos

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

Clemenss
Active Contributor
0 Kudos

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

Former Member
0 Kudos

Wow, thx! Very good example and very useful.

I found myself a way to , to refer directly to a data dictionary type by using:

go_data type ref to cl_abap_datadescr

and use in my loop :

go_data ?= cl_abap_datadescr=>describe_by_name ( gs_fields )

and then just use

   gs_comp-type = go_data.

This is a bit faster for exercise. But it all depends on what you have to do.

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)

Did you try handling double_click in alv oo? making a local class , and maybe registering the events? i'm a start so i'm not sure

Clemenss
Active Contributor
0 Kudos

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