Skip to Content
author's profile photo Former Member
Former Member

Creation of table of table dynamically

Hi everyone,

i have created an alv grid with a dynamic number of columns. Now i need to edit specific rows in the alv table. In the BCALV_EDIT_02 you need to create in the data table a field CELLTAB (wich is also a table), how can i do this ?

Xavier

Add a comment
10|10000 characters needed characters exceeded

Assigned Tags

Related questions

4 Answers

  • Best Answer
    Posted on May 22, 2007 at 09:10 PM

    Hello Xavier

    The following sample report shows you how to create <b>complex </b>structures (and table types) dynamically.

    *&---------------------------------------------------------------------*
    *& Report  ZUS_SDN_RTTI_CREATE_STRUCTURES
    *&
    *&---------------------------------------------------------------------*
    *&
    *&
    *&---------------------------------------------------------------------*
    
    REPORT  zus_sdn_rtti_create_structures.
    
    
    TYPE-POOLS: abap.
    
    
    DATA:
      celltab          TYPE lvc_t_styl.
    
    DATA:
      go_table         TYPE REF TO cl_salv_table,
      go_sdescr        TYPE REF TO cl_abap_structdescr,
      go_tdescr        TYPE REF TO cl_abap_tabledescr,
      gdo_data         TYPE REF TO data,
      gdo_handle       TYPE REF TO data,
      gs_comp          TYPE abap_componentdescr,
      gt_components    TYPE abap_component_tab.
    *
    *    name       TYPE string,
    *    type       TYPE REF TO cl_abap_datadescr,
    *    as_include TYPE abap_bool,
    *    suffix     TYPE string,
    
    FIELD-SYMBOLS:
      <gd_fld>      TYPE ANY,
      <gs_struc>    TYPE ANY,
      <gt_itab>     TYPE table.
    
    
    PARAMETER:
      p_tabnam      TYPE tabname  DEFAULT 'KNB1'.
    
    START-OF-SELECTION.
    
    * Create dynamically structure
      CREATE DATA gdo_data TYPE (p_tabnam).
      ASSIGN gdo_data->* TO <gs_struc>.
      CHECK ( <gs_struc> IS ASSIGNED ).
    
    
    * Simulate dynamic addition of columns to ALV list
      DO 10 TIMES.
        ASSIGN COMPONENT syst-index OF STRUCTURE <gs_struc> TO <gd_fld>.
    
        CLEAR: gs_comp.
        gs_comp-type ?= cl_abap_datadescr=>describe_by_data( <gd_fld> ).
        gs_comp-name  = gs_comp-type->get_relative_name( ).
        APPEND gs_comp TO gt_components.
    
        go_sdescr  = cl_abap_structdescr=>create( gt_components ).
        go_tdescr  = cl_abap_tabledescr=>create( go_sdescr ).
        CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
        ASSIGN gdo_handle->* TO <gt_itab>.
    
    *   Dynamic select
        SELECT        * FROM  (p_tabnam)
          INTO CORRESPONDING FIELDS OF TABLE <gt_itab>
               WHERE  bukrs  = '2000'.
    
        TRY.
            CALL METHOD cl_salv_table=>factory
              IMPORTING
                r_salv_table = go_table
              CHANGING
                t_table      = <gt_itab>.
            go_table->display( ).
          CATCH cx_salv_msg .
        ENDTRY.
    
      ENDDO.
    
    
      " Add table type as field to structure
      CLEAR: gs_comp.
      gs_comp-type ?= cl_abap_typedescr=>describe_by_data( celltab ).
      gs_comp-name  = 'CELLTAB'.
      APPEND gs_comp TO gt_components.
    
      go_sdescr  = cl_abap_structdescr=>create( gt_components ).
      go_tdescr  = cl_abap_tabledescr=>create( go_sdescr ).
      CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
      ASSIGN gdo_handle->* TO <gt_itab>.
    
    *   Dynamic select
      SELECT        * FROM  (p_tabnam)
        INTO CORRESPONDING FIELDS OF TABLE <gt_itab>
             WHERE  bukrs  = '2000'.
    
    END-OF-SELECTION.

    Regards

    Uwe

    Add a comment
    10|10000 characters needed characters exceeded

    • Hello Frederico

      The once again revised version of my sample report demonstrates how to store PBO and PAI data. Please note the following naming convention:

      - OUTTAB ==> itab for ALV list display with CELLTAB (i.e. a complex type)
      - ITAB      ==> flat itab without CELLTAB

      *&---------------------------------------------------------------------*
      *& Report  ZUS_SDN_RTTI_CREATE_STRUCTUR_2
      *&
      *&---------------------------------------------------------------------*
      *& NOTE: 1st revised version of ZUS_SDN_RTTI_CREATE_STRUCTUR_1
      *&
      *&---------------------------------------------------------------------*
      
      REPORT  zus_sdn_rtti_create_structur_2.
      
      
      TYPE-POOLS: abap.
      
      
      DATA:
        celltab          TYPE lvc_t_styl.
      
      DATA:
        gd_tabnam        TYPE string,
        gd_tabfield      TYPE string,
        go_table         TYPE REF TO cl_salv_table,
        go_sdescr        TYPE REF TO cl_abap_structdescr,
        go_sdescr_new    TYPE REF TO cl_abap_structdescr,
        go_tdescr        TYPE REF TO cl_abap_tabledescr,
        go_typedescr     TYPE REF TO cl_abap_typedescr,
        gdo_data         TYPE REF TO data,
        gdo_handle       TYPE REF TO data,
        gs_component     TYPE abap_compdescr,
        gs_comp          TYPE abap_componentdescr,
        gt_components    TYPE abap_component_tab.
      *
      *    name       TYPE string,
      *    type       TYPE REF TO cl_abap_datadescr,
      *    as_include TYPE abap_bool,
      *    suffix     TYPE string,
      
      FIELD-SYMBOLS:
        <gd_fld>            TYPE ANY,  " single field
        <gs_outtab>         TYPE ANY,  " structure with CELLTAB
        <gs_itab>           TYPE ANY,  " structure without CELLTAB
        <gt_itab_pbo>       TYPE STANDARD TABLE,  " without CELLTAB
        <gt_itab_pai>       TYPE STANDARD TABLE,  " without CELLTAB
        <gt_outtab_pbo>     TYPE STANDARD TABLE,  " with CELLTAB
        <gt_outtab_pai>     TYPE STANDARD TABLE.  " with CELLTAB
      
      
      PARAMETER:
        p_tabnam      TYPE tabname  DEFAULT 'KNB1'.
      
      PARAMETERS:
        p_skip        AS CHECKBOX  DEFAULT 'X'.  " skip simulation
      
      
      START-OF-SELECTION.
      
        " Describe structure
        go_sdescr ?= cl_abap_structdescr=>describe_by_name( p_tabnam ).
        gd_tabnam     = go_sdescr->get_relative_name( ).
      
      
      
      * Simulate dynamic addition of columns to ALV list
        DO 5 TIMES.
          READ TABLE go_sdescr->components INTO gs_component INDEX syst-index.
      
          "   Build fieldname
          CONCATENATE gd_tabnam gs_component-name INTO gd_tabfield
                                                  SEPARATED BY '-'.
      
          CLEAR: gs_comp.
          gs_comp-type ?= cl_abap_datadescr=>describe_by_name( gd_tabfield ).
          gs_comp-name  = gs_component-name.
          APPEND gs_comp TO gt_components.
      
      
          go_sdescr_new  = cl_abap_structdescr=>create( gt_components ).
          go_tdescr      = cl_abap_tabledescr=>create( go_sdescr_new ).
          "   Create data refence followed by table creation
          CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
          ASSIGN gdo_handle->* TO <gt_outtab_pbo>.
      
      *   Dynamic select
          SELECT        * FROM  (p_tabnam) UP TO 10 ROWS
            INTO CORRESPONDING FIELDS OF TABLE <gt_outtab_pbo>
                 WHERE  bukrs  = '2000'.
      
          IF ( p_skip = abap_false ).
            TRY.
                CALL METHOD cl_salv_table=>factory
                  IMPORTING
                    r_salv_table = go_table
                  CHANGING
                    t_table      = <gt_outtab_pbo>.
                go_table->display( ).
              CATCH cx_salv_msg .
            ENDTRY.
          ENDIF.
      
        ENDDO.
      
        TRY.
            CALL METHOD cl_salv_table=>factory
              IMPORTING
                r_salv_table = go_table
              CHANGING
                t_table      = <gt_outtab_pbo>.
            go_table->display( ).
          CATCH cx_salv_msg .
        ENDTRY.
      
      
        " Display component list in order to prove that indeed the field names
        " are used (instead of the data element names)
        TRY.
            CALL METHOD cl_salv_table=>factory
              IMPORTING
                r_salv_table = go_table
              CHANGING
                t_table      = gt_components.
            go_table->display( ).
          CATCH cx_salv_msg .
        ENDTRY.
      
      
        " Create data reference for structure (without CELLTAB)!!!
        CREATE DATA gdo_handle TYPE HANDLE go_sdescr_new.
      
      
        REFRESH: gt_components.
        CLEAR: gs_comp.
        gs_comp-type ?=
              cl_abap_structdescr=>describe_by_data_ref( gdo_handle ).
        gs_comp-name       = 'DATA'.
        gs_comp-as_include = abap_true.
        APPEND gs_comp TO gt_components.
      
      
        " Add table type as field to structure ==> complex structure
        CLEAR: gs_comp.
        gs_comp-type ?= cl_abap_typedescr=>describe_by_data( celltab ).
        gs_comp-name  = 'CELLTAB'.
        APPEND gs_comp TO gt_components.
      
        go_sdescr  = cl_abap_structdescr=>create( gt_components ).
        go_tdescr  = cl_abap_tabledescr=>create( go_sdescr ).
        CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
        ASSIGN gdo_handle->* TO <gt_outtab_pbo>.
      
      *   Dynamic select
        SELECT        * FROM  (p_tabnam) UP TO 10 ROWS
          INTO CORRESPONDING FIELDS OF TABLE <gt_outtab_pbo>
               WHERE  bukrs  = '2000'.
      
      
        PERFORM fill_celltab.
      
      
      
        " Create second itab (PAI data)
        CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
        ASSIGN gdo_handle->* TO <gt_outtab_pai>.
      
        <gt_outtab_pai> = <gt_outtab_pbo>.  " PAI data = PBO data
        " Renumbering of customer makes it easier to spot the differences
        LOOP AT <gt_outtab_pai> ASSIGNING <gs_outtab>.
          ASSIGN COMPONENT 'KUNNR' OF STRUCTURE <gs_outtab> TO <gd_fld>.
          <gd_fld> = syst-tabix.  " new numbering of customers
        ENDLOOP.
        LOOP AT <gt_outtab_pbo> ASSIGNING <gs_outtab>.
          ASSIGN COMPONENT 'KUNNR' OF STRUCTURE <gs_outtab> TO <gd_fld>.
          <gd_fld> = syst-tabix.  " new numbering of customers
        ENDLOOP.
      
        DELETE <gt_outtab_pbo> INDEX 3.  " ==>  3rd row in PAI data is new
        DELETE <gt_outtab_pai> INDEX 7.  " ==>  7th row in PBO data is DELE
      
      
      
        " Shuffle data from outtab to corresponding itab (w/o CELLTAB)
        PERFORM shuffle_outtab_to_itab.
      
      
      
      
        " List output
        PERFORM write_list.
      
      
        EXIT.
      
        " Simplified version of table creation:
        CLEAR: gdo_data.
        UNASSIGN <gt_outtab_pbo>.
      
        CREATE DATA gdo_data TYPE STANDARD TABLE OF (p_tabnam).
        ASSIGN gdo_data->* TO <gt_outtab_pbo>.
      
      
      
      END-OF-SELECTION.
      
      
      *&---------------------------------------------------------------------*
      *&      Form  FILL_CELLTAB
      *&---------------------------------------------------------------------*
      *       text
      *----------------------------------------------------------------------*
      *  -->  p1        text
      *  <--  p2        text
      *----------------------------------------------------------------------*
      FORM fill_celltab .
      * define local data
        DATA:
          ls_cell       TYPE lvc_s_styl,
          lt_celltab    TYPE lvc_t_styl.
      
      
        FIELD-SYMBOLS:
          <gs_struc>    TYPE ANY,
          <lt_celltab>  TYPE lvc_t_styl.
      
      
        " Create dummy entry for local CELLTAB
        ls_cell-fieldname = 'BUKRS'.
        ls_cell-style     = cl_gui_alv_grid=>mc_style_enabled.
        INSERT ls_cell INTO TABLE lt_celltab.
      
      
        LOOP AT <gt_outtab_pbo> ASSIGNING <gs_struc>.
          ASSIGN COMPONENT 'CELLTAB' OF STRUCTURE <gs_struc> TO <lt_celltab>.
      
          <lt_celltab> = lt_celltab.
      
          "   No MODIFY required because we are working with the field symbol
        ENDLOOP.
      
      ENDFORM.                    " FILL_CELLTAB
      
      *&---------------------------------------------------------------------*
      *&      Form  SHUFFLE_OUTTAB_TO_ITAB
      *&---------------------------------------------------------------------*
      *       text
      *----------------------------------------------------------------------*
      *  -->  p1        text
      *  <--  p2        text
      *----------------------------------------------------------------------*
      FORM shuffle_outtab_to_itab .
      
        go_tdescr  = cl_abap_tabledescr=>create( go_sdescr_new ).
        CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
        ASSIGN gdo_handle->* TO <gt_itab_pbo>.
      *
        go_tdescr  = cl_abap_tabledescr=>create( go_sdescr_new ).
        CREATE DATA gdo_handle TYPE HANDLE go_tdescr.
        ASSIGN gdo_handle->* TO <gt_itab_pai>.
      
        LOOP AT <gt_outtab_pbo> ASSIGNING <gs_outtab>.
          ASSIGN COMPONENT 'DATA' OF STRUCTURE <gs_outtab> TO <gs_itab>.
          APPEND <gs_itab> TO <gt_itab_pbo>.
        ENDLOOP.
      *
        LOOP AT <gt_outtab_pai> ASSIGNING <gs_outtab>.
          ASSIGN COMPONENT 'DATA' OF STRUCTURE <gs_outtab> TO <gs_itab>.
          APPEND <gs_itab> TO <gt_itab_pai>.
        ENDLOOP.
      
      ENDFORM.                    " SHUFFLE_OUTTAB_TO_ITAB
      
      
      *&---------------------------------------------------------------------*
      *&      Form  WRITE_LIST
      *&---------------------------------------------------------------------*
      *       text
      *----------------------------------------------------------------------*
      *  -->  p1        text
      *  <--  p2        text
      *----------------------------------------------------------------------*
      FORM write_list .
      
        WRITE: / 'PBO data:'.
        LOOP AT <gt_itab_pbo> ASSIGNING <gs_itab>.
          WRITE: / 'Record No.=', syst-tabix, '==>'.
          DO.
            ASSIGN COMPONENT syst-index OF STRUCTURE <gs_itab> TO <gd_fld>.
            IF ( syst-subrc NE 0 ).
              EXIT.
            ENDIF.
      
            WRITE: <gd_fld>.
      
          ENDDO.
        ENDLOOP.
        SKIP 2.
      
        WRITE: / 'PAI data:'.
        LOOP AT <gt_itab_pai> ASSIGNING <gs_itab>.
          WRITE: / 'Record No.=', syst-tabix, '==>'.
          DO.
            ASSIGN COMPONENT syst-index OF STRUCTURE <gs_itab> TO <gd_fld>.
            IF ( syst-subrc NE 0 ).
              EXIT.
            ENDIF.
      
            WRITE: <gd_fld>.
      
          ENDDO.
        ENDLOOP.
      
      ENDFORM.                    " WRITE_LIST

      Finally, if you want to know the <i>differences </i>between PAI and PBO data, that is which records have been deleted, updated or inserted have a look at my code sample

      https://wiki.sdn.sap.com/wiki/display/Snippets/ComparingTwoInternalTables-AGeneric+Approach">Comparing Two Internal Tables - A Generic Approach</a>

      Regards

      Uwe

  • Posted on May 23, 2007 at 03:49 PM

    Hi, Xavier!

    The celltab is a new field created in addition to the table you show in your ALV. This field will not be shown, but there you can add qualities to a field that will be shown, like disabling/enabling the field. The fieldcatalog treats all the column, but with the CELLTAB you have the chance of treat only one cell.

    The way of declaring that field is that showed in the report you say:

    DATA: BEGIN OF gt_outtab occurs 0.  "with header line
            include structure sflight.
    DATA: celltab type LVC_T_STYL.
    DATA: END OF gt_outtab.

    I always use TYPES statement which is asier to interpret:

    TYPES: BEGIN OF ty_outtab.     "here starts the structure type definition
              INCLUDE STRUCTURE sflight.
    TYPES:    celltab TYPE lvc_t_styl.
    TYPES: END OF ty_outtab.       "here ends the structure type definition
    
    TYPES: ty_outtabt TYPE STANDARD TABLE OF  ty_outtab.

    Then you have a structure type which contains the structure of the ALV and the field CELLTAB (TY_OUTTAB); and also a table type of this structure type.

    Then you fill the field like is used in the subrutine 'FILL_CELLTAB' or like here:

      DATA ls_celltab TYPE lvc_s_styl,
           ls_outtab  TYPE ty_outtab.
    
      LOOP AT gt_outtab INTO ls_outtab.
         lv_index = SY-TABIX.
    
         ls_celltab-fieldname = 'CARRID'.  "The field you want to treat
         IF "here you can put a condition or do that in the LOOP sentence using WHERE
            ls_celltab-style = cl_gui_alv_grid=>mc_style_disabled.
            INSERT ls_celltab INTO TABLE ls_outtab-celltab.
            MODIFY gt_outtab FROM ls_outtab INDEX lv_index.
         ELSE.
            ls_celltab-style = cl_gui_alv_grid=>mc_style_enabled.
            INSERT ls_celltab INTO TABLE ls_outtab-celltab.
            MODIFY gt_outtab FROM ls_outtab INDEX lv_index.
         ENDIF.
    
      ENDLOOP.

    Where GT_OUTTAB has been declared in the TOP INCLUDE with the TYPE defined TY_OUTTABT.

    If you watch the class 'CL_GUI_ALV_GRID' attributes, there you can find other qualities you can give your cells using the CELLTAB.

    Hopping it will be useful,

    Sergio

    Add a comment
    10|10000 characters needed characters exceeded

  • author's profile photo Former Member
    Former Member
    Posted on Jun 22, 2007 at 03:09 PM

    Hi Xavier,

    I Have de same problem.

    Do you have a solution ?

    Add a comment
    10|10000 characters needed characters exceeded

  • author's profile photo Former Member
    Former Member
    Posted on Oct 20, 2008 at 03:32 PM

    Hi Uwe,

    Wy is not possible to make a select with JOIN into a table so declared:

    <gt_outtab> as standard table.

    Thanks and regards

    Christian

    Add a comment
    10|10000 characters needed characters exceeded

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.