| Creating internal tables with ... | Details/Code Snippet |
| Standard table keys | ``` abap "Standard table without explicit primary table key specification. "Note that STANDARD is not explicitly specified. "Implicitly, the standard key is used; all non-numeric table fields "make up the primary table key. DATA it1 TYPE TABLE OF zdemo_abap_flsch. "Explicitly specifying STANDARD for a standard table. "Explicitly specifying the standard table key. The declaration "corresponds to it1. DATA it2 TYPE STANDARD TABLE OF zdemo_abap_flsch WITH DEFAULT KEY. "Hashed table with unique standard table key DATA it3 TYPE HASHED TABLE OF zdemo_abap_flsch WITH UNIQUE DEFAULT KEY. "Sorted table with non-unique standard table key DATA it4 TYPE SORTED TABLE OF zdemo_abap_flsch WITH NON-UNIQUE DEFAULT KEY. ``` |
| Primary table keys | ``` abap "Specifying the primary table key "In standard tables, only a non-unique key is possible. "The following two examples are the same. NON-UNIQUE can be ommitted but "is implicitly added. DATA it5 TYPE TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY carrid. DATA it6 TYPE TABLE OF zdemo_abap_flsch WITH KEY carrid. "Sorted tables: both UNIQUE and NON-UNIQUE possible DATA it7 TYPE SORTED TABLE OF zdemo_abap_flsch WITH UNIQUE KEY carrid connid. DATA it8 TYPE SORTED TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY carrid connid cityfrom. "Hashed tables: UNIQUE KEY must be specified DATA it9 TYPE HASHED TABLE OF zdemo_abap_flsch WITH UNIQUE KEY carrid. "Explicitly specifying the predefined name primary_key and listing the components. "The example is the same as it5 and it6. DATA it10 TYPE TABLE OF zdemo_abap_flsch WITH KEY primary_key COMPONENTS carrid. "The following example is the same as it8. DATA it11 TYPE SORTED TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY primary_key COMPONENTS carrid connid cityfrom. "Specifying an alias name for a primary table key. "Only possible for sorted/hashed tables. DATA it12 TYPE SORTED TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY primary_key ALIAS p1 COMPONENTS carrid connid cityfrom. "Specifying a key that is composed of the entire line using the "predefined table_line. "In the example, an alias name is defined for a primary table key. DATA it13 TYPE HASHED TABLE OF zdemo_abap_flsch WITH UNIQUE KEY primary_key ALIAS p2 COMPONENTS table_line. ``` |
| Empty keys | ``` abap "Empty keys are only possible for standard tables DATA it14 TYPE TABLE OF zdemo_abap_flsch WITH EMPTY KEY. "Empty primary table key, secondary table key specified DATA it15 TYPE TABLE OF zdemo_abap_flsch WITH EMPTY KEY WITH UNIQUE SORTED KEY cities COMPONENTS cityfrom cityto. "Excursion: The inline declaration in a SELECT statement "produces a standard table with empty key. SELECT * FROM zdemo_abap_flsch INTO TABLE @DATA(it16). ``` |
| Secondary table keys | ``` abap "The following examples demonstrate secondary table keys that are "possible for all table categories. DATA it17 TYPE TABLE OF zdemo_abap_flsch "standard table WITH NON-UNIQUE KEY carrid connid "primary table key WITH UNIQUE SORTED KEY cities COMPONENTS cityfrom cityto. "secondary table key DATA it18 TYPE HASHED TABLE OF zdemo_abap_flsch "hashed table WITH UNIQUE KEY carrid connid WITH NON-UNIQUE SORTED KEY airports COMPONENTS airpfrom airpto. DATA it19 TYPE SORTED TABLE OF zdemo_abap_flsch "sorted table WITH UNIQUE KEY carrid connid WITH UNIQUE HASHED KEY countries COMPONENTS countryfr countryto. "Multiple secondary keys are possible DATA it20 TYPE TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY primary_key COMPONENTS carrid connid WITH NON-UNIQUE SORTED KEY cities COMPONENTS cityfrom cityto WITH UNIQUE HASHED KEY airports COMPONENTS airpfrom airpto. "Alias names for secondary table keys (and also for the primary "table key in the example) DATA it21 TYPE SORTED TABLE OF zdemo_abap_flsch WITH NON-UNIQUE KEY primary_key ALIAS k1 COMPONENTS carrid connid WITH NON-UNIQUE SORTED KEY cities ALIAS s1 COMPONENTS cityfrom cityto WITH UNIQUE HASHED KEY airports ALIAS s2 COMPONENTS airpfrom airpto. "Excursion: Example of using table keys and alias names using a LOOP AT statement. "All of the statements below are possible. "Note that if the secondary table key is not specified (and if the USING KEY addition is not "used in the example), the primary table key is respected by default. "Further ABAP statements, such as READ or MODIFY, are available in which the key can be "explicitly specified to process internal tables. LOOP AT it21 INTO DATA(wa) USING KEY primary_key. "LOOP AT it21 INTO DATA(wa) USING KEY k1. "LOOP AT it21 INTO DATA(wa) USING KEY cities. "LOOP AT it21 INTO DATA(wa) USING KEY s1. "LOOP AT it21 INTO DATA(wa) USING KEY airports. "LOOP AT it21 INTO DATA(wa) USING KEY s2. ... ENDLOOP. ``` |
| Subject | Details/Code Snippet |
| Elementary line types | ``` abap "The whole table line is the standard table key. "The following examples use built-in ABAP types. Besides these types, "you can also use locally declared elementary types, globally declared "elementary types such as DDIC data elements, CDS simple types, types "that are declared in the public visibility section of classes/interfaces, "etc.. As shown further down, there are released table types with elementary "line types. DATA it28 TYPE TABLE OF i. DATA it29 TYPE TABLE OF string WITH EMPTY KEY. DATA it30 TYPE TABLE OF xstring WITH EMPTY KEY. DATA it31 TYPE TABLE OF utclong WITH EMPTY KEY. "Elementary type declared in an interface DATA it32 TYPE TABLE OF zdemo_abap_get_data_itf=>occ_rate WITH EMPTY KEY. "Using a DDIC data element DATA it_dtel TYPE TABLE OF timestamp WITH EMPTY KEY. ``` |
| Structured types | ``` abap "Apart from the line type of a database table, these types can also "be local structured types (as shown below), local structured types declared "in the public visibility section of classes/interfaces, DDIC structures, CDS "entities, etc. "CDS view entity DATA it33 TYPE TABLE OF zdemo_abap_carr_ve WITH EMPTY KEY. "CDS abstract entity DATA it34 TYPE TABLE OF zdemo_abap_abstract_ent WITH EMPTY KEY. ``` |
| Table types | ``` abap "As shown above, the table types can be locally declared. DATA it35 TYPE TABLE OF zdemo_abap_get_data_itf=>carr_tab. "Global table type declared in an interface DATA it36 TYPE zdemo_abap_get_data_itf=>carr_tab. "The following examples use globally available and released table "types with elementary lines types. DATA it37 TYPE string_table. DATA it38 TYPE string_hashed_table. DATA it39 TYPE xstring_table. ``` |
| Deep internal tables | ``` abap "The previous examples mostly demonstrate flat line types. "Deep line types are also possible, that is, the line type "can include components such as strings, references, structures, "and internal tables. TYPES: BEGIN OF ls_deep, key_field TYPE i, char TYPE c LENGTH 10, str TYPE string, dref TYPE REF TO i, struct TYPE zdemo_abap_flsch, str_tab TYPE string_table, tab TYPE TABLE OF zdemo_abap_flsch WITH EMPTY KEY, END OF ls_deep. DATA it40 TYPE TABLE OF ls_deep WITH EMPTY KEY. ``` |
| References as line types | ``` abap DATA it_ref TYPE TABLE OF REF TO i. ``` |
APPEND and INSERT| Subject | Details/Code Snippet |
| Adding a line to an internal table |
The example shows both a structure that is created using the `VALUE` operator as well as an existing structure that is added.
``` abap APPEND VALUE #( comp1 = a comp2 = b ... ) TO itab. APPEND struc TO itab. INSERT VALUE #( comp1 = a comp2 = b ... ) INTO TABLE itab. INSERT struc INTO TABLE itab. ``` |
| Adding an initial line |
... to an internal table without providing any field values.
``` abap APPEND INITIAL LINE TO itab. INSERT INITIAL LINE INTO TABLE itab. ``` |
| Adding a line and assigning the added line to a field symbol or data reference variable |
```abap
"When inserting single lines, you can specify the optional additions
"ASSIGNING and REFERENCE INTO. If the insertion is successful, the
"line is assigned to a field symbol or a data reference variable.
"The targets can also be created inline.
APPEND VALUE #( comp1 = a comp2 = b ... ) TO itab ASSIGNING FIELD-SYMBOL( |
| Adding all lines from another internal table | ``` abap APPEND LINES OF itab2 TO itab. INSERT LINES OF itab2 INTO TABLE itab. ``` |
| Adding multiple lines from another internal table with a specified index range |
- Both `FROM` and `TO` are not mandatory in one statement. it is possible to use only one of them.
- If you use only ...
- `FROM`, all lines up to the last table entry are respected.
- `TO`, all lines starting with the first table entry are respected.
``` abap APPEND LINES OF itab2 FROM 3 TO 5 TO itab. APPEND LINES OF itab2 FROM 3 TO itab. APPEND LINES OF itab2 TO 7 TO itab. INSERT LINES OF itab2 FROM 5 TO 9 INTO TABLE itab. ``` |
| Inserting one line or multiple lines from another internal table at a specific position |
`FROM` and `TO` can be used here, too.
``` abap INSERT struc INTO itab2 INDEX i. INSERT LINES OF itab2 INTO itab INDEX i. ``` |
| Subject | Details/Code Snippet |
| Populating an existing internal table by assigning an internal table that is constructed inline |
In the example below, the internal table is populated by assigning an
internal table that is constructed inline with the `VALUE`
operator. The inline constructed table has two lines. `line`
represents an existing structure with a compatible line type. The
other line is constructed inline.
> **💡 Note** > - The extra pair of parentheses represents a table line. The `#` character indicates that the line type can be derived from the context. The assignment deletes the existing content of the internal table on the left side. > - The existing content of the internal table is deleted, and the new content, which is created in place, is added. ``` abap itab = VALUE #( ( line ) ( comp1 = a comp2 = b ... ) ). ``` |
| Creating an internal table by inline declaration and adding lines with a constructor expression | ``` abap "Internal table type TYPES it_type LIKE itab. "Inline declaration "The # character would not be possible here since the line type "cannot be derived from the context. DATA(it_in) = VALUE it_type( ( comp1 = a comp2 = b ... ) ( comp1 = c comp2 = d ... ) ). "Creating string tables DATA(str_tab_a) = VALUE string_table( ( `Hallo` ) ( `World` ) ). DATA(str_tab_b) = VALUE string_table( ). "In the previous statement, the internal table is declared "inline, however, no content, no table lines are provided. "This means that an initial string table was created. This "way, the statement has the same effect as the following "statement. DATA str_tab_c TYPE string_table. ``` |
| Adding new lines without deleting existing content |
When you use the above assignments to an existing internal table (`itab = ...`), the internal table is initialized and the existing content is deleted. To add new lines without deleting existing content, use the [`BASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvalue_constructor_params_itab.htm) addition.
``` abap itab = VALUE #( BASE itab ( comp1 = a comp2 = b ... ) ( comp1 = c comp2 = d ... ) ). ``` |
| Adding lines of other tables |
... using the `LINES OF` addition to the `VALUE` operator.
Without the `BASE` addition, the existing content is deleted. It is assumed that the line type of the source table is compatible with that of the target table. You have multiple syntax options following the `LINES OF` addition, e.g. you can further determine and restrict the lines to be added using `FROM` and `TO`.
``` abap itab = VALUE #( ( comp1 = a comp2 = b ...) ( comp1 = a comp2 = b ...) "All lines ( LINES OF itab2 ) "More syntax options ( LINES OF itab3 FROM 2 TO 5 ) ( LINES OF itab4 FROM 3 ) ( LINES OF itab5 TO 7 ) ( LINES OF itab6 STEP 2 ) ( LINES OF itab7 USING KEY primary_key FROM 3 TO 6 ) ... ). ``` |
| Subject | Details/Code Snippet |
| Copying the content of another internal table |
... using the
[`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator.
- Note that the existing content is deleted.
- As an alternative to the `CORRESPONDING` operator, you can use [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm) statements.
- The example assumes that the line types of the source and target table are not compatible. However, if the line types are compatible, the syntax will also work.
- Several additions are possible. They can also be combined. Check the ABAP Keyword Documentation.
``` abap itab = CORRESPONDING #( itab3 ). MOVE-CORRESPONDING itab3 TO itab. ``` |
| Copying content and retaining existing content |
... using the `CORRESPONDING` operator.
The `KEEPING TARGET LINES` addition of the `MOVE-CORRESPONDING` statement preserves the table content.
``` abap itab = CORRESPONDING #( BASE ( itab ) itab3 ). MOVE-CORRESPONDING itab3 TO itab KEEPING TARGET LINES. ``` |
| Assigning components using mapping relationships |
- You can use the `MAPPING` addition of the `CORRESPONDING` operator to specify components of a source table that are assigned to the components of a target table in mapping relationships.
- For elementary components, the assignment is made according to the associated assignment rules.
``` abap itab = CORRESPONDING #( itab3 MAPPING a = c b = d ). ``` |
| Excluding components from the assignment |
... using the `EXCEPT` addition to the `CORRESPONDING` operator.
- This is particularly useful if there are identically named components in the source and target tables that are not compatible or convertible. You can avoid syntax errors or runtime errors.
- Instead of a component list, `EXCEPT` can also be followed by `*` to exclude all components that are not mentioned in a previous mapping of components.
- If `EXCEPT *` is used without the `MAPPING` addition, all components remain initial.
``` abap itab = CORRESPONDING #( itab3 EXCEPT e ). itab = CORRESPONDING #( itab3 EXCEPT * ). ``` |
| Preventing runtime errors when duplicate lines are assigned |
... to the target table that is defined to accept only unique keys using the `DISCARDING DUPLICATES` addition of the `CORRESPONDING` operator.
- In this case, the duplicate line is ignored in the source table.
- The addition can also be specified with `MAPPING ...`.
``` abap itab = CORRESPONDING #( itab2 DISCARDING DUPLICATES ). ``` |
| Copying data from deep internal tables |
- A deep internal table is table with [deep](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_glosry.htm) line type, which means the table can itself contain internal tables as components, among others.
- The `BASE` addition does not delete the existing content.
- See also the alternative `MOVE-CORRESPONDING` statements.
``` abap 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. ``` |
| Subject | Details/Code Snippet |
Using READ TABLE statements |
The following example shows `READ TABLE` statements to read a single line from an internal table by specifying the index. You can use the addition `USING KEY` to specify a table key and thus explicitly determine the table index to use. If the table has a sorted secondary
key, the addition can be specified and the line to be read is then determined from its secondary table index. If the primary table key is
specified by its name `primary_key`, the table must be an index table, and the behavior is the same as if `USING KEY` was
not specified.
Note that the examples only show reading into a work area. Other targets are possible as shown above.
``` abap "Primary table index is used by default READ TABLE itab INTO wa INDEX i. "Primary table index is used, primary key's default name specified explicitly READ TABLE itab INTO wa INDEX i USING KEY primary_key. "Secondary table index is used (assuming a secondary table key sec_key exists) READ TABLE itab INTO wa INDEX i USING KEY sec_key. "Note: You can also use alias names for the keys if specified. ``` |
| Using table expressions |
Using [table
expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expressions.htm),
the read result is stored in a variable that can be declared inline.
The number in the square brackets represents the index. A line that is
not found results in an runtime error. To avoid an error, you can
use a [`TRY ... CATCH ... ENDTRY.`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptry.htm) block.
``` abap "In the examples, integer values are specified for the index. DATA(lv1) = itab[ 1 ]. TRY. DATA(lv2) = itab[ 2 ]. CATCH cx_sy_itab_line_not_found. ... ENDTRY. DATA(lv3) = itab[ KEY primary_key INDEX 3 ]. "Copying a table line via table expression and embedding in constructor expression DATA(lv4) = VALUE #( itab[ 4 ] ). "Reading into data reference variable using the REF operator DATA(lv5_ref) = REF #( itab[ 5 ] ). ``` |
| Avoiding an exception when using table expressions |
When you read a non-existent line using a table expression, you may not want to throw an exception. You can also embed the table expression
in a constructor expression using the `OPTIONAL` addition. This way, an unsuccessful read will not trigger the
exception. The result returned is a line with initial values.
Alternatively, you can use the `DEFAULT` addition to return a
default line in case of an unsuccessful read operation, which can also be another table expression or constructor expression.
``` abap DATA(line1) = VALUE #( itab[ 6 ] OPTIONAL ). DATA(line2) = VALUE #( itab[ 7 ] DEFAULT itab[ 1 ] ). DATA(line3) = VALUE #( itab[ 8 ] DEFAULT VALUE #( ) ). ``` |
| Subject | Details/Code Snippet |
| Sorting by primary table key | ``` abap "Implicit sorting by primary table key and in ascending order by default SORT itab. "Optional additions to determine the sort order "As mentioned above, ASCENDING is used implicitly. Here, specifying it explicitly. SORT itab ASCENDING. SORT itab DESCENDING. ``` The effect of sorting can have an unexpected result if you use the simple form of the statement and do not explicitly specify the keys. If an internal table has a structured line type and (perhaps inadvertently) the standard key as the primary table key, that is, all character-like and byte-like components make up the primary table key, all these components are taken into account when the table is sorted. ``` abap "Is basically the same as it2 DATA it1 TYPE TABLE OF zdemo_abap_fli. DATA it2 TYPE STANDARD TABLE OF zdemo_abap_fli WITH DEFAULT KEY. "Respecting the standard key when sorting SORT it1. ``` Plus: Suppose there are only elementary numeric components in an internal table with a structured line type. In this case, sorting has no effect because the primary table key is considered empty. This is certainly also true for tables declared with `EMPTY KEY`. |
| Sorting by explicitly specifying components |
You can sort by any component of the internal table. It is also possible to specify the sort order
(even component-wise). Explicitly specifying the components has the advantage that your code is easier to understand and you can avoid unexpected results if you accidentally use `SORT` without the `BY` addition on empty and standard table keys.
``` abap DATA it3 TYPE TABLE OF struc WITH NON-UNIQUE KEY a. "Sorting by primary table key a SORT itab. "Specifying the component to sort for; here, it is the same as the key; "this way, the sorting is easier to understand SORT itab BY a. "Syntax showing multiple component sorting with component-wise sort order SORT itab BY a b ASCENDING c DESCENDING. "Sorting respecting the entire line (e. g. in the context of tables with "empty or standard keys) SORT itab BY table_line. ``` |