From the ABAP release 6.40, SAP has provided RTTS – Run Time Type Services to create types, internal tables at run-time. This RTTS can also be used to describe the properties of the types as well as the fields, internal tables etc.
Sometimes, when we write a program, we don’t have all the information of the fields of the internal table. For example: we are accessing the cost element Actul posting data from the table COSP. Now, we have a requirement to generate an output which will have some specified columns – like amount of period 4 to 8 or Amount of period 1 to 3 or some other combination. This kind of secnarioes are perfect examples of the RTTS. We will see how to create a dynamic internal table using this example.
Steps to Create Dynamic ITAB
To create a dynamic internal table, we need to:
1. Gather all the Components
2. Generate a Type from this components
3. Generate a Table Type from this created type
4. Create a Data reference of this Table Type
5. Assign this data reference to the Field-Symbol of table type. This Field-symbol will act as our dyanmic internal table
Demo Application
In today’s example we will see how to:
1. Create Dynamic internal table
2. Write dynamic select query to data into this dynamic table
3. Change the contents of this dynamic internal table
4. Generate the ALV display using SALV model for this dynamic internal table. Explore how to create ALV using SALV from Tutorials > SALV Table Display
We will provide the selection of the period for which user wants to generate an output. Based on the entered periods we will create a dynamic type containg the KSTAR (Costing Element) and Amount fields for the month. After creating the dynamic type, we will create a dynamic table type. Using this table type we will create a reference of the data. From this data reference we will assign the internal table to field-symbols.
So, let’s see the code snippet to create Dynamic ITAB:
*&---------------------------------------------------------------------*
*& This Code snippet shows how to
*& Create Dynamic Internal Table
*& Dynamic Selection of data
*& Accessing Dynamic data selection
*& Displaying Dynamic internal table in ALV
*&---------------------------------------------------------------------*
report zdynamic_itab.
*
* Exisiting Table type
TYPES: BEGIN OF ty_kstar,
kstar TYPE kstar,
END OF ty_kstar.
*
* Dynamic Table creation
DATA: lo_struct TYPE REF TO cl_abap_structdescr,
lo_element TYPE REF TO cl_abap_elemdescr,
lo_new_type TYPE REF TO cl_abap_structdescr,
lo_new_tab TYPE REF TO cl_abap_tabledescr,
lo_data TYPE REF TO data,
lt_comp TYPE cl_abap_structdescr=>component_table,
lt_tot_comp TYPE cl_abap_structdescr=>component_table,
la_comp LIKE LINE OF lt_comp,
lf_months TYPE monat,
lf_run_mon TYPE monat.
*
* Dynamic Selection fields
TYPES: BEGIN OF ty_fields,
field TYPE char30,
END OF ty_fields.
*
DATA: lt_fields TYPE STANDARD TABLE OF ty_fields,
la_fields TYPE ty_fields.
*
* field symbols to access the dynamic table
FIELD-SYMBOLS: <f_tab> TYPE ANY TABLE,
<f_line> TYPE ANY,
<f_field> TYPE ANY.
*
* Selection Screen
PARAMETERS: p_mon_fr TYPE monat,
p_mon_to TYPE monat.
*
START-OF-SELECTION.
*
*$*$*...............Dynamic Internal Table........................*$*$*
* 1. Getting Compoents from existing type
lo_struct ?= cl_abap_typedescr=>describe_by_name( 'TY_KSTAR' ).
lt_comp = lo_struct->get_components( ).
APPEND LINES OF lt_comp TO lt_tot_comp.
*
* 2. Adding required fields based on the single data element
* Determining Number of fields
lf_months = ( p_mon_to - p_mon_fr ) + 1.
lf_run_mon = p_mon_fr.
*
DO lf_months TIMES.
*
* Element Description
lo_element ?= cl_abap_elemdescr=>describe_by_name( 'WTGXXX' ).
*
* Field name
CONCATENATE 'WTG0' lf_run_mon INTO la_comp-name.
*
* Field type
la_comp-type = cl_abap_elemdescr=>get_p(
p_length = lo_element->length
p_decimals = lo_element->decimals ).
*
* Filling the component table
APPEND la_comp TO lt_tot_comp.
CLEAR: la_comp.
*
lf_run_mon = lf_run_mon + 1.
ENDDO.
*
* 3. Create a New Type
lo_new_type = cl_abap_structdescr=>create( lt_tot_comp ).
*
* 4. New Table type
lo_new_tab = cl_abap_tabledescr=>create(
p_line_type = lo_new_type
p_table_kind = cl_abap_tabledescr=>tablekind_std
p_unique = abap_false ).
*
* 5. data to handle the new table type
CREATE DATA lo_data TYPE HANDLE lo_new_tab.
*
* 6. New internal table in the fieldsymbols
ASSIGN lo_data->* TO <f_tab>.
*
*$*$*...............Dynamic Selection.............................*$*$*
* Filling up the table for the Selection fields of Select Query
LOOP AT lt_tot_comp INTO la_comp.
la_fields-field = la_comp-name.
APPEND la_fields TO lt_fields.
CLEAR: la_comp, la_fields.
ENDLOOP.
*
* Selecting data
SELECT (lt_fields)
INTO TABLE <f_tab>
FROM cosp
UP TO 10 ROWS.
*
*$*$*...............Accessing dynamic table.......................*$*$*
LOOP AT <f_tab> ASSIGNING <f_line>.
ASSIGN COMPONENT 'WTG004' OF STRUCTURE <f_line> TO <f_field>.
<f_field> = '100.00'.
ENDLOOP.
*
*
*$*$*...............Displaying using SALV model...................*$*$*
*
DATA: lo_alv TYPE REF TO cl_salv_table.
*
TRY.
cl_salv_table=>factory(
EXPORTING
list_display = abap_false
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = <f_tab> ).
CATCH cx_salv_msg .
ENDTRY.
*
lo_alv->display( ).
Check out all ways to Create Dynamic ITAB
You would love to check out all other ways to create Dynamic Internal Tables.
Hi,
I read your tutorial about using using class CL_ALV_TABLE_CREATE to create a dynamic table on your blog. And it was very helpful. I have a question that how we add or change the column header of the period (month) column. There are 16 periods. For those fields that I add manually in the field catalog, i can change theirs heading by using class cl_salv_columns_table. However, this method doesn't work for dynamic columns which are period fields. For example i tried
TRY.
gr_columns = go_alv->get_columns( ).
gr_column ?= gr_columns->get_column( 'WOG001' ).
gr_column->set_long_text( 'Period 1' ).
gr_column->set_medium_text( 'Period 1' ).
gr_column->set_short_text( 'Jan' ).
CATCH cx_salv_not_found.
MESSAGE e043(zu) WITH text-e01 'Period 1'.
EXIT.
ENDTRY.
Then I ran the program, it gave msg error about not being able to set up column for Period 1.
How to fix this problem.
Thanks a lot your help,
Tracie.
Hello Tracie,
Changing the column heading works very well for me. I have extended the sam example:
DATA: lo_cols TYPE REF TO cl_salv_columns.
* get columns object
lo_cols = lo_alv->get_columns( ).
*…Individual Column
DATA: lo_column TYPE REF TO cl_salv_column.
* WTG004
TRY.
lo_column = lo_cols->get_column( 'WTG004' ). " <<
lo_column->set_long_text( 'Period 4' ).
lo_column->set_medium_text( 'Period 4' ).
lo_column->set_short_text( 'Per 4' ).
lo_column->set_output_length( 10 ).
CATCH cx_salv_not_found. "#EC NO_HANDLER
ENDTRY.
*
lo_alv->display( ).
If you are referring to the columns used in the example on the blog, than the column name would be WTG0xx, not the WOG0xx.
Regards,
Naimesh Patel
Hi Naimesh,
Well, Creating of Dynamic structure and table is fine. Could you also help in creating a Complex Structure.
Ex: Structre XYZ having table LVC_T_SCOL, so that we can colour the fields while displaying.
Thanks,
Kaleem
Hello Kaleem,
You asked:
Structre XYZ having table LVC_T_SCOL, so that we can colour the fields while displaying.
Yes, I already created a post on that topic. Check this post:
http://help-abap.blogspot.com/2008/10/dynamic-internal-table-with-deep.html
Regards,
Naimesh Patel
Hai Naimesh,
I have developed a program to update standard table. I am using dynamic itab creation concept. But my dynamic internal table is having width only 1200 bytes. But many standard tables have more than that width. Do you have any input create dynamic internal table with more than 1200 bytes width..Expecting reply ..
Thanks
Venkat
Hi Naimesh,
I used CALL METHOD cl_alv_table_create=>create_dynamic_table to create the dynamic internal table , now I want to make given lines of the dynamic alv editable, so need to add one more field celltab type lvc_t_styl to the dynamic table, but it cause a dump at the call method statement,I tried the way you introduced above, it seems I can't use it in version 6.4. Any suggestion on adding the lvc_t_styl field ?
Expecting your responses,thanks in advance
Regards,
Daisy
Hello Daisy,
You asked:
"I used CALL METHOD cl_alv_table_create=>create_dynamic_table to create the dynamic internal table , now I want to make given lines of the dynamic alv editable, so need to add one more field celltab type lvc_t_styl to the dynamic table, but it cause a dump at the call method statement,I tried the way you introduced above, it seems I can't use it in version 6.4. Any suggestion on adding the lvc_t_styl field ?"
You can pass the I_STYLE_TABLE = 'X' in the method to get the STYLE table added in your dynamic table.
Like:
call method cl_alv_table_create=>create_dynamic_table
exporting
it_fieldcatalog = pt_fieldcat
I_STYLE_TABLE = 'X' "<< To create a style table type LVC_T_STYL
importing
ep_table = g_hts.
Find this link:
https://forums.sdn.sap.com/thread.jspa?threadID=925673
Regards,
Naimesh Patel
Hi Naimesh,
Thank you very much for quick reply , the issue got solved ! one more question , I want to set the position of cursor on given cell, instead of the default first line first column, how should I achieve this ?
Best Regards,
Daisy
Hi,
I was read your blogspot to many explaining but i have one question when i run my report i have long time error to get cost product analysis .
WHY???
Best Regards,
Eman
Hi,
can u pls tel me why the column names are not dispalyed. wht to do to correct that.
can i display the columns taken into the field symbol as the columns of my ALV.
I had made a report refering this code. pls help. since i m a beginer in ABAP i m struggling here.
Thanks,
Vani
Hi,
can u pls tel me why the column names are not dispalyed. wht to do to correct that.
can i display the columns taken into the field symbol as the columns of my ALV.
I had made a report refering this code. pls help. since i m a beginer in ABAP i m struggling here.
Thanks,
Vani
Hi,
can u pls tel me why the column names are not dispalyed. wht to do to correct that.
can i display the columns taken into the field symbol as the columns of my ALV.
I had made a report refering this code. pls help. since i m a beginer in ABAP i m struggling here.
Thanks,
Vani
Hi Naimesh,
I have some questions about this dynamic table usage in my ALV report.
This is my coding.
—
types:
* Table 1
begin of ty_table1,
tabname type tabname,
ddtext type as4text,
end of ty_table1,
* Table 2
begin of ty_table2,
name type progname,
text type repti,
end of ty_table2,
* Table 3
begin of ty_table3,
pgmid type pgmid,
object type trobjtype,
obj_name type sobj_name,
end of ty_table3.
data:
ta_table1 type table of ty_table1,
st_table1 type ty_table1,
ta_table2 type table of ty_table2,
st_table2 type ty_table2,
ta_table3 type table of ty_table3,
st_table3 type ty_table3,
RF_CL_ALV TYPE REF TO CL_SALV_TABLE.
FIELD-SYMBOLS:
TYPE TY_TABLE1,
TYPE TY_TABLE2,
TYPE TY_TABLE3.
* Selection Screen – Tables
PARAMETERS: PA_TAB1 TYPE CHAR1 DEFAULT 'X'.
PARAMETERS: PA_TAB2 TYPE CHAR1.
PARAMETERS: PA_TAB3 TYPE CHAR1.
* Get Data
* Table 1
IF PA_TAB1 = C_TRUE.
SELECT … FROM …
INTO CORRESPONDING FIELDS OF TABLE TA_TABLE1 BYPASSING BUFFER
WHERE …
LOOP AT TA_TABLE1 ASSIGNING .
-ddtext = 'Table 1'.
ENDLOOP.
* Table 2
ELSEIF PA_TAB2 = C_TRUE.
SELECT … FROM …
INTO CORRESPONDING FIELDS OF TABLE TA_TABLE2 BYPASSING BUFFER
WHERE …
LOOP AT TA_TABLE1 ASSIGNING
-text = 'Table 2'.
ENDLOOP.
* Table 3
ELSEIF PA_TAB3 = C_TRUE.
SELECT … FROM …
INTO CORRESPONDING FIELDS OF TABLE TA_TABLE3 BYPASSING BUFFER
WHERE …
ENDIF.
* Display Report
FIELD-SYMBOLS: TYPE TABLE.
* Table 1
IF PA_TAB1 = C_TRUE.
ASSIGN TA_TABLE1 TO .
* Table 2
ELSEIF PA_TAB2 = C_TRUE.
ASSIGN TA_TABLE2 TO .
* Table 3
ELSEIF PA_TAB3 = C_TRUE.
ASSIGN TA_TABLE3 TO .
ENDIF.
TRY.
CL_SALV_TABLE=>FACTORY(
* EXPORTING
* LIST_DISPLAY = C_TRUE
IMPORTING
R_SALV_TABLE = RF_CL_ALV
CHANGING
T_TABLE = ).
CATCH CX_SALV_MSG.
ENDTRY.
* Set the columns
PERFORM SET_COLUMNS.
* Display the table
RF_CL_ALV->DISPLAY( ).
*& — Form SET_COLUMNS —
FORM SET_COLUMNS.
DATA:
LRF_CL_COLUMN TYPE REF TO CL_SALV_COLUMN_TABLE,
LRF_CL_COLUMNS TYPE REF TO CL_SALV_COLUMNS_TABLE.
* Get columns object
LRF_CL_COLUMNS = RF_CL_ALV->GET_COLUMNS( ).
* Check Table 1
IF PA_TAB1 = C_TRUE.
PERFORM SET_COLUMN_NAME USING 'DDTEXT'(C01)
'Table1_S'(C02)
'Table1_M'(C03)
'Table1_L'(C04)
''
''
''
''.
ENDIF.
* Check Table 2
IF PA_TAB1 = C_TRUE.
PERFORM SET_COLUMN_NAME USING 'TEXT'(C05)
'Table2_S'(C06)
'Table2_M'(C07)
'Table2_L'(C08)
''
''
''
''.
ENDIF.
…cont.
*& — Form SET_COLUMN_NAME —
FORM SET_COLUMN_NAME USING U_COLNAME TYPE LVC_FNAME "Column name
U_OUTPS TYPE SCRTEXT_S "Short text
U_OUTPM TYPE SCRTEXT_M "Medium text
U_OUTPL TYPE SCRTEXT_L "Long text
U_OUTPK TYPE SAP_BOOL "Key column
U_OUTPC TYPE LVC_CFNAME "Currency column
U_OUTPH TYPE SAP_BOOL "Hide column
U_OUTPT TYPE SAP_BOOL. "Technical column (not shown anywhere)
DATA:
LRF_CL_COLUMN TYPE REF TO CL_SALV_COLUMN_TABLE,
LRF_CL_COLUMNS TYPE REF TO CL_SALV_COLUMNS_TABLE.
* Get columns
LRF_CL_COLUMNS = RF_CL_ALV->GET_COLUMNS( ).
* Set the column names
TRY.
LRF_CL_COLUMN ?= LRF_CL_COLUMNS->GET_COLUMN( U_COLNAME ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
* Set Short Text
IF NOT U_OUTPS IS INITIAL.
TRY.
LRF_CL_COLUMN->SET_SHORT_TEXT( U_OUTPS ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
* Set Medium Text
IF NOT U_OUTPM IS INITIAL.
TRY.
LRF_CL_COLUMN->SET_MEDIUM_TEXT( U_OUTPM ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
* Set Long Text
IF NOT U_OUTPL IS INITIAL.
TRY.
LRF_CL_COLUMN->SET_LONG_TEXT( U_OUTPL ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
* Set Key Columns
IF U_OUTPK = ABAP_TRUE.
TRY.
LRF_CL_COLUMN->SET_KEY( ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
* Set Currency Column
IF NOT U_OUTPC IS INITIAL.
TRY.
LRF_CL_COLUMN->SET_CURRENCY_COLUMN( VALUE = U_OUTPC ).
CATCH CX_SALV_NOT_FOUND.
CATCH CX_SALV_DATA_ERROR.
ENDTRY.
ENDIF.
* Set Hidden Column
IF U_OUTPH = ABAP_TRUE.
TRY.
LRF_CL_COLUMN->SET_VISIBLE( VALUE = IF_SALV_C_BOOL_SAP=>FALSE ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
* Set Technical Column
IF U_OUTPT = ABAP_TRUE.
TRY.
LRF_CL_COLUMN->SET_TECHNICAL( ).
CATCH CX_SALV_NOT_FOUND.
ENDTRY.
ENDIF.
ENDFORM. " SET_COLUMN_NAME
—
Say I have 3 tables that I would like to use in the same field symbol, depending.
How can I use the same field symbols for all tables using this:
FIELD-SYMBOLS:
TYPE ANY TABLE,
TYPE ANY,
TYPE ANY.
I don't want to check what table it is in any place. The header will give errors and program dumps if not checked which table it is.
The loop I would like to use dynamically, so I only have these field symbols above that I refer to.
Can you please comment on this?
Regards,
/Fredrik Brandt (fredrik.brandt@sonyericsson.com)
Hi
I have created a dynamic table with its dynamic columns and its value. The ALV is displayed.
On the output report, the user has a option to update a custom table that determines the columns in my dynamic table. Once the user updates this table, he/she then press the Refresh icon.
The dynamic table needs to be re-created with its new columns (from custom table) and its values.
Question: Is there a way to “delete” the instance of the first dynamic table (its columns + fields) so that it can be re-created.
I can only delete the rows but the “old” columns values are still exist.
Thank you.
Hi,
I just recently saw this post and have not done much RND.
But when i try to create
* Element Description
lo_element ?= cl_abap_elemdescr=>describe_by_name( 'CHAR30' ).
** Field name
CONCATENATE 'WTG0' lf_run_mon INTO la_comp-name.
*
* Field type
la_comp-type = cl_abap_elemdescr=>get_p( p_length = lo_element->length p_decimals = lo_element->decimals ).
This code gives me error cause char30 length greater than 16
Can any one help on this?
Hi Naimesh,
I am a beginner in ABAP.
I have come across the theread from where I am putting this question to you.
I don't know how and where to receive your reply, therefore this is my email id.
yogeshpathakk@gmail.com
Please mail your reply to my email ID.
I am developing a report program for Where Batch used List based on AUFM table.
I want to use an internal table dynamically to fetch the data from AUFM table, for example, gt_sel_1, gt_sel_2, gt_sel_3 and on.
A loop is running on the above internal table.
Code context for your idea:
IF gt_261_t[] IS NOT INITIAL.
SELECT bwart
matnr
werks
charg
dmbtr
erfmg
meins
aufnr
mblnr
mjahr
zeile
FROM aufm
INTO CORRESPONDING FIELDS OF TABLE t_sel_t
FOR ALL ENTRIES IN gt_261_t
WHERE matnr EQ gt_261_t-matnr
AND charg EQ gt_261_t-charg
AND werks EQ p_werks
AND bwart EQ '101'.
Please revert back as I am relying on your reply.
With warm Regards,
Yogesh Pathak
Colourtex,Surat,Gujarat,India.
Hi,
I am a beginner in RTTS. I went through your code but for a beginner like me its a bit complicated to understand. So for starting what i want to try is just declare an itab dynamically(whose type i dont know until runtime) and fetch the data from database table (of that type of course) into that itab and print the contents of that itab in classical reports by write statement.
If possible can u suggest some material for RTTS for beginners.
Kindly reply me by mail
THANK you
[…] friends / Colleagues. 10k Pageviews of home page. Enjoy the animation both by CSS3 and JS 8456 Dynamic Table creation using RTTS is the Most visited post of all time 1500 Most visited post created in 2011 is CLASS_CONSTRUCTOR […]
Hi Naimesh,
That is wonderful to have this use of RTTS.
wel, I am migrating my code to RTTS.
Currently I am using METHOD ‘cl_alv_table_create=>create_dynamic_table’ to create my dynamic internal table but you might be aware that it can not be used more than 36 time in a single session. So I am facing dump issue for same.
I am adopting RTTS approach now but I am stuck up at certain points.
How my internal table ” will be replaced with RTTS.?
How I can migrate it in container placed within a module pool screen.?
I’ll thankful to you if you will guide me.
For your reference find the code shown below. It is being called at METHOD handle_data_changed.
Thanks,
Maharshi Vyas
Hello Maharshi,
You need to collect all the fields of an internal table into a itab. E.g. for this example, you would try to add them in lt_comp.
If I understood correctly, you have a container on a Module Pool. Once you have table created, you would be able to get the data reference into a table type Field-Symbol. Use this FS to generate your ALV.
Regards,
Naimesh Patel
Hi Naimesh,
Thank you very much for the reply.
Yes you are correct I have container for module pool.
currently I am not able to transport my fields to dynamic internal table.
I have internal table which is having all field names as rows.
I am not able to apply same at ‘cl_abap_typedescr=>describe_by_data( ???? ).’
so I tried to get it done via one by one approach.
like I put this statement inside loop
‘cl_abap_elemdescr=>describe_by_data( wa-fname ).’
but I got issue at length calculation.
As my each field will have different lengths I am not able to pass it to p_length.
here lo_element->length indicates length of the field defined(fname). it is not results length of the field name which we are passing one by one dynamically in loop.
la_comp-type = cl_abap_elemdescr=>get_p(
p_length = lo_element->length
p_decimals = lo_element->decimals.
I tried to achieve it by passing some field symbols but it gives dump where length exceeds 16 number.
might be it is taking it in some different format(perhaps in bytes).
Hope things are clear to you.
If you want we can discuss on call. Let me know your contact number. my id is maharshi.vyas82@gmail.com
I will be much thankful to you.
Thanks,
Maharshi Vyas
GET_P is only applicable to TYPE P variables. You should be able to get the data reference of each value by using their respective Data Elements. So, in your internal table, you need to have few more columns to make it more intuitive which type of data objects you are using.
I’ll try to create a sample code …
Regards,
Naimesh Patel
Hi Naimesh,
It’s done..
I have used various methods for data type passing along with length and now it is working fine for all dynamic fields.
Thank you very much for your help. 🙂
– Maharshi Vyas
Hi Naimesh,
I created the ALV using the code posted by you but my ALV does not show any column heading for the additional columns…below is the code that I am using:
lo_element ?= cl_abap_elemdescr=>describe_by_name( ‘LGART’ ).
CONCATENATE ‘LGART’ i_index INTO la_comp-name.
* Field type
la_comp-type = cl_abap_elemdescr=>get_c(
p_length = lo_element->length ).
APPEND la_comp TO lt_tot_comp.
Please advise.
Thanks,
Payal Mathur
Hi Payal,
I think the issue is with the field name you are passing.
You are concatenating with ‘i_index’ and no such data element is available in DDIC so it is not considering.
It should follow any DDIC structure or a DDIC property.
@Naimesh, Correct me if I am wrong.
Thanks,
Maharshi Vyas
Hello Payal,
You wish to get all the properties from the data element, you need to pass the LO_ELEMENT as the Type for the component.
Regards,
Naimesh Patel
Hi Sir,
I am able to upload the Tab delimited text file in ALV report.
I have created the local structure for the columns available in the .txt file.
But I am not getting the way to find the columns details available in .txt file.
Please Guide me regarding how to get the column details from the loaded file for creation of internal table.
Hello Dileep,
I’m clear about your requirement. If you have uploaded the records in your table, there could be to options – a) move data from file to the itab at Fixed length or b) have a file with a separator.
If you have dynamic columns, I would suggest to have a separator based file. You load the records a long string of a table using Upload FM. Once loaded, split them into a smaller table. Create your Table based on these columns. But you would still need to get the “TYPES” of the columns which you can only have if you know the type of the columns.
Once you move your data to your final table and display as ALV.
Regards,
Naimesh Patel