Ansicht
Dokumentation

ABAPSHEETS_INTERNAL_TABLES - SHEETS INTERNAL TABLES

ABAPSHEETS_INTERNAL_TABLES - SHEETS INTERNAL TABLES

SUBST_MERGE_LIST - merge external lists to one complete list with #if... logic for R3up   rdisp/max_wprun_time - Maximum work process run time  
This documentation is copyright by SAP AG.
SAP E-Book

Working with Internal Tables

This cheat sheet provides quick information about working with internal tables in ABAP. Furthermore, it serves as a collection of syntax and code snippets in one place for your reference. For more details, refer to the respective topic in the ABAP Keyword Documentation.

Internal Tables ...

  • are data types in ABAP.
  • can be seen as collections of table lines.
  • usually take up data from a fixed structure and store it in the working memory in ABAP, i. e. the data is stored line by line in memory, and each line has the same structure.
  • are relevant ...
  • ... whenever you want to process a data set with a fixed structure within a program.

  • ... when managing multiple related data records of the same data type in a single variable.

  • ... for storing and formatting data from a database table within a program. Due to their existence in memory, the data access with internal tables is a lot faster than accessing the data on database tables.

  • are declared within ABAP source code.
  • are dynamic data objects, i. e. they can be processed in many different ways:
  • table lines can, for example, be inserted, deleted, or updated.

  • the way how to access the tables can vary, e. g. access by index or key, and they can be processed sequentially in a loop.

  • are only temporarily available in the memory; after the program has been terminated, the content of an internal table are not available any more.
  • are simple to manage for developers since the runtime system is responsible for the memory management, i. e. the runtime system calculates an appropriate initial memory allocation for the internal table when it is declared; when you add more data to the table, the table grows automatically; when you empty the table, the system automatically releases excess memory.
  • are characterized by their line types, table categories and key attributes.

More information: Internal Tables

Declaring Internal Tables

The relevant syntactical element is TABLE OF in combination with TYPES (to declare an internal table type) and DATA (to create the internal table) and the additions TYPE or LIKE. See more details and examples in section Creating internal tables further down.

Examples

TYPES itab_type1 TYPE STANDARD TABLE OF data_type ...
TYPES itab_type2 LIKE SORTED   TABLE OF data_object ...
DATA  itab1      TYPE          TABLE OF data_type ...
DATA  itab2      TYPE HASHED   TABLE OF data_type ...
DATA  itab3      TYPE                   table_type ...
DATA  itab4      LIKE                   table ...

If the table category (see below) is not specified (...TYPE TABLE OF...), it is automatically ...TYPE STANDARD TABLE OF...

Characteristics

Each internal table is characterized by three aspects. More details: Internal Tables - Overview.

Line Type

  • Defines how each line of the internal table is set up, i. e. it describes what columns the table has
  • It can be any ABAP data type, e. g. a structure or an internal table
  • In most cases, the line type is a structure, which means that every line in the internal table contains a column with the name and type of the corresponding structure component
  • In a simple case, the line consists of a flat structure with elementary data objects; however, it can also be a deep structure whose components can be structures themselves or even internal tables

Table Category

  • Determines how internal tables are managed and stored internally as well as how individual table entries will be accessed
  • Why relevant? The different approaches to accessing the data can make significant performance differences.
  • There are two ways of accessing internal tables:
  • Access by index: A line of an internal table is addressed by its line number.

  • Access by key: A line of an internal table is addressed by looking for particular values in particular columns. The columns in which you search may be key columns, but it can also be non-key columns.

  • There are three table categories:
Category Details When to use Hints
STANDARD - content is not stored in a particular sort order (but can be sorted with SORT), yet they have an internal linear index (that is also true for sorted tables, hence, both are called index tables) \lbr \lbr - can be accessed by index and key \lbr \lbr - the key is never unique, hence duplicate entries are always allowed; adding new lines is fairly quick since there is no check necessary if an entry already exists \lbr \lbr - a standard table can be even declared with an empty key if the key is not needed (addition WITH EMPTY KEY) - if accessing single entries via their index or sequential processing are the primary use cases \lbr \lbr - rule of thumb: if you add a lot to internal tables and do not read from them too often, standard tables are a good choice; if you read a lot from internal tables and modify them often, sorted and hashed tables are a good choice - avoid large standard tables if table is accessed mainly via primary table key \lbr \lbr - lines should be added using APPEND \lbr \lbr - Read, modify and delete operations should be done by specifying the index (i. e. using the INDEX ABAP word with the relevant ABAP command) \lbr \lbr - Standard tables have the least administration costs compared to hashed and sorted tables \lbr \lbr - if the access by key is the primary access type, large standard tables (i. e. more than 100 lines) are not the appropriate table category because of the linear search
SORTED - content of sorted tables is always and automatically sorted by the table key in ascending order \lbr \lbr - they have an internal linear index (that is also true for standard tables, hence, both are called index tables) \lbr \lbr - can be accessed by index and key \lbr \lbr - key can be either unique or non-unique - if fast access to single entries via their key is the primary use case \lbr \lbr - it is also suitable for partially sequential processing in loops (e. g. when specifying the table key and the WHERE condition) or index access; in principle, the data access is more efficient than with standard tables since the data is always sorted - Sorted tables have lower administration costs compared to hashed tables ( Depending on the length of the key and the number of lines in an internal table, data access in the context of a sorted table might be as fast as or even faster than using a hashed table. Hence, if the table is not too big and the memory space is critical, a sorted table is preferable to a hashed table.)
HASHED - hashed tables do not have a linear index; they are managed using a special hash algorithm \lbr \lbr - can be accessed by a unique key - in case of large tables (e. g. if you want to use an internal table which resembles a large database table or for generally processing large amounts of data) \lbr \lbr - if key access is the primary use case and a unique key can be defined - duplicates are never allowed \lbr \lbr - the response time is constant and independent of the number of table entries since the table entries are accessed using a hash algorithm \lbr \lbr - hashed tables guarantee fast access but have the highest administration costs due to a greater memory overhead

Key Attributes

  • key identifies the table line; this can be one or more table columns according to which a table line is identified
  • every internal table has a primary table key; optionally, they may also have secondary keys
  • key can be unique or non-unique (more than one line with the same key, i.e. duplicates, can exist in the internal table), the definition depends on the table category

Excursion: Primary and secondary table keys

More information: Table Key.

Examples for primary table keys:

... WITH     UNIQUE KEY comp1 comp2 ...
... WITH     UNIQUE KEY primary_key COMPONENTS comp1 comp2 ...
... WITH NON-UNIQUE KEY primary_key COMPONENTS comp1 comp2 ...
... WITH     UNIQUE KEY primary_key ALIAS key_name ... COMPONENTS ...
... WITH     UNIQUE KEY primary_key COMPONENTS table_line ...

The definition of the predefined primary table key primary_key is optional. Hence, the first and second example are the same. When adding an alias (with the addition ALIAS), a self-defined key name can be specified for the primary key. The pseudo component table_line can be used to define the entire line of the internal table as primary key. However, table_line is meant to be used with unstructured line types, long keys should be avoided.

... WITH     UNIQUE DEFAULT KEY.
... WITH NON-UNIQUE DEFAULT KEY.

Instead of specifying individual components for the primary key, there is also an implicit form to determine the components using DEFAULT KEY:

  • in case of a structured line type: the primary key is composed of data fields that have a non-numeric, elementary data type
  • in case of a non-structured line type or the line type is not a table type: the primary key is composed of the whole table line
  • if the line type is an internal table: the primary key of standard tables remains empty; for sorted and hashed tables, the system reports a syntax error

If an internal table is declared using DATA without explicitly defining the primary key, the addition WITH DEFAULT KEY is automatically added; however, if a table is declared using TYPES, this automatic addition does not happen. Since it might lead to unexpected consequences later, it is recommended that the keys are always defined explicitly. Or, explicitly define an empty key for standard tables to avoid issues regarding the keys without artificially defining keys that are actually not relevant.

... WITH EMPTY KEY.

Examples for secondary table keys:

... WITH     UNIQUE HASHED KEY key_name COMPONENTS comp1 comp2 ...
... WITH     UNIQUE SORTED KEY key_name COMPONENTS comp1 comp2 ...
... WITH NON-UNIQUE SORTED KEY key_name COMPONENTS comp1 comp2 ...
... WITH NON-UNIQUE SORTED KEY key_name ALIAS a_name COMPONENTS comp1 comp2 ...

Secondary keys always have a self-defined name. They can be hashed and sorted while hashed secondary keys must be unique. The key components of the secondary key must be components of the line type. If the line type is not a structured data type, only the pseudo component table_line can be specified as single component. An alias can be defined for a secondary key as well. In doing so, the secondary key can be addressed by the self-defined name as well as the alias.

When should secondary keys be used?

  • to improve the performance of data retrieval from internal tables and guarantee uniqueness when accessing data
  • to enable optimized access to standard tables (huge advantage: secondary keys can be added to existing standard tables, thus, gaining the benefits of the other table types with respect to performance)
  • mainly for very large internal tables (where only few modifications occur afterwards); not suitable for small internal tables (less than 50 lines) since each secondary key means additional administration costs (they consume additional memory)

Examples

TYPES itab_type TYPE HASHED TABLE OF spfli
   WITH     UNIQUE KEY carrid connid
   WITH NON-UNIQUE SORTED KEY city_key COMPONENTS cityfrom cityto
   WITH NON-UNIQUE SORTED KEY airp_key COMPONENTS airpfrom airpto.

A table type is declared for a hashed table with the line type of the database table spfli. Two components are used as primary table key. Furthermore, two secondary keys are declared with a self-defined name. The following example is identical to the one above, however, the implicit predefined primary key name primary_key is mentioned explicitly:

TYPES itab_type TYPE HASHED TABLE OF spfli
  WITH     UNIQUE        KEY primary_key COMPONENTS carrid connid
  WITH NON-UNIQUE SORTED KEY city_key COMPONENTS cityfrom cityto
  WITH NON-UNIQUE SORTED KEY airp_key COMPONENTS airpfrom airpto.

The following example includes an alias for the primary key.

TYPES itab_type TYPE HASHED TABLE OF spfli
  WITH     UNIQUE        KEY primary_key ALIAS a_name COMPONENTS carrid connid
  WITH NON-UNIQUE SORTED KEY city_key COMPONENTS cityfrom cityto
  WITH NON-UNIQUE SORTED KEY airp_key COMPONENTS airpfrom airpto.

In expressions and ABAP statements, the keys can be addressed using the defined names. Taking the LOOP statement as an example, all the keys can be addressed with the addition USING KEY plus the name. For the primary keys, either primary_key or the self-defined alias can be used.

LOOP AT itab INTO wa USING KEY ...
...
ENDLOOP.

Working with Internal Tables

Creating Internal Tables

As a best practice for declaring internal tables, it is recommended that an internal table with this pattern is created in a program:

  • Define a structured data type
  • Define an internal table type
  • Create a variable, i. e. the internal table, that refers to that type.

You will also see internal tables that are declared by combining the variable creation and table type definition in one go. If the structured data and internal table types are globally available in the DDIC, a local definition within a program is not needed. The following example shows the pattern and various examples of declaring internal tables and types by including the local definition of structured data and internal table types for demonstration purposes.

Example

The following source code section taken from DEMO_CS_ITAB demonstrates various internal table definitions.

Filling Internal Tables

Add one line to an internal table using an existing structure (lv_struc) and the VALUE operator. Existing values in the internal table are cleared using this way.

itab = VALUE #( ( lv_struc ) ).

You can also add a line directly to the internal table without an existing structure using the VALUE operator. The extra pair of brackets denotes a table line that is added. As shown further down, it is also possible to add more table lines to the internal table in this way. The # sign in the example below denotes that the line type can be derived from the table itab, i. e. the lines, and thus the components and values that are specified in the brackets following the # sign automatically assume the line type of itab. You can also use a line type in that position before the brackets to determine the type, e. g. if the type cannot be derived. In the second example, an internal table is declared inline. It is assigned a line type via VALUE and the specified type (dtype).

itab = VALUE #( ( comp1 = a comp2 = b ... ) ).

DATA(some_itab) = VALUE dtype( ( comp1 = a comp2 = b ... ) ).

Add multiple lines directly using the VALUE operator.

itab = VALUE #( ( comp1 = a comp2 = b ... )
                ( comp1 = c comp2 = d ... )
                ( comp1 = e comp2 = f ... ) ).

When using the assignments above (itab = ...), the internal table is initialized and the existing content is deleted. To add new lines without deleting existing content, use the addition BASE.

itab = VALUE #( BASE itab ( comp1 = a comp2 = b ... )
                          ( comp1 = c comp2 = d ... ) ).

Copy content from another internal table that has the same line type. Existing content is deleted.

itab = itab2.

Excursion: Copy content - How was it done in former ABAP times? Do not use it! Obsolete syntax.

MOVE itab2 TO itab.

Copy content from another internal table that has a different line type using the CORRESPONDING operator. Existing content is deleted. See the ABAP Keyword Documentation for more syntax options and information, for example, the mapping rules when dealing with nonidentical field names.

itab = CORRESPONDING #( itab3 ).

Copy content from another internal table that has a different line type using the CORRESPONDING operator while keeping existing content.

itab = CORRESPONDING #( BASE ( itab ) itab3 ).

As an alternative to the CORRESPONDING operator, statements with CORRESPONDING can be used. The addition KEEPING TARGET LINES preserves the table content.

MOVE-CORRESPONDING itab3 TO itab.
MOVE-CORRESPONDING itab3 TO itab KEEPING TARGET LINES.

Add multiple lines from a database table to an internal table using SELECT, for example, based on a condition. In the case below, the internal table is created inline. If the variable exists, it is ... @itab. In this case, it is assumed that itab has the same line type as the database table. Note the @ sign before the internal table (see host expressions). There are many more syntax options for SELECT statements. Check the ABAP Keyword Documentation of the ABAP cheat sheet ABAP SQL: Working with Persisted Data in Database Tables for more information.

SELECT FROM dbtab
  FIELDS comp1, comp2 ...
  WHERE ...
  INTO TABLE @DATA(itab_sel).

Sequentially add multiple rows from a database table to an internal table using SELECT ... ENDSELECT., for example, based on a condition. In this case, the selected data is first stored in a structure which can be further processed and added to an internal table.

SELECT FROM dbtab
  FIELDS comp1, comp2 ...
  WHERE ...
  INTO @DATA(struc_sel).

  IF sy-subrc = 0.
    APPEND struc_sel TO itab.
  ...
  ENDIF.
ENDSELECT.

Add multiple lines from a database table using SELECT, for example, based on a condition, if the database table has a different line type as the internal table. The * sign means that all fields are selected. In the other examples, specific fields are defined. The addition APPENDING CORRESPONDING FIELDS INTO TABLE adds the selected data to the bottom of the table without deleting existing table entries. The addition INTO CORRESPONDING FIELDS OF TABLE adds lines and deletes existing table entries.

SELECT FROM dbtab2
  FIELDS *
  WHERE ...
  APPENDING CORRESPONDING FIELDS INTO TABLE @itab.
  "INTO CORRESPONDING FIELDS OF TABLE @itab.

Add multiple lines from an internal table to another internal table using SELECT. Note the alias name that must be defined for the internal table.

SELECT comp1, comp2, ...
  FROM @itab2 AS it_alias
  INTO TABLE @DATA(itab_sel).

Excursions with the SELECT statement

Combine data of multiple tables into an internal table using an inner join. In below example, data of an internal and a database table is joined with a SELECT statement and the addition INNER JOIN. Note the field list including fields from both tables. The fields are referred to using ~.

SELECT it_alias~comp1, it_alias~comp2, dbtab~comp3 ...
  FROM @itab AS it_alias
  INNER JOIN dbtab ON it_alias~comp1 = dbtab~comp1
  INTO TABLE @DATA(it_join_result).

Fill internal table from a database table using subqueries. In both of the following examples, an internal table is filled from a database table. In the first example, a subquery is specified in the WHERE clause with the ABAP words NOT IN. A check is made to verify whether a value matches a value in a set of values specified in parentheses. In the second example, an internal table is filled depending on data in another table. A subquery is specified in the WHERE clause with the ABAP word EXISTS. In this case, it checks the result of the subquery that consists of another SELECT statement, i. e. a check is made if an entry exists in a table based on the specified conditions.

SELECT comp1, comp2, ...
  FROM dbtab
  WHERE comp1 NOT IN ( a, b, c ... )
  INTO TABLE @DATA(it_subquery_result1).

SELECT comp1, comp2, ...
  FROM dbtab
  WHERE EXISTS
    ( SELECT 'X' FROM @itab AS itab_alias
      WHERE comp1 = dbtab~comp1 )
  INTO TABLE @DATA(it_subquery_result2).

Fill internal table from a table based on the existence of data in another table using the addition FOR ALL ENTRIES.

Ensure that the internal table from which to read is not initial. It is therefore recommended that a subquery is used as shown above: ... ( SELECT ... FROM @itab AS itab_alias WHERE ...).

IF itab IS NOT INITIAL.
SELECT dbtab~comp1, dbtab~comp2, ...
  FROM dbtab
  FOR ALL ENTRIES IN @itab
  WHERE comp1 = @itab-comp1
  INTO TABLE @DATA(it_select_result).
ENDIF.

Adding lines using the keywords APPEND and INSERT

Both statements add one or more data sets to an internal table. While APPEND adds at the bottom of the internal table, INSERT can be used to add lines at a specific position in tables. If you do not specify the position, then the lines are added at the bottom of the table, too. However, when using INSERT, sy-tabix is not set unlike APPEND. See more details here: APPEND, INSERT.

Notes on using APPEND:

  • Standard tables: Lines are appended directly and without checking the content of the internal table.
  • Sorted tables: Lines are only appended if they match the sort order and do not create duplicate entries if the primary table key is unique.
  • Hashed tables: Lines cannot be appended.

Add a line to the internal table. The example shows both a structure that is created using the VALUE operator and added as well as an existing structure that is added.

APPEND VALUE #( comp1 = a comp2 = b ... ) TO itab.

APPEND lv_struc TO itab.

Add an initial line to the internal table without providing any field values.

APPEND INITIAL LINE TO itab.

Add all lines from another internal table. See the section on the VALUE operator below for an alternative to this.

APPEND LINES OF itab2 TO itab.

Add lines from another internal table with a specified index range.

APPEND LINES OF itab2 FROM i1 TO i2 TO itab.

Insert a line into an internal table. The example shows both, a structure that is created using the VALUE operator and inserted as well as an existing structure that is inserted.

INSERT VALUE #( comp1 = a comp2 = b ... ) INTO TABLE itab.

INSERT lv_struc INTO itab.

Insert an initial line into the internal table without providing any field values.

INSERT INITIAL LINE INTO TABLE itab.

Insert lines from another internal table.

INSERT LINES OF itab2 INTO TABLE itab.

Insert lines from another internal table with a specified index range.

INSERT LINES OF itab2 FROM i1 TO i2 INTO itab.

Insert lines from another internal table at a specific position. The specification of the range (... FROM ... TO ...) is optional here.

INSERT LINES OF itab2 FROM i1 TO i2 INTO itab INDEX 3.

Collect values into internal table

Use the COLLECT keyword, for example, to add the values of numeric components to the corresponding values in an internal table. Use it mainly for internal tables with a unique primary key, especially hashed tables.

COLLECT VALUE dtype( comp1 = a comp2 = b ... ) INTO itab.

Reading from Internal Tables

Read single line by index ...

... using a table expression. The read result is stored in a variable that might be declared inline. The number in the square brackets represents the index. A line that is not found results in an error. Hence, to avoid a runtime error, you can use a TRY ... CATCH ... ENDTRY. block. The following examples do not have this block. The addition KEY ... INDEX ... used in the third example is optional. It determines the line to be read from the primary table index. If the addition is not used, the internal table must be an index table.

DATA(lv1) = itab[ i ].

TRY.
  DATA(lv2) = itab[ i ].
  CATCH cx_sy_itab_line_not_found.
  ...
ENDTRY.

DATA(lv3) = itab[ KEY primary_key INDEX i ].

... into a work area or a field symbol using a READ TABLE statement.

Some of the following examples with READ TABLE only show one option, e. g. with work area or field symbol. The advantage of using a field symbol is that is serves as a pointer (compared to a variable as work area for which content is actually copied) and improves the performance. You might also want to choose to read into a data reference variable (... REFERENCE INTO ...). As a rule, you should choose the appropriate output behavior as described in the topic target area.

The addition USING KEY used in the third example is optional. It determines the line to be read from the primary table index. If the addition is not used, the internal table must be an index table.

READ TABLE itab INTO DATA(wa1a) INDEX i.

READ TABLE itab ASSIGNING FIELD-SYMBOL(<fs1>) INDEX i.

READ TABLE itab INTO DATA(wa1b) INDEX i USING KEY primary_key.

Read single component by index ...

... using a table expression.

DATA(lv3) = itab[ i ]-comp1.

... after reading a line into a work area or field symbol using a READ TABLE statement.

READ TABLE itab INTO DATA(wa2) INDEX i.
DATA(lv4) = wa2-comp1.

READ TABLE itab ASSIGNING FIELD-SYMBOL(<fs2>) INDEX i.
DATA(lv5) = <fs2>-comp1.

Read single line using a table key

Read line using the primary key (or the alias if available). The examples show how a line can be read using the explicitly specified table key, here the primary key, using both table expressions and READ TABLE statements. When using table expressions, the addition COMPONENTS is optional. This is not true for READ TABLE statements when explicitly specifying the table key in this context. However, it is possible to go without the addition COMPONENTS and the explicit table key here. In that case, the primary table key is used and all components belonging to the primary key must be specified.

DATA(lv6) = itab[ KEY primary_key COMPONENTS comp1 = a ... ].

DATA(lv_alias) = itab[ KEY pkey_alias COMPONENTS comp1 = a ... ]. "alias

DATA(lv7) = itab[ KEY primary_key comp1 = a ... ].

READ TABLE itab INTO DATA(wa) WITH TABLE KEY
    primary_key COMPONENTS comp1 = a ... .

READ TABLE itab INTO DATA(wa) WITH TABLE KEY comp1 = a ... .

Read line using the secondary key (or its alias, if available). It is actually the same syntax as above with the key name following KEY.

DATA(lv9) = itab[ KEY sec_key COMPONENTS comp2 = b ... ].

DATA(lv10) = itab[ KEY sec_key_alias COMPONENTS comp2 = b ... ].

READ TABLE itab INTO DATA(wa4) WITH TABLE KEY sec_key COMPONENTS comp2 = b ...

Read single line by free key ...

... using a table expression and READ TABLE statements. The specified components need not belong to a table key.

DATA(lv11) = itab[ comp3 = c comp4 = d ... ].

READ TABLE itab INTO DATA(wa4) WITH KEY comp3 = c comp4 = d ...

Read multiple lines using loops

Sequentially read all lines of a table one after another, for example, into a work area. You might also choose not to use any addition to the LOOP statement, i. e. just LOOP AT itab. ... ENDLOOP.. In this case, all lines of the internal table are sequentially read. Within the LOOP ... ENDLOOP statement, you write the statements that process each table line.

LOOP AT itab INTO DATA(wa5).
  ...
ENDLOOP.

Sequentially read multiple lines of a table into a work area by specifying an index range.

LOOP AT itab INTO DATA(wa6) FROM i1 TO i2.
  ...
ENDLOOP.

Sequentially read multiple lines of a table into a field symbol by specifying a condition.

LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs3>) WHERE comp1 <> a AND comp2 < i ...
  ...
ENDLOOP.

Sequentially read multiple lines of a table into a field symbol by (primary or secondary) key

LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs4>) USING KEY sec_key.
  ...
ENDLOOP.

Sequentially read multiple lines of a table without an interest in the table field values, for example, if you are interested in system fields. The WHERE clause must be defined, too.

LOOP AT itab TRANSPORTING NO FIELDS WHERE comp1 = ...
  ...
ENDLOOP.

Sequentially read multiple lines of a table while grouping, i. e. you form groups with lines that have the same values in specified fields. You might also want to loop across the group itself.

LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs>) GROUP BY ...
  ...
ENDLOOP.
...
LOOP AT GROUP <fs> ASSIGNING FIELD-SYMBOL(<fs2>) ...
  ...
ENDLOOP.

Sorting Internal Tables

Standard and hashed tables can be sorted using the keyword SORT in various ways, e. g. by specifying the sort order and also including a component.

SORT itab ASCENDING.
SORT itab DESCENDING.
SORT itab BY comp1 ASCENDING.
SORT itab BY comp2 DESCENDING.

Modifying Internal Tables

Modify ...

... a whole line from a work area or an existing structure. The work area or structure must be compatible to the line type of the internal table. The first line found in the internal table is processed whose values in the columns of the table key used match those of the corresponding components of the work area or structure. If the key fields in the work area are empty, no entries are processed.

MODIFY TABLE itab FROM VALUE #( comp1 = a comp2 = b ... ).

MODIFY TABLE itab FROM lv_struc.

... a whole line from a work area by specifying an index. Note that it is only MODIFY instead of MODIFY TABLE as above.

MODIFY itab FROM VALUE #( comp1 = a comp2 = b ... ) INDEX i.

... particular fields of a line without overwriting other fields. The below example includes the addition INDEX. Only those fields that are specified after the addition TRANSPORTING are changed.

MODIFY itab FROM VALUE #( comp1 = a comp2 = b ... ) INDEX i TRANSPORTING comp1 comp2.

... a line based on a condition. The below example includes the addition TRANSPORTING.

MODIFY itab FROM VALUE #( comp1 = a comp2 = b ... ) TRANSPORTING    comp1 comp2 WHERE comp2 < ...

... a line by specifying a table key. The work area or structure must be compatible to the line type of the internal table. The first line found in the internal table is processed whose values in the columns of the table key used match those of the corresponding components of the work area or structure. If the key fields in the work area are empty no entries are processed. The below example also includes the addition TRANSPORTING.

MODIFY TABLE itab FROM VALUE #( comp1 = a comp2 = b ... )
  USING KEY sec_key TRANSPORTING comp2 ...
MODIFY TABLE itab FROM lv_struc.

More information on the MODIFY statement: MODIFY.

Modify a table entry ...

... in a particular line by specifying the index.

itab[ i ]-comp1 = ...

... by key expression. See more examples for possible key expressions, i. e. with primary or secondary key, above.

itab[ comp1 = a comp2 = b ... ]-comp1 = ...

Modify multiple table entries ...

... using a loop.

Note that the LOOP statement can be enriched with various options, for example, by setting a condition. See more options in the section Reading from internal tables above. There might also be other options to achieve the same purpose, for example, by using a table expression or a MODIFY statement within a loop. Both alternatives must be handled with care if working with an implicit index. Hence, the explicit specification of the table index is recommended.

LOOP AT itab ASSIGNING FIELD-SYMBOL(&lt;fs&gt;).
  &lt;fs&gt;-comp1 = y.
  &lt;fs&gt;-comp2 = z.
  ...
ENDLOOP.

Delete ...

... a line by explicitly specifying the key. The following two examples can be considered as alternatives when referring to primary keys. The first statement explicitly specifies the primary key with the addition COMPONENTS. In the second example, the COMPONENTS can be considered optional if the primary key components are fully specified.

DELETE TABLE itab WITH TABLE KEY primary_key
    COMPONENTS comp1 = ...

DELETE TABLE itab WITH TABLE KEY comp1 = ...

... a line from a work area or structure by implicitly specifying the key. The key is implicitly specified within the work area.

DELETE TABLE itab FROM VALUE #( comp1 = ...).

... a line by index.

DELETE itab INDEX i.

... multiple lines by specifying an index range.

DELETE itab FROM i1 TO i2.

... multiple lines by specifying a condition.

DELETE itab WHERE comp1 &lt; i ...

... adjacent duplicates. Note that the duplicates must actually be next to each other in the table. You can sort standard tables before triggering this kind of deletion.

DELETE ADJACENT DUPLICATES FROM itab.

... values of a whole column using a loop.

LOOP AT itab ASSIGNING FIELD-SYMBOL(&lt;del&gt;).
  CLEAR &lt;del&gt;-comp.
ENDLOOP.

More information on the DELETE statement: DELETE.

... complete table, i. e. remove the whole content using the keywords CLEAR or FREE. With using FREE, you also release the memory area occupied by the internal table. This is not true for CLEAR which is beneficial for the performance. See more information here: CLEAR, FREE.

CLEAR itab.

FREE itab.

Internal Table Functions

More information: Table Functions.

line_exists( ): Check whether a line exists.

IF line_exists( itab[ comp1 = a ... ] ).
  ...
ENDIF.

lines( ): Check how many lines exist in an internal table. The function returns an integer.

DATA(itab_lines) = lines( itab ).

line_index( ): Check the index of a specific line. The function returns an integer.

DATA(idx) = line_index( itab[ comp1 = a ...] ).

Excursion: Constructor Expressions

VALUE operator

Add lines of other tables using the addition LINES OF. Without the addition BASE existing content is deleted. The line type of the other internal table must match the one of the target internal table.

itab = VALUE #( ( comp1 = a comp2 = b ...)
                ( comp1 = a comp2 = b ...)
                ( LINES OF itab2 )
                ... ).

CORRESPONDING operator

Copy data from a deep internal table to another deep internal table. If used, the addition BASE keeps the content. See also the alternative MOVE-CORRESPONDING statements.

itab_nested2 = CORRESPONDING #( DEEP itab_nested1 ).
itab_nested2 = CORRESPONDING #( DEEP BASE ( itab_nested2 ) itab_nested1 ).

MOVE-CORRESPONDING itab_nested1 TO itab_nested2 EXPANDING NESTED TABLES.
MOVE-CORRESPONDING itab_nested1 TO itab_nested2 EXPANDING NESTED TABLES KEEPING TARGET LINES.

COND and SWITCH operators

Modify multiple table entries based on conditions in a loop.

LOOP AT itab ASSIGNING FIELD-SYMBOL(&lt;fs5&gt;).
  &lt;fs5&gt;-comp5 = COND #( WHEN &lt;fs5&gt;-comp5 = a
                        THEN b
                        ELSE c ).
  &lt;fs5&gt;-comp6 = COND #( WHEN &lt;fs5&gt;-comp6 < d
                        THEN e
                        ELSE f ).
  &lt;fs5&gt;-comp7 = COND #( WHEN &lt;fs5&gt;-comp7 < g AND &lt;fs5&gt;-comp6 > h
                        THEN i
                        ELSE j
  ...
ENDLOOP.

LOOP AT itab ASSIGNING FIELD-SYMBOL(&lt;fs6&gt;).
  &lt;fs6&gt;-comp5 = SWITCH #( &lt;fs6&gt;-comp5 WHEN a
                                      THEN b
                                      ELSE c).
  &lt;fs6&gt;-comp6 = SWITCH #( &lt;fs6&gt;-comp6 WHEN d
                                      THEN e
                                      ELSE f).
  ...
ENDLOOP.

FILTER operator

Create an internal table by copying data from another internal table filtering out lines that do not match the WHERE condition. Filter internal table, i. e. extract data from internal tables, ...

... by condition.

DATA(filter1) = FILTER #( itab WHERE comp1 < i ).

... by condition with the addition EXCEPT that excludes data according to a condition.

DATA(filter2) = FILTER #( itab EXCEPT WHERE comp1 < i ).

... by using a filter table.

DATA(filter3) = FILTER #( itab IN filter_tab WHERE comp1 < i.

Iterations with FOR

Get values of (one column in) an internal table. In below example, ls1 represents an iteration variable that holds the data while looping over the table. In contrast to LOOP statements, the sequential processing cannot be debugged. The components, and thus the table line, that should be returned are specified within the pair of parentheses before the closing parenthesis. In the case below it is one component, but can also be more. The demonstration program Working with Internal Tables includes more options with FOR.

DATA(lv) = VALUE dtype( FOR ls1 IN itab ( ls1-comp1 ) ).

Get values of (one column in) an internal table based on conditions.

DATA(lv2) = VALUE dtype( FOR ls2 IN itab WHERE ( comp1 &lt; i ) ( ls2-comp1 ) ).

Demonstration Program

The example Working with Internal Tables demonstrates the syntax options mentioned above in one program.






General Data in Customer Master   Fill RESBD Structure from EBP Component Structure  
This documentation is copyright by SAP AG.

Length: 49453 Date: 20240509 Time: 053051     sap01-206 ( 593 ms )