What is an Internal Table?
Internal tables are used to obtain data from a fixed structure for dynamic use in ABAP. Each line in the internal table has the same field structure. The main use for internal tables is for storing and formatting data from a database table within a program.
In this tutorial you will learn:
What is a Work Area ?
Work areas are single rows of data. They should have the same format as any of the internal tables. It is used to process the data in an internal table one line at a time.
Difference Between Internal Table and a Work Area ?
A picture says a thousand words :-)
Types of Internal Tables
There are two types of internal tables.
- Internal tables with HEADER line
- Internal tables without HEADER line.
Internal Tables with Header Line
- Here the system automatically creates the work area.
- The work area has the same data type as internal table.
- This work area is called the HEADER line.
- It is here that all the changes or any of the action on the contents of the table are done. As a result of this, records can be directly inserted into the table or accessed from the internal table directly.
Internal Tables without Header Line :
- Here there is no work area associated with the table.
- Work area is to be explicitly specified when we need to access such tables.
- Hence these tables cannot be accessed directly.
Creating Internal Tables
There are many ways to create an Internal Table. Lets look at them one by one-
1.By Using the Type Statement
Let us now create a Internal table itab using the TYPE statement.
The syntax is -
Example:TYPES : begin of line, empno type I, empname(20) type c , end of line.
The TYPES statement creates a structure line as defined.
To actually create an Internal Table itab use the following command-
An internal table itab is created with the structure of line.Besides declaring the structure of an internal table, the OCCURS clause also defines how many table entries are maintained in main storage(in this case 10). Extra records are written out to paging area and can effect performance
2.By referring to another Table
You can create an internal table by referring to an existing table. The existing table could be a standard SAP table, a Z table or another internal table.
Example-DATA itab TYPE line OCCURS 10 with header line.
Here an internal table itab is created of the type line with a header line. Please note "with header line" is optional
3.By referring to existing Structure
Example-DATA itab LIKE sline OCCURS 10.
Here a table itab is created having a structure same as that of sline
4.By creating a new Structure
Let us now create an internal table with a structure of our own. Here the table is created with an Header line, by default.
Example -Data : Begin of itab occurs 10, column1 type I, column2(4) type C, column3 like mara-ernam, End of itab.
Internal table itab is created
Populating Internal Tables
Now that we have successfully created some internal tables, let us see how do we populate them with some records. There are various methods available to populate tables
1.Append Data line by line
Using the APPEND statement we can either add one line from another work area to the internal table or we can add one initial line to the internal table..
APPEND [<wa> TO / INITIAL LINE TO] <itable>. Here work area <wa> or the Initial Line is appended to the internal table <itable>.
The system variable SY-TABIX contains the index of the appended line.
Data: Begin of itab occurs 10, col1 type C, col2 type I, end of itab. Append initial line to itab.
Results : ' ' '0'
Initial lines adds a line initialized with the correct value for its type to the table. Here , col1 is an integer and col2 is a character. Then APPEND initial line , adds a line initialized with respect to the data type of the columns, i.e. 0 for Col1 and space for Col2.
2.Using COLLECT statement
COLLECT [<wa> INTO] <itable>.
Incase of tables with Header line, INTO option is omitted. Suppose there is already an entry having a key same as the one you are trying to append, then a new line is not added to the table, but the numeric fields of both the entries are added and only one entry corresponding to the key is present. Value of SY-TABIX is changed to the row of the original entry. Else COLLECT acts similar to APPEND and SY-TABIX contains the index of the processed line.
3.Using INSERT statement
INSERT statement adds a line/work area to the internal table. You can specify the position at which the new line is to be added by using the INDEX clause with the INSERT statement.
INSERT [<wa> INTO / INITIAL LINE INTO] <itable> [index <idx>].
Here, the work area <wa> or INITIAL LINE is inserted into internal table <itable> at index <idx>.
Copying Internal TablesThe contents of one internal table can be copied to another by using the APPEND LINES or INSERT LINES statement. A more simpler way is to usetany of the following syntax's.
MOVE <itab1> To <itab2>. OR <itab1> = <itab2>.
These copy the contents of ITAB1 to ITAB2. Incase of internal tables with header line we have to use  inorder to distinguish from work area. So, to copy contents of internal tables with header line the syntax becomes,
itab1 = itab2.
Read Internal TablesWe are now familiar with the creation of internal tables and populating them with data. We will now see how do we actually use the data or retrieve the data from the internal tables.
1. Using Loop -Endloop
One of the ways of accessing or reading the internal table is by using LOOP-ENDLOOP.
Syntax LOOP AT <itable> [INTO <wa>] ................................... ENDLOOP.
Here when you say LOOP AT ITABLE, then the internal table ITABLE is read line by line. You can access the values of the columns for that line during any part of the LOOP-ENDLOOP structure. The value of the SY-SUBRC is set to 0, even if only one record is read.
2. Using READ
The other method of reading the internal table is by using the READ statement.
READ TABLE <itable> [INTO <wa>] INDEX <idx>.
This statement reads the current line or line as specified by index <idx>. The value of SY-TABIX is the index of the line read. If an entry with the specified index is found, then SY-SUBRC is set to 0. If the specified index is less than 0, then run-time error occurs. If the specified index exceeds table size then SY-SUBRC is set to 4.
Deleting Internal TablesThere are many ways for deleting lines from an internal table.
1.Deleting lines in a loop.
This is the simplest way for deleting lines.
This statement works only within a loop. It deletes the current line. You can delete the lines in a loop conditionally by adding the WHERE clause.
2.Deleting lines using the index.
This is used to delete a line from internal table at any know index.
DELETE <ITABLE> INDEX <IDX>. The line with the index <IDX> is deleted. The index of the following line is decremented by 1.
Clients always want faster ABAP programs. And for a good reason too. If programs work faster, less time is wasted and the overall productivity would be increased – in theory at least. In practice, it might mean “More time to loaf on Facebook!” to some employees but hey, it’s their own Karma – they can mess it up if they want to. Our purpose is to love others and give them more time – the most scarce and irreplaceable resource of nowadays – by making our ABAP programs faster.
One of the methods to speed things up is to have faster internal table operations. In classic ABAP, we tend to use header lines or work areas to access a certain line in an internal table. However, this method has a high performance cost. In this article, I will show you how to use pointers in internal table operations for much faster execution.
Here is a simple loop written with classic ABAP:data: gt_itab type table of ztable, gs_itab type ztable.
loop at gt_itab into gs_itab.
Technically, that works. However; if you have 5.000 records in gt_itab, it means that you are copying the contents of each record into gs_itab once – 5.000 times in total. You can avoid that performance cost simply by using a pointer instead:data: gt_itab type table of ztable, gr_itab type ref to ztable.
loop at gt_itab reference into gr_itab.
In this approach, no data is copied. The pointer gr_itab simple points to a line within gt_itab. We can directly access a field using the operator -> . Therefore, it is *much* faster. Pointers can be used with other table operations as well; let’s see some examples.
You can “read table” using pointers:read table gt_itab index 1 reference into gr_itab. check sy-subrc eq 0. write:/ gr_itab->matnr.
You can “append” using pointers:append initial line to gt_itab reference into gr_itab. gr_itab->matnr = 'M123'.
Please note that we don’t need to use the command “modify” any more. When we modified gr_itab->matnr , we modified the actual “cell” within the internal table directly. Very unlike and much faster than using a work area.
Don’t get too creative and use the “append initial line” all over the place though.This doesn’t work on ITAB’s with hashed / sorted keys for obvious reasons. If it’s not too obvious for you, stick to my blog – I might be talking about hash / sort stuff in my upcoming posts. Let’s stick to our subject for now.
Following the same logic, it is also possible to access & modify internal table “cells” directly with loop & read commands:read table gt_itab index 1 reference into gr_itab. if sy-subrc eq 0. gr_itab->matnr = 'M123'. endif.
loop at gt_itab reference into gr_itab where werks eq p_werks.
gr_itab->flag = ‘X’.
If you need to access the entire line (like a regular work area), you can easily achieve that by using the star token:“ Set pointer read table gt_itab index 1 reference into gr_itab. check sy-subrc eq 0.
“ Example 1: Move-Corresponding
move-corresponding gr_itab->* to gs_temp.
“ Example 2: Use as parameter
call method show_itab_lin
im_s_line = gr_itab->*.
Did you notice that I always “check sy-subrc” after a table operation? That has a good reason in terms of stability. If, for example, gt_itab is empty and gr_itab is not assigned; it means that a nice big short dump is coming your way. Check the following example:refresh gt_itab. read table gt_itab index 1 reference into gr_itab. gr_itab->matnr = 'M123'. " Here comes the short dump!!!
To avoid that, you can either check sy-subrc, or check the reference variable directly.refresh gt_itab.
“ Method 1
read table gt_itab index 1 reference into gr_itab.
if sy-subrc eq 0.
gr_itab->matnr = ‘M123’.
“ Method 2
read table gt_itab index 1 reference into gr_itab.
if gr_itab is not initial.
gr_itab->matnr = ‘M123’.
Sometimes, you “read table” just to check if there is a corresponding record or not. You don’t actually need the data in the internal table. In that case, you can increase the performance even more by not even using a pointer. Check the following examples:read table gt_itab transporting no fields with key matnr = lv_matnr. check sy-subrc eq 0.
Same applies to loops as well:loop at gt_itab transporting no fields where werks eq p_werks. add 1 to lv_count. endloop.
Pointers will help you write faster ABAP programs – and impress your friends as well. Seniors will surround you drooling & asking how you managed to turn a turtle-program into a race rabbit; and debugging juniors will go to the corner in tears, wondering why & how you managed to avoid the “modify” command and still changed the data. Be nice, humble, and share the know-how. Otherwise, you would be serving your ego and not the universe; which ultimately leads to disconnection (bad Karma alert).
Feel free to post a comment if you have questions.