diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md index 9f9d8e1..78dbd8e 100644 --- a/01_Internal_Tables.md +++ b/01_Internal_Tables.md @@ -11,16 +11,16 @@ - [Copying Internal Tables](#copying-internal-tables) - [Using INSERT and APPEND Statements to Populate Internal Tables](#using-insert-and-append-statements-to-populate-internal-tables) - [Creating and Populating Internal Tables Using Constructor Expressions](#creating-and-populating-internal-tables-using-constructor-expressions) - - [VALUE operator](#value-operator) - - [CORRESPONDING Operator](#corresponding-operator) + - [VALUE Operator](#value-operator) + - [CORRESPONDING Operator and MOVE-CORRESPONDING Statements](#corresponding-operator-and-move-corresponding-statements) - [FILTER Operator](#filter-operator) - [NEW Operator](#new-operator) - [Example: Exploring Populating Internal Tables](#example-exploring-populating-internal-tables) - [Reading Single Lines from Internal Tables](#reading-single-lines-from-internal-tables) - [Determining the Target Area when Reading Single Lines in READ TABLE Statements](#determining-the-target-area-when-reading-single-lines-in-read-table-statements) - - [Reading a Single Line by Index](#reading-a-single-line-by-index) - - [Reading a Single Line Using Table Keys](#reading-a-single-line-using-table-keys) - - [Reading a Single Line Using a Free Key](#reading-a-single-line-using-a-free-key) + - [Reading Single Lines by Index](#reading-single-lines-by-index) + - [Reading Single Lines Using Table Keys](#reading-single-lines-using-table-keys) + - [Reading Single Lines Using a Free Key](#reading-single-lines-using-a-free-key) - [Examples of Addressing Individual Components of Read Lines](#examples-of-addressing-individual-components-of-read-lines) - [Excursions with READ TABLE Statements](#excursions-with-read-table-statements) - [System Field Setting in READ TABLE Statements](#system-field-setting-in-read-table-statements) @@ -456,6 +456,8 @@ FINAL(itab4) = itab. > - An assignment can trigger an uncatchable exception if, for example, the target table is assigned a duplicate of a unique primary table key or secondary table. > - More information: [Conversion Rules for Internal Tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_itab.htm) +
+ ### Using INSERT and APPEND Statements to Populate Internal Tables You can use the ABAP keywords @@ -501,7 +503,17 @@ to add lines to internal tables.| 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. @@ -511,7 +523,15 @@ 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. + |
+
| Adding an initial line | +
+
+... to an internal table without providing any field values.
+ ``` abap APPEND INITIAL LINE TO itab. @@ -519,7 +539,12 @@ 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**. + |
+
| 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
@@ -533,7 +558,11 @@ INSERT INITIAL LINE INTO TABLE itab REFERENCE INTO DATA(dref).
"of the (initial) line and assign values, e.g. |
+
| Adding all lines from another internal table | +``` abap APPEND LINES OF itab2 TO itab. @@ -541,33 +570,53 @@ 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**. + | +
| 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 -"i1/i2 represent integer values +APPEND LINES OF itab2 FROM 3 TO 5 TO itab. -APPEND LINES OF itab2 FROM i1 TO i2 TO itab. +APPEND LINES OF itab2 FROM 3 TO itab. -APPEND LINES OF itab2 FROM i1 TO itab. +APPEND LINES OF itab2 TO 7 TO itab. -APPEND LINES OF itab2 TO i2 TO itab. - -INSERT LINES OF itab2 FROM i1 TO i2 INTO TABLE 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**. + + |
+
| 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 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. + |
+
| Creating an internal table by inline declaration and adding lines with a constructor expression | ++ ``` abap "Internal table type TYPES it_type LIKE itab. @@ -620,75 +686,156 @@ DATA(str_tab_b) = VALUE string_table( ). DATA str_tab_c TYPE string_table. ``` -When you use the above assignments (`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. + | +
| 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. -> **💡 Note** -> 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. + |
+
| 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 ) ... ). ``` -#### CORRESPONDING Operator + |
+
| 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. + |
+
| 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** + + |
+
| 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. + |
+
| 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. + |
+
| 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**. + |
+
| Copying data from deep internal tables | +
+
- The `BASE` addition does not delete the existing content.
- See also the alternative `MOVE-CORRESPONDING` statements.
+
+ + ``` abap itab_nested2 = CORRESPONDING #( DEEP itab_nested1 ). @@ -699,6 +846,16 @@ 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. @@ -1184,12 +1353,20 @@ READ TABLE itab INTO wa INDEX i USING KEY sec_key. "Note: You can also use alias names for the keys if specified. ``` -Using a [table -expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expressions.htm), + |
+
| 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. @@ -1210,21 +1387,37 @@ DATA(lv4) = VALUE #( itab[ 4 ] ). 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 ] ). ``` + + |
+
| Subject | Details/Code Snippet | +
| Sorting by primary table key | ++ ``` abap "Implicit sorting by primary table key and in ascending order by default SORT itab. @@ -2801,11 +3030,18 @@ 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* + | +
| 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. @@ -2824,6 +3060,10 @@ SORT itab BY a b ASCENDING c DESCENDING. SORT itab BY table_line. ``` + |
+
| Subject | Details/Code Snippet | +
| Using an inner join | +
+
+[Inner join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninner_join_glosry.htm):
- Columns of two or more data sources in a result set can be joined.
- Result set:
- Columns of the rows in the result set of the left side with the columns of the rows in the result set of the right side are joined into a single result set.
@@ -796,6 +806,9 @@ SELECT comp1, comp2, comp3
- If there are identical column names in multiple data sources, use the [column
selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_comp_selector_glosry.htm "Glossary Entry")
`~`.
+
+ + ``` abap SELECT a~comp1, a~comp2, b~comp3, c~comp4 FROM dbtab1 AS a @@ -805,13 +818,22 @@ SELECT a~comp1, a~comp2, b~comp3, c~comp4 INTO ... ``` -**Using an [outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenouter_join_glosry.htm)**: + |
+
| Using an outer join | +
+
+[Outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenouter_join_glosry.htm):
- Realized by either a [left outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenleft_outer_join_glosry.htm) or
a [right outer join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenright_outer_join_glosry.htm).
- Result set:
- Same result set as the inner join.
- Difference: For each selected row on the left side as `LEFT OUTER JOIN` or on the right side as `RIGHT OUTER JOIN`, at least one row is created in the result set even if no rows on the other side meet the condition. The columns on the other side that do not meet the condition are filled with [null values](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm).
+ + ``` abap "Example for a left outer join SELECT a~comp1, a~comp2, b~comp3, @@ -820,11 +842,17 @@ SELECT a~comp1, a~comp2, b~comp3, WHERE ... INTO ... ``` -> **💡 Note** -> There are more join variants and syntax options available. See the ABAP Keyword Documentation on [joins](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_join.htm) -for more information. -**Merging the result sets of multiple queries into a single result set** using the [set operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_set_operators_glosry.htm) [`UNION`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapunion.htm#!ABAP_VARIANT_1@1@). In this case, the rows of the result set of the query after `UNION` are inserted into the result set of the query in front of `UNION`. + |
+
| Merging the result sets of multiple queries into a single result set | +
+
+... using the [set operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_set_operators_glosry.htm) [`UNION`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapunion.htm#!ABAP_VARIANT_1@1@). In this case, the rows of the result set of the query after `UNION` are inserted into the result set of the query in front of `UNION`.
+
+ ``` abap SELECT FROM dbtab1 @@ -837,8 +865,16 @@ SELECT FROM dbtab2 INTO ... ``` -**Returning distinct rows of a result set (1)** of a query specified before the `INTERSECT` addition that are also available in the result set of the query after the `INTERSECT` addition. + |
+
| Returning distinct rows of a result set (1) | +
+
+... of a query specified before the `INTERSECT` addition that are also available in the result set of the query after the `INTERSECT` addition.
+
+ ``` abap "If you have imported the cheat sheet repository and already run an example class to fill @@ -860,7 +896,16 @@ SELECT carrid, carrname INTO TABLE @DATA(itab_w_intersect). ``` -**Returning distinct rows of a result set (2)** of a query specified before the `EXCEPT` addition that are not available in the result set of the query after the `EXCEPT` addition. + |
+
| Returning distinct rows of a result set (2) | +
+
+... of a query specified before the `EXCEPT` addition that are not available in the result set of the query after the `EXCEPT` addition.
+
+ ```abap "If you have imported the cheat sheet repository and already run an example class to fill @@ -890,8 +935,16 @@ SELECT carrid INTO TABLE @DATA(itab_w_except). ``` + |
+