메뉴 건너뛰기

SAP 한국 커뮤니티

Dynamic Internal Table

sapjoy 2007.02.12 00:30 조회 수 : 8102 추천:40

Dynamic Internal Table
Subramanian Venkateswaran
Company: L&T Infotech
Nov. 19, 2004 11:45 PM
Permalink

On searching the ABAP forums, I did find many queries (in fact, there were
a few queries last week as well) to create a dynamic internal table. I have
identified a couple of scenarios and methods by which we can create a dynamic
internal table.


Tools Required
Knowledge on data references, field-symbols is an added advantage, as they
are extensively used in all the approaches.


Create a Dynamic Internal Table

Scenario 1
-------------------------------------
Assuming, in an internal table, you have entries of field names, which should
be present as columns of a dynamic internal table.

For e.g. we have an internal table, LT_INTERNALTABLE.

Entries in LT_INTERNALTABLE are:

FIELDNAME
MANDT
CARRID
CONNID
FLDATE
PRICE
CURRENCY


To be converted to

MANDT CARRID CONNID FLDATE PRICE CURRENCY
100 LH 0400 28.02.1995 899 DEM
100 LH 0454 17.11.1995 1499 DEM


Data Definition
*** Tables
DATA: LT_DATA type ref to DATA.
DATA: LT_FIELDCATALOG type LVC_T_FCAT.

*** Structure
DATA: LS_FIELDCATALOG type LVC_S_FCAT.

*** Data References
DATA: NEW_LINE type ref to data.

*** Field Symbols
FIELD-SYMBOLS: <FS_DATA> type ref to DATA,
               <FS_1> type any table,
               <FS_2>,
               <FS_3>.

Populating the internal table with fieldnames required for our dynamic
internal table

LS_FIELDCATALOG-FIELDNAME = 'MANDT'.
append LS_FIELDCATALOG to LT_FIELDCATALOG.

LS_FIELDCATALOG-FIELDNAME = 'CARRID'. "Fieldname
LS_FIELDCATALOG-INTTYPE = 'C'. "Internal Type C-> Character
append LS_FIELDCATALOG to LT_FIELDCATALOG.

LS_FIELDCATALOG-FIELDNAME = 'CONNID'.
LS_FIELDCATALOG-INTTYPE = 'N'.
append LS_FIELDCATALOG to LT_FIELDCATALOG.

LS_FIELDCATALOG-FIELDNAME = 'FLDATE'.
LS_FIELDCATALOG-INTTYPE = 'D'.
append LS_FIELDCATALOG to LT_FIELDCATALOG.

LS_FIELDCATALOG-FIELDNAME = 'PRICE'.
LS_FIELDCATALOG-INTTYPE = 'P'.
append LS_FIELDCATALOG to LT_FIELDCATALOG.

LS_FIELDCATALOG-FIELDNAME = 'CURRENCY'.
LS_FIELDCATALOG-INTTYPE = 'C'.
append LS_FIELDCATALOG to LT_FIELDCATALOG.


Assigning Field-Symbol to our dynamic internal table

assign LT_DATA to <FS_DATA>.


Calling the method CREATE_DYNAMIC_TABLE

call method cl_alv_table_create=create_dynamic_table
     exporting
       it_fieldcatalog = LT_FIELDCATALOG
     importing
       ep_table = FS_DATA
     exceptions
       generate_subpool_dir_full = 1
       others = 2
                .
if sy-subrc <> 0.
endif.


Internal Table is ready, now to put data in that table

If you check the field-symbol, <FS_DATA>, it now refers to dynamic internal
table that you wanted to create at start.
Next steps are to put data inside. For this, we first assign the data contents
of <FS_DATA> to a field-symbol <FS_1>.

*** So <FS_1> now points to our dynamic internal table.

assign <FS_DATA>->* to <FS_1>.

*** Next step is to create a work area for our dynamic internal table.

create data NEW_LINE like line of <FS_1>.

*** A field-symbol to access that work area
assign NEW_LINE->*  to <FS_2>.

*** And to put the data in the internal table
select MANDT CARRID CONNID FLDATE PRICE CURRENCY
  from SFLIGHT
  into corresponding fields of table <FS_1>.

*** Access contents of internal table
loop at <FS_1> assigning <FS_2>.

  assign component 1 of structure <FS_2> to <FS_3>.
  write: / <FS_3>.
endloop.


Scenario 2

In case you know the name of the DDIC structure, then it becomes all
the more simple.

data: lv_tablename type string value 'SFLIGHT'.
data: lv_dref type ref to DATA.

CREATE DATA lv_dref type table of (lv_tablename).

FIELD-SYMBOLS: <FS> TYPE STANDARD TABLE.

ASSIGN lv_dref->* TO <FS>.

select *
  from sflight
  into table <FS>.


WAS 6.40 Approach
----------------------------------------------
Thomas Jung shares with us the approach that can be used in WAS 6.40 ,
which is more elegant and it removes some of the issues associated with
cl_alv_table_create.

report yes_tjung_sflight_test.

*** Data Declaration

data: sflighttype type ref to cl_abap_structdescr,
      tabletype   type ref to cl_abap_tabledescr,
      comp_tab    type cl_abap_structdescr=>component_table,
      new_comp_tab like comp_tab,
      linetype type ref to cl_abap_structdescr,
      dref type ref to data.

*** Field Symbols

field-symbols: <wa_comp> like line of comp_tab.
field-symbols: <table> type any table.

sflighttype ?= cl_abap_typedescr=>describe_by_name('SFLIGHT').
comp_tab = sflighttype->get_components( ).

loop at comp_tab assigning <wa_comp>.
  case <wa_comp>-name.
    when 'CARRID' or 'CONNID' or 'FLDATE' or 'PRICE' or 'CURRENCY'.
      append <wa_comp> to new_comp_tab.
  endcase.
endloop.

linetype = cl_abap_structdescr=>create( new_comp_tab ).
tabletype = cl_abap_tabledescr=>create(
p_line_type = linetype
p_table_kind = cl_abap_tabledescr=>tablekind_std ).

create data dref type handle tabletype.
assign dref->* to <table>.

select * from sflight into corresponding fields of table <table>.

field-symbols: <wa_data> type any.
field-symbols: <wa_field> type any.

loop at <table> assigning <wa_data>.
  write: /.
  loop at new_comp_tab assigning <wa_comp>.
    assign component sy-tabix of structure <wa_data> to <wa_field>.
    write: <wa_field>.
  endloop.
endloop.

For more see the comments section of this weblog, you may also find the
Dynamic Function Module Interface.

Also check this section of the comments, where Thomas Jung shares some
important information from developers perspective :

https://weblogs.sdn.sap.com/cs/user/view/cs_msg/1599


Dynamic Function Module Parameter Creation
------------------------------------------------------
2004-11-15 06:28:52 Thomas Jung [Reply]

While we are on the subject of dynamic internal table creation; here is
another method. I have used this in 620 to dynamically create data areas for
making RFC calls to a 46C system. I read the data type from the function
Interface and then use the CREATE DATA statement. Also included are the
exceptions you will probably want to catch any bad casts.

****Dynamically read the interface of the function module we are going
****to call
data: irfc type table of rfc_fint_p.
field-symbols: <wa_rfc> like line of irfc.

call function 'RFC_GET_FUNCTION_INTERFACE_P'
  destination me->rfcdest
  exporting
    funcname = me->rfcfunction
  tables
    params_p = irfc
  exceptions
    fu_not_found = 1
    nametab_fault = 2
    others = 3.
if sy-subrc <> 0.
  me->message = 'Unable to read function interface'(e05).
  exit.
endif.

****Read the datatype of the IDATA Exporting Parameter
read table irfc assigning <wa_rfc>
  with key paramclass = 'E' "Exporting
parameter = 'IDATA'.
if sy-subrc ne 0.
  me->message = 'Specified RFC Exit does not have the correct interface'(e06).
  exit.
endif.

data_type = <wa_rfc>-tabname.
****We need a DataType
if data_type is initial.
  me->message = 'Data Type of Value Help can not be blank'(e02).
  exit.
endif.

****Create a Importing Parameter for the DataType Specified
data: error1 type ref to cx_sy_create_data_error .
try.
  create data me->idata type (data_type).
catch cx_sy_create_data_error into error1.
  me->message = error1->get_text( ).
  exit.
endtry.

data: error2 type ref to cx_sy_assign_cast_illegal_cast.
data: error3 type ref to cx_sy_assign_cast_unknown_type .
try.
  field-symbols: <tab1> type standard table.
  assign me->idata->* to <tab1>.
catch cx_sy_assign_cast_illegal_cast into error2.
  me->message = error2->get_text( ).
  exit.
catch cx_sy_assign_cast_unknown_type into error3.
  me->message = error3->get_text( ).
  exit.
endtry.


Dynamic Internal Table in 640
---------------------------------------------------------------------
2004-11-15 05:38:35 Thomas Jung [Reply]

Since you mentioned that this can be done easier in 640, I thought I might
share this 640 code sample. In 640 we have public classes and kernel support
instead of dynamically generated code inside cl_alv_table_create. This give
greater flexibility.

report yes_tjung_sflight_test.

data: sflighttype type ref to cl_abap_structdescr,
      tabletype type ref to cl_abap_tabledescr,
      comp_tab type cl_abap_structdescr=>component_table,
      new_comp_tab like comp_tab,
      linetype type ref to cl_abap_structdescr,
      dref type ref to data.

field-symbols: <wa_comp> like line of comp_tab.
field-symbols: <table> type any table.

sflighttype ?= cl_abap_typedescr=>describe_by_name('SFLIGHT').
comp_tab = sflighttype->get_components( ).

loop at comp_tab assigning <wa_comp>.
  case <wa_comp>-name.
    when 'CARRID' or 'CONNID' or 'FLDATE' or 'PRICE' or 'CURRENCY'.
      append <wa_comp> to new_comp_tab.
  endcase.
endloop.

linetype = cl_abap_structdescr=>create( new_comp_tab ).
tabletype = cl_abap_tabledescr=>create(
                p_line_type = linetype
                p_table_kind = cl_abap_tabledescr=>tablekind_std ).

create data dref type handle tabletype.
assign dref->* to <table>.

select * from sflight into corresponding fields of table <table>.

field-symbols: <wa_data> type any.
field-symbols: <wa_field> type any.

loop at <table> assigning <wa_data>.
  write: /.
  loop at new_comp_tab assigning <wa_comp>.
    assign component sy-tabix of structure <wa_data> to <wa_field>.
    write: <wa_field>.
  endloop.
endloop.