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: 

Dynamic tables derived from ddic tables

rainer_hbenthal
Active Contributor
0 Kudos

I'm trying to create an internal table, which contains a lot of components of existing tables, but not all.

So i tried to get the type description of the existing table, delete the not needed fields and create a new table by RTTS.

Here is my code:


REPORT  ZCA_SW_DYNAMIC_TYPES.

data:
  dref          type ref to data,
  desc_table    type ref to cl_abap_tabledescr,
  desc_struc    type ref to cl_abap_structdescr,

   it_components type abap_component_tab,
   wa_components type abap_componentdescr.

FIELD-SYMBOLS:
  <it_out>      type STANDARD TABLE.

START-OF-SELECTION.

    desc_struc ?= cl_abap_typedescr=>describe_by_name( 'T001' ).
    it_components = desc_struc->get_components( ).

    delete it_components WHERE name = 'MANDT'.

    desc_struc = cl_abap_structdescr=>create( it_components ).
    desc_table = cl_abap_tabledescr=>create( desc_struc ).
    create data dref type HANDLE desc_table.
    assign dref->* to <it_out>.

    select *
    from t001
    into CORRESPONDING FIELDS OF TABLE <it_out>.

    write:/ 'Done'.

This works fine, but now i'm stucked. The reason is that it_components does not contain all compoents by name, T001 has an include and an append, and these are not resolved in the table it_components. If i want to delete the component BUKRS_GLOB i cant do that cause its in an include.

How can i get it_componets filled so that only elementary compoents are given and resulting includes are resolved?

1 ACCEPTED SOLUTION

Former Member
0 Kudos

Hi Rainer,

I suggest you to use method get_included_view of class CL_ABAP_STRUCTDESCR instead of get_components : it will give you all fields.

DATA :  it_incl_view  TYPE abap_component_view_tab.
  it_incl_view = desc_struc->get_included_view( ).

Best regards,

Samuel

9 REPLIES 9

Former Member
0 Kudos

Hi

Try to manage every single field (field by field) in order to create the internal table:

.PARAMETERS: P_TAB TYPE DDOBJNAME.

DATA: T_FIELDS TYPE TABLE OF DFIES.

DATA: _LEN           TYPE I,
      _DEC           TYPE I.

DATA: LR_VALUE_DESCR  TYPE REF TO CL_ABAP_ELEMDESCR.


DATA:
  DREF          TYPE REF TO DATA,
  DESC_TABLE    TYPE REF TO CL_ABAP_TABLEDESCR,
  DESC_STRUC    TYPE REF TO CL_ABAP_STRUCTDESCR,

   IT_COMPONENTS TYPE ABAP_COMPONENT_TAB,
   WA_COMPONENTS TYPE ABAP_COMPONENTDESCR.

FIELD-SYMBOLS:
  <IT_OUT>      TYPE STANDARD TABLE.

START-OF-SELECTION.

  CALL FUNCTION 'DDIF_FIELDINFO_GET'
    EXPORTING
      TABNAME   = P_TAB
    TABLES
      DFIES_TAB = T_FIELDS.

  LOOP AT T_FIELDS INTO DFIES WHERE FIELDNAME NE 'MANDT'.
    WA_COMPONENTS-NAME = DFIES-FIELDNAME.

    MOVE DFIES-LENG     TO _LEN.
    MOVE DFIES-DECIMALS TO _DEC.

    CASE DFIES-DATATYPE.
      WHEN 'CHAR' OR 'LANG' OR 'CUKY'.
        MOVE CL_ABAP_ELEMDESCR=>GET_C( P_LENGTH = _LEN )
                                                      TO LR_VALUE_DESCR.
      WHEN 'NUMC'.
        MOVE CL_ABAP_ELEMDESCR=>GET_N( P_LENGTH = _LEN )
                                                      TO LR_VALUE_DESCR.
      WHEN 'INT1' OR 'INT2' OR 'INT4'.
        MOVE CL_ABAP_ELEMDESCR=>GET_I( ) TO LR_VALUE_DESCR.
      WHEN 'DATS'.
        MOVE CL_ABAP_ELEMDESCR=>GET_D( ) TO LR_VALUE_DESCR.
      WHEN 'DEC' OR 'CURR'.
        MOVE CL_ABAP_ELEMDESCR=>GET_P( P_LENGTH   = _LEN
                                       P_DECIMALS = _DEC )
                                                      TO LR_VALUE_DESCR.
      WHEN 'TIMS'.
        MOVE  CL_ABAP_ELEMDESCR=>GET_T( ) TO LR_VALUE_DESCR.
      WHEN OTHERS'.
        CONTINUE.
    ENDCASE.

    WA_COMPONENTS-TYPE = LR_VALUE_DESCR.
    INSERT WA_COMPONENTS INTO TABLE IT_COMPONENTS.
  ENDLOOP.
*
  DESC_STRUC = CL_ABAP_STRUCTDESCR=>CREATE( IT_COMPONENTS ).
  DESC_TABLE = CL_ABAP_TABLEDESCR=>CREATE( DESC_STRUC ).
  CREATE DATA DREF TYPE HANDLE DESC_TABLE.
  ASSIGN DREF->* TO <IT_OUT>.

  SELECT *
  FROM (P_TAB)
  INTO CORRESPONDING FIELDS OF TABLE <IT_OUT>.

  WRITE:/ 'Done'.

.

Max

MarcinPciak
Active Contributor
0 Kudos

it_components has field AS_ICNLUDE which is set to 'X' if a field is an include. Just skip this one.

Regards

Marcin

0 Kudos

> it_components has field AS_ICNLUDE which is set to 'X' if a field is an include. Just skip this one.

How should that help if i need to omit bukrs_globl?

0 Kudos

Hi

Just as I wrote in my sample, u should use the fm DDIF_FIELDINFO_GET in order to get all fields of dictionary table and then u can decide which field has to be used or doesn't have to be used.

CALL FUNCTION 'DDIF_FIELDINFO_GET'
    EXPORTING
      TABNAME   = P_TAB
    TABLES
      DFIES_TAB = T_FIELDS.
 
  LOOP AT T_FIELDS INTO DFIES WHERE FIELDNAME NE 'MANDT' AND FIELDNAME NE .....

Max

Edited by: max bianchi on Oct 7, 2009 11:34 AM

Former Member
0 Kudos

Hi,

This is a slight modification to your own code. Please try this. it is working for me.

REPORT zren_rnd.

DATA:

dref TYPE REF TO data,

desc_table TYPE REF TO cl_abap_tabledescr,

desc_struc TYPE REF TO cl_abap_structdescr,

it_components TYPE abap_component_tab,

it_components1 TYPE abap_component_tab,

wa_components TYPE abap_componentdescr,

l_type TYPE REF TO cl_abap_structdescr,

l_tabix TYPE sy-tabix.

FIELD-SYMBOLS:

<it_out> TYPE STANDARD TABLE.

START-OF-SELECTION.

desc_struc ?= cl_abap_typedescr=>describe_by_name( 'T001' ).

it_components = desc_struc->get_components( ).

LOOP AT it_components INTO wa_components WHERE as_include EQ 'X'.

l_tabix = sy-tabix.

REFRESH it_components1[].

l_type ?= wa_components-type.

it_components1 = l_type->get_components( ).

DELETE it_components INDEX l_tabix.

APPEND LINES OF it_components1 TO it_components.

ENDLOOP.

DELETE it_components WHERE name = 'BUKRS_GLOB'.

desc_struc = cl_abap_structdescr=>create( it_components ).

desc_table = cl_abap_tabledescr=>create( desc_struc ).

CREATE DATA dref TYPE HANDLE desc_table.

ASSIGN dref->* TO <it_out>.

SELECT *

FROM t001

INTO CORRESPONDING FIELDS OF TABLE <it_out>.

WRITE:/ 'Done'.

Thanks,

Renjith

MarcinPciak
Active Contributor
0 Kudos

Try this one


data:
   help_struct  type ref to cl_abap_structdescr,

   it_components type abap_component_tab,
   wa_components type abap_componentdescr,
   help_components type abap_component_tab.

FIELD-SYMBOLS:
  <it_out>      type STANDARD TABLE.

START-OF-SELECTION.

    desc_struc ?= cl_abap_typedescr=>describe_by_name( 'T001' ).
    it_components = desc_struc->get_components( ).

    loop at it_components into wa_components
         where as_include = 'X'.

      refresh help_components.
      help_struct ?= wa_components-type.
      help_components = help_struct->get_components( ).
      delete help_components where name = 'BUKRS_GLOB'.
      append lines of help_components to it_components.
    endloop.

    delete it_components where as_include = 'X'.

Now you have only basic fields

Regards

Marcin

Former Member
0 Kudos

Hi Rainer,

I suggest you to use method get_included_view of class CL_ABAP_STRUCTDESCR instead of get_components : it will give you all fields.

DATA :  it_incl_view  TYPE abap_component_view_tab.
  it_incl_view = desc_struc->get_included_view( ).

Best regards,

Samuel

0 Kudos

>

> I suggest you to use method get_included_view of class CL_ABAP_STRUCTDESCR instead of get_components : it will give you all fields.

> Samuel

Hi Samuel, thats the solution i prefer most and to be honest, i hat a look at the existing methods but didnt made the conclusion that this method with that name is what i'm looking for.

Unfortunately, the returning type of get_incliuded_view is not compatible with get_components and therefor not compatible with the create

WTF omitted those last two columns?????? What crude idea is that?

So at least i'm lloking now for a widening cast of


  it_components          TYPE abap_component_tab,
  it_components_incl     type abap_component_view_tab,

it_components = it_components_incl.

I cant really believe this.... So again o have those stupid intermediate temporary vars to copy the content

rainer_hbenthal
Active Contributor
0 Kudos

So this is how it looks like now:


REPORT  zca_sw_dynamic_types.

DATA:
  dref                   TYPE REF TO data,
  desc_table             TYPE REF TO cl_abap_tabledescr,
  desc_struc             TYPE REF TO cl_abap_structdescr,

  it_components          TYPE abap_component_tab,
  it_components_incl     TYPE abap_component_view_tab,
  wa_components          TYPE abap_componentdescr.

FIELD-SYMBOLS:
  <it_out>               TYPE STANDARD TABLE,
  <p_components_incl>     TYPE abap_simple_componentdescr.

START-OF-SELECTION.

  desc_struc ?= cl_abap_typedescr=>describe_by_name( 'T001' ).
  it_components_incl = desc_struc->get_included_view( ).

  LOOP AT it_components_incl ASSIGNING <p_components_incl>.
    wa_components-name = <p_components_incl>-name.
    wa_components-type = <p_components_incl>-type.
    APPEND wa_components TO it_components.
  ENDLOOP.

  DELETE it_components WHERE name = 'MANDT'.

  desc_struc = cl_abap_structdescr=>create( it_components ).
  desc_table = cl_abap_tabledescr=>create( desc_struc ).
  CREATE DATA dref TYPE HANDLE desc_table.
  ASSIGN dref->* TO <it_out>.

  SELECT *
  FROM t001
  INTO CORRESPONDING FIELDS OF TABLE <it_out>.

  WRITE:/ 'Done'.

So the only ugly thing is now the conversion loop between both tables...