dynamicabaprtts

Create table type by name then add an arbitrary column?


I am attempting to write a class that can accept a table name, add a couple of extra columns for data ingestion purposes, then generate a CSV. I have it working for a table by sending in a table name as a parameter:

" Get the data dictionary object for the table
table_type ?= cl_abap_typedescr=>describe_by_name( table ).
" Create a table description object with the line type
table_descr = cl_abap_tabledescr=>create( p_line_type = table_type ).
" Declare the internal table using the generic type
create data gt_data type handle table_descr.

This generic code gets me home to then create a SQL call via cl_sql_statement and fill the gt_data object. My question is:

Can I add a column to the generic type? I wanted to add a timestamp column to the front of the object as to when I have extracted the data from the system.

I also may want to run queries with a JOIN where I may need a single field from another table that the generic type doesn't handle, so I may need to add a single extra column. How can this be done?


Solution

  • Youre pretty close to the solution already. Using the RTTS classes.
    There is an example in your ABAP system that does what you are looking for.

    See ABAP demo_create_data_via_handle The Docu covers this process as well.

    Here is a snippet from the Program.

    METHOD main.
        DATA: struct_type TYPE REF TO cl_abap_structdescr,
              dref        TYPE REF TO data,
              oref        TYPE REF TO cx_sy_struct_creation.
    
        DATA column1 TYPE c LENGTH 30.
        DATA column2 TYPE c LENGTH 30.
    
        FIELD-SYMBOLS: <struc>  TYPE any,
                       <comp1>  TYPE any,
                       <comp2>  TYPE any.
    
        cl_demo_input=>add_field( CHANGING field = column1 ).
        cl_demo_input=>add_field( CHANGING field = column2 ).
        cl_demo_input=>request( ).
    
        column1 = to_upper( column1 ).
        column2 = to_upper( column2 ).
    
        TRY.
            struct_type = cl_abap_structdescr=>get(
              VALUE #(
                ( name = column1 type = cl_abap_elemdescr=>get_c( 40 ) )
                ( name = column2 type = cl_abap_elemdescr=>get_i( )    )
                     )
                                                   ).
            CREATE DATA dref TYPE HANDLE struct_type.
          CATCH cx_sy_struct_creation INTO oref.
            cl_demo_output=>display( oref->get_text( ) ).
            RETURN.
        ENDTRY.
    
        ASSIGN dref->* TO <struc>.
        ASSIGN COMPONENT column1 OF STRUCTURE <struc> TO <comp1>.
        <comp1> = 'Amount'.
    
        ASSIGN dref->* TO <struc>.
        ASSIGN COMPONENT column2 OF STRUCTURE <struc> TO <comp2>.
        <comp2> = 11.
    
        cl_demo_output=>display( |{ column1 WIDTH = 32 } { <comp1> }\n| &
                                 |{ column2 WIDTH = 32 } { <comp2> }| ).
      ENDMETHOD.