-
-## Basic Properties of Internal Tables
-
-
- Expand to view the details
-
-
-**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. an [elementary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm) or complex data type as well as a [reference type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_type_glosry.htm).
-- In most cases, the line type is [structured](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructured_type_glosry.htm). In this case, the individual components of a line are also referred to as the columns of the internal table.
-- In a simple case, the line consists of a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm) with elementary data objects; however, it can also be a [deep structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm) whose components can be structures themselves or even internal tables.
-
-**Table Category**
-
-- Defines how internal tables are managed and stored internally, and how to access individual table entries.
-- Why is it relevant? The use of a suitable table category should meet your requirements, i.e. if the internal tables are large, the different categories can have significant performance differences when accessing table content.
-- Note: There are two ways to access internal tables:
- - Access by table index: A line of an internal table is accessed by its line number. This kind of access is the fastest way to access table lines.
- - Access by table key: A line of an internal table is accessed by searching for specific values in specific columns. Note: The columns in which you search can be key columns, but they can also be non-key columns.
-
-
-| Category | Internally managed by | Access | Primary table key | When to use | Hints |
-|---|---|---|---|---|---|
-|`STANDARD`|Primary table index (that's why these tables are called [index tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenindex_table_glosry.htm))|
Table index
Table key
|
Always non-unique, i.e. duplicate entries are always allowed
Definition of an empty key is possible if the key is not relevant(`WITH EMPTY KEY`)
|
If you primarily access the table content for sequential processing or via the table index.
Response time for accessing the table using the primary key: This kind of table access is optimized only for sorted and hashed tables. For standard tables, primary key access uses a linear search across all lines. That means that large standard tables (more than 100 lines) are not ideal if the you primarily access the table using the table key.>
|
There is no particular sort order, but the tables can be sorted using `SORT`.
Filling this kind of table: Lines are either appended at the end of the table or inserted at a specific position.
[Secondary table keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm) can be defined to make key access to standard tables more efficient.
Standard and sorted tables have the least [administration costs (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenadmin_costs_dyn_mem_obj_guidl.htm).
|
-|`SORTED`|Primary table index (that's why these tables are called [index tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenindex_table_glosry.htm))|
Table index
Table key
|
Non-unique
Unique
... used to sort the table in ascending order.
|
Enables an optimized access to table content using table key and index.
If access via table key is the main access method, but no unique key can be defined.
|
Sorting is done automatically when lines are inserted or deleted. As a consequence, the table index must usually be reorganized.
The response time for accessing the table using the primary key depends logarithmically on the number of table entries, since a binary search is used.
Standard and sorted tables have the least administration costs.
Optimized for key access. Access to table content via table key is the main access method and a unique key can be defined.
|
The response time for primary key access is constant and independent of the number of entries in the table.
Hashed tables have the highest administration costs.
|
-
-
-
-**Key Attributes**
-
-- There are two types of table keys: a [primary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_table_key_glosry.htm) and [secondary table keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm).
-- Table keys ...
- - are intended to provide an optimized access to the content of internal tables.
- - are either unique or non-unique, i.e. more than one line with the same key (duplicates) can exist in the internal table or not. Regarding the primary table key, the definition depends on the table category. For the secondary table key, the definition depends on the key type. For standard tables, the primary table key can also be defined as empty, i.e. it does not contain any key columns. Note that for standard tables, an optimized access is only possible with secondary table keys.
- - Type of keys:
- - Sorted keys:
- - Are either the primary table keys of sorted tables or the secondary table keys of any table.
- - Are managed internally by a table index. In the case of sorted tables, this is the primary table index. In the case of secondary table keys, a secondary table index is added.
- - Access via sorted keys means an optimized binary search.
- - Hashed keys:
- - Are either the primary table key of hashed tables or secondary table keys of any table.
- - Internally managed by a hash algorithm.
- - There is no table index for a hashed key.
-
-**Further information**
-- [Internal Tables - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab_oview.htm)
-- [Programming guidelines: Internal Tables (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenadmin_costs_dyn_mem_obj_guidl.htm)
-
-
-
-
-## Table Keys in Internal Tables (Primary, Secondary, Standard, Empty)
-
-
- Expand to view the details
-
-
-**Primary table key**
-
-- Each internal table has a primary table key.
-- Can be either a self-defined key or the [standard key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_key_glosry.htm).
-- The primary table key is ...
- - sorted for sorted tables.
- - hashed for hashed tables.
-- Note that the key fields in sorted and hashed tables are read-only. This is not valid for standard tables.
-- The specification of the primary key can be omitted only for standard tables. The primary table key is then automatically defined as a non-unique standard key.
-- The primary table key has the predefined name `primary_key`, by which it can also be addressed explicitly. However, its use is optional, and it is usually not necessary to specify it explicitly. You can also specify an alias name for the primary key.
-- When accessing internal tables using the table key, the primary key is always used implicitly in processing statements if no secondary key is specified. Note that the primary table key must be specified in table expressions if the primary key is to be used explicitly.
-
-> **💡 Note**
-> The key can consist of individual key fields or the entire line of the internal table. In this case, the pseudo component `table_line` can be used to denote the primary table key. For non-structured line types, this is the only way to define the key.
-
-**Standard key**
-- The [standard key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_key_glosry.htm) is a special primary table key.
-- It can be declared either explicitly or implicitly.
-- Standard key of an internal table with a ...
- - structured line type: The primary table key consists of all fields with character-like and byte-like data types.
- - non-structured/elementary line type: The entire table is the key (`table_line`).
-- An internal table with no explicit key specification implicitly has the standard table key as the primary table key.
-- Why respecting standard keys is important:
- - Sorting of a table can produce unexpected results.
- - Since the standard key can consist of many fields, it affects the performance when accessing the internal table via the keys.
- - The key fields of the primary table key of sorted and hashed tables are always read-only, i.e. using the standard key with these table categories and then (unintentionally) modifying fields can cause unexpected runtime errors.
- - Specifying keys explicitly has the advantage of making the code more readable and preventing the standard key from being set by mistake.
-
-**Empty key**
-- The primary table key of a standard table can be empty, i.e. it does not contain any key fields.
-- An empty key is not possible for sorted and hashed tables.
-- When used:
- - When the definition of a table key is not important.
- - To explicitly state that a table key is not required, instead of specifying no key definition. Otherwise, the standard key is used, which can lead to unexpected results as mentioned above.
-- Declaration:
- - Explicit declaration using the addition `EMPTY KEY`.
- - Implicit declaration when using the standard key if a structured
- line type does not contain non-numeric elementary components or
- if an unstructured line type is tabular.
- - Note: When using an [inline declaration](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry") such as `... INTO TABLE @DATA(itab) ...` in `SELECT` statements, the resulting table is a standard table and has an empty key.
-
-**Secondary table keys**
-
-- Secondary table keys ...
- - are optional for all table categories.
- - can be unique/non-unique sorted keys or unique hash keys.
- - have a self-defined name. An alias name can also be specified.
-- A secondary table index is created internally for each sorted secondary key. This allows index access to hashed tables via the secondary table key. In this case, `sy-tabix` is set.
-- When accessing internal tables using the secondary table key, the key name (or the alias if specified) must be specified. They are not selected automatically. If no secondary key is specified in a processing statement, the primary key or primary table index is always used. If you want to make use of this key in ABAP statements, for example, `READ`, `LOOP AT` or `MODIFY` statements, you must specify the key explicitly using the appropriate additions, for example, `WITH ... KEY ... COMPONENTS` or `USING KEY`.
-- Use cases:
- - To improve read performance.
- - For very large internal tables (that are filled once and changed very often)
- - Standard tables, whose primary table keys cannot be unique, can be provided with a means of ensuring that unique table entries are read.
- - Note that defining secondary table keys involves additional administration costs (additional memory consumption). Therefore, the use of secondary table keys should be reserved for cases where the benefits outweigh the extra costs.
-- For more details, see the programming guidelines for secondary keys: [Secondary
- Key (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensecondary_key_guidl.htm "Guideline").
-
-> **💡 Note**
-> - See examples of internal table declarations using the table keys mentioned above in the following section.
-> - See an example that uses secondary table keys [below](#improving-read-performance-with-secondary-table-keys).
-
-
-
-
-
-
-## Creating Internal Tables and Types
-
-You can declare internal tables and internal table types in [ABAP programs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm) using the [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm) and [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) statements. The relevant syntax elements for internal tables are `TABLE OF` in combination
-with the additions [`TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_simple.htm)
-or [`LIKE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_referring.htm).
-
-``` abap
-TYPES itab_type1 TYPE STANDARD TABLE OF data_type ... "Standard table type
-TYPES itab_type2 LIKE SORTED TABLE OF data_object ... "Sorted table type
-
-DATA itab1 TYPE TABLE OF data_type ... "Standard table by default
-DATA itab2 TYPE HASHED TABLE OF data_type ... "Hashed table
-DATA itab3 TYPE itab_type1 ... "Based on an existing internal table type
-DATA itab4 LIKE itab1 ... "Based on an existing internal table
-```
-
-> **💡 Note**
-> If the table category is not specified (`... TYPE TABLE OF ...`), it is automatically `... TYPE STANDARD TABLE OF ...`.
-
-The following code snippet contains various internal table declarations. It is intended to demonstrate a selection of the rich variety of possible internal tables mentioned in the previous sections, e.g. in *Table Keys in Internal Tables*.
-In the examples, the internal tables are created using the structured type of a demo database table in the DDIC. The line type of the database table is automatically used when defining an internal table.
-
-
-``` abap
-"------------------ Standard table key ------------------
-
-"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_fli.
-
-"Explicitly specifying STANDARD for a standard table.
-"Explicitly specifying the standard table key. It is the same as it1.
-DATA it2 TYPE STANDARD TABLE OF zdemo_abap_fli WITH DEFAULT KEY.
-
-"Hashed table with unique standard table key
-DATA it3 TYPE HASHED TABLE OF zdemo_abap_fli WITH UNIQUE DEFAULT KEY.
-
-"Sorted table with non-unique standard table key
-DATA it4 TYPE SORTED TABLE OF zdemo_abap_fli WITH NON-UNIQUE DEFAULT KEY.
-
-"Elementary line type; the whole table line is the standard table key
-DATA it5 TYPE TABLE OF i.
-
-"------------------ Primary table key ------------------
-
-"Specifying the primary table key
-"Standard tables: only a non-unique key possible
-"The following two examples are the same. NON-UNIQUE can be ommitted but is implicitly added.
-DATA it6 TYPE TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid.
-DATA it7 TYPE TABLE OF zdemo_abap_fli WITH KEY carrid.
-
-"Sorted tables: both UNIQUE and NON-UNIQUE possible
-DATA it8 TYPE SORTED TABLE OF zdemo_abap_fli WITH UNIQUE KEY carrid connid.
-DATA it9 TYPE SORTED TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid connid cityfrom.
-
-"Hashed tables: UNIQUE KEY must be specified
-DATA it10 TYPE HASHED TABLE OF zdemo_abap_fli WITH UNIQUE KEY carrid.
-
-"Explicitly specifying the predefined name primary_key and listing the components.
-"The example is the same as it6 and it7.
-DATA it11 TYPE TABLE OF zdemo_abap_fli WITH KEY primary_key COMPONENTS carrid.
-
-"The following example is the same as it9.
-DATA it12 TYPE SORTED TABLE OF zdemo_abap_fli
- 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 it13 TYPE SORTED TABLE OF zdemo_abap_fli
- 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 it14 TYPE HASHED TABLE OF zdemo_abap_fli
- WITH UNIQUE KEY primary_key
- ALIAS p2 COMPONENTS table_line.
-
-"------------------ Empty key ------------------
-
-"Empty keys only possible for standard tables
-DATA it15 TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
-
-"Excursion: The inline declaration in a SELECT statement produces a standard table with empty key.
-SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(it16).
-
-"------------------ Secondary table key ------------------
-
-"The following examples demonstrate secondary table keys that are possible for all table categories.
-DATA it17 TYPE TABLE OF zdemo_abap_fli "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_fli "hashed table
- WITH UNIQUE KEY carrid connid
- WITH NON-UNIQUE SORTED KEY airports COMPONENTS airpfrom airpto.
-
-DATA it19 TYPE SORTED TABLE OF zdemo_abap_fli "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_fli
- 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_fli
- WITH NON-UNIQUE KEY primary_key ALIAS k1 COMPONENTS carrid connid city
- WITH NON-UNIQUE SORTED KEY cities ALIAS s1 COMPONENTS cityfrom cityto
- WITH UNIQUE HASHED KEY airports ALIAS s2 COMPONENTS airpfrom airpto.
-
-"Example for 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.
-```
-
-As mentioned, the examples above demonstrate internal tables that are created using the structured type of a database table in the DDIC.
-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.
-
-Steps:
-1. Define a structured data type (locally or globally).
- This is not necessary if you use, for example, the name of a database table or [CDS view](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm) in the internal table declaration. In these cases their line type is used automatically.
-2. Define an internal table type.
-3. Create the internal table, i.e. a data object that uses this type.
-
-You can also create an internal table by ...
-- combining the data object creation and table type definition in one step.
-- using an [inline declaration](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry"). Such inline declarations are possible at suitable [declaration
-positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeclaration_positions.htm)
-if the operand type can be fully determined, for example, using a
-`DATA` statement (or [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) for immutable variables).
-
-
-``` abap
-"1. Defining line type locally
-
-TYPES: BEGIN OF ls_loc,
- key_field TYPE i,
- char1 TYPE c LENGTH 10,
- char2 TYPE c LENGTH 10,
- num1 TYPE i,
- num2 TYPE i,
- END OF ls_loc.
-
-"2. Defining internal table types
-"All of the examples use the short form:
-
-TYPES:
- "Standard table type based on locally defined structure type.
- tt_loc_str TYPE TABLE OF ls_loc WITH NON-UNIQUE KEY key_field,
-
- "Based on global structure type
- tt_gl_str TYPE TABLE OF zsome_global_struc_type WITH NON-UNIQUE KEY key_field,
-
- "Based on database table (could also be, e. g. a CDS view)
- "In this case, the line type of the table is automatically used.
- tt_gl_tab TYPE TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid,
-
- "Based on an elementary type
- tt_el_type TYPE TABLE OF i.
-
-"3. Creating internal tables ...
-"... from locally defined table types
-DATA: itab_a1 TYPE tt_loc_str,
- itab_a2 TYPE tt_gl_str,
- itab_a3 TYPE tt_gl_tab,
- itab_a4 TYPE tt_el_type.
-
-"... from global internal table types
-DATA itab_a5 TYPE string_table.
-
-"Combining data object and table type definition
-DATA itab_a6 TYPE TABLE OF ls_loc WITH NON-UNIQUE KEY key_field.
-
-"Internal table based on an already existing internal table using LIKE.
-DATA itab_a7 LIKE TABLE OF itab_a6.
-
-"Creating internal tables by inline declarations
-
-"Table declared inline in the context of an assignment
-"The examples show the copying of a table including the content on the fly
-"and creating the table in one step. The data type of the
-"declared variable is determined by the right side.
-DATA(it_inline1) = itab_a1.
-DATA(it_inline2) = it_inline1.
-
-"Using FINAL for creating immutable variables
-FINAL(it_final) = it_inline1.
-
-"Using the VALUE operator and an internal table type
-DATA(it_inline3) = VALUE tt_loc_str( ( ... ) ).
-
-"Table declared inline in the context of a SELECT statement;
-"a prior extra declaration of an internal table is not needed.
-SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(it_inline4).
-
-"Instead of
-DATA it_sel TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
-SELECT * FROM zdemo_abap_fli INTO TABLE @it_sel.
-
-"Using FINAL
-SELECT * FROM zdemo_abap_fli INTO TABLE @FINAL(it_inline5).
-```
-
-
-
-## Filling and Copying Internal Tables
-
-You can use the ABAP keywords
-[`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_itab.htm)
-and [`APPEND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapappend.htm)
-to add lines to internal tables.
-
-
- Notes on using APPEND and INSERT
-
-
-- `APPEND` ...
- - always adds lines at the bottom of the internal table.
- - is not a problem for standard tables where lines are managed
- by an index. When the statement is used, the system field
- `sy-tabix` is set to the index of the recently added
- line. `sy-tabix` is always set to the index with respect
- to the primary table index.
- - cannot be used for hashed tables. For sorted tables,
- lines are appended only if they match the sort order, and no
- duplicate entries are created if the primary table key is unique.
- Therefore, `INSERT` should be used when adding lines to
- sorted tables.
-- `INSERT` ...
- - can be used to add lines at a specific position in tables (by
- specifying the target index). In doing so, all the following
- lines are moved down one position.
- - without specifying the position adds the lines at the bottom of
- the table in case of standard tables. However, when using
- `INSERT`, `sy-tabix` is not set unlike
- `APPEND`. In case of sorted tables, the line is
- automatically inserted at the correct position.
- - With `INSERT`, you can specify the position in the internal table at which lines are inserted after `INTO`.
- - `... INTO TABLE itab ...`: Line is inserted in ...
- - standard tables as last line (i.e. appended)
- - sorted tables in the sort order in accordance with primary key values
- - hashed table by the hash administration in accordance with primary key values
- - `... INTO itab INDEX n`: Possible for index tables. The line is inserted before the line with the line number `n` in the primary table index.
- - Note: In the case of unique primary table keys, the table cannot have entries with duplicate
- keys. If a duplicate is inserted, the insertion fails and the
- system field `sy-subrc` is set to 4.
-- What to use? The recommendation is the `INSERT` statement. It covers all table and key types. Consider potential issues when you change table/key types, and you use `APPEND` in your code.
-
-
-
-**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 lv_struc TO itab.
-
-INSERT VALUE #( comp1 = a comp2 = b ... ) INTO TABLE itab.
-INSERT lv_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().
-APPEND INITIAL LINE TO itab ASSIGNING .
-INSERT INITIAL LINE INTO TABLE itab REFERENCE INTO DATA(dref).
-```
-
-**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
-"i1/i2 represent integer values
-
-APPEND LINES OF itab2 FROM i1 TO i2 TO itab.
-
-APPEND LINES OF itab2 FROM i1 TO itab.
-
-APPEND LINES OF itab2 TO i2 TO itab.
-
-INSERT LINES OF itab2 FROM i1 TO i2 INTO 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 lv_struc INTO itab2 INDEX i.
-
-INSERT LINES OF itab2 INTO itab INDEX i.
-```
-
-
-
-**Adding lines using constructor expressions**
-
-As mentioned above, table lines that are constructed inline as
-arguments to the `VALUE` operator, for example, can be added to
-internal tables. In the following cases, internal tables are populated
-using constructor expressions in the context of
-[assignments](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_glosry.htm "Glossary Entry").
-
-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.
-
-``` 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 ... ) ).
-```
-
-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.
-
-``` 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.
-``` abap
-itab = VALUE #( ( comp1 = a comp2 = b ...)
- ( comp1 = a comp2 = b ...)
- ( LINES OF itab2 )
- ... ).
-```
-A simple assignment without a constructor expression that **copies the content of another internal table** (note that the existing content in `itab` are deleted). The example below assumes that the source and target table have compatible line types.
-``` abap
-itab = itab2.
-```
-> **💡 Note**
-> - Internal tables can only be assigned to internal tables.
-> - Internal tables can be assigned to each other if their line types are [compatible](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencompatible_glosry.htm) or [convertible](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconvertible_glosry.htm).
-> - 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)
-
-**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**.
-- 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.
-```
-
-
-
-### Excursions with Internal Tables
-For more details on ABAP SQL, see the cheat sheet on [ABAP SQL](03_ABAP_SQL.md).
-
-**Adding multiple lines from a database table to an internal table** using
-[`SELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm),
-for example, based on a condition. In the case below, the internal table
-is created inline.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2 ...
- WHERE ...
- INTO TABLE @DATA(itab_sel).
-```
-
-**Sequentially adding 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 that can be further processed and added to an internal table.
-
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2 ...
- WHERE ...
- INTO @DATA(struc_sel).
-
- IF sy-subrc = 0.
- APPEND struc_sel TO itab.
- ...
- ENDIF.
-ENDSELECT.
-```
-
-Adding multiple lines from a database table using `SELECT`, for example, based on a condition when the database table has a line type that is incompatible with the internal table. The `*` character means that all fields are selected. The other examples define specific fields.
-The `APPENDING CORRESPONDING FIELDS INTO TABLE` addition appends the selected data to the end of the table without deleting existing
-table entries. The `INTO CORRESPONDING FIELDS OF TABLE` addition adds lines and deletes existing table entries.
-``` abap
-SELECT FROM dbtab2
- FIELDS *
- WHERE ...
- APPENDING CORRESPONDING FIELDS OF TABLE @itab.
-
-SELECT FROM dbtab2
- FIELDS *
- WHERE ...
- INTO CORRESPONDING FIELDS OF TABLE @itab.
-```
-Adding multiple lines from an internal table to another internal table using `SELECT`. Note the alias name that must be defined for the
-internal table.
-``` abap
-SELECT comp1, comp2, ...
- FROM @itab2 AS it_alias
- INTO TABLE @DATA(itab_sel).
-```
-
-**Combining data from multiple tables into one internal table** using an [inner
-join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninner_join_glosry.htm "Glossary Entry").
-The following example joins data of an internal and a database table
-using a `SELECT` statement and the [`INNER JOIN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_join.htm) addition. Note that the field list includes fields from both tables. The fields are referred to using `~`.
-``` abap
-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).
-```
-
-Filling an internal table from a database table using
-[subqueries](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry").
-The following two examples fill an internal table from a database table. In the first example, a subquery is specified in the
-`WHERE` clause with the `NOT IN` addition. It checks whether a value matches a value in a set of values
-specified in parentheses. The second example fills an internal table depending on data in another table. A subquery with the `EXISTS` addition is specified in
-the `WHERE` clause. In this
-case, the result of the subquery, which is another
-`SELECT` statement, is checked to see if an entry exists in
-a table based on the specified conditions.
-
-``` abap
-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).
-```
-
-Filling internal table from a table based on the existence of data in
-another table using the [`FOR ALL ENTRIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm) addition.
-
-> **💡 Note**
-> Make sure that the internal table you are reading from is not initial. Therefore, it is recommended that you use a subquery as shown above: `... ( SELECT ... FROM @itab AS itab_alias WHERE ...`).
-
-``` abap
-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.
-```
-
-**Using the `FILTER` operator**
-
-To create an internal table by copying data from another internal table and
-filtering out lines that do not meet the `WHERE` condition, you can use the [`FILTER`
-operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_filter.htm).
-
-- The
- `FILTER` operator constructs an internal table according to a specified type (which can be an explicitly specified, non-generic table type or the `#` character as a symbol for the [operand type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_type_glosry.htm) before the first parenthesis).
-- The lines for the new internal table are taken from an
- existing internal table based on conditions specified in a `WHERE` clause. Note that the table type of the existing internal table must be convertible into the specified target type.
-- The conditions can be based on either single values or a [filter
- table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_filter_table.htm).
-- Additions:
-
-|Addition |Details |
-|---|---|
-|`USING KEY` | Specifies the [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm "Glossary Entry") used to evaluate the `WHERE` condition: either a [sorted key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensorted_key_glosry.htm "Glossary Entry") or a [hash key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhash_key_glosry.htm "Glossary Entry"). If the internal table does not have either of these, it must have a [secondary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm "Glossary Entry"), which must be specified after `USING KEY`. |
-| `EXCEPT` | Specifying `EXCEPT` means that those lines of the existing table are used that do not meet the condition specified in the `WHERE` clause. If `EXCEPT` is not specified, those lines of the existing table that meet the condition are used. |
-
-Examples:
-```abap
-"FILTER on conditions based on single values
-"Assumption: The component num is of type i.
-DATA itab1 TYPE SORTED TABLE OF struc WITH NON-UNIQUE KEY num.
-DATA itab2 TYPE STANDARD TABLE OF struc WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS num.
-DATA itab3 TYPE HASHED TABLE OF struc WITH UNIQUE KEY num.
-
-"The lines meeting the condition are respected.
-"Note: The source table must have at least one sorted or hashed key.
-"Here, the primary key is used
-DATA(f1) = FILTER #( itab1 WHERE num >= 3 ).
-
-"USING KEY primary_key explicitly specified; same as above
-DATA(f2) = FILTER #( itab1 USING KEY primary_key WHERE num >= 3 ).
-
-"EXCEPT addition
-DATA(f3) = FILTER #( itab1 EXCEPT WHERE num >= 3 ).
-DATA(f4) = FILTER #( itab1 EXCEPT USING KEY primary_key WHERE num >= 3 ).
-
-"Secondary table key specified after USING KEY
-DATA(f5) = FILTER #( itab2 USING KEY sec_key WHERE num >= 4 ).
-DATA(f6) = FILTER #( itab2 EXCEPT USING KEY sec_key WHERE num >= 3 ).
-
-"Note: In case of a hash key, exactly one comparison expression for each key component is allowed;
-"only = as comparison operator possible.
-DATA(f7) = FILTER #( itab3 WHERE num = 3 ).
-
-"Using a filter table
-"In the WHERE condition, the columns of source and filter table are compared.
-"Those lines in the source table are used for which at least one line in the filter
-"table meets the condition. EXCEPT and USING KEY are also possible.
-
-DATA filter_tab1 TYPE SORTED TABLE OF i
- WITH NON-UNIQUE KEY table_line.
-
-DATA filter_tab2 TYPE STANDARD TABLE OF i
- WITH EMPTY KEY
- WITH UNIQUE SORTED KEY line COMPONENTS table_line.
-
-DATA(f8) = FILTER #( itab1 IN filter_tab1 WHERE num = table_line ).
-
-"EXCEPT addition
-DATA(f9) = FILTER #( itab1 EXCEPT IN filter_tab1 WHERE num = table_line ).
-
-"USING KEY is specified for the filter table
-DATA(f10) = FILTER #( itab2 IN filter_tab2 USING KEY line WHERE num = table_line ).
-
-"USING KEY is specified for the source table, including EXCEPT
-DATA(f11) = FILTER #( itab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE num = table_line ).
-```
-
-**Collecting values**
-
-Use the
-[`COLLECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcollect.htm)
-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.
-``` abap
-COLLECT VALUE dtype( comp1 = a comp2 = b ... ) INTO itab.
-```
-
-
-
-## Reading from Internal Tables
-
-There are three different ways to specify the line to read:
-
-- by index (only index tables)
-- by table keys (only tables for which a key is defined)
-- by free key
-
-The following code snippets include [`READ TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_table.htm) statements and [table expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expressions.htm) to read from internal tables.
-
-**Reading single lines**
-
-*Determining the target area*
-
-- Copying a line to a data object using the addition `INTO`.
- After the copying, the line found exists separately in the internal table and
- in the data object. If you change the
- data object or the table line, the change does not affect the other.
- However, you can modify the copied table line and use a
- `MODIFY` statement to modify the table based on the modified
- table line (see below). The `TRANSPORTING` addition
- specifies which components to copy. If
- it is not specified, all components are respected.
- ``` abap
- READ TABLE itab INTO dobj ... "dobj must have the table's structure type
-
- READ TABLE itab INTO DATA(dobj_inl) ...
-
- READ TABLE itab INTO ... TRANSPORTING comp1 [comp2 ... ].
- ```
-
-- Assigning a line to a [field
- symbol](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm "Glossary Entry"),
- for example, using an inline declaration (`ASSIGNING `). When you then access the field symbol, it means that you access the found table line. There is no actual copying of
- content. Therefore, modifying the field symbol means
- modifying the table line directly. Note that you cannot use the
- `TRANSPORTING` addition since the entire table is
- assigned to the field symbol.
-
- ``` abap
- READ TABLE itab ASSIGNING ... "The field symbol must have an appropriate type.
-
- READ TABLE itab ASSIGNING FIELD-SYMBOL() ... "The field symbol is created inline.
- ```
-
-- Reading a line into a [data reference
- variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_variable_glosry.htm "Glossary Entry")
- using `REFERENCE INTO`. In this case, no copying takes place. If you want to address the line, you must first [dereference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm) the data reference. You cannot use the addition `TRANSPORTING`.
-
- ``` abap
- READ TABLE itab REFERENCE INTO dref ...
-
- READ TABLE itab REFERENCE INTO DATA(dref_inl) ...
- ```
-
-**Which to use then?** Since all syntax options provide the same
-functionality, your use case, the
-performance or readability of the code may play a role. For more information, see
-the programming guidelines for the [target
-area (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentable_output_guidl.htm "Guideline").
-A use case for `INTO dobj` is when the table should
-not be changed using the copied table line. However, copying comes
-at a performance cost. Imagine that your table contains many columns or
-nested components. In this case, it is better not to copy at all (although you can use
-the `TRANSPORTING` addition to restrict the fields to be copied).
-
-
-
-*Reading a single line by index*
-
-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
-READ TABLE itab INTO wa INDEX i.
-
-READ TABLE itab INTO wa INDEX i USING KEY primary_key.
-```
-
-Using a [table
-expression](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 ] ).
-```
-
-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[ 8 ] ).
-```
-
-
-
-*Reading single lines using table keys*
-
-Lines can be read by explicitly specifying the table keys or the alias names, if any.
-```abap
-"Example internal table with primary and secondary table key and alias names
-"Assumption: All components are of type i
-
-DATA it TYPE SORTED TABLE OF struc
- WITH NON-UNIQUE KEY primary_key ALIAS pk COMPONENTS a b
- WITH NON-UNIQUE SORTED KEY sec_key ALIAS sk COMPONENTS c d.
-
-"Table expressions
-
-"Key must be fully specified
-line = it[ KEY primary_key COMPONENTS a = 1 b = 2 ].
-
-"The addition COMPONENTS is optional; same as above
-line = it[ KEY primary_key a = 1 b = 2 ].
-
-"Primary key alias
-line = it[ KEY pk a = 1 b = 2 ].
-
-"Secondary table key
-line = it[ KEY sec_key c = 3 d = 4 ].
-
-"Secondary table key alias
-line = it[ KEY sk c = 3 d = 4 ].
-
-"READ TABLE statements
-"Primary table key
-READ TABLE it INTO wa WITH TABLE KEY primary_key COMPONENTS a = 1 b = 2.
-
-"Alias
-READ TABLE it INTO wa WITH TABLE KEY pk COMPONENTS a = 1 b = 2.
-
-"Secondary table key
-READ TABLE it INTO wa WITH TABLE KEY sec_key COMPONENTS c = 3 d = 4.
-
-"Alias
-READ TABLE it INTO wa WITH TABLE KEY sk COMPONENTS c = 3 d = 4.
-
-"Reading a line based on keys specified in a work area
-"Work area containing primary and secondary table key values; the line type
-"must be compatible to the internal table
-DATA(pr_keys) = VALUE struc( a = 1 b = 2 ).
-
-DATA(sec_keys) = VALUE struc( c = 3 d = 4 ).
-
-READ TABLE it FROM pr_keys INTO wa.
-
-"If USING KEY is not specified, the primary table key is used.
-"If it is used, the specified table key is used.
-READ TABLE it FROM pr_keys USING KEY primary_key INTO wa.
-
-READ TABLE it FROM sec_keys USING KEY sec_key INTO wa.
-
-"Alias
-READ TABLE it FROM sec_keys USING KEY sk INTO wa.
-```
-
-
-
-**Reading a single line using a free key**
-
-The specified components used as keys need not be part of a table key.
-``` abap
-line = it[ b = 2 ].
-
-READ TABLE it INTO wa WITH KEY b = 2.
-```
-
-*Addressing individual components*
-
-When reading single lines in general, you can also address individual
-components of the line using the [component
-selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_selector_glosry.htm "Glossary Entry")
-`-` (or the [dereferencing
-operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm "Glossary Entry")
-`->*` in the case of data reference variables).
-``` abap
-DATA(comp1) = it[ b = 2 ]-c.
-
-READ TABLE it INTO DATA(wa) WITH KEY b = 2.
-DATA(comp2) = wa-c.
-
-READ TABLE it ASSIGNING FIELD-SYMBOL() WITH KEY b = 2.
-DATA(comp3) = -c.
-
-READ TABLE it REFERENCE INTO DATA(dref) WITH KEY b = 2.
-DATA(comp4) = dref->c.
-"Note: The syntax dref->*-c is also possible.
-```
-
-
-
-**Checking the existence and the index of a line in an internal table**
-
-This is relevant if you are not interested in the content of a table
-line, but only want to find out whether a line exists that matches to the
-index or key specifications. To do this, use a [`READ TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_table.htm)
-statement with the `TRANSPORTING NO FIELDS` addition. The
-addition indicates that no actual content is to be read. If the search was
-successful and an entry exists, the system field `sy-subrc` is
-set to 0.
-
-A newer way to check the existence of a line is the [predicate
-function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_function_glosry.htm "Glossary Entry")
-[`line_exists( )`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenline_exists_function.htm).
-This function expects a [table
-expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expression_glosry.htm "Glossary Entry") as an argument.
-See below for more on table expressions. Note that table expressions do not set system fields.
-``` abap
-"Read using the key
-READ TABLE it WITH KEY b = 2 TRANSPORTING NO FIELDS.
-
-IF sy-subrc = 0.
- ...
-ENDIF.
-
-"Read using the index
-READ TABLE it INDEX 1 TRANSPORTING NO FIELDS.
-
-IF sy-subrc = 0.
- ...
-ENDIF.
-
-"Read using the key
-IF line_exists( it[ b = 2 ] ).
- ...
-ENDIF.
-
-"Read using the index
-IF line_exists( it[ 1 ] ).
- ...
-ENDIF.
-```
-
-If you want to find out about the index of a line in an internal table, you can also make use of the `READ TABLE` statement above. If
-the line is found, the system field `sy-tabix` is set to the number of the index. Otherwise, the built-in function
-[`line_index( )`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenline_index_function.htm) can be used. It returns the index of the found line or 0 if the line does not exist.
-
-``` abap
-DATA(idx) = line_index( it[ b = 2 ] ).
-```
-
-`lines( )` is another built-in function that you can use to check how many lines exist in an internal table. It returns an integer value.
-
-``` abap
-DATA(number_of_lines) = lines( it ).
-```
-
-
-
-## Processing Multiple Internal Table Lines Sequentially
-
-If you are interested not only in single table lines, but in the entire
-table content or in specific parts of it, you can use [`LOOP
-AT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab.htm)
-statements to process table lines sequentially. As above, you
-can use multiple options for target areas: work area, field
-symbol, data reference. There are multiple additions to the `LOOP AT`
-statements to further restrict the table content to be processed.
-
-Simple form:
-``` abap
-"The target is an existing work area.
-DATA wa LIKE LINE OF it.
-
-LOOP AT it INTO wa.
- "No addition of the loop statement; all lines are processed
- "Statements in this block are relevant for each individual table line.
- ...
-ENDLOOP.
-
-"Work area declared inline
-LOOP AT itab INTO DATA(wa_inl).
- ...
-ENDLOOP.
-
-"Field symbols
-FIELD-SYMBOLS LIKE LINE OF it.
-
-LOOP AT it ASSIGNING .
- ...
-ENDLOOP.
-
-LOOP AT it ASSIGNING FIELD-SYMBOL().
- ...
-ENDLOOP.
-
-"Data reference variables
-DATA dref TYPE REF TO dbtab.
-
-LOOP AT it REFERENCE INTO dref.
- ...
-ENDLOOP.
-
-LOOP AT it REFERENCE INTO DATA(dref_inl).
- ...
-ENDLOOP.
-```
-
-- The order in which tables are iterated depends on the table category.
- - Note the [`STEP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_cond.htm#!ABAP_ADDITION_3@3@) addition, which is also available for other ABAP statements.
-- Index tables are looped over in ascending order by the index.
-- Hashed tables are looped in the order in which the lines were added to the table. You can also sort the table before the loop.
-- During the loop, the system field `sy-tabix` is set to the number of the currently processed table
-line. This is not true for hashed tables. There, `sy-tabix` is `0`.
-- Note that if you want to work with the value of `sy-tabix`, you
-should do so immediately after the `LOOP` statement to avoid possible overwriting in statements contained in the loop block.
-
-*Restricting the area of the table to be looped over*
-
-The additions of `LOOP` statements come into play when you want to restrict the table content to be respected by the loop because
-you do not want to loop over the entire table. Note that the examples only show work areas as target objects to hold the table line read.
-Other options are possible as shown above.
-
-``` abap
-"FROM/TO: Only for index tables
-
-"Specifying an index range
-LOOP AT it INTO wa FROM 2 TO 5.
- ...
-ENDLOOP.
-
-"From specified line until the end
-LOOP AT it INTO wa FROM 2.
- ...
-ENDLOOP.
-
-"From first line until the specified line
-LOOP AT it INTO wa TO 5.
- ...
-ENDLOOP.
-
-"WHERE clause: Restricting lines based on logical expression
-
-LOOP AT it INTO wa WHERE a > 1 AND b < 4.
- ...
-ENDLOOP.
-
-"No interest in the table content; only relevant system fields are filled
-
-"Mandatory WHERE clause
-LOOP AT it TRANSPORTING NO FIELDS WHERE a < 5.
- ...
-ENDLOOP.
-
-"Table key specification (snippet uses example table from above)
-"The specified table key affects the order in which the table lines
-"are accessed and the evaluation of the other conditions.
-
-LOOP AT it INTO wa USING KEY primary_key.
-"LOOP AT it INTO wa USING KEY pk. "primary key alias
-"LOOP AT it INTO wa USING KEY sec_key. "secondary key
-"LOOP AT it INTO wa USING KEY sk. "secondary key alias
- ...
-ENDLOOP.
-
-"STEP addition for defining the step size and the direction of the loop
-"- Step size: Specified by the absolute value of an integer
-"- Direction: Specified by a positive (forward loop) or negative
-" (loop in reverse order) integer
-
-"Reversing the loop order using a negative integer
-"Each line is read indicated by the absolute value 1
-LOOP AT it INTO wa STEP -1.
- ...
-ENDLOOP.
-
-"Forward loop by specifiying a positive integer
-"In the example, every second line is read.
-"Note: Omitting STEP means STEP 1 by default.
-LOOP AT it INTO wa STEP 2.
- ...
-ENDLOOP.
-
-"STEP with other additions
-"The example uses the additions FROM and TO.
-"Note: If the value after STEP is negative, the value
-"after FROM must be greater than the value after TO.
-LOOP AT it INTO wa FROM 6 TO 3 STEP -2.
- ...
-ENDLOOP.
-```
-
-### Iteration Expressions
-
-Iteration expressions with [`FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor.htm) as part of certain constructor expressions allow you to create content of an internal table by evaluating one or more source tables.
-
-The expressions are covered in the cheat sheet [Constructor Expressions](05_Constructor_Expressions.md):
-- [Iteration Expressions Using FOR](05_Constructor_Expressions.md#iteration-expressions-using-for)
-- Special reduction operator `REDUCE` that is based on iteration expressions: [REDUCE](05_Constructor_Expressions.md#reduce)
-
-
-
-## Sorting Internal Tables
-
-- Sorted tables are stored in the memory in an automatically sorted
- order, hence, they cannot be sorted explicitly with
- [`SORT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsort_itab.htm).
-- For standard and hashed tables, the order can be changed.
-- When using `SORT` statements, the sort order is derived either
- by the primary table key (Note: Secondary keys
- cannot be used for the sorting.) or by explicitly specifying the
- fields to be sorted by.
-- Explicit specification is the recommended way because it is
- easier to understand and can prevent unwanted sorting results,
- especially with tables with standard key.
-
-*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.
-```
-
-
-
-## Modifying Internal Table Content
-
-As mentioned above, you can modify the content of internal table lines directly in the context of `READ TABLE` and `LOOP AT` statements using field symbols and data reference variables. You can also use table expressions for direct modification. Note that the key fields of the primary table key of sorted and hashed tables are always read-only. If you try to modify a key field, a runtime error occurs. However, this is not checked until runtime.
-
-The following examples demonstrate direct modification of recently read table lines:
-``` abap
-"Table declarations
-
-DATA it_st TYPE TABLE OF struc WITH NON-UNIQUE KEY a.
-
-DATA it_so TYPE SORTED TABLE OF struc WITH UNIQUE KEY a.
-
-"Reading table line into target area
-
-READ TABLE it_st ASSIGNING FIELD-SYMBOL() INDEX 1.
-
-READ TABLE it_so REFERENCE INTO DATA(dref) INDEX 2.
-
-"Modification examples
-"Modifying the entire table line while keeping the values of other components;
-"this way is not possible for it_so because of key value change.
-
- = VALUE #( BASE a = 1 b = 2 ).
-
-"Modifying a single component via field symbol
-
--c = 3.
-
-"Modification via dereferencing
-
-ref->b = 4.
-
-"Table expressions
-
-it_st[ 1 ] = VALUE #( a = 1 b = 2 ).
-
-it_st[ 2 ]-c = 3.
-
-"Sorted table: no key field change
-
-it_so[ 2 ]-d = 4.
-```
-
-> **💡 Note**
-> If you want to modify recently read lines in a work area, for example, within a loop (`LOOP AT INTO dobj`), you can modify the line and then use a `MODIFY` statement to modify the internal table based on this line.
-
-[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_itab.htm)
-statements provide multiple ways of changing the content of single and multiple table lines by specifying the table key or a table index,
-without first reading the lines into a target area.
-
-``` abap
-"Addition FROM ...; specified key values determine the line to be modified
-
-"line: existing line including key values
-MODIFY TABLE it FROM line.
-
-"line constructed inline
-MODIFY TABLE it FROM VALUE #( a = 1 b = 2 ... ).
-
-"Respecting only specified fields with the addition TRANSPORTING
-"In case of sorted/hashed tables, key values cannot be specified.
-MODIFY TABLE it FROM line TRANSPORTING b c.
-
-"Modification via index
-"Note that it is only MODIFY, not MODIFY TABLE.
-"Example: It modifies the line with number 1 in the primary table index.
-MODIFY it FROM line INDEX 1.
-
-"Without the addition TRANSPORTING, the entire line is changed.
-"Example: It modifies specific values.
-MODIFY it FROM line INDEX 1 TRANSPORTING b c.
-
-"USING KEY addition
-"If the addition is not specified, the primary table key is used;
-"otherwise, it is the explicitly specified table key that is used.
-"Example: It is the same as MODIFY it FROM line INDEX 1.
-MODIFY it FROM line USING KEY primary_key INDEX 1.
-
-"The statement below uses a secondary key and an index specification
-"for the secondary table index. Only specific fields are modified.
-MODIFY it FROM line USING KEY sec_key INDEX 1 TRANSPORTING c d.
-
-"Modifying multiple lines in internal tables
-"All lines matching the logical expression in the WHERE clause are modified
-"as specified in line.
-"The additions TRANSPORTING and WHERE are both mandatory; USING KEY is optional.
-MODIFY it FROM line TRANSPORTING b c WHERE a < 5.
-```
-> **💡 Note**
-> - The system field `sy-subrc` is set to `0` if at least one line was changed. It is set to `4` if no lines were changed.
-> - `MODIFY`, `DELETE`, and `INSERT` statements can be specified with and without the `TABLE` addition. With `TABLE` means an index access. Without `TABLE` means an access via the table key.
-
-
-
-## Deleting Internal Table Content
-
-You can use [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdelete_itab.htm) statements to delete single and multiple lines in internal tables. The following additions can be used: `USING KEY` (for specifying a table key), `FROM`/`TO` (for specifying row ranges), `STEP` (for specifying the step size), and `WHERE` (for specifying conditions).
-
-``` abap
-"Deleting via index
-"Example: The first line in the table is deleted.
-DELETE it INDEX 1.
-
-"If USING KEY is not used, INDEX can only be used with index tables.
-"If doing so, it determines the line from the primary table index.
-"If a secondary key is specified, the secondary table index is respected
-"Example: same as above
-DELETE it INDEX 1 USING KEY primary_key.
-
-"Deleting an index range; FROM or TO alone can also be specified
-DELETE it FROM 2 TO 5.
-
-"Deleting via keys
-"The line must have a compatible type to the tables line type and
-"include key values. The first found line with the corresponding keys
-"is deleted.
-"If the key is empty, no line is deleted.
-DELETE TABLE it FROM line.
-
-"Instead of specifying the keys using a data object ("line" above),
-"the keys can be specified separately. All key values must be specified.
-"Example: Respects keys from primary table index.
-DELETE TABLE it WITH TABLE KEY a = 1.
-
-"You can also specify secondary keys.
-"Example: Same as above
-DELETE TABLE it WITH TABLE KEY primary_key COMPONENTS a = 1.
-
-DELETE TABLE it_sec WITH TABLE KEY sec_key COMPONENTS ...
-
-"Deleting multiple lines based on a WHERE condition
-"Specifying the additions USING KEY, FROM, TO is also possible.
-DELETE it WHERE a < 6.
-
-"Excursion: Deleting in a LIKE-like fashion you may know from
-"ABAP SQL statements.
-"The LIKE addition is not available for the WHERE clause in DELETE
-"statements for internal tables as is the case for ABAP SQL DELETE statements.
-DATA(str_table) = VALUE string_table( ( `abcZ` ) ( `Zdef` ) ( `gZhi` )
- ( `Zjkl` ) ( `Zmno` ) ( `pqrZ` ) ).
-
-"You can, for example, use logical operators such as CP (conforms to pattern)
-"All lines that begin with Z are to be deleted.
-DELETE str_table WHERE table_line CP `Z*`.
-"Result: abcZ / gZhi / pqrZ
-```
-
-`DELETE ADJACENT DUPLICATES` statements allow you to delete all adjacent lines except for the first line that have the same content in certain components. You usually need to perform some appropriate sorting before using these statements.
-``` abap
-"Implicitly using the primary table key
-DELETE ADJACENT DUPLICATES FROM it.
-
-"Deletion respecting the values of the entire line
-DELETE ADJACENT DUPLICATES FROM it COMPARING ALL FIELDS.
-
-"Only lines are deleted with matching content in specific fields
-DELETE ADJACENT DUPLICATES FROM it COMPARING a c.
-
-"Deletion respecting a specified table key
-"Same as first example above
-DELETE ADJACENT DUPLICATES FROM it USING KEY primary_key.
-
-DELETE ADJACENT DUPLICATES FROM it USING KEY sec_key.
-```
-
-> **💡 Note**
-> The system field `sy-subrc` is set to `0` if at least one line has been deleted. It is set to `4` if no lines were deleted.
-
-The
-[`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm)
-and
-[`FREE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfree_dataobject.htm)
-statements allow you to delete the entire table content.
-
-The difference between the two is in the handling of the memory space originally allocated to the table. When a table is cleared with `CLEAR`,
-the content is removed, but the memory space initially requested remains
-allocated. If the table is filled again later, the memory space is still
-available, which is a performance advantage over
-clearing an internal table with `FREE`. Such a statement also
-deletes the table content, but it also releases the memory
-space.
-Note that an assignment using the `VALUE` operator without entries in the parentheses clears the internal table.
-
-``` abap
-CLEAR it.
-
-"This statement additionally releases memory space.
-FREE it.
-
-"Assignment using the VALUE operator without entries in the parentheses
-it = VALUE #( ).
-```
-
-
-## Excursions
-
-### Improving Read Performance with Secondary Table Keys
-
-The following example creates two demo internal tables. One without a secondary
-table key and the other with a secondary table key. Consider a scenario where you
-have an internal table without a secondary table key, and you want to add a secondary table key later to improve read performance. The tables are populated with a lot of data. Then, in a DO loop, many reads are performed on the internal tables. One example uses a free key for the read, the other uses a secondary table key. Before and after the reads, the current timestamp is stored in variables, from which the elapsed time is calculated. There should be a significant delta of the elapsed time.
-
-```abap
-CLASS zcl_some_class DEFINITION PUBLIC FINAL CREATE PUBLIC.
- PUBLIC SECTION.
- INTERFACES if_oo_adt_classrun.
- PROTECTED SECTION.
- PRIVATE SECTION.
-ENDCLASS.
-CLASS zcl_some_class IMPLEMENTATION.
- METHOD if_oo_adt_classrun~main.
- TYPES: BEGIN OF demo_struc,
- idx TYPE i,
- str TYPE string,
- num TYPE i,
- END OF demo_struc.
-
- DATA itab TYPE HASHED TABLE OF demo_struc WITH UNIQUE KEY idx.
- DATA itab_sec TYPE HASHED TABLE OF demo_struc
- WITH UNIQUE KEY idx
- WITH NON-UNIQUE SORTED KEY sk
- COMPONENTS str num.
-
- DO 500 TIMES.
- INSERT VALUE #( idx = sy-index
- str = |INDEX{ sy-index }|
- num = sy-index ) INTO TABLE itab.
- ENDDO.
- itab_sec = itab.
-
- DATA(ts1) = utclong_current( ).
- DO 500 TIMES.
- "Reading into a data reference variable using using a free key.
- "This key corresponds to the secondary table key specified for
- "the table in the second example.
- DATA(dref) = REF #( itab[ str = `INDEX250` num = 250 ] ).
- ENDDO.
- DATA(ts2) = utclong_current( ).
-
- cl_abap_utclong=>diff( EXPORTING high = ts2
- low = ts1
- IMPORTING seconds = DATA(seconds) ).
-
- out->write( `Elapsed time for the reads using a free key:` ).
- out->write( seconds ).
- out->write( `----------------------------------------------------------` ).
-
- ts1 = utclong_current( ).
- DO 500 TIMES.
- "Reading from an internal table using the secondary table key
- dref = REF #( itab_sec[ KEY sk str = `INDEX250` num = 250 ] ).
- ENDDO.
- ts2 = utclong_current( ).
-
- cl_abap_utclong=>diff( EXPORTING high = ts2
- low = ts1
- IMPORTING seconds = seconds ).
- out->write( `Elapsed time for the reads using a secondary table key:` ).
- out->write( seconds ).
- ENDMETHOD.
-ENDCLASS.
-```
-
-
-
-### Searching and Replacing Substrings in Internal Tables with Character-Like Data Types
-
-You can use [`FIND ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_itab.htm) statements to search for substrings in internal tables (standard tables without secondary table keys; with character-like line type) line by line.
-
-``` abap
-DATA(str_table) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
-
-"Finding all occurrences in a table
-"Note: res_tab is of type match_result_tab
-"You can also restrict the search range in an internal table; see an example in REPLACE ... IN TABLE
-FIND ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- RESULTS DATA(res_tab)
- RESPECTING CASE.
-
-"4 entries in table res_tab (tables in SUBMATCHES are initial since no regular expression is used)
-"1. line: 1, offset: 1, length: 1, submatches: (initial)
-"2. line: 1, offset: 4, length: 1, ...
-"3. line: 2, offset: 2, length: 1, ...
-"4. line: 3, offset: 0, length: 1, ...
-
-"Finding the first occurrence in a table
-"Note: res_struc, which is declared inline here, is of type match_result
-FIND FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- RESULTS DATA(res_struc)
- RESPECTING CASE.
-
-"Entries in structure res_struc
-"line: 1, offset: 1, length: 1, submatches: (initial)
-
-"Alternative to the statement above (storing the information in individual data objects)
-FIND FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- MATCH LINE DATA(line) "1
- MATCH OFFSET DATA(off) "1
- MATCH LENGTH DATA(len) "1
- RESPECTING CASE.
-```
-
-Replacements in internal tables with [`REPLACE ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace_itab.htm):
-
-``` abap
-DATA(str_table_original) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
-DATA(str_table) = str_table_original.
-
-"Replacing all occurrences in a table
-"RESULTS addition: Storing information in an internal table of type repl_result_tab
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- WITH `#`
- RESULTS DATA(res_table)
- RESPECTING CASE.
-
-"str_table: a#bz# / cd#ze / #zzf / ghz
-"res_table:
-"LINE OFFSET LENGTH
-"1 1 1
-"1 4 1
-"2 2 1
-"3 0 1
-
-str_table = str_table_original.
-
-"Replacing the first occurrence in a table
-"RESULTS addition: Storing information in a structure of type repl_result
-REPLACE FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- WITH `#`
- RESULTS DATA(res_structure)
- RESPECTING CASE.
-
-"str_table: a#bzZ / cdZze / Zzzf / ghz
-"res_structure:
-"LINE OFFSET LENGTH
-"1 1 1
-
-str_table = str_table_original.
-
-"Restricting the search range in an internal table
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- FROM 1 TO 2
- WITH `#`
- RESPECTING CASE.
-
-"str_table: a#bz# / cd#ze / Zzzf / ghz
-
-str_table = str_table_original.
-
-"Offsets can be optionally specified (also only the offset of start or end line possible)
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- FROM 1 OFFSET 3 TO 2 OFFSET 2
- WITH `#`
- RESPECTING CASE.
-
-"str_table: aZbz# / cdZze / Zzzf / ghz
-```
-
-
-
-### Ranges Tables
-
-- Internal tables that have the predefined columns `SIGN`, `OPTION`, `LOW`, and `HIGH`
-- Declared with the `TYPE RANGE OF` addition in `DATA` and `TYPES` statements
-- Used to store range conditions that can be evaluated in expressions using the `IN` operator (each row in the table represents a separate comparison)
-
-```abap
-"Populating an integer table with values from 1 to 20
-TYPES int_tab_type TYPE TABLE OF i WITH EMPTY KEY.
-DATA(inttab) = VALUE int_tab_type( FOR x = 1 WHILE x <= 20 ( x ) ).
-
-"Declaring a ranges table
-DATA rangestab TYPE RANGE OF i.
-
-"Populating a ranges table using VALUE
-rangestab = VALUE #( sign = 'I'
- option = 'BT' ( low = 1 high = 3 )
- ( low = 6 high = 8 )
- ( low = 12 high = 15 )
- option = 'GE' ( low = 18 ) ).
-
-"Using a SELECT statement and the IN addition to retrieve internal table
-"content based on the ranges table specifications
-SELECT * FROM @inttab AS tab
- WHERE table_line IN @rangestab
- INTO TABLE @DATA(result).
-"result: 1, 2, 3, 6, 7, 8, 12, 13, 14, 15, 18, 19, 20
-```
-
-
-
-## More Information
-Topic [Internal Tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab.htm) in the ABAP Keyword Documentation.
-
-## Executable Example
-[zcl_demo_abap_internal_tables](./src/zcl_demo_abap_internal_tables.clas.abap)
-
-> **💡 Note**
-> - The executable example covers the following topics, among others: Creating, populating, reading from, sorting, modifying internal tables
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+
+
+# Internal Tables
+
+- [Internal Tables](#internal-tables)
+ - [Introduction](#introduction)
+ - [Basic Properties of Internal Tables](#basic-properties-of-internal-tables)
+ - [Table Keys in Internal Tables (Primary, Secondary, Standard, Empty)](#table-keys-in-internal-tables-primary-secondary-standard-empty)
+ - [Creating Internal Tables and Types](#creating-internal-tables-and-types)
+ - [Filling and Copying Internal Tables](#filling-and-copying-internal-tables)
+ - [Excursions with Internal Tables](#excursions-with-internal-tables)
+ - [Reading from Internal Tables](#reading-from-internal-tables)
+ - [Processing Multiple Internal Table Lines Sequentially](#processing-multiple-internal-table-lines-sequentially)
+ - [Iteration Expressions](#iteration-expressions)
+ - [Sorting Internal Tables](#sorting-internal-tables)
+ - [Modifying Internal Table Content](#modifying-internal-table-content)
+ - [Deleting Internal Table Content](#deleting-internal-table-content)
+ - [Excursions](#excursions)
+ - [Improving Read Performance with Secondary Table Keys](#improving-read-performance-with-secondary-table-keys)
+ - [Searching and Replacing Substrings in Internal Tables with Character-Like Data Types](#searching-and-replacing-substrings-in-internal-tables-with-character-like-data-types)
+ - [Ranges Tables](#ranges-tables)
+ - [More Information](#more-information)
+ - [Executable Example](#executable-example)
+
+
+## Introduction
+
+Internal Tables ...
+
+- are [dynamic data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_data_object_glosry.htm), i.e. all properties apart from the memory consumption are determined statically by the [data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_type_glosry.htm).
+- consist of a variable sequence of lines of the same data type.
+- have a [table type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_type_glosry.htm) as its data type (it is a [complex data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplex_data_type_glosry.htm)), which defines the following properties:
+ - [line type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrow_type_glosry.htm)
+ - [table category](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_category_glosry.htm)
+ - [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm)
+- are used when a variable data set of a random data type needs to be processed in a structured way.
+- allow access to individual table lines via a [table index](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_index_glosry.htm) or a [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm).
+
+
+
+## Basic Properties of Internal Tables
+
+
+ Expand to view the details
+
+
+**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. an [elementary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm) or complex data type as well as a [reference type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_type_glosry.htm).
+- In most cases, the line type is [structured](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructured_type_glosry.htm). In this case, the individual components of a line are also referred to as the columns of the internal table.
+- In a simple case, the line consists of a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm) with elementary data objects; however, it can also be a [deep structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm) whose components can be structures themselves or even internal tables.
+
+**Table Category**
+
+- Defines how internal tables are managed and stored internally, and how to access individual table entries.
+- Why is it relevant? The use of a suitable table category should meet your requirements, i.e. if the internal tables are large, the different categories can have significant performance differences when accessing table content.
+- Note: There are two ways to access internal tables:
+ - Access by table index: A line of an internal table is accessed by its line number. This kind of access is the fastest way to access table lines.
+ - Access by table key: A line of an internal table is accessed by searching for specific values in specific columns. Note: The columns in which you search can be key columns, but they can also be non-key columns.
+
+
+| Category | Internally managed by | Access | Primary table key | When to use | Hints |
+|---|---|---|---|---|---|
+|`STANDARD`|Primary table index (that's why these tables are called [index tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenindex_table_glosry.htm))|
Table index
Table key
|
Always non-unique, i.e. duplicate entries are always allowed
Definition of an empty key is possible if the key is not relevant(`WITH EMPTY KEY`)
|
If you primarily access the table content for sequential processing or via the table index.
Response time for accessing the table using the primary key: This kind of table access is optimized only for sorted and hashed tables. For standard tables, primary key access uses a linear search across all lines. That means that large standard tables (more than 100 lines) are not ideal if the you primarily access the table using the table key.>
|
There is no particular sort order, but the tables can be sorted using `SORT`.
Filling this kind of table: Lines are either appended at the end of the table or inserted at a specific position.
[Secondary table keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm) can be defined to make key access to standard tables more efficient.
Standard and sorted tables have the least [administration costs (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenadmin_costs_dyn_mem_obj_guidl.htm).
|
+|`SORTED`|Primary table index (that's why these tables are called [index tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenindex_table_glosry.htm))|
Table index
Table key
|
Non-unique
Unique
... used to sort the table in ascending order.
|
Enables an optimized access to table content using table key and index.
If access via table key is the main access method, but no unique key can be defined.
|
Sorting is done automatically when lines are inserted or deleted. As a consequence, the table index must usually be reorganized.
The response time for accessing the table using the primary key depends logarithmically on the number of table entries, since a binary search is used.
Standard and sorted tables have the least administration costs.
Optimized for key access. Access to table content via table key is the main access method and a unique key can be defined.
|
The response time for primary key access is constant and independent of the number of entries in the table.
Hashed tables have the highest administration costs.
|
+
+
+
+**Key Attributes**
+
+- There are two types of table keys: a [primary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_table_key_glosry.htm) and [secondary table keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm).
+- Table keys ...
+ - are intended to provide an optimized access to the content of internal tables.
+ - are either unique or non-unique, i.e. more than one line with the same key (duplicates) can exist in the internal table or not. Regarding the primary table key, the definition depends on the table category. For the secondary table key, the definition depends on the key type. For standard tables, the primary table key can also be defined as empty, i.e. it does not contain any key columns. Note that for standard tables, an optimized access is only possible with secondary table keys.
+ - Type of keys:
+ - Sorted keys:
+ - Are either the primary table keys of sorted tables or the secondary table keys of any table.
+ - Are managed internally by a table index. In the case of sorted tables, this is the primary table index. In the case of secondary table keys, a secondary table index is added.
+ - Access via sorted keys means an optimized binary search.
+ - Hashed keys:
+ - Are either the primary table key of hashed tables or secondary table keys of any table.
+ - Internally managed by a hash algorithm.
+ - There is no table index for a hashed key.
+
+**Further information**
+- [Internal Tables - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab_oview.htm)
+- [Programming guidelines: Internal Tables (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenadmin_costs_dyn_mem_obj_guidl.htm)
+
+
+
+
+## Table Keys in Internal Tables (Primary, Secondary, Standard, Empty)
+
+
+ Expand to view the details
+
+
+**Primary table key**
+
+- Each internal table has a primary table key.
+- Can be either a self-defined key or the [standard key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_key_glosry.htm).
+- The primary table key is ...
+ - sorted for sorted tables.
+ - hashed for hashed tables.
+- Note that the key fields in sorted and hashed tables are read-only. This is not valid for standard tables.
+- The specification of the primary key can be omitted only for standard tables. The primary table key is then automatically defined as a non-unique standard key.
+- The primary table key has the predefined name `primary_key`, by which it can also be addressed explicitly. However, its use is optional, and it is usually not necessary to specify it explicitly. You can also specify an alias name for the primary key.
+- When accessing internal tables using the table key, the primary key is always used implicitly in processing statements if no secondary key is specified. Note that the primary table key must be specified in table expressions if the primary key is to be used explicitly.
+
+> **💡 Note**
+> The key can consist of individual key fields or the entire line of the internal table. In this case, the pseudo component `table_line` can be used to denote the primary table key. For non-structured line types, this is the only way to define the key.
+
+**Standard key**
+- The [standard key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_key_glosry.htm) is a special primary table key.
+- It can be declared either explicitly or implicitly.
+- Standard key of an internal table with a ...
+ - structured line type: The primary table key consists of all fields with character-like and byte-like data types.
+ - non-structured/elementary line type: The entire table is the key (`table_line`).
+- An internal table with no explicit key specification implicitly has the standard table key as the primary table key.
+- Why respecting standard keys is important:
+ - Sorting of a table can produce unexpected results.
+ - Since the standard key can consist of many fields, it affects the performance when accessing the internal table via the keys.
+ - The key fields of the primary table key of sorted and hashed tables are always read-only, i.e. using the standard key with these table categories and then (unintentionally) modifying fields can cause unexpected runtime errors.
+ - Specifying keys explicitly has the advantage of making the code more readable and preventing the standard key from being set by mistake.
+
+**Empty key**
+- The primary table key of a standard table can be empty, i.e. it does not contain any key fields.
+- An empty key is not possible for sorted and hashed tables.
+- When used:
+ - When the definition of a table key is not important.
+ - To explicitly state that a table key is not required, instead of specifying no key definition. Otherwise, the standard key is used, which can lead to unexpected results as mentioned above.
+- Declaration:
+ - Explicit declaration using the addition `EMPTY KEY`.
+ - Implicit declaration when using the standard key if a structured
+ line type does not contain non-numeric elementary components or
+ if an unstructured line type is tabular.
+ - Note: When using an [inline declaration](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry") such as `... INTO TABLE @DATA(itab) ...` in `SELECT` statements, the resulting table is a standard table and has an empty key.
+
+**Secondary table keys**
+
+- Secondary table keys ...
+ - are optional for all table categories.
+ - can be unique/non-unique sorted keys or unique hash keys.
+ - have a self-defined name. An alias name can also be specified.
+- A secondary table index is created internally for each sorted secondary key. This allows index access to hashed tables via the secondary table key. In this case, `sy-tabix` is set.
+- When accessing internal tables using the secondary table key, the key name (or the alias if specified) must be specified. They are not selected automatically. If no secondary key is specified in a processing statement, the primary key or primary table index is always used. If you want to make use of this key in ABAP statements, for example, `READ`, `LOOP AT` or `MODIFY` statements, you must specify the key explicitly using the appropriate additions, for example, `WITH ... KEY ... COMPONENTS` or `USING KEY`.
+- Use cases:
+ - To improve read performance.
+ - For very large internal tables (that are filled once and changed very often)
+ - Standard tables, whose primary table keys cannot be unique, can be provided with a means of ensuring that unique table entries are read.
+ - Note that defining secondary table keys involves additional administration costs (additional memory consumption). Therefore, the use of secondary table keys should be reserved for cases where the benefits outweigh the extra costs.
+- For more details, see the programming guidelines for secondary keys: [Secondary
+ Key (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensecondary_key_guidl.htm "Guideline").
+
+> **💡 Note**
+> - See examples of internal table declarations using the table keys mentioned above in the following section.
+> - See an example that uses secondary table keys [below](#improving-read-performance-with-secondary-table-keys).
+
+
+
+
+
+
+## Creating Internal Tables and Types
+
+You can declare internal tables and internal table types in [ABAP programs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm) using the [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm) and [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) statements. The relevant syntax elements for internal tables are `TABLE OF` in combination
+with the additions [`TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_simple.htm)
+or [`LIKE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_referring.htm).
+
+``` abap
+TYPES itab_type1 TYPE STANDARD TABLE OF data_type ... "Standard table type
+TYPES itab_type2 LIKE SORTED TABLE OF data_object ... "Sorted table type
+
+DATA itab1 TYPE TABLE OF data_type ... "Standard table by default
+DATA itab2 TYPE HASHED TABLE OF data_type ... "Hashed table
+DATA itab3 TYPE itab_type1 ... "Based on an existing internal table type
+DATA itab4 LIKE itab1 ... "Based on an existing internal table
+```
+
+> **💡 Note**
+> If the table category is not specified (`... TYPE TABLE OF ...`), it is automatically `... TYPE STANDARD TABLE OF ...`.
+
+The following code snippet contains various internal table declarations. It is intended to demonstrate a selection of the rich variety of possible internal tables mentioned in the previous sections, e.g. in *Table Keys in Internal Tables*.
+In the examples, the internal tables are created using the structured type of a demo database table in the DDIC. The line type of the database table is automatically used when defining an internal table.
+
+
+``` abap
+"------------------ Standard table key ------------------
+
+"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_fli.
+
+"Explicitly specifying STANDARD for a standard table.
+"Explicitly specifying the standard table key. It is the same as it1.
+DATA it2 TYPE STANDARD TABLE OF zdemo_abap_fli WITH DEFAULT KEY.
+
+"Hashed table with unique standard table key
+DATA it3 TYPE HASHED TABLE OF zdemo_abap_fli WITH UNIQUE DEFAULT KEY.
+
+"Sorted table with non-unique standard table key
+DATA it4 TYPE SORTED TABLE OF zdemo_abap_fli WITH NON-UNIQUE DEFAULT KEY.
+
+"Elementary line type; the whole table line is the standard table key
+DATA it5 TYPE TABLE OF i.
+
+"------------------ Primary table key ------------------
+
+"Specifying the primary table key
+"Standard tables: only a non-unique key possible
+"The following two examples are the same. NON-UNIQUE can be ommitted but is implicitly added.
+DATA it6 TYPE TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid.
+DATA it7 TYPE TABLE OF zdemo_abap_fli WITH KEY carrid.
+
+"Sorted tables: both UNIQUE and NON-UNIQUE possible
+DATA it8 TYPE SORTED TABLE OF zdemo_abap_fli WITH UNIQUE KEY carrid connid.
+DATA it9 TYPE SORTED TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid connid cityfrom.
+
+"Hashed tables: UNIQUE KEY must be specified
+DATA it10 TYPE HASHED TABLE OF zdemo_abap_fli WITH UNIQUE KEY carrid.
+
+"Explicitly specifying the predefined name primary_key and listing the components.
+"The example is the same as it6 and it7.
+DATA it11 TYPE TABLE OF zdemo_abap_fli WITH KEY primary_key COMPONENTS carrid.
+
+"The following example is the same as it9.
+DATA it12 TYPE SORTED TABLE OF zdemo_abap_fli
+ 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 it13 TYPE SORTED TABLE OF zdemo_abap_fli
+ 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 it14 TYPE HASHED TABLE OF zdemo_abap_fli
+ WITH UNIQUE KEY primary_key
+ ALIAS p2 COMPONENTS table_line.
+
+"------------------ Empty key ------------------
+
+"Empty keys only possible for standard tables
+DATA it15 TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
+
+"Excursion: The inline declaration in a SELECT statement produces a standard table with empty key.
+SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(it16).
+
+"------------------ Secondary table key ------------------
+
+"The following examples demonstrate secondary table keys that are possible for all table categories.
+DATA it17 TYPE TABLE OF zdemo_abap_fli "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_fli "hashed table
+ WITH UNIQUE KEY carrid connid
+ WITH NON-UNIQUE SORTED KEY airports COMPONENTS airpfrom airpto.
+
+DATA it19 TYPE SORTED TABLE OF zdemo_abap_fli "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_fli
+ 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_fli
+ WITH NON-UNIQUE KEY primary_key ALIAS k1 COMPONENTS carrid connid city
+ WITH NON-UNIQUE SORTED KEY cities ALIAS s1 COMPONENTS cityfrom cityto
+ WITH UNIQUE HASHED KEY airports ALIAS s2 COMPONENTS airpfrom airpto.
+
+"Example for 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.
+```
+
+As mentioned, the examples above demonstrate internal tables that are created using the structured type of a database table in the DDIC.
+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.
+
+Steps:
+1. Define a structured data type (locally or globally).
+ This is not necessary if you use, for example, the name of a database table or [CDS view](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm) in the internal table declaration. In these cases their line type is used automatically.
+2. Define an internal table type.
+3. Create the internal table, i.e. a data object that uses this type.
+
+You can also create an internal table by ...
+- combining the data object creation and table type definition in one step.
+- using an [inline declaration](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry"). Such inline declarations are possible at suitable [declaration
+positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeclaration_positions.htm)
+if the operand type can be fully determined, for example, using a
+`DATA` statement (or [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) for immutable variables).
+
+
+``` abap
+"1. Defining line type locally
+
+TYPES: BEGIN OF ls_loc,
+ key_field TYPE i,
+ char1 TYPE c LENGTH 10,
+ char2 TYPE c LENGTH 10,
+ num1 TYPE i,
+ num2 TYPE i,
+ END OF ls_loc.
+
+"2. Defining internal table types
+"All of the examples use the short form:
+
+TYPES:
+ "Standard table type based on locally defined structure type.
+ tt_loc_str TYPE TABLE OF ls_loc WITH NON-UNIQUE KEY key_field,
+
+ "Based on global structure type
+ tt_gl_str TYPE TABLE OF zsome_global_struc_type WITH NON-UNIQUE KEY key_field,
+
+ "Based on database table (could also be, e. g. a CDS view)
+ "In this case, the line type of the table is automatically used.
+ tt_gl_tab TYPE TABLE OF zdemo_abap_fli WITH NON-UNIQUE KEY carrid,
+
+ "Based on an elementary type
+ tt_el_type TYPE TABLE OF i.
+
+"3. Creating internal tables ...
+"... from locally defined table types
+DATA: itab_a1 TYPE tt_loc_str,
+ itab_a2 TYPE tt_gl_str,
+ itab_a3 TYPE tt_gl_tab,
+ itab_a4 TYPE tt_el_type.
+
+"... from global internal table types
+DATA itab_a5 TYPE string_table.
+
+"Combining data object and table type definition
+DATA itab_a6 TYPE TABLE OF ls_loc WITH NON-UNIQUE KEY key_field.
+
+"Internal table based on an already existing internal table using LIKE.
+"Here, an internal table is created containing internal tables of the
+"type of itab_a6.
+DATA itab_a7 LIKE TABLE OF itab_a6.
+
+"Creating internal tables by inline declarations
+
+"Table declared inline in the context of an assignment
+"The examples show the copying of a table including the content on the fly
+"and creating the table in one step. The data type of the
+"declared variable is determined by the right side.
+DATA(it_inline1) = itab_a1.
+DATA(it_inline2) = it_inline1.
+
+"Using FINAL for creating immutable variables
+FINAL(it_final) = it_inline1.
+
+"Using the VALUE operator and an internal table type
+DATA(it_inline3) = VALUE tt_loc_str( ( ... ) ).
+
+"Table declared inline in the context of a SELECT statement;
+"a prior extra declaration of an internal table is not needed.
+SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(it_inline4).
+
+"Instead of
+DATA it_sel TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
+SELECT * FROM zdemo_abap_fli INTO TABLE @it_sel.
+
+"Using FINAL
+SELECT * FROM zdemo_abap_fli INTO TABLE @FINAL(it_inline5).
+```
+
+
+
+## Filling and Copying Internal Tables
+
+You can use the ABAP keywords
+[`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_itab.htm)
+and [`APPEND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapappend.htm)
+to add lines to internal tables.
+
+
+ Notes on using APPEND and INSERT
+
+
+- `APPEND` ...
+ - always adds lines at the bottom of the internal table.
+ - is not a problem for standard tables where lines are managed
+ by an index. When the statement is used, the system field
+ `sy-tabix` is set to the index of the recently added
+ line. `sy-tabix` is always set to the index with respect
+ to the primary table index.
+ - cannot be used for hashed tables. For sorted tables,
+ lines are appended only if they match the sort order, and no
+ duplicate entries are created if the primary table key is unique.
+ Therefore, `INSERT` should be used when adding lines to
+ sorted tables.
+- `INSERT` ...
+ - can be used to add lines at a specific position in tables (by
+ specifying the target index). In doing so, all the following
+ lines are moved down one position.
+ - without specifying the position adds the lines at the bottom of
+ the table in case of standard tables. However, when using
+ `INSERT`, `sy-tabix` is not set unlike
+ `APPEND`. In case of sorted tables, the line is
+ automatically inserted at the correct position.
+ - With `INSERT`, you can specify the position in the internal table at which lines are inserted after `INTO`.
+ - `... INTO TABLE itab ...`: Line is inserted in ...
+ - standard tables as last line (i.e. appended)
+ - sorted tables in the sort order in accordance with primary key values
+ - hashed table by the hash administration in accordance with primary key values
+ - `... INTO itab INDEX n`: Possible for index tables. The line is inserted before the line with the line number `n` in the primary table index.
+ - Note: In the case of unique primary table keys, the table cannot have entries with duplicate
+ keys. If a duplicate is inserted, the insertion fails and the
+ system field `sy-subrc` is set to 4.
+- What to use? The recommendation is the `INSERT` statement. It covers all table and key types. Consider potential issues when you change table/key types, and you use `APPEND` in your code.
+
+
+
+**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 lv_struc TO itab.
+
+INSERT VALUE #( comp1 = a comp2 = b ... ) INTO TABLE itab.
+INSERT lv_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().
+APPEND INITIAL LINE TO itab ASSIGNING .
+INSERT INITIAL LINE INTO TABLE itab REFERENCE INTO DATA(dref).
+```
+
+**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
+"i1/i2 represent integer values
+
+APPEND LINES OF itab2 FROM i1 TO i2 TO itab.
+
+APPEND LINES OF itab2 FROM i1 TO itab.
+
+APPEND LINES OF itab2 TO i2 TO itab.
+
+INSERT LINES OF itab2 FROM i1 TO i2 INTO 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 lv_struc INTO itab2 INDEX i.
+
+INSERT LINES OF itab2 INTO itab INDEX i.
+```
+
+
+
+**Adding lines using constructor expressions**
+
+As mentioned above, table lines that are constructed inline as
+arguments to the `VALUE` operator, for example, can be added to
+internal tables. In the following cases, internal tables are populated
+using constructor expressions in the context of
+[assignments](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_glosry.htm "Glossary Entry").
+
+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.
+
+``` 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 ... ) ).
+```
+
+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.
+
+``` 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.
+``` abap
+itab = VALUE #( ( comp1 = a comp2 = b ...)
+ ( comp1 = a comp2 = b ...)
+ ( LINES OF itab2 )
+ ... ).
+```
+A simple assignment without a constructor expression that **copies the content of another internal table** (note that the existing content in `itab` are deleted). The example below assumes that the source and target table have compatible line types.
+``` abap
+itab = itab2.
+```
+> **💡 Note**
+> - Internal tables can only be assigned to internal tables.
+> - Internal tables can be assigned to each other if their line types are [compatible](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencompatible_glosry.htm) or [convertible](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconvertible_glosry.htm).
+> - 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)
+
+**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**.
+- 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.
+```
+
+
+
+### Excursions with Internal Tables
+For more details on ABAP SQL, see the cheat sheet on [ABAP SQL](03_ABAP_SQL.md).
+
+**Adding multiple lines from a database table to an internal table** using
+[`SELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm),
+for example, based on a condition. In the case below, the internal table
+is created inline.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2 ...
+ WHERE ...
+ INTO TABLE @DATA(itab_sel).
+```
+
+**Sequentially adding 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 that can be further processed and added to an internal table.
+
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2 ...
+ WHERE ...
+ INTO @DATA(struc_sel).
+
+ IF sy-subrc = 0.
+ APPEND struc_sel TO itab.
+ ...
+ ENDIF.
+ENDSELECT.
+```
+
+Adding multiple lines from a database table using `SELECT`, for example, based on a condition when the database table has a line type that is incompatible with the internal table. The `*` character means that all fields are selected. The other examples define specific fields.
+The `APPENDING CORRESPONDING FIELDS INTO TABLE` addition appends the selected data to the end of the table without deleting existing
+table entries. The `INTO CORRESPONDING FIELDS OF TABLE` addition adds lines and deletes existing table entries.
+``` abap
+SELECT FROM dbtab2
+ FIELDS *
+ WHERE ...
+ APPENDING CORRESPONDING FIELDS OF TABLE @itab.
+
+SELECT FROM dbtab2
+ FIELDS *
+ WHERE ...
+ INTO CORRESPONDING FIELDS OF TABLE @itab.
+```
+Adding multiple lines from an internal table to another internal table using `SELECT`. Note the alias name that must be defined for the
+internal table.
+``` abap
+SELECT comp1, comp2, ...
+ FROM @itab2 AS it_alias
+ INTO TABLE @DATA(itab_sel).
+```
+
+**Combining data from multiple tables into one internal table** using an [inner
+join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninner_join_glosry.htm "Glossary Entry").
+The following example joins data of an internal and a database table
+using a `SELECT` statement and the [`INNER JOIN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_join.htm) addition. Note that the field list includes fields from both tables. The fields are referred to using `~`.
+``` abap
+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).
+```
+
+Filling an internal table from a database table using
+[subqueries](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry").
+The following two examples fill an internal table from a database table. In the first example, a subquery is specified in the
+`WHERE` clause with the `NOT IN` addition. It checks whether a value matches a value in a set of values
+specified in parentheses. The second example fills an internal table depending on data in another table. A subquery with the `EXISTS` addition is specified in
+the `WHERE` clause. In this
+case, the result of the subquery, which is another
+`SELECT` statement, is checked to see if an entry exists in
+a table based on the specified conditions.
+
+``` abap
+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).
+```
+
+Filling internal table from a table based on the existence of data in
+another table using the [`FOR ALL ENTRIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm) addition.
+
+> **💡 Note**
+> Make sure that the internal table you are reading from is not initial. Therefore, it is recommended that you use a subquery as shown above: `... ( SELECT ... FROM @itab AS itab_alias WHERE ...`).
+
+``` abap
+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.
+```
+
+**Using the `FILTER` operator**
+
+To create an internal table by copying data from another internal table and
+filtering out lines that do not meet the `WHERE` condition, you can use the [`FILTER`
+operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_filter.htm).
+
+- The
+ `FILTER` operator constructs an internal table according to a specified type (which can be an explicitly specified, non-generic table type or the `#` character as a symbol for the [operand type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_type_glosry.htm) before the first parenthesis).
+- The lines for the new internal table are taken from an
+ existing internal table based on conditions specified in a `WHERE` clause. Note that the table type of the existing internal table must be convertible into the specified target type.
+- The conditions can be based on either single values or a [filter
+ table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_filter_table.htm).
+- Additions:
+
+|Addition |Details |
+|---|---|
+|`USING KEY` | Specifies the [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm "Glossary Entry") used to evaluate the `WHERE` condition: either a [sorted key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensorted_key_glosry.htm "Glossary Entry") or a [hash key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhash_key_glosry.htm "Glossary Entry"). If the internal table does not have either of these, it must have a [secondary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm "Glossary Entry"), which must be specified after `USING KEY`. |
+| `EXCEPT` | Specifying `EXCEPT` means that those lines of the existing table are used that do not meet the condition specified in the `WHERE` clause. If `EXCEPT` is not specified, those lines of the existing table that meet the condition are used. |
+
+Examples:
+```abap
+"FILTER on conditions based on single values
+"Assumption: The component num is of type i.
+DATA itab1 TYPE SORTED TABLE OF struc WITH NON-UNIQUE KEY num.
+DATA itab2 TYPE STANDARD TABLE OF struc WITH NON-UNIQUE SORTED KEY sec_key COMPONENTS num.
+DATA itab3 TYPE HASHED TABLE OF struc WITH UNIQUE KEY num.
+
+"The lines meeting the condition are respected.
+"Note: The source table must have at least one sorted or hashed key.
+"Here, the primary key is used
+DATA(f1) = FILTER #( itab1 WHERE num >= 3 ).
+
+"USING KEY primary_key explicitly specified; same as above
+DATA(f2) = FILTER #( itab1 USING KEY primary_key WHERE num >= 3 ).
+
+"EXCEPT addition
+DATA(f3) = FILTER #( itab1 EXCEPT WHERE num >= 3 ).
+DATA(f4) = FILTER #( itab1 EXCEPT USING KEY primary_key WHERE num >= 3 ).
+
+"Secondary table key specified after USING KEY
+DATA(f5) = FILTER #( itab2 USING KEY sec_key WHERE num >= 4 ).
+DATA(f6) = FILTER #( itab2 EXCEPT USING KEY sec_key WHERE num >= 3 ).
+
+"Note: In case of a hash key, exactly one comparison expression for each key component is allowed;
+"only = as comparison operator possible.
+DATA(f7) = FILTER #( itab3 WHERE num = 3 ).
+
+"Using a filter table
+"In the WHERE condition, the columns of source and filter table are compared.
+"Those lines in the source table are used for which at least one line in the filter
+"table meets the condition. EXCEPT and USING KEY are also possible.
+
+DATA filter_tab1 TYPE SORTED TABLE OF i
+ WITH NON-UNIQUE KEY table_line.
+
+DATA filter_tab2 TYPE STANDARD TABLE OF i
+ WITH EMPTY KEY
+ WITH UNIQUE SORTED KEY line COMPONENTS table_line.
+
+DATA(f8) = FILTER #( itab1 IN filter_tab1 WHERE num = table_line ).
+
+"EXCEPT addition
+DATA(f9) = FILTER #( itab1 EXCEPT IN filter_tab1 WHERE num = table_line ).
+
+"USING KEY is specified for the filter table
+DATA(f10) = FILTER #( itab2 IN filter_tab2 USING KEY line WHERE num = table_line ).
+
+"USING KEY is specified for the source table, including EXCEPT
+DATA(f11) = FILTER #( itab2 USING KEY sec_key EXCEPT IN filter_tab2 WHERE num = table_line ).
+```
+
+**Collecting values**
+
+Use the
+[`COLLECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcollect.htm)
+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.
+``` abap
+COLLECT VALUE dtype( comp1 = a comp2 = b ... ) INTO itab.
+```
+
+
+
+## Reading from Internal Tables
+
+There are three different ways to specify the line to read:
+
+- by index (only index tables)
+- by table keys (only tables for which a key is defined)
+- by free key
+
+The following code snippets include [`READ TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_table.htm) statements and [table expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expressions.htm) to read from internal tables.
+
+**Reading single lines**
+
+*Determining the target area*
+
+- Copying a line to a data object using the addition `INTO`.
+ After the copying, the line found exists separately in the internal table and
+ in the data object. If you change the
+ data object or the table line, the change does not affect the other.
+ However, you can modify the copied table line and use a
+ `MODIFY` statement to modify the table based on the modified
+ table line (see below). The `TRANSPORTING` addition
+ specifies which components to copy. If
+ it is not specified, all components are respected.
+ ``` abap
+ READ TABLE itab INTO dobj ... "dobj must have the table's structure type
+
+ READ TABLE itab INTO DATA(dobj_inl) ...
+
+ READ TABLE itab INTO ... TRANSPORTING comp1 [comp2 ... ].
+ ```
+
+- Assigning a line to a [field
+ symbol](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm "Glossary Entry"),
+ for example, using an inline declaration (`ASSIGNING `). When you then access the field symbol, it means that you access the found table line. There is no actual copying of
+ content. Therefore, modifying the field symbol means
+ modifying the table line directly. Note that you cannot use the
+ `TRANSPORTING` addition since the entire table is
+ assigned to the field symbol.
+
+ ``` abap
+ READ TABLE itab ASSIGNING ... "The field symbol must have an appropriate type.
+
+ READ TABLE itab ASSIGNING FIELD-SYMBOL() ... "The field symbol is created inline.
+ ```
+
+- Reading a line into a [data reference
+ variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_variable_glosry.htm "Glossary Entry")
+ using `REFERENCE INTO`. In this case, no copying takes place. If you want to address the line, you must first [dereference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm) the data reference. You cannot use the addition `TRANSPORTING`.
+
+ ``` abap
+ READ TABLE itab REFERENCE INTO dref ...
+
+ READ TABLE itab REFERENCE INTO DATA(dref_inl) ...
+ ```
+
+**Which to use then?** Since all syntax options provide the same
+functionality, your use case, the
+performance or readability of the code may play a role. For more information, see
+the programming guidelines for the [target
+area (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentable_output_guidl.htm "Guideline").
+A use case for `INTO dobj` is when the table should
+not be changed using the copied table line. However, copying comes
+at a performance cost. Imagine that your table contains many columns or
+nested components. In this case, it is better not to copy at all (although you can use
+the `TRANSPORTING` addition to restrict the fields to be copied).
+
+
+
+*Reading a single line by index*
+
+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
+READ TABLE itab INTO wa INDEX i.
+
+READ TABLE itab INTO wa INDEX i USING KEY primary_key.
+```
+
+Using a [table
+expression](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 ] ).
+```
+
+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[ 8 ] ).
+```
+
+
+
+*Reading single lines using table keys*
+
+Lines can be read by explicitly specifying the table keys or the alias names, if any.
+```abap
+"Example internal table with primary and secondary table key and alias names
+"Assumption: All components are of type i
+
+DATA it TYPE SORTED TABLE OF struc
+ WITH NON-UNIQUE KEY primary_key ALIAS pk COMPONENTS a b
+ WITH NON-UNIQUE SORTED KEY sec_key ALIAS sk COMPONENTS c d.
+
+"Table expressions
+
+"Key must be fully specified
+line = it[ KEY primary_key COMPONENTS a = 1 b = 2 ].
+
+"The addition COMPONENTS is optional; same as above
+line = it[ KEY primary_key a = 1 b = 2 ].
+
+"Primary key alias
+line = it[ KEY pk a = 1 b = 2 ].
+
+"Secondary table key
+line = it[ KEY sec_key c = 3 d = 4 ].
+
+"Secondary table key alias
+line = it[ KEY sk c = 3 d = 4 ].
+
+"READ TABLE statements
+"Primary table key
+READ TABLE it INTO wa WITH TABLE KEY primary_key COMPONENTS a = 1 b = 2.
+
+"Alias
+READ TABLE it INTO wa WITH TABLE KEY pk COMPONENTS a = 1 b = 2.
+
+"Secondary table key
+READ TABLE it INTO wa WITH TABLE KEY sec_key COMPONENTS c = 3 d = 4.
+
+"Alias
+READ TABLE it INTO wa WITH TABLE KEY sk COMPONENTS c = 3 d = 4.
+
+"Reading a line based on keys specified in a work area
+"Work area containing primary and secondary table key values; the line type
+"must be compatible to the internal table
+DATA(pr_keys) = VALUE struc( a = 1 b = 2 ).
+
+DATA(sec_keys) = VALUE struc( c = 3 d = 4 ).
+
+READ TABLE it FROM pr_keys INTO wa.
+
+"If USING KEY is not specified, the primary table key is used.
+"If it is used, the specified table key is used.
+READ TABLE it FROM pr_keys USING KEY primary_key INTO wa.
+
+READ TABLE it FROM sec_keys USING KEY sec_key INTO wa.
+
+"Alias
+READ TABLE it FROM sec_keys USING KEY sk INTO wa.
+```
+
+
+
+**Reading a single line using a free key**
+
+The specified components used as keys need not be part of a table key.
+``` abap
+line = it[ b = 2 ].
+
+READ TABLE it INTO wa WITH KEY b = 2.
+```
+
+*Addressing individual components*
+
+When reading single lines in general, you can also address individual
+components of the line using the [component
+selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_selector_glosry.htm "Glossary Entry")
+`-` (or the [dereferencing
+operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm "Glossary Entry")
+`->*` in the case of data reference variables).
+``` abap
+DATA(comp1) = it[ b = 2 ]-c.
+
+READ TABLE it INTO DATA(wa) WITH KEY b = 2.
+DATA(comp2) = wa-c.
+
+READ TABLE it ASSIGNING FIELD-SYMBOL() WITH KEY b = 2.
+DATA(comp3) = -c.
+
+READ TABLE it REFERENCE INTO DATA(dref) WITH KEY b = 2.
+DATA(comp4) = dref->c.
+"Note: The syntax dref->*-c is also possible.
+```
+
+
+
+**Checking the existence and the index of a line in an internal table**
+
+This is relevant if you are not interested in the content of a table
+line, but only want to find out whether a line exists that matches to the
+index or key specifications. To do this, use a [`READ TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_table.htm)
+statement with the `TRANSPORTING NO FIELDS` addition. The
+addition indicates that no actual content is to be read. If the search was
+successful and an entry exists, the system field `sy-subrc` is
+set to 0.
+
+A newer way to check the existence of a line is the [predicate
+function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_function_glosry.htm "Glossary Entry")
+[`line_exists( )`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenline_exists_function.htm).
+This function expects a [table
+expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expression_glosry.htm "Glossary Entry") as an argument.
+See below for more on table expressions. Note that table expressions do not set system fields.
+``` abap
+"Read using the key
+READ TABLE it WITH KEY b = 2 TRANSPORTING NO FIELDS.
+
+IF sy-subrc = 0.
+ ...
+ENDIF.
+
+"Read using the index
+READ TABLE it INDEX 1 TRANSPORTING NO FIELDS.
+
+IF sy-subrc = 0.
+ ...
+ENDIF.
+
+"Read using the key
+IF line_exists( it[ b = 2 ] ).
+ ...
+ENDIF.
+
+"Read using the index
+IF line_exists( it[ 1 ] ).
+ ...
+ENDIF.
+```
+
+If you want to find out about the index of a line in an internal table, you can also make use of the `READ TABLE` statement above. If
+the line is found, the system field `sy-tabix` is set to the number of the index. Otherwise, the built-in function
+[`line_index( )`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenline_index_function.htm) can be used. It returns the index of the found line or 0 if the line does not exist.
+
+``` abap
+DATA(idx) = line_index( it[ b = 2 ] ).
+```
+
+`lines( )` is another built-in function that you can use to check how many lines exist in an internal table. It returns an integer value.
+
+``` abap
+DATA(number_of_lines) = lines( it ).
+```
+
+
+
+## Processing Multiple Internal Table Lines Sequentially
+
+If you are interested not only in single table lines, but in the entire
+table content or in specific parts of it, you can use [`LOOP
+AT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab.htm)
+statements to process table lines sequentially. As above, you
+can use multiple options for target areas: work area, field
+symbol, data reference. There are multiple additions to the `LOOP AT`
+statements to further restrict the table content to be processed.
+
+Simple form:
+``` abap
+"The target is an existing work area.
+DATA wa LIKE LINE OF it.
+
+LOOP AT it INTO wa.
+ "No addition of the loop statement; all lines are processed
+ "Statements in this block are relevant for each individual table line.
+ ...
+ENDLOOP.
+
+"Work area declared inline
+LOOP AT itab INTO DATA(wa_inl).
+ ...
+ENDLOOP.
+
+"Field symbols
+FIELD-SYMBOLS LIKE LINE OF it.
+
+LOOP AT it ASSIGNING .
+ ...
+ENDLOOP.
+
+LOOP AT it ASSIGNING FIELD-SYMBOL().
+ ...
+ENDLOOP.
+
+"Data reference variables
+DATA dref TYPE REF TO dbtab.
+
+LOOP AT it REFERENCE INTO dref.
+ ...
+ENDLOOP.
+
+LOOP AT it REFERENCE INTO DATA(dref_inl).
+ ...
+ENDLOOP.
+```
+
+- The order in which tables are iterated depends on the table category.
+ - Note the [`STEP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_cond.htm#!ABAP_ADDITION_3@3@) addition, which is also available for other ABAP statements.
+- Index tables are looped over in ascending order by the index.
+- Hashed tables are looped in the order in which the lines were added to the table. You can also sort the table before the loop.
+- During the loop, the system field `sy-tabix` is set to the number of the currently processed table
+line. This is not true for hashed tables. There, `sy-tabix` is `0`.
+- Note that if you want to work with the value of `sy-tabix`, you
+should do so immediately after the `LOOP` statement to avoid possible overwriting in statements contained in the loop block.
+
+*Restricting the area of the table to be looped over*
+
+The additions of `LOOP` statements come into play when you want to restrict the table content to be respected by the loop because
+you do not want to loop over the entire table. Note that the examples only show work areas as target objects to hold the table line read.
+Other options are possible as shown above.
+
+``` abap
+"FROM/TO: Only for index tables
+
+"Specifying an index range
+LOOP AT it INTO wa FROM 2 TO 5.
+ ...
+ENDLOOP.
+
+"From specified line until the end
+LOOP AT it INTO wa FROM 2.
+ ...
+ENDLOOP.
+
+"From first line until the specified line
+LOOP AT it INTO wa TO 5.
+ ...
+ENDLOOP.
+
+"WHERE clause: Restricting lines based on logical expression
+
+LOOP AT it INTO wa WHERE a > 1 AND b < 4.
+ ...
+ENDLOOP.
+
+"No interest in the table content; only relevant system fields are filled
+
+"Mandatory WHERE clause
+LOOP AT it TRANSPORTING NO FIELDS WHERE a < 5.
+ ...
+ENDLOOP.
+
+"Table key specification (snippet uses example table from above)
+"The specified table key affects the order in which the table lines
+"are accessed and the evaluation of the other conditions.
+
+LOOP AT it INTO wa USING KEY primary_key.
+"LOOP AT it INTO wa USING KEY pk. "primary key alias
+"LOOP AT it INTO wa USING KEY sec_key. "secondary key
+"LOOP AT it INTO wa USING KEY sk. "secondary key alias
+ ...
+ENDLOOP.
+
+"STEP addition for defining the step size and the direction of the loop
+"- Step size: Specified by the absolute value of an integer
+"- Direction: Specified by a positive (forward loop) or negative
+" (loop in reverse order) integer
+
+"Reversing the loop order using a negative integer
+"Each line is read indicated by the absolute value 1
+LOOP AT it INTO wa STEP -1.
+ ...
+ENDLOOP.
+
+"Forward loop by specifiying a positive integer
+"In the example, every second line is read.
+"Note: Omitting STEP means STEP 1 by default.
+LOOP AT it INTO wa STEP 2.
+ ...
+ENDLOOP.
+
+"STEP with other additions
+"The example uses the additions FROM and TO.
+"Note: If the value after STEP is negative, the value
+"after FROM must be greater than the value after TO.
+LOOP AT it INTO wa FROM 6 TO 3 STEP -2.
+ ...
+ENDLOOP.
+```
+
+### Iteration Expressions
+
+Iteration expressions with [`FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfor.htm) as part of certain constructor expressions allow you to create content of an internal table by evaluating one or more source tables.
+
+The expressions are covered in the cheat sheet [Constructor Expressions](05_Constructor_Expressions.md):
+- [Iteration Expressions Using FOR](05_Constructor_Expressions.md#iteration-expressions-using-for)
+- Special reduction operator `REDUCE` that is based on iteration expressions: [REDUCE](05_Constructor_Expressions.md#reduce)
+
+
+
+## Sorting Internal Tables
+
+- Sorted tables are stored in the memory in an automatically sorted
+ order, hence, they cannot be sorted explicitly with
+ [`SORT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsort_itab.htm).
+- For standard and hashed tables, the order can be changed.
+- When using `SORT` statements, the sort order is derived either
+ by the primary table key (Note: Secondary keys
+ cannot be used for the sorting.) or by explicitly specifying the
+ fields to be sorted by.
+- Explicit specification is the recommended way because it is
+ easier to understand and can prevent unwanted sorting results,
+ especially with tables with standard key.
+
+*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.
+```
+
+
+
+## Modifying Internal Table Content
+
+As mentioned above, you can modify the content of internal table lines directly in the context of `READ TABLE` and `LOOP AT` statements using field symbols and data reference variables. You can also use table expressions for direct modification. Note that the key fields of the primary table key of sorted and hashed tables are always read-only. If you try to modify a key field, a runtime error occurs. However, this is not checked until runtime.
+
+The following examples demonstrate direct modification of recently read table lines:
+``` abap
+"Table declarations
+
+DATA it_st TYPE TABLE OF struc WITH NON-UNIQUE KEY a.
+
+DATA it_so TYPE SORTED TABLE OF struc WITH UNIQUE KEY a.
+
+"Reading table line into target area
+
+READ TABLE it_st ASSIGNING FIELD-SYMBOL() INDEX 1.
+
+READ TABLE it_so REFERENCE INTO DATA(dref) INDEX 2.
+
+"Modification examples
+"Modifying the entire table line while keeping the values of other components;
+"this way is not possible for it_so because of key value change.
+
+ = VALUE #( BASE a = 1 b = 2 ).
+
+"Modifying a single component via field symbol
+
+-c = 3.
+
+"Modification via dereferencing
+
+ref->b = 4.
+
+"Table expressions
+
+it_st[ 1 ] = VALUE #( a = 1 b = 2 ).
+
+it_st[ 2 ]-c = 3.
+
+"Sorted table: no key field change
+
+it_so[ 2 ]-d = 4.
+```
+
+> **💡 Note**
+> If you want to modify recently read lines in a work area, for example, within a loop (`LOOP AT INTO dobj`), you can modify the line and then use a `MODIFY` statement to modify the internal table based on this line.
+
+[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_itab.htm)
+statements provide multiple ways of changing the content of single and multiple table lines by specifying the table key or a table index,
+without first reading the lines into a target area.
+
+``` abap
+"Addition FROM ...; specified key values determine the line to be modified
+
+"line: existing line including key values
+MODIFY TABLE it FROM line.
+
+"line constructed inline
+MODIFY TABLE it FROM VALUE #( a = 1 b = 2 ... ).
+
+"Respecting only specified fields with the addition TRANSPORTING
+"In case of sorted/hashed tables, key values cannot be specified.
+MODIFY TABLE it FROM line TRANSPORTING b c.
+
+"Modification via index
+"Note that it is only MODIFY, not MODIFY TABLE.
+"Example: It modifies the line with number 1 in the primary table index.
+MODIFY it FROM line INDEX 1.
+
+"Without the addition TRANSPORTING, the entire line is changed.
+"Example: It modifies specific values.
+MODIFY it FROM line INDEX 1 TRANSPORTING b c.
+
+"USING KEY addition
+"If the addition is not specified, the primary table key is used;
+"otherwise, it is the explicitly specified table key that is used.
+"Example: It is the same as MODIFY it FROM line INDEX 1.
+MODIFY it FROM line USING KEY primary_key INDEX 1.
+
+"The statement below uses a secondary key and an index specification
+"for the secondary table index. Only specific fields are modified.
+MODIFY it FROM line USING KEY sec_key INDEX 1 TRANSPORTING c d.
+
+"Modifying multiple lines in internal tables
+"All lines matching the logical expression in the WHERE clause are modified
+"as specified in line.
+"The additions TRANSPORTING and WHERE are both mandatory; USING KEY is optional.
+MODIFY it FROM line TRANSPORTING b c WHERE a < 5.
+```
+> **💡 Note**
+> - The system field `sy-subrc` is set to `0` if at least one line was changed. It is set to `4` if no lines were changed.
+> - `MODIFY`, `DELETE`, and `INSERT` statements can be specified with and without the `TABLE` addition. With `TABLE` means an index access. Without `TABLE` means an access via the table key.
+
+
+
+## Deleting Internal Table Content
+
+You can use [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdelete_itab.htm) statements to delete single and multiple lines in internal tables. The following additions can be used: `USING KEY` (for specifying a table key), `FROM`/`TO` (for specifying row ranges), `STEP` (for specifying the step size), and `WHERE` (for specifying conditions).
+
+``` abap
+"Deleting via index
+"Example: The first line in the table is deleted.
+DELETE it INDEX 1.
+
+"If USING KEY is not used, INDEX can only be used with index tables.
+"If doing so, it determines the line from the primary table index.
+"If a secondary key is specified, the secondary table index is respected
+"Example: same as above
+DELETE it INDEX 1 USING KEY primary_key.
+
+"Deleting an index range; FROM or TO alone can also be specified
+DELETE it FROM 2 TO 5.
+
+"Deleting via keys
+"The line must have a compatible type to the tables line type and
+"include key values. The first found line with the corresponding keys
+"is deleted.
+"If the key is empty, no line is deleted.
+DELETE TABLE it FROM line.
+
+"Instead of specifying the keys using a data object ("line" above),
+"the keys can be specified separately. All key values must be specified.
+"Example: Respects keys from primary table index.
+DELETE TABLE it WITH TABLE KEY a = 1.
+
+"You can also specify secondary keys.
+"Example: Same as above
+DELETE TABLE it WITH TABLE KEY primary_key COMPONENTS a = 1.
+
+DELETE TABLE it_sec WITH TABLE KEY sec_key COMPONENTS ...
+
+"Deleting multiple lines based on a WHERE condition
+"Specifying the additions USING KEY, FROM, TO is also possible.
+DELETE it WHERE a < 6.
+
+"Excursion: Deleting in a LIKE-like fashion you may know from
+"ABAP SQL statements.
+"The LIKE addition is not available for the WHERE clause in DELETE
+"statements for internal tables as is the case for ABAP SQL DELETE statements.
+DATA(str_table) = VALUE string_table( ( `abcZ` ) ( `Zdef` ) ( `gZhi` )
+ ( `Zjkl` ) ( `Zmno` ) ( `pqrZ` ) ).
+
+"You can, for example, use logical operators such as CP (conforms to pattern)
+"All lines that begin with Z are to be deleted.
+DELETE str_table WHERE table_line CP `Z*`.
+"Result: abcZ / gZhi / pqrZ
+```
+
+`DELETE ADJACENT DUPLICATES` statements allow you to delete all adjacent lines except for the first line that have the same content in certain components. You usually need to perform some appropriate sorting before using these statements.
+``` abap
+"Implicitly using the primary table key
+DELETE ADJACENT DUPLICATES FROM it.
+
+"Deletion respecting the values of the entire line
+DELETE ADJACENT DUPLICATES FROM it COMPARING ALL FIELDS.
+
+"Only lines are deleted with matching content in specific fields
+DELETE ADJACENT DUPLICATES FROM it COMPARING a c.
+
+"Deletion respecting a specified table key
+"Same as first example above
+DELETE ADJACENT DUPLICATES FROM it USING KEY primary_key.
+
+DELETE ADJACENT DUPLICATES FROM it USING KEY sec_key.
+```
+
+> **💡 Note**
+> The system field `sy-subrc` is set to `0` if at least one line has been deleted. It is set to `4` if no lines were deleted.
+
+The
+[`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm)
+and
+[`FREE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfree_dataobject.htm)
+statements allow you to delete the entire table content.
+
+The difference between the two is in the handling of the memory space originally allocated to the table. When a table is cleared with `CLEAR`,
+the content is removed, but the memory space initially requested remains
+allocated. If the table is filled again later, the memory space is still
+available, which is a performance advantage over
+clearing an internal table with `FREE`. Such a statement also
+deletes the table content, but it also releases the memory
+space.
+Note that an assignment using the `VALUE` operator without entries in the parentheses clears the internal table.
+
+``` abap
+CLEAR it.
+
+"This statement additionally releases memory space.
+FREE it.
+
+"Assignment using the VALUE operator without entries in the parentheses
+it = VALUE #( ).
+```
+
+
+## Excursions
+
+### Improving Read Performance with Secondary Table Keys
+
+The following example creates two demo internal tables. One without a secondary
+table key and the other with a secondary table key. Consider a scenario where you
+have an internal table without a secondary table key, and you want to add a secondary table key later to improve read performance. The tables are populated with a lot of data. Then, in a DO loop, many reads are performed on the internal tables. One example uses a free key for the read, the other uses a secondary table key. Before and after the reads, the current timestamp is stored in variables, from which the elapsed time is calculated. There should be a significant delta of the elapsed time.
+
+```abap
+CLASS zcl_some_class DEFINITION PUBLIC FINAL CREATE PUBLIC.
+ PUBLIC SECTION.
+ INTERFACES if_oo_adt_classrun.
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+ENDCLASS.
+CLASS zcl_some_class IMPLEMENTATION.
+ METHOD if_oo_adt_classrun~main.
+ TYPES: BEGIN OF demo_struc,
+ idx TYPE i,
+ str TYPE string,
+ num TYPE i,
+ END OF demo_struc.
+
+ DATA itab TYPE HASHED TABLE OF demo_struc WITH UNIQUE KEY idx.
+ DATA itab_sec TYPE HASHED TABLE OF demo_struc
+ WITH UNIQUE KEY idx
+ WITH NON-UNIQUE SORTED KEY sk
+ COMPONENTS str num.
+
+ DO 500 TIMES.
+ INSERT VALUE #( idx = sy-index
+ str = |INDEX{ sy-index }|
+ num = sy-index ) INTO TABLE itab.
+ ENDDO.
+ itab_sec = itab.
+
+ DATA(ts1) = utclong_current( ).
+ DO 500 TIMES.
+ "Reading into a data reference variable using using a free key.
+ "This key corresponds to the secondary table key specified for
+ "the table in the second example.
+ DATA(dref) = REF #( itab[ str = `INDEX250` num = 250 ] ).
+ ENDDO.
+ DATA(ts2) = utclong_current( ).
+
+ cl_abap_utclong=>diff( EXPORTING high = ts2
+ low = ts1
+ IMPORTING seconds = DATA(seconds) ).
+
+ out->write( `Elapsed time for the reads using a free key:` ).
+ out->write( seconds ).
+ out->write( `----------------------------------------------------------` ).
+
+ ts1 = utclong_current( ).
+ DO 500 TIMES.
+ "Reading from an internal table using the secondary table key
+ dref = REF #( itab_sec[ KEY sk str = `INDEX250` num = 250 ] ).
+ ENDDO.
+ ts2 = utclong_current( ).
+
+ cl_abap_utclong=>diff( EXPORTING high = ts2
+ low = ts1
+ IMPORTING seconds = seconds ).
+ out->write( `Elapsed time for the reads using a secondary table key:` ).
+ out->write( seconds ).
+ ENDMETHOD.
+ENDCLASS.
+```
+
+
+
+### Searching and Replacing Substrings in Internal Tables with Character-Like Data Types
+
+You can use [`FIND ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_itab.htm) statements to search for substrings in internal tables (standard tables without secondary table keys; with character-like line type) line by line.
+
+``` abap
+DATA(str_table) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
+
+"Finding all occurrences in a table
+"Note: res_tab is of type match_result_tab
+"You can also restrict the search range in an internal table; see an example in REPLACE ... IN TABLE
+FIND ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ RESULTS DATA(res_tab)
+ RESPECTING CASE.
+
+"4 entries in table res_tab (tables in SUBMATCHES are initial since no regular expression is used)
+"1. line: 1, offset: 1, length: 1, submatches: (initial)
+"2. line: 1, offset: 4, length: 1, ...
+"3. line: 2, offset: 2, length: 1, ...
+"4. line: 3, offset: 0, length: 1, ...
+
+"Finding the first occurrence in a table
+"Note: res_struc, which is declared inline here, is of type match_result
+FIND FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ RESULTS DATA(res_struc)
+ RESPECTING CASE.
+
+"Entries in structure res_struc
+"line: 1, offset: 1, length: 1, submatches: (initial)
+
+"Alternative to the statement above (storing the information in individual data objects)
+FIND FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ MATCH LINE DATA(line) "1
+ MATCH OFFSET DATA(off) "1
+ MATCH LENGTH DATA(len) "1
+ RESPECTING CASE.
+```
+
+Replacements in internal tables with [`REPLACE ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace_itab.htm):
+
+``` abap
+DATA(str_table_original) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
+DATA(str_table) = str_table_original.
+
+"Replacing all occurrences in a table
+"RESULTS addition: Storing information in an internal table of type repl_result_tab
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ WITH `#`
+ RESULTS DATA(res_table)
+ RESPECTING CASE.
+
+"str_table: a#bz# / cd#ze / #zzf / ghz
+"res_table:
+"LINE OFFSET LENGTH
+"1 1 1
+"1 4 1
+"2 2 1
+"3 0 1
+
+str_table = str_table_original.
+
+"Replacing the first occurrence in a table
+"RESULTS addition: Storing information in a structure of type repl_result
+REPLACE FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ WITH `#`
+ RESULTS DATA(res_structure)
+ RESPECTING CASE.
+
+"str_table: a#bzZ / cdZze / Zzzf / ghz
+"res_structure:
+"LINE OFFSET LENGTH
+"1 1 1
+
+str_table = str_table_original.
+
+"Restricting the search range in an internal table
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ FROM 1 TO 2
+ WITH `#`
+ RESPECTING CASE.
+
+"str_table: a#bz# / cd#ze / Zzzf / ghz
+
+str_table = str_table_original.
+
+"Offsets can be optionally specified (also only the offset of start or end line possible)
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ FROM 1 OFFSET 3 TO 2 OFFSET 2
+ WITH `#`
+ RESPECTING CASE.
+
+"str_table: aZbz# / cdZze / Zzzf / ghz
+```
+
+
+
+### Ranges Tables
+
+- Internal tables that have the predefined columns `SIGN`, `OPTION`, `LOW`, and `HIGH`
+- Declared with the `TYPE RANGE OF` addition in `DATA` and `TYPES` statements
+- Used to store range conditions that can be evaluated in expressions using the `IN` operator (each row in the table represents a separate comparison)
+
+```abap
+"Populating an integer table with values from 1 to 20
+TYPES int_tab_type TYPE TABLE OF i WITH EMPTY KEY.
+DATA(inttab) = VALUE int_tab_type( FOR x = 1 WHILE x <= 20 ( x ) ).
+
+"Declaring a ranges table
+DATA rangestab TYPE RANGE OF i.
+
+"Populating a ranges table using VALUE
+rangestab = VALUE #( sign = 'I'
+ option = 'BT' ( low = 1 high = 3 )
+ ( low = 6 high = 8 )
+ ( low = 12 high = 15 )
+ option = 'GE' ( low = 18 ) ).
+
+"Using a SELECT statement and the IN addition to retrieve internal table
+"content based on the ranges table specifications
+SELECT * FROM @inttab AS tab
+ WHERE table_line IN @rangestab
+ INTO TABLE @DATA(result).
+"result: 1, 2, 3, 6, 7, 8, 12, 13, 14, 15, 18, 19, 20
+```
+
+
+
+## More Information
+Topic [Internal Tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenitab.htm) in the ABAP Keyword Documentation.
+
+## Executable Example
+[zcl_demo_abap_internal_tables](./src/zcl_demo_abap_internal_tables.clas.abap)
+
+> **💡 Note**
+> - The executable example covers the following topics, among others: Creating, populating, reading from, sorting, modifying internal tables
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
\ No newline at end of file
diff --git a/02_Structures.md b/02_Structures.md
index f19a991..10deaa2 100644
--- a/02_Structures.md
+++ b/02_Structures.md
@@ -1,745 +1,727 @@
-
-
-# Structures
-
-- [Structures](#structures)
- - [Introduction](#introduction)
- - [Creating Structures and Structured Types](#creating-structures-and-structured-types)
- - [Variants of Structures](#variants-of-structures)
- - [Accessing (Components of) Structures](#accessing-components-of-structures)
- - [Populating Structures](#populating-structures)
- - [Using the VALUE Operator](#using-the-value-operator)
- - [Using the NEW Operator](#using-the-new-operator)
- - [Using the CORRESPONDING Operator and MOVE-CORRESPONDING Statements](#using-the-corresponding-operator-and-move-corresponding-statements)
- - [Clearing Structures](#clearing-structures)
- - [Processing Structures](#processing-structures)
- - [Excursion: Including Structures](#excursion-including-structures)
- - [Executable Example](#executable-example)
-
-## Introduction
-Structures ...
-
-- are [data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm "Glossary Entry")
- with [structured data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructured_type_glosry.htm "Glossary Entry") (which is a [complex data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplex_data_type_glosry.htm "Glossary Entry") because it is composed of other data types).
-- consist of a sequence of [components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_glosry.htm "Glossary Entry") of any data type, that is, the components of a structure can be, for example, [elementary data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_object_glosry.htm), structures themselves, [internal tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninternal_table_glosry.htm "Glossary Entry") or [references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm).
-- are used to combine different data objects that belong together. A typical example is an address. It has several components, such as name, street, city, and so on, that belong together.
-- play an important role in the context of internal tables and [database tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_table_glosry.htm "Glossary Entry"). Structured types serve as [line types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrow_type_glosry.htm) for these tables. Most internal tables across [ABAP programs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm) may have structured line types. For database tables, there is no alternative to structured line types.
-- can be created locally in an ABAP program. You can also create them as global [DDIC structures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_structure_glosry.htm) in the [ABAP Dictionary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_dictionary_glosry.htm). Such a DDIC structure defines a globally available structured type ([DDIC type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_type_glosry.htm)).
- - Note: There are other structured types available globally, which may be the structured types most commonly used in ABAP programs:
- - [Database tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_db_table_glosry.htm) defined in the ABAP Dictionary can be used as data types just like DDIC structures in an ABAP program. This means that when you create a structure in your ABAP program, for example, you can simply use the name of a database table to address the line type of the table. The structure you created will then have the same structured type as the database table. Typically, you use the database tables to create structures of such a type, or internal tables of such a structured line type, to process data read from the database table in structures or internal tables.
- - A [CDS entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_glosry.htm) such as a [CDS view](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm) also represents a structured data type and can be used as such in ABAP programs (but not in the ABAP Dictionary). The same applies to [DDIC views](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_view_glosry.htm) that are only available in [Standard ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_abap_glosry.htm).
- - Structures and structured data types can also be defined in the public [visibility section](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm) of [global classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm) or in [global interfaces](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_interface_glosry.htm) and then used globally.
-
-
-
-## Creating Structures and Structured Types
-
-The typical language elements for creating structures and structured types locally in an ABAP program are [`BEGIN OF ... END OF ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes_struc.htm). They are used in combination with the [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm) keyword to create a structured type and the [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) keyword to create a structure.
-
-> **💡 Note**
-> This cheat sheet focuses on locally defined structures and structured types.
-
-**Creating structured types**
-
-- The following statement defines a structured type introduced by `TYPES`. The type name is preceded by `BEGIN OF` (which marks the beginning of the structured type definition) and `END OF` (the end of the definition).
-- The components - at least one must be defined - are listed in between.
-- Such structured type definitions are usually grouped together in a [chained statement](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenchained_statement_glosry.htm), i.e. `TYPES` is followed by a colon, and the components are separated by commas.
-
-
-``` abap
-TYPES: BEGIN OF struc_type,
- comp1 TYPE ...,
- comp2 TYPE ...,
- comp3 TYPE ...,
- ...,
- END OF struc_type.
-```
-
-Alternatively, you can also use the following syntax. However, a chained statement provides better readability.
-``` abap
-TYPES BEGIN OF struc_type.
- TYPES comp1 TYPE ... .
- TYPES comp2 TYPE ... .
- TYPES comp3 TYPE ... .
- ... .
-TYPES END OF struc_type.
-```
-
-
-- The simplest structures and structured types have [elementary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm "Glossary Entry")
-components.
-- As mentioned above, the components can be of any type, i.e. they can be of structured types themselves, internal table types, or [reference types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_type_glosry.htm).
-- You can use the [`TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_simple.htm)
-and [`LIKE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_referring.htm) additions for the types of the components.
-You can use the `LINE OF` addition to refer to a table type or an internal table.
-
-
-``` abap
-TYPES: BEGIN OF struc_type,
- comp1 TYPE i, "elementary type
- comp2 TYPE c LENGTH 5, "elementary type
- comp3 TYPE structured_type, "structured type
- comp4 TYPE itab_type, "internal table type
- comp5 TYPE ddic_type, "DDIC type
- comp6 TYPE REF TO i, "data reference
- comp7 LIKE data_object, "deriving type from a data object
- comp8 TYPE LINE OF itab_type, "component has structured type, type derived from internal table type
- comp9 LIKE LINE OF itab, "component has structured type, type derived from internal table
- comp10, "no TYPE/LIKE specification: component is of type c length 1
- ...,
- END OF struc_type.
-```
-
-
-> **💡 Note**
-> Outside of classes, you can also refer to DDIC types using `LIKE` (`... comp11 LIKE ddic_type, ...`). If you actually want to refer to an existing data object, but due to typing errors you inadvertently specify a name that exists as DDIC type, errors may be unavoidable.
-
-
-**Creating structures**
-
-- To create a structure in an ABAP program, you can use the `DATA` keyword. - It works in the same way as the `TYPES` statement above.
-- Unlike the `TYPES` statement, you can use the [`VALUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_options.htm) addition to set default values.
-
-``` abap
-DATA: BEGIN OF struc,
- comp1 TYPE ...,
- comp2 TYPE ... VALUE ...,
- comp3 TYPE i VALUE 99,
- comp4 TYPE i VALUE IS INITIAL, "Without the addition VALUE, or if IS INITIAL is specified,
- "the content is initial.
- comp5 TYPE local_structured_type,
- ...,
- END OF struc.
-```
-
-Alternatively, you can use the following syntax. Similar to above, a chained statement provides better readability.
-
-``` abap
-DATA BEGIN OF struc.
- DATA comp1 TYPE ... .
- DATA comp2 TYPE ... VALUE ... .
-... .
-DATA END OF struc.
-```
-
-> **💡 Note**
->- The keywords [`CLASS-DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass-data.htm) and [`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm) can also be used to create structures. In principle, they represent special cases of the general statement shown above. See the ABAP Keyword Documentation for more information.
->- Structures can also be created [inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm) using [`DATA(...)`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm) or [`FINAL(...)`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm), as shown below.
-
-Creating structures using existing structured types:
-
-``` abap
-"Local structured type
-TYPES: BEGIN OF struc_type,
- comp1 TYPE i,
- comp2 TYPE c LENGTH 5,
- END OF struc_type.
-
-"Creating a structure using a local structured type
-DATA struc_1 TYPE struc_type.
-
-"Creating structures based on globally available types from the DDIC
-"Note: When referring to such types, you cannot provide start values for the individual components.
-DATA: struc_2 TYPE some_ddic_structure,
- struc_3 TYPE some_ddic_table,
- struc_4 TYPE some_cds_view.
-
-"Structure based on a structured type that is available in the public
-"visibility section of a global class
-DATA struc_5 TYPE cl_some_class=>struc_type.
-
-"Creating structures by referring to local data objects and internal table types
-DATA: struc_6 LIKE struc_1,
- struc_7 LIKE LINE OF some_itab,
- struc_8 TYPE LINE OF some_itab_type.
-```
-
-
-Creating structures by inline declaration using `DATA(...)`
-- This is particularly useful for declaring data objects at the [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm) where you actually need them.
-- In this way, you can avoid an extra declaration of the structure in different contexts.
-- You can also use the [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) declaration operator to create [immutable variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenimmutable_variable_glosry.htm).
-
-``` abap
-"Structures created inline instead of an extra declared variable
-DATA struc_9 LIKE struc_1.
-struc_9 = struc_1
-
-"Type is derived from the right-hand structure; the content of struc is assigned, too.
-DATA(struc_10) = struc_1.
-FINAL(struc_11) = struc_9.
-
-"Structures declared inline instead of an extra declared variable
-
-"Example: SELECT statement
-"Extra declaration
-DATA struc_12 TYPE zdemo_abap_fli.
-
-SELECT SINGLE *
- FROM zdemo_abap_fli
- WHERE carrid = 'LH'
- INTO @struc_12.
-
-"Inline declaration
-SELECT SINGLE *
- FROM zdemo_abap_fli
- WHERE carrid = 'LH'
- INTO @DATA(struc_13).
-
-"Example: Loop over an internal table
-DATA itab TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
-... "itab is filled
-
-"Extra declaration
-DATA wa_1 LIKE LINE OF itab.
-
-LOOP AT itab INTO wa_1.
- ...
-ENDLOOP.
-
-"Inline declaration
-LOOP AT itab INTO DATA(wa_2).
- ...
-ENDLOOP.
-```
-
-
-
-## Variants of Structures
-
-Depending on the component type, the structure can be a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm "Glossary Entry"),
-a [nested structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennested_structure_glosry.htm "Glossary Entry"),
-or a [deep structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm "Glossary Entry").
-
-- **Flat structures** contain only elementary types that have a fixed length, that is, there are no internal tables, reference types or strings as components. Nesting does not matter in this context. Even a nested structure is considered flat unless a substructure contains a deep component.
- ``` abap
- DATA: BEGIN OF struc,
- comp1 TYPE i,
- comp2 TYPE c LENGTH 15,
- comp3 TYPE p LENGTH 8 DECIMALS 2,
- ...,
- END OF struc.
- ```
-
-- **Nested structures**: At least one component of a structure is a [substructure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstructure_glosry.htm "Glossary Entry"),
-that is, it refers to another structure. The following example has multiple substructures.
- ``` abap
- DATA: BEGIN OF address_n,
- BEGIN OF name,
- title TYPE string VALUE `Mr.`,
- prename TYPE string VALUE `Duncan`,
- surname TYPE string VALUE `Pea`,
- END OF name,
- BEGIN OF street,
- name TYPE string VALUE `Vegetable Lane`,
- num TYPE string VALUE `11`,
- END OF street,
- BEGIN OF city,
- zipcode TYPE string VALUE `349875`,
- name TYPE string VALUE `Botanica`,
- END OF city,
- END OF address_n.
- ```
-
-- **Deep structures**: Contains at least one internal table, reference type, or string as a component.
- ``` abap
- DATA: BEGIN OF address_d,
- name TYPE string VALUE `Mr. Duncan Pea`,
- street TYPE string VALUE `Vegetable Lane 11`,
- city TYPE string VALUE `349875 Botanica`,
- details TYPE TABLE OF some_table WITH EMPTY KEY,
- END OF address_d.
- ```
- Although the following structure looks quite simple, it is not a flat structure, but a deep structure, because it contains strings.
- ``` abap
- DATA: BEGIN OF address,
- name TYPE string VALUE `Mr. Duncan Pea`,
- street TYPE string VALUE `Vegetable Lane 11`,
- city TYPE string VALUE `349875 Botanica`,
- END OF address.
- ```
-
-> **💡 Note**
->- The data types of DDIC types are all flat (not nested) structures. Exception: Components of type `string` can be contained.
->- [Work areas](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm) of ABAP SQL statements cannot contain any deep components other than strings among others.
->- Especially for assignments and comparisons of deep structures, the compatibility of the source and target structure must be taken into account.
-
-
-
-## Accessing (Components of) Structures
-
-- Structures can be accessed as a whole. You can also address the individual components of structures at the appropriate operand positions.
-- To address the components, use the [structure component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructure_component_sel_glosry.htm "Glossary Entry")
-`-`.
-- For variables with reference to a structured data object, the [object component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm) `->` can be used: `...dref->comp ...`. The following syntax also works, but is less *convenient*: `... dref->*-comp ...`.
-- ADT and the ABAP Editor provide code completion for structure components after the component selectors.
-``` abap
-"Addressing components via the structure component selector
-... struc-comp1 ...
-... struc-comp2 ...
-... struc-comp3 ...
-
-"Examples for addressing the whole structure and individual components
-IF struc IS INITIAL.
- ...
-ENDIF.
-
-IF struc-comp1 = 1.
- ...
-ENDIF.
-
-DATA(complete_struc) = struc.
-DATA(comp_value) = struc-comp2.
-
-"Type and data declarations
-TYPES: type_1 TYPE structured_type-comp1,
- type_2 LIKE struc-comp1.
-
-DATA: var_1 TYPE structured_type-comp1,
- var_2 LIKE struc-comp1.
-
-"Variables with reference to a structured data object
-DATA ref_struc_1 TYPE REF TO structured_type.
-ref_struc_1 = NEW #( ).
-"Excursion: Creating a reference variable using inline declaration
-DATA(ref_struc_2) = NEW structured_type( ).
-
-... ref_struc_1->comp1 ...
-... ref_struc_1->*-comp1 ... "Using the dereferencing operator
-... ref_struc_2->-comp2 ...
-... ref_struc_2->*-comp2 ... "Using the dereferencing operator
-```
-
-Nested components can be addressed using chaining:
-``` abap
-... struc-substructure-comp1 ...
-... address_n-name-title ...
-```
-
-> **💡 Note**
-> There are syntax options for dynamically accessing structure components. See the [Dynamic Porgramming](06_Dynamic_Programming.md) cheat sheet.
-
-
-
-## Populating Structures
-
-You can copy the content of a structure to another using the [assignment operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm) `=`.
-In the following example, it is assumed that the target and source structures are of compatible types. In general, note that special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) apply to value assignments involving structures.
-``` abap
-some_struc = another_struc.
-
-"When creating a new structure by inline declaration, the type of
-"the right-hand structure is derived and the content is assigned.
-
-DATA(struc_inl) = some_struc.
-```
-
-To assign values to individual structure components, use the component selector.
-``` abap
-TYPES: BEGIN OF addr_struc,
- name TYPE string,
- street TYPE string,
- city TYPE string,
- END OF addr_struc.
-
-DATA address TYPE addr_struc.
-
-address-name = `Mr. Duncan Pea`.
-
-address-street = `Vegetable Lane 11`.
-
-address-city = `349875 Botanica`.
-```
-
-
-
-### Using the VALUE Operator
-
-- The [`VALUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_value.htm) operator can be used to construct the content of complex data objects such as structures or internal tables.
-- It is particularly useful because assigning values by addressing the structure components individually can be very cumbersome, especially when assigning values to structure components at the [operand position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry").
-- If the type of the operand can be inferred implicitly, the `#` character can be used used before the parentheses. Otherwise, the type must be specified explicitly.
-- The `VALUE` operator and inline declarations can be used to create and populate structures in one go.
-- Note that there are special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) rules for structures. See the ABAP Keyword Documentation for more details.
-
-
-``` abap
-"# used: type of the operand can be implicitly derived
-address = VALUE #( name = `Mr. Duncan Pea`
- street = `Vegetable Lane 11`
- city = `349875 Botanica` ).
-
-"Declaring a structure inline
-"Type used explicitly: type of the operand cannot be implicitly derived
-DATA(addr) = VALUE addr_struc( name = `Mr. Duncan Pea`
- street = `Vegetable Lane 11`
- city = `349875 Botanica` ).
-
-"Nesting value operators
-TYPES: BEGIN OF struc_nested,
- a TYPE i,
- BEGIN OF nested_1,
- b TYPE i,
- c TYPE i,
- END OF nested_1,
- BEGIN OF nested_2,
- d TYPE i,
- e TYPE i,
- END OF nested_2,
- END OF struc_nested.
-
-DATA str_1 TYPE struc_nested.
-
-str_1 = VALUE #( a = 1
- nested_1 = VALUE #( b = 2 c = 3 )
- nested_2 = VALUE #( d = 4 e = 5 ) ).
-
-"Inline declaration
-"Component a is not specified here, i.e. its value remains initial.
-DATA(str_2) = VALUE struc_nested( nested_1 = VALUE #( b = 2 c = 3 )
- nested_2 = VALUE #( d = 4 e = 5 ) ).
-
-"Apart from the VALUE operator, the NEW operator can be used to create
-"a data reference variable (and populate the structure)
-DATA(str_ref) = NEW struc_nested( a = 1
- nested_1 = VALUE #( b = 2 c = 3 )
- nested_2 = VALUE #( d = 4 e = 5 ) ).
-```
-
-
-
-### Using the NEW Operator
-
-Using the instance operator [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_new.htm), you can create [anonymous data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm "Glossary Entry"), such as anonymous structures. You can access the components or the entire data objects by [dereferencing](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm). For more information, refer to the [Dynamic Programming](06_Dynamic_Programming.md) and [Constructor Expressions](05_Constructor_Expressions.md) cheat sheets.
-
-```abap
-"Creating a data reference variable
-DATA addr_ref1 TYPE REF TO addr_struc.
-
-"Populating the anonymous structure
-addr_ref1 = NEW #( name = `Mr. Duncan Pea`
- street = `Vegetable Lane 11`
- city = `349875 Botanica` ).
-
-addr_ref1->name = `Mrs. Jane Doe`.
-
-"Declaring an anonymous structure/a data reference variable inline
-DATA(addr_ref2) = NEW addr_struc( name = `Mr. Duncan Pea`
- street = `Vegetable Lane 11`
- city = `349875 Botanica` ).
-
-addr_ref2->* = VALUE #( BASE addr_ref2->* name = `Mr. John Doe` ).
-```
-
-
-
-### Using the CORRESPONDING Operator and MOVE-CORRESPONDING Statements
-
-- You can use statements with [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm)
-and the [`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator to assign values to structure components, especially when assigning values from a source structure to a target structure which have incompatible types and/or differently named components.
-- Both are used to assign identically named components of structures to each other.
-- The syntax also works for structures of the same type.
-- Also note the special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) rules for structures in this context.
-
-> **💡 Note**
->- The [`CL_ABAP_CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencl_abap_corresponding.htm) system class is available for making assignments. See the ABAP Keyword Documentation for the details.
->- The `INTO` clause of ABAP SQL statements has the `CORRESPONDING` addition. There, the following basic rule applies, which affects the value assignment: Without the `CORRESPONDING ...` addition, column names do not matter, only the position. With the `CORRESPONDING ...` addition, the position of the columns does not matter, only the name. See examples in the ABAP SQL cheat sheet.
-
-The following examples demonstrate the value assignment using `MOVE-CORRESPONDING` statements and the `CORRESPONDING` operator with various additions.
-The focus is on flat structures only.
-
-``` abap
-"Moves identically named components; content in other components
-"of the targets structure are kept.
-
-MOVE-CORRESPONDING struc TO diff_struc.
-
-"Initializes target structure; moves identically named components
-
-diff_struc = CORRESPONDING #( struc ).
-
-"Same effect as the first MOVE-CORRESPONDING statement;
-"addition BASE keeps existing content
-
-diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc ).
-
-"MAPPING addition: Specifying components of a source structure that are
-"assigned to the components of a target structure in mapping
-"relationships.
-
-diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc MAPPING comp1 = compa ).
-
-"EXCEPT addition: Excluding components from the assignment.
-
-diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc EXCEPT comp1 ).
-```
-
-Value assignments in deep structures
-- In the context of deep structures, there are additional syntax variants available for [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm) statements and the [`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator.
-- The following examples focus on internal tables as structure components. Check out the syntax in action in the executable example.
-
-``` abap
-"Nonidentical elementary component types are kept in target
-"structure which is true for the below MOVE-CORRESPONDING statements;
-"existing internal table content is replaced by content of
-"the source table irrespective of identically named components
-
-MOVE-CORRESPONDING deep_struc TO diff_deep_struc.
-
-"Existing internal table content is replaced but the value
-"assignment happens for identically named components only.
-
-MOVE-CORRESPONDING deep_struc TO diff_deep_struc EXPANDING NESTED TABLES.
-
-"Existing internal table content is kept; table content of the source
-"structure are added but the value assignment happens like the first
-"MOVE-CORRESPONDING statement without further syntax additions.
-
-MOVE-CORRESPONDING deep_struc TO diff_deep_struc KEEPING TARGET LINES.
-
-"Existing internal table content is kept; table content of the source
-"structure are added; the value assignment happens like the statement
-"MOVE-CORRESPONDING ... EXPANDING NESTED TABLES.
-
-MOVE-CORRESPONDING deep_struc TO diff_deep_struc EXPANDING NESTED TABLES KEEPING TARGET LINES.
-
-"Target structure is initialized; the value assignment for an internal
-"table happens irrespective of identically named components.
-
-diff_deep_struc = CORRESPONDING #( deep_struc ).
-
-"Target structure is initialized; the value assignment for an internal
-"table happens for identically named components only.
-
-diff_deep_struc = CORRESPONDING #( DEEP deep_struc ).
-
-"Nonidentical elementary component types are kept in target structure;
-"internal table content is replaced; there, the value assignment
-"happens like using the CORRESPONDING operator without addition.
-
-diff_deep_struc = CORRESPONDING #( BASE ( diff_struc ) deep_struc ).
-
-"Nonidentical elementary component types are kept in target structure;
-"internal table content is replaced; there, the value assignment
-"happens like using the CORRESPONDING operator with the addition DEEP.
-
-diff_deep_struc = CORRESPONDING #( DEEP BASE ( diff_struc ) deep_struc ).
-
-"Nonidentical elementary component types are kept in target structure;
-"internal table content is kept, too, and table content of the
-"source structure are added; there, the value assignment
-"happens like using the CORRESPONDING operator without addition.
-
-diff_deep_struc = CORRESPONDING #( APPENDING BASE ( diff_struc ) deep_struc ).
-
-"Nonidentical elementary component types are kept in target structure;
-"internal table content is kept, too, and table content of the
-"source structure are added; there, the value assignment
-"happens like using the CORRESPONDING operator with the addition DEEP.
-
-diff_deep_struc = CORRESPONDING #( DEEP APPENDING BASE ( diff_struc ) deep_struc ).
-```
-
-
-
-## Clearing Structures
-
-You can reset individual components to their initial values and clear the
-entire structure using the [`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm) keyword.
-
-``` abap
-CLEAR struc-component.
-
-CLEAR struc.
-
-"Note: An assignment using the VALUE operator without entries in the parentheses clears the structure.
-struc = VALUE #( ).
-```
-
-
-
-## Processing Structures
-Structures are primarily used to process data from tables. In this context, structures often take on the role of a [work area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry").
-The following code snippets cover only a selection. For more examples, see the cheat sheets about internal tables and ABAP SQL.
-
-**Reading a row from a database table into a structure that has a compatible type**. Note that, since database tables are flat, the
-target structure must also be flat. In the example below, the [`SINGLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_single.htm)
-addition reads only a single row into the structure. It returns the first entry that matches the `WHERE` condition.
-
-``` abap
-"Creating a structure with a compatible type
-DATA ls_fli1 TYPE zdemo_abap_fli.
-
-SELECT SINGLE FROM zdemo_abap_fli
- FIELDS *
- WHERE carrid = 'LH'
- INTO @ls_fli1.
-
-"Target structure declared inline
-SELECT SINGLE FROM zdemo_abap_fli
- FIELDS *
- WHERE carrid = 'LH'
- INTO @DATA(ls_fli2).
-```
-**Reading a row from a database table into a structure that has an incompatible type**.
-Components in the structure with identical names are filled.
-
-``` abap
-SELECT SINGLE FROM zdemo_abap_fli
- FIELDS *
- WHERE carrid = 'AA'
- INTO CORRESPONDING FIELDS OF @ls_fli_diff.
-```
-**Reading a line from an internal table into a structure** ...
-
-... using a `SELECT` statement. Note the specified alias name and that ABAP variables like internal tables must be escaped with `@`. The addition `INTO CORRESPONDING FIELDS OF` also applies here.
-``` abap
-SELECT SINGLE FROM @itab AS itab_alias
- FIELDS *
- WHERE ...
- INTO @DATA(ls_struc).
- "INTO CORRESPONDING FIELDS OF @some_existing_struc.
-```
-... using a `READ TABLE` statement. The code snippet below shows the reading of a line into a [work area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry"), a [field symbol](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm "Glossary Entry"), and a [data reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_variable_glosry.htm "Glossary Entry"), all of which
-represent structured data objects that are declared inline. In the following example, a line is read based on the line number by
-specifying `INDEX`. For more details, see the section *Determining the target area* in the cheat sheet [Internal Tables](01_Internal_Tables.md#).
-``` abap
-READ TABLE itab INTO DATA(wa) INDEX 1.
-
-READ TABLE itab ASSIGNING FIELD-SYMBOL() INDEX 2.
-
-READ TABLE itab REFERENCE INTO DATA(dref) INDEX 3.
-```
-... using a [table expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expression_glosry.htm "Glossary Entry").
-The code snippet shows how to read a line into a structure declared inline. The index is given in square brackets.
-``` abap
-DATA(ls_table_exp) = itab[ 3 ].
-```
-
-**Sequentially reading** ...
-
-... a row from a database table into a structure. A `SELECT` loop can be specified with the syntax `SELECT ... ENDSELECT.`.
-In the following example, the row found and returned in a structure declared inline can be processed further.
-``` abap
-SELECT FROM zdemo_abap_fli
- FIELDS *
- WHERE carrid = 'AZ'
- INTO @DATA(ls_sel_loop).
-
- IF sy-subrc = 0.
- ...
- ENDIF.
-ENDSELECT.
-```
-... a line from an internal table into a structure using a [`LOOP AT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_variants.htm) statement. There are many ways to specify the condition on which the loop is based. The following example covers the option of reading all lines sequentially into a field symbol declared inline. When using a field symbol, you can, for example, directly modify components.
-``` abap
-LOOP AT itab ASSIGNING FIELD-SYMBOL().
- -comp1 = ...
- ...
-ENDLOOP.
-```
-
-**Inserting a single row into a database table from a structure** using ABAP SQL statements with
-[`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_dbtab.htm). The following statements can be considered as alternatives. The third statement shows that instead of inserting a row from an existing structure, you can create and fill a structure directly.
-Note that you should avoid inserting a row with a particular key into the database table if a row with the same key already exists.
-``` abap
-INSERT INTO dbtab VALUES @struc.
-
-INSERT dbtab FROM @struc.
-
-INSERT dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
-```
-**Updating a single row in a database table from a structure** using ABAP SQL statements with [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapupdate.htm). Note that this syntax changes the entire row and all of its components.
-``` abap
-UPDATE dbtab FROM @struc.
-
-UPDATE dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
-```
-If you want to update a database table row from a structure by specifying components to be changed without overwriting other components, you can use the following method. First, read the desired row from the database table into a structure. Then, use the `VALUE` operator with the `BASE` addition and specify the components to be changed.
-``` abap
-SELECT SINGLE *
- FROM dbtab
- WHERE ...
- INTO @DATA(wa).
-
-UPDATE dbtab FROM @( VALUE #( BASE wa comp2 = ... comp4 = ... ) ).
-```
-**Updating or creating a single row in a database table from a structure** using ABAP SQL statements with
-[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_dbtab.htm). If a row with the same key as specified in the structure already exists in the database table, the row is updated. If no row with the keys specified in the structure exists, a new row is created in the database table.
-``` abap
-MODIFY dbtab FROM @struc.
-
-MODIFY dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
-```
-**Adding lines to and updating single lines in an internal table from a structure** using `INSERT`,
-`APPEND`, and `MODIFY` statements.
-- Note that all statements, including `INSERT` and `MODIFY`, are ABAP statements in this context, not ABAP SQL statements.
-- Both `INSERT` and `APPEND` add one or more lines 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 the table. If you do not specify the position, the lines are also added at the bottom of the table. However, unlike `APPEND`, `INSERT` does not set `sy-tabix`.
-- `MODIFY` changes the content of an internal table entry.
-- Statements using the `VALUE` operator to directly create and populate the structures are also possible. For more information and code
-snippets, see the [Internal Tables](01_Internal_Tables.md#) cheat sheet.
-``` abap
-INSERT struc INTO TABLE itab.
-
-APPEND struc TO itab.
-
-MODIFY TABLE itab FROM struc.
-```
-
-
-
-## Excursion: Including Structures
-
-- [`INCLUDE TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinclude_type.htm)
-and [`INCLUDE STRUCTURE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinclude_type.htm) statements
-are used in the context of local structures.
-- Structured data objects and types created with `... BEGIN OF... END OF ...` can use this syntax to include components of another structure, whether it is a locally defined or global structure, without creating substructures.
-- `INCLUDE TYPE` can be used to include a structured type.
-- You can use `INCLUDE STRUCTURE` to include a structure.
-
-> **💡 Note**
-> - They are not additions of `... BEGIN OF ... END OF ...` but individual ABAP statements.
-> - If you use a chained statement with a colon to declare the structure, the inclusion of other structures with these statements interrupts the chained statement, that is, the components of the included structures are included as direct components of the [superstructure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperstructure_glosry.htm "Glossary Entry").
->- By using the optional `AS` addition and specifying a name, the included components can be addressed by this common name as if they were actually components of a substructure.
->- The optional `RENAMING WITH SUFFIX` addition, followed by a name, gives the included components a suffix name to avoid naming conflicts with other components.
-
-The following example shows how structured types and data objects are included in another structure. First, three structured types and a structured data object based on one of these types are created. Then, the types and the structure are included in the structured type `address_type`. The executable example demonstrates a structure that includes other structures in this way.
-``` abap
-TYPES: BEGIN OF name_type,
- title TYPE string,
- prename TYPE string,
- surname TYPE string,
- END OF name_type,
- BEGIN OF street_type,
- name TYPE string,
- num TYPE string,
- END OF street_type,
- BEGIN OF city_type,
- zipcode TYPE string,
- name TYPE string,
- END OF city_type.
-
-DATA city_struc TYPE city_type.
-
-TYPES BEGIN OF address_type.
- INCLUDE TYPE name_type AS name.
- INCLUDE TYPE street_type AS street RENAMING WITH SUFFIX _street.
- INCLUDE STRUCTURE city_struc AS city RENAMING WITH SUFFIX _city.
-TYPES END OF address_type.
-```
-
-
-
-
-## Executable Example
-[zcl_demo_abap_structures](./src/zcl_demo_abap_structures.clas.abap)
-
-> **💡 Note**
-> - The executable example covers the following topics, among others:
-> - Creating structures and structured types
-> - Variants of structures
-> - Accessing, populating, and clearing structures
-> - Structures in the context of tables
-> - Including structures
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+
+
+# Structures
+
+- [Structures](#structures)
+ - [Introduction](#introduction)
+ - [Creating Structures and Structured Types](#creating-structures-and-structured-types)
+ - [Variants of Structures](#variants-of-structures)
+ - [Accessing (Components of) Structures](#accessing-components-of-structures)
+ - [Populating Structures](#populating-structures)
+ - [Using the VALUE Operator](#using-the-value-operator)
+ - [Using the NEW Operator](#using-the-new-operator)
+ - [Using the CORRESPONDING Operator and MOVE-CORRESPONDING Statements](#using-the-corresponding-operator-and-move-corresponding-statements)
+ - [Clearing Structures](#clearing-structures)
+ - [Processing Structures](#processing-structures)
+ - [Excursion: Including Structures](#excursion-including-structures)
+ - [Executable Example](#executable-example)
+
+## Introduction
+Structures ...
+
+- are [data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm "Glossary Entry")
+ with [structured data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructured_type_glosry.htm "Glossary Entry") (which is a [complex data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplex_data_type_glosry.htm "Glossary Entry") because it is composed of other data types).
+- consist of a sequence of [components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_glosry.htm "Glossary Entry") of any data type, that is, the components of a structure can be, for example, [elementary data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_object_glosry.htm), structures themselves, [internal tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninternal_table_glosry.htm "Glossary Entry") or [references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm).
+- are used to combine different data objects that belong together. A typical example is an address. It has several components, such as name, street, city, and so on, that belong together.
+- play an important role in the context of internal tables and [database tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_table_glosry.htm "Glossary Entry"). Structured types serve as [line types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrow_type_glosry.htm) for these tables. Most internal tables across [ABAP programs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm) may have structured line types. For database tables, there is no alternative to structured line types.
+- can be created locally in an ABAP program. You can also create them as global [DDIC structures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_structure_glosry.htm) in the [ABAP Dictionary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_dictionary_glosry.htm). Such a DDIC structure defines a globally available structured type ([DDIC type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_type_glosry.htm)).
+ - Note: There are other structured types available globally, which may be the structured types most commonly used in ABAP programs:
+ - [Database tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_db_table_glosry.htm) defined in the ABAP Dictionary can be used as data types just like DDIC structures in an ABAP program. This means that when you create a structure in your ABAP program, for example, you can simply use the name of a database table to address the line type of the table. The structure you created will then have the same structured type as the database table. Typically, you use the database tables to create structures of such a type, or internal tables of such a structured line type, to process data read from the database table in structures or internal tables.
+ - A [CDS entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_glosry.htm) such as a [CDS view](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm) also represents a structured data type and can be used as such in ABAP programs (but not in the ABAP Dictionary). The same applies to [DDIC views](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_view_glosry.htm) that are only available in [Standard ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_abap_glosry.htm).
+ - Structures and structured data types can also be defined in the public [visibility section](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm) of [global classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm) or in [global interfaces](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_interface_glosry.htm) and then used globally.
+
+
+
+## Creating Structures and Structured Types
+
+The typical language elements for creating structures and structured types locally in an ABAP program are [`BEGIN OF ... END OF ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes_struc.htm). They are used in combination with the [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm) keyword to create a structured type and the [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) keyword to create a structure.
+
+> **💡 Note**
+> This cheat sheet focuses on locally defined structures and structured types.
+
+**Creating structured types**
+
+- The following statement defines a structured type introduced by `TYPES`. The type name is preceded by `BEGIN OF` (which marks the beginning of the structured type definition) and `END OF` (the end of the definition).
+- The components - at least one must be defined - are listed in between.
+- Such structured type definitions are usually grouped together in a [chained statement](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenchained_statement_glosry.htm), i.e. `TYPES` is followed by a colon, and the components are separated by commas.
+
+
+``` abap
+TYPES: BEGIN OF struc_type,
+ comp1 TYPE ...,
+ comp2 TYPE ...,
+ comp3 TYPE ...,
+ ...,
+ END OF struc_type.
+```
+
+Alternatively, you can also use the following syntax. However, a chained statement provides better readability.
+``` abap
+TYPES BEGIN OF struc_type.
+ TYPES comp1 TYPE ... .
+ TYPES comp2 TYPE ... .
+ TYPES comp3 TYPE ... .
+ ... .
+TYPES END OF struc_type.
+```
+
+- The simplest structures and structured types have [elementary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm "Glossary Entry")
+components.
+- As mentioned above, the components can be of any type, i.e. they can be of structured types themselves, internal table types, or [reference types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_type_glosry.htm).
+- You can use the [`TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_simple.htm)
+and [`LIKE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_referring.htm) additions for the types of the components.
+You can use the `LINE OF` addition to refer to a table type or an internal table.
+
+
+``` abap
+TYPES: BEGIN OF struc_type,
+ comp1 TYPE i, "elementary type
+ comp2 TYPE c LENGTH 5, "elementary type
+ comp3 TYPE structured_type, "structured type
+ comp4 TYPE itab_type, "internal table type
+ comp5 TYPE ddic_type, "DDIC type
+ comp6 TYPE REF TO i, "data reference
+ comp7 LIKE data_object, "deriving type from a data object
+ comp8 TYPE LINE OF itab_type, "component has structured type, type derived from internal table type
+ comp9 LIKE LINE OF itab, "component has structured type, type derived from internal table
+ comp10, "no TYPE/LIKE specification: component is of type c length 1
+ ...,
+ END OF struc_type.
+```
+
+
+> **💡 Note**
+> Outside of classes, you can also refer to DDIC types using `LIKE` (`... comp11 LIKE ddic_type, ...`). If you actually want to refer to an existing data object, but due to typing errors you inadvertently specify a name that exists as DDIC type, errors may be unavoidable.
+
+
+**Creating structures**
+
+- To create a structure in an ABAP program, you can use the `DATA` keyword. - It works in the same way as the `TYPES` statement above.
+- Unlike the `TYPES` statement, you can use the [`VALUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_options.htm) addition to set default values.
+
+``` abap
+DATA: BEGIN OF struc,
+ comp1 TYPE ...,
+ comp2 TYPE ... VALUE ...,
+ comp3 TYPE i VALUE 99,
+ comp4 TYPE i VALUE IS INITIAL, "Without the addition VALUE, or if IS INITIAL is specified,
+ "the content is initial.
+ comp5 TYPE local_structured_type,
+ ...,
+ END OF struc.
+```
+
+Alternatively, you can use the following syntax. Similar to above, a chained statement provides better readability.
+
+``` abap
+DATA BEGIN OF struc.
+ DATA comp1 TYPE ... .
+ DATA comp2 TYPE ... VALUE ... .
+... .
+DATA END OF struc.
+```
+
+> **💡 Note**
+>- The keywords [`CLASS-DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass-data.htm) and [`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm) can also be used to create structures. In principle, they represent special cases of the general statement shown above. See the ABAP Keyword Documentation for more information.
+>- Structures can also be created [inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm) using [`DATA(...)`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm) or [`FINAL(...)`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm), as shown below.
+
+Creating structures using existing structured types:
+
+``` abap
+"Local structured type
+TYPES: BEGIN OF struc_type,
+ comp1 TYPE i,
+ comp2 TYPE c LENGTH 5,
+ END OF struc_type.
+
+"Creating a structure using a local structured type
+DATA struc_1 TYPE struc_type.
+
+"Creating structures based on globally available types from the DDIC
+"Note: When referring to such types, you cannot provide start values for the individual components.
+DATA: struc_2 TYPE some_ddic_structure,
+ struc_3 TYPE some_ddic_table,
+ struc_4 TYPE some_cds_view.
+
+"Structure based on a structured type that is available in the public
+"visibility section of a global class
+DATA struc_5 TYPE cl_some_class=>struc_type.
+
+"Creating structures by referring to local data objects and internal table types
+DATA: struc_6 LIKE struc_1,
+ struc_7 LIKE LINE OF some_itab,
+ struc_8 TYPE LINE OF some_itab_type.
+```
+
+
+Creating structures by inline declaration using `DATA(...)`
+- This is particularly useful for declaring data objects at the [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm) where you actually need them.
+- In this way, you can avoid an extra declaration of the structure in different contexts.
+- You can also use the [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) declaration operator to create [immutable variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenimmutable_variable_glosry.htm).
+
+``` abap
+"Structures created inline instead of an extra declared variable
+DATA struc_9 LIKE struc_1.
+struc_9 = struc_1
+
+"Type is derived from the right-hand structure; the content of struc is assigned, too.
+DATA(struc_10) = struc_1.
+FINAL(struc_11) = struc_9.
+
+"Structures declared inline instead of an extra declared variable
+
+"Example: SELECT statement
+"Extra declaration
+DATA struc_12 TYPE zdemo_abap_fli.
+
+SELECT SINGLE *
+ FROM zdemo_abap_fli
+ WHERE carrid = 'LH'
+ INTO @struc_12.
+
+"Inline declaration
+SELECT SINGLE *
+ FROM zdemo_abap_fli
+ WHERE carrid = 'LH'
+ INTO @DATA(struc_13).
+
+"Example: Loop over an internal table
+DATA itab TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
+... "itab is filled
+
+"Extra declaration
+DATA wa_1 LIKE LINE OF itab.
+
+LOOP AT itab INTO wa_1.
+ ...
+ENDLOOP.
+
+"Inline declaration
+LOOP AT itab INTO DATA(wa_2).
+ ...
+ENDLOOP.
+```
+
+
+
+## Variants of Structures
+
+Depending on the component type, the structure can be a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm "Glossary Entry"),
+a [nested structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennested_structure_glosry.htm "Glossary Entry"),
+or a [deep structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm "Glossary Entry").
+
+- **Flat structures** contain only elementary types that have a fixed length, that is, there are no internal tables, reference types or strings as components. Nesting does not matter in this context. Even a nested structure is considered flat unless a substructure contains a deep component.
+ ``` abap
+ DATA: BEGIN OF struc,
+ comp1 TYPE i,
+ comp2 TYPE c LENGTH 15,
+ comp3 TYPE p LENGTH 8 DECIMALS 2,
+ ...,
+ END OF struc.
+ ```
+
+- **Nested structures**: At least one component of a structure is a [substructure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstructure_glosry.htm "Glossary Entry"),
+that is, it refers to another structure. The following example has multiple substructures.
+ ``` abap
+ DATA: BEGIN OF address_n,
+ BEGIN OF name,
+ title TYPE string VALUE `Mr.`,
+ prename TYPE string VALUE `Duncan`,
+ surname TYPE string VALUE `Pea`,
+ END OF name,
+ BEGIN OF street,
+ name TYPE string VALUE `Vegetable Lane`,
+ num TYPE string VALUE `11`,
+ END OF street,
+ BEGIN OF city,
+ zipcode TYPE string VALUE `349875`,
+ name TYPE string VALUE `Botanica`,
+ END OF city,
+ END OF address_n.
+ ```
+
+- **Deep structures**: Contains at least one internal table, reference type, or string as a component.
+ ``` abap
+ DATA: BEGIN OF address_d,
+ name TYPE string VALUE `Mr. Duncan Pea`,
+ street TYPE string VALUE `Vegetable Lane 11`,
+ city TYPE string VALUE `349875 Botanica`,
+ details TYPE TABLE OF some_table WITH EMPTY KEY,
+ END OF address_d.
+ ```
+ Although the following structure looks quite simple, it is not a flat structure, but a deep structure, because it contains strings.
+ ``` abap
+ DATA: BEGIN OF address,
+ name TYPE string VALUE `Mr. Duncan Pea`,
+ street TYPE string VALUE `Vegetable Lane 11`,
+ city TYPE string VALUE `349875 Botanica`,
+ END OF address.
+ ```
+
+> **💡 Note**
+>- The data types of DDIC types are all flat (not nested) structures. Exception: Components of type `string` can be contained.
+>- [Work areas](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm) of ABAP SQL statements cannot contain any deep components other than strings among others.
+>- Especially for assignments and comparisons of deep structures, the compatibility of the source and target structure must be taken into account.
+
+
+
+## Accessing (Components of) Structures
+
+- Structures can be accessed as a whole. You can also address the individual components of structures at the appropriate operand positions.
+- To address the components, use the [structure component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructure_component_sel_glosry.htm "Glossary Entry")
+`-`.
+- For variables with reference to a structured data object, the [object component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm) `->` can be used: `...dref->comp ...`. The following syntax also works, but is less *convenient*: `... dref->*-comp ...`.
+- ADT and the ABAP Editor provide code completion for structure components after the component selectors.
+``` abap
+"Addressing components via the structure component selector
+... struc-comp1 ...
+... struc-comp2 ...
+... struc-comp3 ...
+
+"Examples for addressing the whole structure and individual components
+IF struc IS INITIAL.
+ ...
+ENDIF.
+
+IF struc-comp1 = 1.
+ ...
+ENDIF.
+
+DATA(complete_struc) = struc.
+DATA(comp_value) = struc-comp2.
+
+"Type and data declarations
+TYPES: type_1 TYPE structured_type-comp1,
+ type_2 LIKE struc-comp1.
+
+DATA: var_1 TYPE structured_type-comp1,
+ var_2 LIKE struc-comp1.
+
+"Variables with reference to a structured data object
+DATA ref_struc_1 TYPE REF TO structured_type.
+ref_struc_1 = NEW #( ).
+"Excursion: Creating a reference variable using inline declaration
+DATA(ref_struc_2) = NEW structured_type( ).
+
+... ref_struc_1->comp1 ...
+... ref_struc_1->*-comp1 ... "Using the dereferencing operator
+... ref_struc_2->-comp2 ...
+... ref_struc_2->*-comp2 ... "Using the dereferencing operator
+```
+
+Nested components can be addressed using chaining:
+``` abap
+... struc-substructure-comp1 ...
+... address_n-name-title ...
+```
+
+> **💡 Note**
+> There are syntax options for dynamically accessing structure components. See the [Dynamic Porgramming](06_Dynamic_Programming.md) cheat sheet.
+
+
+
+## Populating Structures
+
+You can copy the content of a structure to another using the [assignment operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm) `=`.
+In the following example, it is assumed that the target and source structures are of compatible types. In general, note that special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) apply to value assignments involving structures.
+``` abap
+some_struc = another_struc.
+
+"When creating a new structure by inline declaration, the type of
+"the right-hand structure is derived and the content is assigned.
+
+DATA(struc_inl) = some_struc.
+```
+
+To assign values to individual structure components, use the component selector.
+``` abap
+TYPES: BEGIN OF addr_struc,
+ name TYPE string,
+ street TYPE string,
+ city TYPE string,
+ END OF addr_struc.
+
+DATA address TYPE addr_struc.
+
+address-name = `Mr. Duncan Pea`.
+address-street = `Vegetable Lane 11`.
+address-city = `349875 Botanica`.
+```
+
+
+
+### Using the VALUE Operator
+
+- The [`VALUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_value.htm) operator can be used to construct the content of complex data objects such as structures or internal tables.
+- It is particularly useful because assigning values by addressing the structure components individually can be very cumbersome, especially when assigning values to structure components at the [operand position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry").
+- If the type of the operand can be inferred implicitly, the `#` character can be used used before the parentheses. Otherwise, the type must be specified explicitly.
+- The `VALUE` operator and inline declarations can be used to create and populate structures in one go.
+- Note that there are special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) rules for structures. See the ABAP Keyword Documentation for more details.
+
+
+``` abap
+"# used: type of the operand can be implicitly derived
+address = VALUE #( name = `Mr. Duncan Pea`
+ street = `Vegetable Lane 11`
+ city = `349875 Botanica` ).
+
+"Declaring a structure inline
+"Type used explicitly: type of the operand cannot be implicitly derived
+DATA(addr) = VALUE addr_struc( name = `Mr. Duncan Pea`
+ street = `Vegetable Lane 11`
+ city = `349875 Botanica` ).
+
+"Nesting value operators
+TYPES: BEGIN OF struc_nested,
+ a TYPE i,
+ BEGIN OF nested_1,
+ b TYPE i,
+ c TYPE i,
+ END OF nested_1,
+ BEGIN OF nested_2,
+ d TYPE i,
+ e TYPE i,
+ END OF nested_2,
+ END OF struc_nested.
+
+DATA str_1 TYPE struc_nested.
+
+str_1 = VALUE #( a = 1
+ nested_1 = VALUE #( b = 2 c = 3 )
+ nested_2 = VALUE #( d = 4 e = 5 ) ).
+
+"Inline declaration
+"Component a is not specified here, i.e. its value remains initial.
+DATA(str_2) = VALUE struc_nested( nested_1 = VALUE #( b = 2 c = 3 )
+ nested_2 = VALUE #( d = 4 e = 5 ) ).
+
+"Apart from the VALUE operator, the NEW operator can be used to create
+"a data reference variable (and populate the structure)
+DATA(str_ref) = NEW struc_nested( a = 1
+ nested_1 = VALUE #( b = 2 c = 3 )
+ nested_2 = VALUE #( d = 4 e = 5 ) ).
+```
+
+
+
+### Using the NEW Operator
+
+Using the instance operator [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_new.htm), you can create [anonymous data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm "Glossary Entry"), such as anonymous structures. You can access the components or the entire data objects by [dereferencing](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendereferencing_operat_glosry.htm). For more information, refer to the [Dynamic Programming](06_Dynamic_Programming.md) and [Constructor Expressions](05_Constructor_Expressions.md) cheat sheets.
+
+```abap
+"Creating a data reference variable
+DATA addr_ref1 TYPE REF TO addr_struc.
+
+"Populating the anonymous structure
+addr_ref1 = NEW #( name = `Mr. Duncan Pea`
+ street = `Vegetable Lane 11`
+ city = `349875 Botanica` ).
+
+addr_ref1->name = `Mrs. Jane Doe`.
+
+"Declaring an anonymous structure/a data reference variable inline
+DATA(addr_ref2) = NEW addr_struc( name = `Mr. Duncan Pea`
+ street = `Vegetable Lane 11`
+ city = `349875 Botanica` ).
+
+addr_ref2->* = VALUE #( BASE addr_ref2->* name = `Mr. John Doe` ).
+```
+
+
+
+### Using the CORRESPONDING Operator and MOVE-CORRESPONDING Statements
+
+- You can use statements with [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm)
+and the [`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator to assign values to structure components, especially when assigning values from a source structure to a target structure which have incompatible types and/or differently named components.
+- Both are used to assign identically named components of structures to each other.
+- The syntax also works for structures of the same type.
+- Also note the special [conversion](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_struc.htm) and [comparison](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules_operands_struc.htm) rules for structures in this context.
+
+> **💡 Note**
+>- The [`CL_ABAP_CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencl_abap_corresponding.htm) system class is available for making assignments. See the ABAP Keyword Documentation for the details.
+>- The `INTO` clause of ABAP SQL statements has the `CORRESPONDING` addition. There, the following basic rule applies, which affects the value assignment: Without the `CORRESPONDING ...` addition, column names do not matter, only the position. With the `CORRESPONDING ...` addition, the position of the columns does not matter, only the name. See examples in the ABAP SQL cheat sheet.
+
+The following examples demonstrate the value assignment using `MOVE-CORRESPONDING` statements and the `CORRESPONDING` operator with various additions.
+The focus is on flat structures only.
+
+``` abap
+"Moves identically named components; content in other components
+"of the targets structure are kept.
+MOVE-CORRESPONDING struc TO diff_struc.
+
+"Initializes target structure; moves identically named components
+diff_struc = CORRESPONDING #( struc ).
+
+"Same effect as the first MOVE-CORRESPONDING statement;
+"addition BASE keeps existing content
+diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc ).
+
+"MAPPING addition: Specifying components of a source structure that are
+"assigned to the components of a target structure in mapping
+"relationships.
+diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc MAPPING comp1 = compa ).
+
+"EXCEPT addition: Excluding components from the assignment.
+diff_struc = CORRESPONDING #( BASE ( diff_struc ) struc EXCEPT comp1 ).
+```
+
+Value assignments in deep structures
+- In the context of deep structures, there are additional syntax variants available for [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm) statements and the [`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator.
+- The following examples focus on internal tables as structure components. Check out the syntax in action in the executable example.
+
+``` abap
+"Nonidentical elementary component types are kept in target
+"structure which is true for the below MOVE-CORRESPONDING statements;
+"existing internal table content is replaced by content of
+"the source table irrespective of identically named components
+MOVE-CORRESPONDING deep_struc TO diff_deep_struc.
+
+"Existing internal table content is replaced but the value
+"assignment happens for identically named components only.
+MOVE-CORRESPONDING deep_struc TO diff_deep_struc EXPANDING NESTED TABLES.
+
+"Existing internal table content is kept; table content of the source
+"structure are added but the value assignment happens like the first
+"MOVE-CORRESPONDING statement without further syntax additions.
+MOVE-CORRESPONDING deep_struc TO diff_deep_struc KEEPING TARGET LINES.
+
+"Existing internal table content is kept; table content of the source
+"structure are added; the value assignment happens like the statement
+"MOVE-CORRESPONDING ... EXPANDING NESTED TABLES.
+MOVE-CORRESPONDING deep_struc TO diff_deep_struc EXPANDING NESTED TABLES KEEPING TARGET LINES.
+
+"Target structure is initialized; the value assignment for an internal
+"table happens irrespective of identically named components.
+diff_deep_struc = CORRESPONDING #( deep_struc ).
+
+"Target structure is initialized; the value assignment for an internal
+"table happens for identically named components only.
+diff_deep_struc = CORRESPONDING #( DEEP deep_struc ).
+
+"Nonidentical elementary component types are kept in target structure;
+"internal table content is replaced; there, the value assignment
+"happens like using the CORRESPONDING operator without addition.
+diff_deep_struc = CORRESPONDING #( BASE ( diff_struc ) deep_struc ).
+
+"Nonidentical elementary component types are kept in target structure;
+"internal table content is replaced; there, the value assignment
+"happens like using the CORRESPONDING operator with the addition DEEP.
+diff_deep_struc = CORRESPONDING #( DEEP BASE ( diff_struc ) deep_struc ).
+
+"Nonidentical elementary component types are kept in target structure;
+"internal table content is kept, too, and table content of the
+"source structure are added; there, the value assignment
+"happens like using the CORRESPONDING operator without addition.
+diff_deep_struc = CORRESPONDING #( APPENDING BASE ( diff_struc ) deep_struc ).
+
+"Nonidentical elementary component types are kept in target structure;
+"internal table content is kept, too, and table content of the
+"source structure are added; there, the value assignment
+"happens like using the CORRESPONDING operator with the addition DEEP.
+diff_deep_struc = CORRESPONDING #( DEEP APPENDING BASE ( diff_struc ) deep_struc ).
+```
+
+
+
+## Clearing Structures
+
+You can reset individual components to their initial values and clear the
+entire structure using the [`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm) keyword.
+
+``` abap
+CLEAR struc-component.
+
+CLEAR struc.
+
+"Note: An assignment using the VALUE operator without entries in the parentheses clears the structure.
+struc = VALUE #( ).
+```
+
+
+
+## Processing Structures
+Structures are primarily used to process data from tables. In this context, structures often take on the role of a [work area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry").
+The following code snippets cover only a selection. For more examples, see the cheat sheets about internal tables and ABAP SQL.
+
+**Reading a row from a database table into a structure that has a compatible type**. Note that, since database tables are flat, the
+target structure must also be flat. In the example below, the [`SINGLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_single.htm)
+addition reads only a single row into the structure. It returns the first entry that matches the `WHERE` condition.
+
+``` abap
+"Creating a structure with a compatible type
+DATA ls_fli1 TYPE zdemo_abap_fli.
+
+SELECT SINGLE FROM zdemo_abap_fli
+ FIELDS *
+ WHERE carrid = 'LH'
+ INTO @ls_fli1.
+
+"Target structure declared inline
+SELECT SINGLE FROM zdemo_abap_fli
+ FIELDS *
+ WHERE carrid = 'LH'
+ INTO @DATA(ls_fli2).
+```
+**Reading a row from a database table into a structure that has an incompatible type**.
+Components in the structure with identical names are filled.
+
+``` abap
+SELECT SINGLE FROM zdemo_abap_fli
+ FIELDS *
+ WHERE carrid = 'AA'
+ INTO CORRESPONDING FIELDS OF @ls_fli_diff.
+```
+**Reading a line from an internal table into a structure** ...
+
+... using a `SELECT` statement. Note the specified alias name and that ABAP variables like internal tables must be escaped with `@`. The addition `INTO CORRESPONDING FIELDS OF` also applies here.
+``` abap
+SELECT SINGLE FROM @itab AS itab_alias
+ FIELDS *
+ WHERE ...
+ INTO @DATA(ls_struc).
+ "INTO CORRESPONDING FIELDS OF @some_existing_struc.
+```
+... using a `READ TABLE` statement. The code snippet below shows the reading of a line into a [work area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry"), a [field symbol](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm "Glossary Entry"), and a [data reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_variable_glosry.htm "Glossary Entry"), all of which
+represent structured data objects that are declared inline. In the following example, a line is read based on the line number by
+specifying `INDEX`. For more details, see the section *Determining the target area* in the cheat sheet [Internal Tables](01_Internal_Tables.md#).
+``` abap
+READ TABLE itab INTO DATA(wa) INDEX 1.
+
+READ TABLE itab ASSIGNING FIELD-SYMBOL() INDEX 2.
+
+READ TABLE itab REFERENCE INTO DATA(dref) INDEX 3.
+```
+... using a [table expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_expression_glosry.htm "Glossary Entry").
+The code snippet shows how to read a line into a structure declared inline. The index is given in square brackets.
+``` abap
+DATA(ls_table_exp) = itab[ 3 ].
+```
+
+**Sequentially reading** ...
+
+... a row from a database table into a structure. A `SELECT` loop can be specified with the syntax `SELECT ... ENDSELECT.`.
+In the following example, the row found and returned in a structure declared inline can be processed further.
+``` abap
+SELECT FROM zdemo_abap_fli
+ FIELDS *
+ WHERE carrid = 'AZ'
+ INTO @DATA(ls_sel_loop).
+
+ IF sy-subrc = 0.
+ ...
+ ENDIF.
+ENDSELECT.
+```
+... a line from an internal table into a structure using a [`LOOP AT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab_variants.htm) statement. There are many ways to specify the condition on which the loop is based. The following example covers the option of reading all lines sequentially into a field symbol declared inline. When using a field symbol, you can, for example, directly modify components.
+``` abap
+LOOP AT itab ASSIGNING FIELD-SYMBOL().
+ -comp1 = ...
+ ...
+ENDLOOP.
+```
+
+**Inserting a single row into a database table from a structure** using ABAP SQL statements with
+[`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_dbtab.htm). The following statements can be considered as alternatives. The third statement shows that instead of inserting a row from an existing structure, you can create and fill a structure directly.
+Note that you should avoid inserting a row with a particular key into the database table if a row with the same key already exists.
+``` abap
+INSERT INTO dbtab VALUES @struc.
+
+INSERT dbtab FROM @struc.
+
+INSERT dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
+```
+**Updating a single row in a database table from a structure** using ABAP SQL statements with [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapupdate.htm). Note that this syntax changes the entire row and all of its components.
+``` abap
+UPDATE dbtab FROM @struc.
+
+UPDATE dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
+```
+If you want to update a database table row from a structure by specifying components to be changed without overwriting other components, you can use the following method. First, read the desired row from the database table into a structure. Then, use the `VALUE` operator with the `BASE` addition and specify the components to be changed.
+``` abap
+SELECT SINGLE *
+ FROM dbtab
+ WHERE ...
+ INTO @DATA(wa).
+
+UPDATE dbtab FROM @( VALUE #( BASE wa comp2 = ... comp4 = ... ) ).
+```
+**Updating or creating a single row in a database table from a structure** using ABAP SQL statements with
+[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_dbtab.htm). If a row with the same key as specified in the structure already exists in the database table, the row is updated. If no row with the keys specified in the structure exists, a new row is created in the database table.
+``` abap
+MODIFY dbtab FROM @struc.
+
+MODIFY dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
+```
+**Adding lines to and updating single lines in an internal table from a structure** using `INSERT`,
+`APPEND`, and `MODIFY` statements.
+- Note that all statements, including `INSERT` and `MODIFY`, are ABAP statements in this context, not ABAP SQL statements.
+- Both `INSERT` and `APPEND` add one or more lines 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 the table. If you do not specify the position, the lines are also added at the bottom of the table. However, unlike `APPEND`, `INSERT` does not set `sy-tabix`.
+- `MODIFY` changes the content of an internal table entry.
+- Statements using the `VALUE` operator to directly create and populate the structures are also possible. For more information and code
+snippets, see the [Internal Tables](01_Internal_Tables.md#) cheat sheet.
+``` abap
+INSERT struc INTO TABLE itab.
+
+APPEND struc TO itab.
+
+MODIFY TABLE itab FROM struc.
+```
+
+
+
+## Excursion: Including Structures
+
+- [`INCLUDE TYPE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinclude_type.htm)
+and [`INCLUDE STRUCTURE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinclude_type.htm) statements
+are used in the context of local structures.
+- Structured data objects and types created with `... BEGIN OF... END OF ...` can use this syntax to include components of another structure, whether it is a locally defined or global structure, without creating substructures.
+- `INCLUDE TYPE` can be used to include a structured type.
+- You can use `INCLUDE STRUCTURE` to include a structure.
+
+> **💡 Note**
+> - They are not additions of `... BEGIN OF ... END OF ...` but individual ABAP statements.
+> - If you use a chained statement with a colon to declare the structure, the inclusion of other structures with these statements interrupts the chained statement, that is, the components of the included structures are included as direct components of the [superstructure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperstructure_glosry.htm "Glossary Entry").
+>- By using the optional `AS` addition and specifying a name, the included components can be addressed by this common name as if they were actually components of a substructure.
+>- The optional `RENAMING WITH SUFFIX` addition, followed by a name, gives the included components a suffix name to avoid naming conflicts with other components.
+
+The following example shows how structured types and data objects are included in another structure. First, three structured types and a structured data object based on one of these types are created. Then, the types and the structure are included in the structured type `address_type`. The executable example demonstrates a structure that includes other structures in this way.
+``` abap
+TYPES: BEGIN OF name_type,
+ title TYPE string,
+ prename TYPE string,
+ surname TYPE string,
+ END OF name_type,
+ BEGIN OF street_type,
+ name TYPE string,
+ num TYPE string,
+ END OF street_type,
+ BEGIN OF city_type,
+ zipcode TYPE string,
+ name TYPE string,
+ END OF city_type.
+
+DATA city_struc TYPE city_type.
+
+TYPES BEGIN OF address_type.
+ INCLUDE TYPE name_type AS name.
+ INCLUDE TYPE street_type AS street RENAMING WITH SUFFIX _street.
+ INCLUDE STRUCTURE city_struc AS city RENAMING WITH SUFFIX _city.
+TYPES END OF address_type.
+```
+
+
+
+
+## Executable Example
+[zcl_demo_abap_structures](./src/zcl_demo_abap_structures.clas.abap)
+
+> **💡 Note**
+> - The executable example covers the following topics, among others:
+> - Creating structures and structured types
+> - Variants of structures
+> - Accessing, populating, and clearing structures
+> - Structures in the context of tables
+> - Including structures
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
\ No newline at end of file
diff --git a/03_ABAP_SQL.md b/03_ABAP_SQL.md
index 677771c..49a49e0 100644
--- a/03_ABAP_SQL.md
+++ b/03_ABAP_SQL.md
@@ -1,1720 +1,1689 @@
-
-
-# ABAP SQL
-
-- [ABAP SQL](#abap-sql)
- - [Introduction](#introduction)
- - [Excursion: Database Tables and Views](#excursion-database-tables-and-views)
- - [Reading Data Using SELECT](#reading-data-using-select)
- - [Basic Syntax](#basic-syntax)
- - [Using SELECT for Multiple Purposes](#using-select-for-multiple-purposes)
- - [Clause Variations and Additions in SELECT Statements](#clause-variations-and-additions-in-select-statements)
- - [More Clauses](#more-clauses)
- - [Operands and Expressions in ABAP SQL Statements](#operands-and-expressions-in-abap-sql-statements)
- - [SQL operands](#sql-operands)
- - [SQL Expressions](#sql-expressions)
- - [Elementary Expressions](#elementary-expressions)
- - [SQL Functions](#sql-functions)
- - [More SQL Expressions](#more-sql-expressions)
- - [Window Expressions](#window-expressions)
- - [SQL Conditions](#sql-conditions)
- - [Selecting Data by Evaluating the Content of Other Tables](#selecting-data-by-evaluating-the-content-of-other-tables)
- - [Combining Data of Multiple Database Tables](#combining-data-of-multiple-database-tables)
- - [Common Table Expressions (CTE)](#common-table-expressions-cte)
- - [Changing Data in Database Tables](#changing-data-in-database-tables)
- - [Using `INSERT`](#using-insert)
- - [Using `UPDATE`](#using-update)
- - [Using `MODIFY`](#using-modify)
- - [Using `DELETE`](#using-delete)
- - [More Information](#more-information)
- - [Executable Example](#executable-example)
-
-## Introduction
-
-- [ABAP SQL](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_glosry.htm) is a subset of [SQL](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_glosry.htm "Glossary Entry")
- which is the standardized language for accessing databases.
-- The main ABAP SQL keywords to read and change data are the
- following:
-
- | Keyword | Purpose |
- | -------- | ------------------------------------------------------------------------- |
- | `SELECT` | Reads data from database tables |
- | `INSERT` | Adds rows to database tables |
- | `UPDATE` | Changes the content of rows of database tables |
- | `MODIFY` | Inserts rows into database tables or changes the content of existing rows |
- | `DELETE` | Deletes rows from database tables |
-
-- ABAP SQL statements use the ABAP SQL interface. This interface transforms all ABAP SQL statements that access the standard database of an AS ABAP to platform-dependent SQL and forwards the results to the database system.
-- Generally bear in mind the [performance notes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql_perfo.htm) when using
- ABAP SQL. The considerations there are not relevant for this cheat sheet since
- the focus is on syntax options.
-
-## Excursion: Database Tables and Views
-
-
- Expand to view the details
-
-
-This section provides bullet points on database tables and views which contain persisted data. Note that the code snippets in this cheat sheet focus on database tables as [data source](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_source_glosry.htm "Glossary Entry") for ABAP SQL statements.
-
-**Database tables in [AS ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenas_abap_glosry.htm "Glossary Entry") ...**
-
-- are objects of the [ABAP Dictionary (DDIC)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_dictionary_glosry.htm "Glossary Entry"). The term *database table* describes a physical database table in the current [standard database](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_db_glosry.htm).
-- are two-dimensional matrices consisting of rows and columns.
-- contain a [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm), i. e. a field or a combination of fields uniquely identifies every row in a table. A [primary key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_key_glosry.htm) must exist for every database table.
- - Note the concept of [foreign keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenforeign_key_glosry.htm) in which one or more columns of a database table can be primary keys of another table. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_forkey.htm).
-- have a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm "Glossary Entry")
- type. Plus, the definition of database tables consists of [technical](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_techstruc.htm) and [semantic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_semastruc.htm) properties.
-- can be referenced as a data type and can be accessed using ABAP SQL.
-
-Find more information in the respective (sub)topics in the ABAP Keyword Documentation [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables.htm).
-
-
-**Views ...**
-
-- are further ABAP Dictionary objects for grouping columns from one or more database tables, among others.
-- usually realize a
- [join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenjoin_glosry.htm "Glossary Entry")
- with defined [join
- conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenjoin_condition_glosry.htm "Glossary Entry").
-- Note:
- - Similar to database tables, the columns of such a view form a
- flat structure. The view's name can be used, for example, as [data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_type_glosry.htm) to declare
- [data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm), too.
- - The views can be accessed by ABAP SQL, especially for reading
- purposes using `SELECT`.
-
-**"Classic"** [DDIC
-Views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenddic_view_glosry.htm "Glossary Entry") ...
-
-- are the oldest form of views and are not available in [ABAP Cloud](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_cloud_glosry.htm).
-- can be accessed by ABAP SQL for read and write operations, however, writing is only supported if the view is created with only one database table.
-- can only be created in the [ABAP Workbench](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_workbench_glosry.htm).
-
-**"Modern" Views (since release 7.40)**
-
-- [External
- views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexternal_view_glosry.htm "Glossary Entry")
- as proxies for [SAP HANA
- views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenhana_view_glosry.htm "Glossary Entry")
- (attribute view, analytic view, calculation view)
- - SAP HANA Views are entities of the SAP HANA database that are
- defined using the [SAP HANA
- Studio](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenhana_studio_glosry.htm "Glossary Entry").
- - They are based on HANA-specific data types.
- - Using external views of the ABAP dictionary, you can make those
- SAP HANA views "known" to the ABAP program. In doing so, the
- external views can be used like classic DDIC views as structured
- data types and as a source for reading operations with ABAP SQL.
- - To be used only if the central database of the AS ABAP is an
- [SAP HANA
- database](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhana_database_glosry.htm "Glossary Entry").
-- [ABAP Core Data Services (ABAP
- CDS)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm "Glossary Entry")
- ...
- - serve the purpose of defining semantically rich data models.
- - have a lot more options than classic views, for example, they
- support [annotations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_annotation_glosry.htm). Data sources can be combined using [associations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_association_glosry.htm), views can be defined with input parameters, and more.
- - are used like a classic database view as structured data types
- and used as a source for reading operations with ABAP SQL (using
- [`SELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm)).
- - are created using [Data Definition
- Language (DDL)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddl_glosry.htm "Glossary Entry")
- in the
- [ADT](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenadt_glosry.htm "Glossary Entry")
- (that is, a source code editor, in contrast to a form-based
- editor).
- - are, in contrast to external views, supported by all database
- systems (that support the ABAP CDS characteristics).
-
-
-
-
-## Reading Data Using SELECT
-
-### Basic Syntax
-
-You use ABAP SQL `SELECT` statements to read data from one or more database tables (or views). This can be done to create a multirow or single row result set by assigning the result set to a suitable data object, i. e. you can store the multirow read result in an internal table or the single row result in a structure.
-The `SELECT` statement includes several clauses that serve
-different purposes. The following code snippet shows the basic syntax:
-``` abap
-SELECT FROM source "What database table or view to read from
- FIELDS field_list "What columns should be read
- WHERE condition "Specifies conditions on which a row/rows should be read
- INTO @target. "Data object to which the result set is assigned (preceded by @)
-```
-> **💡 Note**
->- There are further clauses available of which some are dealt with
- further down. In general, the recommendation is to hit `F1` for the keywords and additions to get all the details in the ABAP Keyword Documentation.
->- Especially in older ABAP programs, you will see other forms of the
- `SELECT` syntax that you should no longer use. Strict syntax check modes might enforce the use
- of specific ABAP SQL syntax. For example, the `INTO` clause should be placed after the other clauses. Furthermore, [host variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm "Glossary Entry") or [host expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_expression_glosry.htm "Glossary Entry") are required for data objects and expressions, i. e. they must be preceded by `@` or `@( ... )`. Further information: [Release-Dependent Syntax Check Modes (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_strict_modes.htm).
->- Regarding host variables as in `SELECT ... INTO @target.` and since they are used in most examples below: A host variable is a data object that is
-> - declared in the ABAP program
-> - prefixed with the `@` character and
-> - specified in an [operand position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm) of an ABAP SQL statement.
-> See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm).
->- The `SELECT` list, i. e. the fields that are specified, can also be specified following the `SELECT`
- keyword before the `FROM` clause - without `FIELDS`. The
- following two `SELECT` statements are basically the same but differently arranged:
-> ``` abap
-> SELECT FROM dbtab
-> FIELDS comp1, comp2, comp3
-> ...
->
-> SELECT comp1, comp2, comp3
-> FROM dbtab
-> ...
-> ```
->- Regarding the target into which data is read: Instead of using a
- variable that is (extra) declared beforehand, you can also make use
- of [inline
- declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry"),
- for example `... INTO TABLE @DATA(itab).`, to comfortably
- create an appropriate variable in place. Note that in case of
- internal tables as targets, the resulting table is a standard table
- and has an empty key which might have an impact when further
- processing the internal table entries. Find more information in the
- ABAP cheat sheet [Internal Tables](01_Internal_Tables.md). In newer ABAP releases, the declaration operator [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) can be used to declare immutable variables.
-
-
-
-### Using SELECT for Multiple Purposes
-
-**Reading a single row into a structure**
-``` abap
-"SINGLE addition
-"Here, all fields of a single row a read. Specifying an
-"asterisk * indicates that all fields are to be read.
-"Alternatively, you can list all the fields separated by comma.
-"Note that if the selection covers more than one row, e. g. in case
-"of a non-unique WHERE clause, one of these rows is included in
-"the result.
-
-SELECT SINGLE FROM dbtab
- FIELDS *
- WHERE ...
- INTO @struc. "Existing structure of dbtab's row type
-
-"Reading a selected set of fields of a single row
-
-SELECT SINGLE FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE ...
- INTO @DATA(struc2). "Structure declared inline
-
-"Alternative syntax without the FIELDS addition
-"Here, the CORRESPONDING FIELDS OF addition is used. Only the content of
-"columns that have identically named components in the target data object
-"is assigned.
-
-SELECT SINGLE comp1, comp2, comp3 "Selected set of fields
- FROM dbtab
- WHERE ...
- INTO CORRESPONDING FIELDS OF @struc. "Existing structure
-```
-> **💡 Note**
->- Although its use is optional, a `WHERE` clause should be specified to further restrict the read result.
->- Regarding the addition `CORRESPONDING FIELDS OF` in the `INTO`
- clause: As mentioned, only the content of columns for which there are identically named components in the target are assigned. However, if you want to read data into an existing data object and particular fields are specified in the `SELECT` list and if the addition is **not** specified, you might stumble on undesired results. The target data object must contain enough components and the content of the columns are assigned to the components of the target from left to right in the order specified after `SELECT`. The content of surplus components of the target is not changed. Plus, pay attention to [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm). Basic rule: Without `CORRESPONDING ...`, column names do not play a role but only the position. With `CORRESPONDING ...`, the position of the columns does not play a role but only the name.
->- Find more information regarding the addition `INTO` [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm).
-
-**Reading multiple rows into an internal table**.
-``` abap
-SELECT FROM dbtab
- FIELDS * "All fields
- WHERE ...
- INTO TABLE @itab. "itab has an appropriate row type
-
-"Alternative syntax without the FIELDS addition
-
-SELECT comp1, comp2, comp3 "Selected set of fields
- FROM dbtab
- WHERE ...
- INTO TABLE @DATA(lv_itab). "Internal table declared inline
-
-"Selected set of fields, existing variable
-"See the note on CORRESPONDING FIELDS OF above
-
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3 "Selected set of fields
- WHERE ...
- INTO CORRESPONDING FIELDS OF TABLE @itab.
-```
-
-**`SELECT` loop: Sequentially reading multiple rows**.
-- A `SELECT` loop can be opened if the assignment is made to a structure and the addition `SINGLE` is not used.
-- If the row is found, the system field `sy-subrc` is set to `0`.
-- The loop must be closed using `ENDSELECT`.
-- To terminate the loop completely, you can use the statement [`EXIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapexit_loop.htm).
-- Note: As covered further down, when using the addition `PACKAGE SIZE` and storing the result in a table, a loop is opened, too.
-
-``` abap
-SELECT FROM dbtab
- FIELDS *
- WHERE ...
- INTO @struc.
-
- IF sy-subrc = 0.
- ... "For example, making changes on data and adding the row to an internal table.
-
- ENDIF.
-
-ENDSELECT.
-```
-
-
-### Clause Variations and Additions in SELECT Statements
-
-`SELECT`/`FROM` clauses:
-
-**Checking the existence of a row in a database table**
-``` abap
-"Instead of @abap_true, you could also use 'X'.
-
-SELECT SINGLE @abap_true
- FROM dbtab
- WHERE ...
- INTO @DATA(exists).
-
-IF exists = abap_true.
- ...
-ENDIF.
-```
-
-**Removing rows that occur more than once in a multirow result set** using the `DISTINCT` addition.
-- Cannot be used with the addition `SINGLE`.
-- See more information here [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_clause.htm).
-``` abap
-SELECT DISTINCT comp1
- FROM dbtab
- WHERE ...
- INTO TABLE @itab.
-```
-
-**SELECT list variants** (some of them are already outlined above)
-
-The following specifications can also be combined:
-- `SELECT * ...`: As outlined above, the `*` character defines all columns to be read from a data source (in the order specified there).
-- `SELECT col1, col2, col3 ...`: A comma-separated list of individual column names.
-- `SELECT data_source~col1, data_source~col2, data_source~col3 ...`: A comma-separated list of individual column names. Here, the name of the data source is explicitly specified and precedes the column name, separated by a tilde.
-- `SELECT data_source~* ...`: In this case, the name of the data source is followed by a tilde and the `*` character to specify all columns. Note that there are [special conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_list.htm#!ABAP_VARIANT_1@1@) when using this variant.
-- `SELECT col1 AS al1, col2 AS al2, col3 AS al3 ...`:
- - Defining alias names for individual columns of the result set with [`AS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_list.htm).
- - Make sure that you use an alias name only once here. In the statement, the alias name can only be used after an `ORDER BY` clause.
- - As shown further down, in some cases (e. g. when using SQL expressions) the specification of an alias name is required. Setting an alias name for the data source is also possible (`SELECT FROM dbtab AS alias_name ...`). See the section on joins further down.
-
-> **💡 Note**
-> You have plenty of options regarding the specification of the columns in the `SELECT` list, among them, the outlined direct specification of the column name. SQL expressions can be specified, too. See more details [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_clause_col_spec.htm) and in the sections on SQL expressions further down.
-
-
-``` abap
-"All fields
-SELECT * FROM dbtab
- WHERE ...
- INTO ...
-
-"Comma-separated list
-SELECT col1, col2, col3
- FROM dbtab
- WHERE ...
- INTO ...
-
-"Comma-separated list, data source explicitly specified
-SELECT dbtab~col1, dbtab~col2, col3
- FROM dbtab
- WHERE ...
- INTO ...
-
-"Data source explicitly specified, all fields
-SELECT dbtab~*
- FROM dbtab
- WHERE ...
- INTO ...
-
-"Alias names
-"Consider the following: You want to read data from a database table into a target data
-"object but, for example, a name in the target is different. Provided that there will
-"not be an issue regarding the type (conversion) when the values are assigned, you might
-"specify an alias name for the database column to match a component's name in the target data object.
-
-SELECT FROM dbtab
- FIELDS comp1 AS comp_a, comp2 AS comp_b, comp3 AS comp_c
- WHERE ...
- INTO CORRESPONDING FIELDS OF TABLE @itab.
-
-"Alias name also possible for the data source
-SELECT ds~col1, ds~col2, ds~col3
- FROM dbtab AS ds
- WHERE ...
- INTO ...
-```
-
-
-
-**Reading data from a database table in another client** ([classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm) only). Note that there are several variants of the `USING ...` addition for switching the [implicit client handling (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_client_handling.htm) from the current client to other clients. See more information [here (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client.htm).
-``` abap
-"Some examples; not available in ABAP for Cloud Development
-
-"Replaces the current client with the specified client
-SELECT *
- FROM dbtab USING CLIENT '000'
- WHERE ...
- INTO TABLE @itab.
-
-"Selects data of any number of clients
-SELECT *
- FROM dbtab USING ALL CLIENTS
- WHERE ...
- INTO TABLE @itab.
-```
-
-**Reading data from an internal table as data source** using `SELECT`. Note that an alias name must be specified for the internal table used as data source.
-Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_itab.htm).
-
-``` abap
-SELECT *
- FROM @itab1 AS tab
- WHERE ...
- INTO TABLE @DATA(itab2).
-```
-
-
-
-`INTO` **clause**:
-
-**Limiting the number of returned table rows** using the optional addition [`UP TO n
-ROWS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm).
-
-``` abap
-"A maximum of five rows are to be returned
-"If the INTO clause is the last clause, the UP TO clause must be positioned after it.
-SELECT * FROM dbtab
- WHERE ...
- INTO TABLE @DATA(itab_upto)
- UP TO 5 ROWS.
-```
-
-**Returning only the table rows after a row with a specified count from the result set** using the optional addition [`OFFSET n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm#!ABAP_ADDITION_2@2@). You can only use the addition, if an `ORDER BY` clause is specified.
-
-``` abap
-"In the example, data of all flights are retrieved, except for the 2 flights
-"with the shortest flight time.
-SELECT *
- FROM ztest_abap_flsch
- WHERE carrid = 'LH'
- ORDER BY fltime ASCENDING
- INTO TABLE @DATA(itab)
- OFFSET 2.
-```
-
-**Reading into individual elementary data objects**.
-Apart from reading into structures and internal tables outlined above, you can also read into individual elementary data objects.
-Here, the individual elementary data objects as target objects are specified in a comma-separated list (e. g. as existing host variables or declared inline with `@DATA(...)`) and put between a pair of parentheses.
-Note:
-- The comma-separated list must have the same number of elements as columns in the result set.
-- The content of the columns in the result set is assigned to the data objects specified in the list from left to right in accordance with the order specified in the `SELECT` list.
-- Note the [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm) also in this context.
-- More information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ALTERNATIVE_1@1@).
-
-
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE ...
- INTO (@res1,@res2,@res3).
- "INTO (@DATA(res1),@DATA(res2),@DATA(res3)). "Using inline declarations
-```
-
-**Appending the result set to an existing internal table**.
-The addition `INTO` initializes the target object. When using the addition `APPENDING`, you can retain existing lines in internal tables. `APPENDING` is also possible with the addition `CORRESPONDING FIELDS OF TABLE`.
-
-``` abap
-SELECT * FROM dbtab
- WHERE ...
- APPENDING TABLE @itab.
-
-SELECT * FROM dbtab
- WHERE ...
- APPENDING CORRESPONDING FIELDS OF TABLE @diff_itab.
-```
-
-**Reading into packages of a specified number of rows** when reading into internal tables. The addition [`PACKAGE SIZE n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ONE_ADD@1@) can be specified after `INTO TABLE` and `APPENDING TABLE`. A `SELECT` loop ist opened. After `PACKAGE SIZE`, the number of rows is specified (which can be a host variable, host expression or a literal of type `i`) denoting the number of rows to be inserted in the target object per iteration.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE ...
- INTO TABLE @DATA(itab_pack) PACKAGE SIZE n.
-...
-ENDSELECT.
-```
-
-**Specifying an [anonymous data object](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm) as target object** using the addition [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_into_target.htm#!ABAP_ALTERNATIVE_3@3@). Only to be used after `INTO` and not `APPENDING`.
-
-``` abap
-"Here, the target object is an anonymous data object declared inline.
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE ...
- INTO TABLE NEW @DATA(dref).
-```
-
-
-
-### More Clauses
-
-[`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm)
-clause: Combining groups of table rows in the result set. You
-might also use [SQL expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm "Glossary Entry")
-here. Multiple clause elements are separated by a comma. Find more
-information on SQL expressions further down.
-
-Note that the `GROUP BY` clause requires all columns that are
-directly specified in the `SELECT` list or specified there as an
-argument of an SQL expression to be specified. An exception to this is
-[aggregate
-functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
-in [aggregate
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_expression_glosry.htm "Glossary Entry")
-(except [grouping
-functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengrouping_glosry.htm "Glossary Entry"))
-as shown in the following example.
-
-In the example below, the database table rows that have the same content in column `comp1` are combined. The lowest and highest values in column `comp2` are determined for each of these groups and placed into the combined row.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, MIN( comp2 ) AS min, MAX( comp2 ) AS max
- WHERE ...
- GROUP BY comp1
- INTO ...
-```
-
-[`HAVING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaphaving_clause.htm)
-clause: Limiting the number of table rows in groups in the
-result by setting conditions on these rows. The rows for which a
-logical expression is true are inserted in the target variable. Note
-that `HAVING` can only be used together with `GROUP BY`.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, MIN( comp2 ) AS min, MAX( comp3 ) AS max
- WHERE ...
- GROUP BY comp1
- HAVING comp1 LIKE '%XYZ%' AND SUM( comp4 ) > 100
- INTO ...
-```
-
-[`ORDER BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaporderby_clause.htm)
-clause: Sorting the result set by specified columns.
-
-The following example shows the ordering of the result set based on the
-content of the primary key of the [data
-source](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_source_glosry.htm "Glossary Entry").
-You can also order by any columns and by explicitly specifying the sort
-order. There are more ordering options, for example, by using SQL
-expressions.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE ...
- ORDER BY PRIMARY KEY
- "comp2 ASCENDING
- "comp2 DESCENDING
- INTO ...
-```
-
-> **💡 Note**
->- Not specifying `ORDER BY` means that the order of entries in the result set is undefined.
->- If `ORDER BY` and `GROUP BY` clauses are used, all columns specified after `ORDER BY` must also be specified after `GROUP BY`.
->- If aggregate functions are specified after `SELECT`, all columns that are specified after `ORDER BY` and that do not have an alias name for an aggregate function must also be specified after `SELECT` and after the `GROUP BY` clause which is required in this case, too.
-
-[`WHERE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwhere.htm) clause: Restricts the number of rows that are included in the result set using logical expressions. See further information on them in the following sections.
-``` abap
-SELECT FROM dbtab
- FIELDS comp1, comp2, comp3
- WHERE comp1 = 'abc'
- AND comp2 < 123
- INTO ...
-```
-
-
-
-### Operands and Expressions in ABAP SQL Statements
-
-ABAP offers plenty of [SQL
-operands](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operand_glosry.htm "Glossary Entry")
-and
-[expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm "Glossary Entry")
-that are possible in ABAP SQL statements, not only in the context of
-`SELECT` statements and the `SELECT` lists which are
-mainly used for the following demonstration examples. Questions about
-when to use what, what is possible in which contexts and positions, is
-beyond the scope of this cheat sheet. Check the details in the
-respective topics in the ABAP Keyword Documentation. Find a general
-overview of important operand positions in ABAP SQL
-[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operand_positions_oview.htm).
-Due to the rich variety of options, the cheat sheet covers a selection.
-
-#### SQL operands
-
-- Are elementary operands in an ABAP SQL statement
-- Can be database table or view columns, a
- [literal](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_glosry.htm "Glossary Entry"),
- [host
- variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm "Glossary Entry")
- (i. e. global or local data objects escaped using `@`:
- `@dobj`) or [host
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_expression_glosry.htm "Glossary Entry")
- (`@( ... )`)
- - Regarding literals: They are not prefixed with the escape
- character `@`. The literals can be
- [typed](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentyped_literal_glosry.htm "Glossary Entry")
- (using the type name and content within a pair of backquotes:
- char\`abc\`) with [built-in ABAP Dictionary
- types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_builtin_types.htm)
- or untyped. Typed literals are preferable for the following
- reasons: Using untyped literals means extra cost in terms of
- performance since they must be converted by the compiler. Plus,
- their use can result in errors at runtime whereas typed literals
- guarantee type compatibility at once.
- - Regarding host expressions: Structures and internal tables are
- possible as host expressions for statements modifying the
- content of database tables as shown further down.
-- See more information
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operands.htm).
-
-Example demonstrating possible operands:
-``` abap
-DATA upto TYPE i VALUE 3.
-
-SELECT FROM zdemo_abap_flsch
- FIELDS
- "Specifies a column of a data source directly using its name
- cityfrom,
-
- "Column selector ~ can be used to prefix every specified column.
- "Here, it is optional. It is non-optional, e. g., if multiple data
- "sources in an ABAP SQL statement are edited and the column name
- "is not unique.
- zdemo_abap_flsch~cityto,
-
- 'Lufthansa' AS name, "Untyped literal
-
- char`X` AS flag, "Typed literal
-
- @upto AS num, "Host variable
-
- @( cl_abap_context_info=>get_system_date( ) ) as date "Host expression
-
- WHERE carrid = 'LH' "Untyped literal
- AND countryfr = char`DE` "Typed literal
-
- "Data object created inline and escaped with @
- INTO TABLE @DATA(it)
-
- "The following clause shows all options having the same effect
- UP TO 3 ROWS. "Untyped numeric literal
- "UP TO int4`3` ROWS. "Typed numeric literal
- "UP TO @upto ROWS. "Host variable
- "UP TO @( 10 - 7 ) ROWS. "Host expression
-```
-
-
-
-#### SQL Expressions
-
-- Expressions in an ABAP SQL statement that are passed to the database
- system for evaluation.
-- For example, SQL expressions can be specified as columns in the
- `SELECT` list as demonstrated in most of the following examples.
- Find information on more possible positions and general information
- on SQL expressions
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsql_expr.htm)
- and the subtopics there.
-
-##### Elementary Expressions
-
-- An elementary expression represents one of the four mentioned
- operands above: A value from the database (the column name) or
- values from an ABAP program passed to the database (literal, host
- variable or host expression).
-- As an example, see the `SELECT` list in the example above.
-- See more information
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_elem.htm).
-
-##### SQL Functions
-
-- You can use built-in functions in ABAP SQL.
-- Result: Value with the associated dictionary type.
-- Arguments of the functions: Cover one or more SQL expressions.
-- See more information
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql_builtin_functions.htm).
-
-Example: [Numeric functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_arith_func.htm)
-``` abap
-SELECT SINGLE
- carrname,
-
- "Division, result rounded to an integer
- "Result: 2
- div( 4, 2 ) AS div,
-
- "Division, 3rd argument: result is rounded to the specified
- "number of decimals
- "Result: 0.33
- division( 1, 3, 2 ) AS division,
-
- "Result is rounded to first greater integer
- "Result: 2
- ceil( decfloat34`1.333` ) AS ceil,
-
- "Result is the remainder of division
- "Result: 1
- mod( 3, 2 ) AS mod,
-
- "Result: Largest integer value not greater than the specified value
- "Result: 1
- floor( decfloat34`1.333` ) AS floor,
-
- "Returns the absolute number
- "Result: 2
- abs( int4`-2` ) AS abs,
-
- "Result is rounded to the specified position after the decimal separator
- "Result: 1.34
- round( decfloat34`1.337`, 2 ) AS round
-
- FROM zdemo_abap_carr
- WHERE carrid = 'AA'
- INTO @DATA(numeric_functions).
-```
-
-
-
-Example: [String functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_string_func.htm)
-
-``` abap
-SELECT SINGLE
- carrid, "LH
- carrname, "Lufthansa
- url, "http://www.lufthansa.com
-
- "Concatenates strings, ignores trailing blanks
- "Result: LHLufthansa
- concat( carrid, carrname ) AS concat,
-
- "Concatenates strings, number denotes the blanks that are inserted
- "Result: LH Lufthansa
- concat_with_space( carrid, carrname, 1 ) AS concat_with_space,
-
- "First letter of a word -> uppercase, all other letters -> lowercase;
- "note that a space and other special characters means a new word.
- "Result: Http://Www.Lufthansa.Com
- initcap( url ) AS initcap,
-
- "Position of the first occurrence of the substring specified
- "Result: 6
- instr( carrname,'a' ) AS instr,
-
- "String of length n starting from the left of an expression;
- "trailing blanks are ignored
- "Result: Luft
- left( carrname, 4 ) AS left,
-
- "Number of characters in an expression, trailing blanks are ignored
- "Result: 24
- length( url ) AS length,
-
- "Checks if expression contains a PCRE expression;
- "case-sensitive by default (case_sensitive parameter can be specified)
- "Notes on the result: 1 = found, 0 = not found
- "Result: 1
- like_regexpr( pcre = '\..', "Period that is followed by any character
- value = url ) AS like_regex,
-
- "Returns position of a substring in an expression,
- "3rd parameter = specifies offset (optional)
- "4th parameter = determines the number of occurrences (optional)
- "Result: 9
- locate( carrname, 'a', 0, 2 ) AS locate,
-
- "Searches a PCRE pattern, returns offset of match;
- "many optional parameters: occurrence, case_sensitive, start, group
- "Result: 21
- locate_regexpr( pcre = '\..', "Period followed by any character
- value = url,
- occurrence = 2 ) "2nd occurrence in the string
- AS locate_regexpr,
-
- "Searches a PCRE pattern, returns offset of match + 1;
- "many optional parameters: occurrence, case_sensitive, start, group
- "Result: 2
- locate_regexpr_after( pcre = '.', "Any character
- value = url,
- occurrence = 1 ) AS locate_regexpr_after,
-
- "Removes leading characters as specified in the 2nd argument,
- "trailing blanks are removed
- "Result: ufthansa
- ltrim( carrname, 'L' ) AS ltrim,
-
- "Counts all occurrences of found PCRE patterns
- "Result: 2
- occurrences_regexpr( pcre = '\..', "Period that is followed by any character
- value = url ) AS occ_regex,
-
- "Replaces the 2nd argument with the 3rd in an expression
- "Result: Lufth#ns#
- replace( carrname, 'a', '#' ) AS replace,
-
- "Replaces a found PCRE expression;
- "more parameters possible: occurrence, case_sensitive, start
- "Result: http://www#ufthansa#om
- replace_regexpr( pcre = '\..', "Period that is followed by any character
- value = url,
- with = '#' ) AS replace_regex,
-
- "Extracts a string with the length specified starting from the right
- "Result: hansa
- right( carrname, 5 ) AS right,
-
- "Expands string to length n (2nd argument); trailing blanks produced
- "are replaced by the characters from the (3rd) argument
- "Note that if n is less than the string, the expression is truncated
- "on the right.
- "Result: Lufthansa###
- rpad( carrname, 12, '#' ) AS rpad,
-
- "All trailing characters that match the character of the 2nd argument
- "are removed; trailing blanks are removed, too
- "Result: Lufthans
- rtrim( carrname, 'a' ) AS rtrim,
-
- "Returns a substring; 2nd argument = position from where to start;
- "3rd argument: length of the extracted substring
- "Result: fth
- substring( carrname, 3, 3 ) AS substring,
-
- "Searches for a PCRE expression and returns the matched substring
- "More parameters possible: occurrence, case_sensitive, start, group
- "Result: .lu
- substring_regexpr( pcre = '\...', "Period that is followed by any two characters
- value = url ) AS substring_regexpr,
-
- "All lower case letters are transformed to upper case letters
- "Result: LUFTHANSA
- upper( carrname ) AS upper
-
- FROM zdemo_abap_carr
- WHERE carrid = 'LH'
- INTO @DATA(string_functions).
-```
-
-
-
-[Aggregate expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_aggregate.htm)
-
-- Consist of [aggregate
- functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
- and aggregate the values of multiple rows of the result set of a
- [query](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenquery_glosry.htm "Glossary Entry")
- into a single value
-- See more information
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_aggregate.htm).
-
-Example:
-``` abap
-"The example shows a selection of available functions
-SELECT
- carrid,
-
- "Average value of the content of a column in a row set
- AVG( fltime ) AS fltime1,
-
- "AVG with data type specification for the result
- AVG( fltime AS DEC( 14,4 ) ) AS fltime2,
-
- "Maximum value of the results in a row set
- MAX( fltime ) AS max,
-
- "Minimum value
- MIN( fltime ) AS min,
-
- "Sum of the results in a row set.
- SUM( fltime ) AS sum,
-
- "Returns the number of rows in a row set.
- "The following two have the same meaning.
- COUNT( * ) AS count2,
- COUNT(*) AS count3,
-
- "Chains the results in a row set.
- "An optional separator can be specified
- STRING_AGG( airpfrom, ', ' ) AS string_agg
-
- FROM zdemo_abap_flsch
- WHERE carrid = 'LH'
- GROUP BY carrid
- INTO TABLE @DATA(agg_exp).
-```
-
-
-
-##### More SQL Expressions
-
-- [Arithmetic
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_arith.htm)
- to perform arithmetic calculations using the operators `+`,
- `-`, `*`, `/`,
-- [Cast
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_cast.htm)
- to convert the value of operands to a dedicated dictionary type.
- Note that there are special [conversion
- rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_cast_rules.htm).
-- [String
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_string.htm)
- using the operator `&&` to concatenate character strings.
-- [Case
- distinctions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_case.htm)
- to carry out either a simple (comparison of the values of a
- dedicated operand) or complex (searched case; evaluation of multiple
- logical expressions) case distinction.
-
-The following example demonstrates the expressions mentioned above:
-``` abap
-SELECT SINGLE
- carrid,
-
- "Arithmethic expressions
- "operators + - *
- "Note that / is not allowed in integer expressions as the one below
- ( 1 + 2 ) * 3 AS calc,
-
- "/ used in an expression using type adjustment in ABAP SQL.
- "A cast expression converts the value of the operands to the
- "specified dictionary type. The result is a representation of the
- "source value in the specified type.
- CAST( 1 AS D34N ) / CAST( 2 AS D34N ) AS ratio,
-
- "String expression using && to concatenate two character strings;
- "the result of the concatenation must not be longer than
- "255 characters.
- carrid && carrname AS concat,
-
- "Case distinction
- "Simple case distinction
- "The expression compares the values of an operand with other
- "operands. Result: The first operand after THEN for which the
- "comparison is true. If no matches are found, the result specified
- "after ELSE is selected.
- CASE currcode
- WHEN 'EUR' THEN 'A'
- WHEN 'USD' THEN 'B'
- ELSE 'C'
- END AS case_simple,
-
- "Complex case distinction
- "The expression evaluates logical expressions. Result: The first
- "operand after THEN for which the logical expression is true. If no
- "logical expressions are true, the result specified after ELSE is
- "selected.
- CASE WHEN length( carrname ) <= 5 THEN 'small'
- WHEN length( carrname ) BETWEEN 6 AND 10 THEN 'mid'
- WHEN length( carrname ) BETWEEN 11 AND 15 THEN 'large'
- ELSE 'huge'
- END AS case_complex
-
-FROM zdemo_abap_carr
-WHERE carrid = 'AA'
-INTO @DATA(more_sql_expr).
-```
-
-
-
-##### Window Expressions
-
-How [window expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_expression_glosry.htm "Glossary Entry") work:
-
-- Define a subset of the result set (i. e. the
- "[window](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_glosry.htm "Glossary Entry")")
- of a database query that implements ABAP SQL
-- Apply a [window
- function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_function_glosry.htm "Glossary Entry") -
- which evaluates the rows of the window and which can, for example,
- be an [aggregate
- function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
- like
- [`AVG`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_agg_func&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_VARIANT_1@1@&tree=X)
- to determine the average value - to the result set
-- I. e. a window is constructed by the rows of the result set for
- which all the window functions have the same result; a value is then
- determined for the rows of a window
-
-Setup of a statement with window expressions:
-
-- Window function, e. g. an aggregate function like `AVG`,
- followed by `OVER( ... )` (the content in the parentheses
- defines the "window")
-- The content in the parentheses can contain the following additions:
- - Optional `PARTITION BY`: Defines the windows using a
- comma-separated list of [SQL
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsql_expr.htm);
- the window function is calculated for the rows of this window;
- note that if the addition is not specified, the window comprises
- all rows of the result set
- - Optional `ORDER BY`: Introduces both an order (you can
- use `ASCENDING` and `DESCENDING`) and a frame
- (as outlined below) within the current window, which further
- restricts the rows for which the window function is calculated
- - A window frame, which stands for a subset of rows inside a
- window, can optionally be defined if `ORDER BY` is
- specified; there are 3 options to define the starting and ending
- frame boundaries (see the example)
-
-See more information on window expressions and the syntax
-[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_over.htm).
-
-Examples:
-``` abap
-"Example 1: A simple window is constructed in the OVER clause;
-"window functions - here aggregate functions - are applied
-SELECT carrid, currency,
- SUM( paymentsum ) OVER( PARTITION BY carrid ) AS sum,
- AVG( price AS DEC( 14,2 ) ) OVER( PARTITION BY carrid ) AS avg,
- MAX( price ) OVER( PARTITION BY carrid ) AS max
- FROM zdemo_abap_fli
- ORDER BY carrid
- INTO TABLE @DATA(win).
-
-"Example 2:
-SELECT carrid, currency, fldate,
- "Sorts the rows by some columns and counts the number of rows from
- "the first row of the window to the current row.
- COUNT( * ) OVER( ORDER BY currency, fldate
- ROWS BETWEEN
- "UNBOUNDED PRECEDING: frame starts at the first row of the window
- UNBOUNDED PRECEDING
- "CURRENT ROW: determines starting or ending at the current row; here, it ends
- AND CURRENT ROW ) AS count1,
-
- "If no window frame is used, the default window frame is
- "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,
- "i. e. the result of count1 equals the result of count2.
- COUNT( * ) OVER( ORDER BY currency, fldate ) AS count2,
-
- "Sorts the rows by some columns and counts the number of rows from
- "the current row to the last row of the window.
- "The result is reverse numbering.
- COUNT( * ) OVER( ORDER BY currency, fldate
- ROWS BETWEEN CURRENT ROW
- UNBOUND FOLLOWING:
- "Determines the ending frame boundary, this addition specifies the last row of the window
- AND UNBOUNDED FOLLOWING ) AS count_reverse,
-
- "Sorts the rows by some columns and calculates the rolling averages
- "of a subset of rows from column price. The subset consists of the
- "current row plus one preceding and one following row. Another use
- "case as below example that uses prices would be that, for example,
- "you can calculate the 3-day-average temperature for every day from
- "a list of temperature data.
- AVG( price AS DEC( 14,2 ) ) OVER( ORDER BY currency, fldate
- ROWS BETWEEN
- "n PRECEDING: for both start and end of frame; frame to start/end n rows above the current row
- 1 PRECEDING
- "n FOLLOWING: for both start and end of frame; frame to start/end n rows beneath the current row
- AND 1 FOLLOWING ) AS avg
-
- FROM zdemo_abap_fli
- INTO TABLE @DATA(result).
-```
-
-
-
-### SQL Conditions
-
-You can formulate conditions in ABAP SQL statements, i. e. [logical
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm "Glossary Entry"),
-especially in the `WHERE` clause to restrict the result. Note
-that without a `WHERE` clause, all rows are respected for the
-operation.
-
-See below a selection of the operators that are possible when specifying
-conditions. For more information, see the subtopics of the [SQL
-Conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenasql_cond.htm)
-topic.
-
-| Operator | Meaning |
-|----------|:-------------:|
-| `=`, `EQ` | The content of two operands is equal.|
-| `<>`, `NE` | The content of two operands is not equal.|
-| `<`, `LT` | The content of one operand is less than the content of the other operand.|
-| `>`, `GT` | The content of one operand is greater than the content of the other operand.|
-| `<=`, `LE` | The content of one operand is less than or equal to the content of the other operand.|
-| `>=`, `GE` | The content of one operand is greater than or equal to the content of the other operand.|
-| `... [NOT] BETWEEN ... AND ...` | The value of an operand is (not) between the value of the two other operands.|
-| `... [NOT] LIKE ...` | The content of an operand matches (does not match) a specified pattern. The pattern can be specified by using wildcard characters. `%` stands for any character string, including an empty string. `_` stands for any character.|
-| `... IS [NOT] INITIAL ...` | The value of an operand is (not) the initial value of its built-in dictionary type.|
-| `... EXISTS ...` | Checks the result set of a [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry"). The expression is true if the result set contains at least one row. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_subquery.htm).|
-| `... [NOT] IN ...` | Checks whether the operands on the left side match a value from a set of values specified in parentheses. On the left side, a single operand or an operand list are possible. On the right side, a comma-separated lists or subqueries can be specified. It is also possible to specify a [ranges table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_table_glosry.htm) to evaluate [ranges conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_condition_glosry.htm).|
-| `... IS [NOT] NULL ...` | Checks whether the value of an operand is (not) the [null value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm). Find more information in the code snippet and in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_null.htm). |
-
-> **💡 Note**
->You can combine multiple logical expressions into one
-logical expression using `AND` or `OR`. To further
-detail out the desired condition, expressions within parentheses are
-possible.
-
-Examples:
-
-``` abap
-"---- SQL conditions demonstrated with the WHERE clause ----
-"Note:
-"- For most of the self-contained examples, an internal table is used as the
-" data source of SELECT statements to work with simple data.
-"- For some examples that are covered, such as subqueries, demo database tables
-" from the cheat sheet repository are used in addition.
-"- Dynamic specifications are also possible. They are not covered here. See
-" the Dynamic Programming cheat sheet.
-
-"---- Types and internal table to work with in the examples ----
-"Note: You cannot use type string columns in WHERE conditions.
-TYPES: BEGIN OF demo_struc,
- id TYPE i,
- name TYPE c LENGTH 15,
- "name TYPE string,
- END OF demo_struc.
-DATA itab TYPE SORTED TABLE OF demo_struc WITH UNIQUE KEY id.
-"Populating internal table with data to work with in the examples
-itab = VALUE #( ( id = 1 name = 'bear' )
- ( id = 2 name = 'camel' )
- ( id = 3 name = 'rabbit' )
- ( id = 4 name = 'zebra' )
- ( id = 5 name = 'dog' )
- ( id = 6 name = 'deer' )
- ( id = 7 name = 'squirrel' )
- ( id = 8 name = 'cheetah' )
- ( id = 9 name = 'elephant' )
- ( id = 10 name = 'donkey' )
- ( id = 11 name = 'fish' )
- ( id = 12 name = 'sheep' ) ).
-
-"---- =, <>, >, >= (as a selection of possible comparison operators) ----
-SELECT id FROM @itab AS tab WHERE name = 'bear' INTO TABLE @DATA(it). "1
-SELECT id FROM @itab AS tab WHERE name <> 'bear' INTO TABLE @it. "2-12
-SELECT id FROM @itab AS tab WHERE id > 10 INTO TABLE @it. "11,12
-SELECT id FROM @itab AS tab WHERE id >= 10 INTO TABLE @it. "10,11,12
-
-"---- Combining logical expressions using AND, OR and parentheses ----
-SELECT id FROM @itab AS tab WHERE id = 1 AND name = 'bear' INTO TABLE @it. "1
-SELECT id FROM @itab AS tab WHERE name = 'bear' OR name = 'sheep' INTO TABLE @it. "1,12
-
-"In the following example, the resulting table is initial. One of the expressions
-"in parentheses is false (AND is used between the expressions in parentheses).
-"In contrast, the example below returns an entry because of using OR.
-SELECT id FROM @itab AS tab
- WHERE ( id = 1 AND name = 'bear' )
- AND ( id = 20 AND name = 'camel' )
- INTO TABLE @it.
-
-SELECT id FROM @itab AS tab
- WHERE ( id = 1 AND name = 'bear' )
- OR ( id = 20 AND name = 'camel' )
- INTO TABLE @it. "1
-
-"------------------------ [NOT] BETWEEN ------------------------
-SELECT id FROM @itab AS tab WHERE id BETWEEN 1 AND 4 INTO TABLE @it. "1,2,3,4
-"The condition with BETWEEN above corresponds to the following condition.
-"The example makes use of a condition specified in parentheses to combine multiple
-"expressions.
-SELECT id FROM @itab AS tab WHERE ( id >= 1 AND id <= 4 ) INTO TABLE @it. "1,2,3,4
-"Negation with NOT
-SELECT id FROM @itab AS tab WHERE id NOT BETWEEN 1 AND 4 INTO TABLE @it. "5-12
-
-"------------------------ IS [NOT] INITIAL ------------------------
-SELECT id FROM @itab AS tab WHERE id IS NOT INITIAL INTO TABLE @it. "1-12
-
-"------------------------ [NOT] LIKE ------------------------
-"For (not) matching a specified pattern
-"Note: % (any character string), _ (any character).
-SELECT name FROM @itab AS tab
- WHERE name LIKE '%ee%'
- OR name LIKE '_o%'
- INTO TABLE @DATA(names). "dog,deer,cheetah,donkey,sheep
-
-"ESCAPE addition for defining a single-character escape character
-"In the following example, this character is #. It is placed before
-"the % character in the specification after LIKE. In this case, %
-"is escaped and does then not stand for any character string in the
-"evaluation.
-"Adding a table entry for this syntax example.
-itab = VALUE #( BASE itab ( id = 13 name = '100%' ) ).
-"Any character sequence followed by the % character
-SELECT name FROM @itab AS tab
- WHERE name LIKE '%#%' ESCAPE '#'
- INTO TABLE @names. "100%
-
-"Deleting the entry because it is not relevant for the further examples.
-DELETE itab INDEX 13.
-
-"------------------------ [NOT] IN (using a value set) ------------------------
-"For (not) matching a value in a set of values specified in parentheses.
-
-"Single operands on the left side of IN
-SELECT id FROM @itab AS tab
- WHERE name IN ( 'camel', 'rabbit', 'dog', 'snake' )
- INTO TABLE @it. "2,3,5
-
-"Negation NOT IN; note to use host variables/expressions for local/global data objects
-DATA(animal) = 'sheep'.
-SELECT id FROM @itab AS tab
- WHERE name NOT IN ( 'fish', @animal )
- INTO TABLE @it. "1-10
-
-"Operand list (a parenthesized comma-separated list) on the left side of IN
-"For (not) matching value tuples from a set of value tuples specified in parentheses on the right side.
-"In the following example, two values are specified in the operand list on the left. Consequently,
-"two values with appropriate types must be specified in parentheses on the right.
-SELECT id FROM @itab AS tab
- WHERE ( id, name ) IN ( ( 1, 'bear' ), ( 3, 'rabbit' ), ( 8, 'zebra' ), ( 20, 'dog' ) )
- INTO TABLE @it. "1,3
-
-
-"------------------------ [NOT] IN (using a subquery) ------------------------
-"[NOT] IN for matching a value contained in the result set of a subquery
-
-"In the following example, the subquery reads data from a demo database table.
-"For a representative result, the table is cleared, and then filled with 'suitable'
-"data sets.
-DELETE FROM zdemo_abap_tab1.
-MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 11 num1 = 11 )
- ( key_field = 12 num1 = 12 )
- ( key_field = 13 num1 = 13 )
- ( key_field = 14 num1 = 14 ) ) ).
-
-SELECT id FROM @itab AS tab
- WHERE id IN ( SELECT key_field FROM zdemo_abap_tab1 ) INTO TABLE @it. "11,12
-
-"------------------------ [NOT] IN (using a ranges table) ------------------------
-"[NOT] IN for checking whether the operands on the left side match a ranges condition in a ranges table
-
-"Declaring a ranges table
-DATA rangestab TYPE RANGE OF i.
-"Populating a ranges table using the VALUE operator
-rangestab = VALUE #( ( sign = 'I' option = 'BT' low = 1 high = 3 )
- ( sign = 'I' option = 'GE' low = 10 ) ).
-
-SELECT id FROM @itab AS tab WHERE id IN @rangestab INTO TABLE @it. "1,2,3,10,11,12
-
-
-"You cannot use logical operators such as CP (conforms to pattern) in the WHERE clause.
-"In a ranges table, they are possible.
-"Note:
-"- Regarding CP: * (any character sequence), + (any character), # (escape character)
-"- An equivalent example above uses the LIKE addition.
-DATA rt TYPE RANGE OF demo_struc-name.
-rt = VALUE #( ( sign = 'I' option = 'CP' low = '*ee*' ) "ee in a string
- ( sign = 'I' option = 'CP' low = '+o*' ) ). "o in second position
-SELECT name FROM @itab AS tab
- WHERE name IN @rt
- INTO TABLE @names. "dog,deer,cheetah,donkey,sheep
-
-"------------------------ EXISTS ------------------------
-"For checking the result set of a subquery.
-"The following example reads all entries from the internal table if entries having
-"the same key also exist in the database table.
-"Note: The SELECT list in the subquery only contains a literal to determine that
-"the entry exists. Specifying explicit column names is not relevant.
-SELECT id FROM @itab AS tab WHERE
- EXISTS ( SELECT @abap_true FROM zdemo_abap_tab1 WHERE key_field = tab~id )
- INTO TABLE @it. "11,12
-
-"------------------------ IS [NOT] NULL ------------------------
-"The null value is a special value that is returned by a database. It indicates an
-"undefined value or result. Note that, in ABAP, there are no special null values. Do
-"not confuse the null value with a type-dependent initial value. When using SELECT
-"statements to read data, null values can be produced by, for example, outer joins.
-"When the null values are passed to a data object, they are transformed to the
-"type-dependent initial values. For more information, refer to the ABAP Keyword Documentation.
-"The following example uses a left outer join to intentionally create null values. For
-"this purpose, two demo database tables of the cheat sheet repository are cleared and
-"populated with specific values to visulaize null values.
-DELETE FROM zdemo_abap_tab1.
-DELETE FROM zdemo_abap_tab2.
-MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' char2 = 'y' )
- ( key_field = 2 char1 = 'b' char2 = 'z' ) ) ).
-MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' )
- ( key_field = 2 char1 = 'a' )
- ( key_field = 3 char1 = 'b' )
- ( key_field = 4 ) ) ).
-"Note that for the entry 'key_field = 4' no char1 value was passed.
-"char1 is a shared column of the two database tables, and which is used in
-"the ON condition of the join. Since there is no entry in char1 for 'key_field = 4',
-"the joined values are null in that case. The WHERE clause uses the addition IS NULL.
-"Therefore, the result only contains this entry. char2 is assigned the type-initial
-"value in the result.
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- WHERE tab1~char1 IS NULL
- INTO TABLE @DATA(joined_tab).
-*KEY_FIELD CHAR2
-*4
-
-"The following example visualizes the null values. The INDICATORS addition of the
-"INTO clause is used to specify indicators such as the null indicator. In the
-"example, an appropriate target table is defined to also store information about
-"which columns of the result set contain the null value and which do not.
-"For more information on the syntax, refer to the ABAP Keyword Documentation.
-TYPES: BEGIN OF st4null,
- BEGIN OF s2,
- key_field TYPE zdemo_abap_tab2-key_field,
- char2 TYPE zdemo_abap_tab1-char2,
- END OF s2,
- BEGIN OF nulls,
- key_field TYPE c LENGTH 1,
- char2 TYPE c LENGTH 1,
- END OF nulls,
- END OF st4null.
-DATA joined_tab_w_null_ind TYPE TABLE OF st4null WITH EMPTY KEY.
-
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- INTO TABLE @joined_tab_w_null_ind INDICATORS NULL STRUCTURE nulls.
-*S2 NULLS
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*1 y
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*2 y
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*3 z
-*KEY_FIELD CHAR2 KEY_FIELD CHAR2
-*4 X
-
-"Negation IS NOT NULL
-SELECT tab2~key_field, tab1~char2
- FROM zdemo_abap_tab2 AS tab2
- LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
- WHERE tab1~char1 IS NOT NULL
- INTO TABLE @joined_tab.
-*KEY_FIELD CHAR2
-*1 y
-*2 y
-*3 z
-```
-
-
-
-### Selecting Data by Evaluating the Content of Other Tables
-
-[`FOR ALL ENTRIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm)
-addition:
-- Components of an internal table can be used in the `WHERE` clause in logical expressions for comparisons with a column of the data source.
-- The logical expression is evaluated for each individual row of the internal table.
-- The result set of the `SELECT` statement is the union set of the result sets produced by the individual evaluations. Rows that occur more than once are removed from the result set automatically. The entire content of a row is respected.
-- If `FOR ALL ENTRIES` is specified, there must be at least one comparison with a column of the internal table.
-- For more information, especially restricitions and things to pay attention to (e. g. making sure that the internal table is not initial), see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm).
-
-``` abap
-"Checking that table is not initial
-IF ( 0 < lines( itab2 ) ).
-
- SELECT comp1, comp2, comp3
- FROM dbtab
- FOR ALL ENTRIES IN @itab2 "Host variable before internal table
- WHERE comp1 = @itab2-comp1 ... "Relational expression on the right side of a comparison
- INTO TABLE @itab1
-
-ENDIF.
-```
-
-**Checking the result set of a subquery** with the addition [`EXISTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_exists.htm)
-
-See possible clauses and additions of a [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm) in a condition in ABAP SQL [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_subquery.htm).
-
-The following code snippet includes a parenthesized subquery following `EXISTS`. Data is only selected from `dbtab1` if the relational expression (`WHERE EXISTS ...`) is true, i. e. if the result set of the subquery contains at least one row. Note the components of the table that are referenced using a tilde.
-
-``` abap
-SELECT comp1, comp2, comp3
- FROM dbtab1 AS tab1
- WHERE EXISTS
- ( SELECT comp1 FROM dbtab2
- WHERE comp1 = tab1~comp1 AND comp2 = tab1~comp2 )
- INTO ...
-```
-
-
-
-### Combining Data of Multiple Database Tables
-
-**Using an [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.
- - Contains all combinations of rows for whose columns the join condition is true.
-- 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
- INNER JOIN dbtab2 AS b ON a~comp1 = b~comp1 AND a~comp2 = b~comp2
- INNER JOIN dbtab3 AS c ON a~comp1 = c~comp1
- WHERE ...
- INTO ...
-```
-
-**Using an [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,
- FROM dbtab1 AS a
- LEFT OUTER JOIN dbtab2 AS b ON a~comp1 = b~comp1
- WHERE ...
- INTO ...
-```
-> **💡 Note**
-> There are more join variants 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`](http://ldcialx.wdf.sap.corp:50018/sap/public/bc/abap/docu?object=abapunion&sap-language=EN&sap-client=000&version=A&tree=X). 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
- FIELDS ...
- WHERE ...
-UNION
- SELECT FROM dbtab2
- FIELDS ...
- WHERE ...
- INTO ...
-```
-
-
-
-#### Common Table Expressions (CTE)
-
-When to use [Common Table Expressions (CTE)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencommon_table_expression_glosry.htm):
-
-- Whenever you need intermediate results in a `SELECT`
- statement and especially if you need them more than once.
-- You get the option of selecting directly from a subquery (`SELECT FROM subquery`), which is not possible in ABAP SQL.
-
-How it works:
-
-- The ABAP SQL keyword
- [`WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwith.htm)
- introduces the definition of CTEs.
-- Each CTE creates a tabular result set in a
- [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry").
-- The result set of such a CTE can then be used in subsequent queries
- as data source; CTEs can be considered as temporary views, which
- only exist for the duration of the database access.
-- The CTEs (at least one) are then used in a final [main
- query](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmainquery_glosry.htm "Glossary Entry"), i.
- e. a `SELECT` statement accesses the result of the
- expressions.
-
-Setup of a statement with CTE:
-
-- Introductory keyword `WITH`
-- A comma-separated list with at least one definition of a CTE
- - Each CTE has a unique name with an initial `+` character
- - An optional list of column names, which should be used in the
- result set, within parentheses
- - `AS` followed by a subquery with `SELECT` which
- creates the tabular result set of the CTE
-- A closing main query with `SELECT` in which the previous
- CTEs are to be used as data source
-- If a `SELECT` loop is opened and data is written into a work
- area in the closing main query, the loop must be closed with
- `ENDWITH.` (which fulfills the same task as
- `ENDSELECT.`).
-
-> **💡 Note**
->- Each CTE must be used at least once, either in another CTE or in the
- main query. The main query must access at least one CTE.
->- The result set of a CTE never has a [client
- column](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclient_column_glosry.htm "Glossary Entry").
->- See more information in [this topic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwith.htm)
-and further options and additions when using CTEs in the subtopics.
-
-Example: The result sets of both common table expressions
-`+connections` and `+sum_seats` are merged in the
-subquery of the CTE `+result` in a join expression. An explicit
-name list assigns names to the resulting columns. These names are used
-in the main query to sort the results. For each flight connection of the
-selected airline, the total number of occupied seats is stored in the
-internal table.
-``` abap
-WITH
-+connections AS (
- SELECT zdemo_abap_flsch~carrid, carrname, connid, cityfrom, cityto
- FROM zdemo_abap_flsch
- INNER JOIN zdemo_abap_carr
- ON zdemo_abap_carr~carrid = zdemo_abap_flsch~carrid
- WHERE zdemo_abap_flsch~carrid BETWEEN 'AA' AND 'JL' ),
-+sum_seats AS (
- SELECT carrid, connid, SUM( seatsocc ) AS sum_seats
- FROM zdemo_abap_fli
- WHERE carrid BETWEEN 'AA' AND 'JL'
- GROUP BY carrid, connid ),
-+result( name, connection, departure, arrival, occupied ) AS (
- SELECT carrname, c~connid, cityfrom, cityto, sum_seats
- FROM +connections AS c
- INNER JOIN +sum_seats AS s
- ON c~carrid = s~carrid AND c~connid = s~connid )
-SELECT *
- FROM +result
- ORDER BY name, connection
- INTO TABLE @DATA(result).
-```
-
-
-
-## Changing Data in Database Tables
-
-### Using [`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_dbtab.htm)
-
-- Inserts one or more rows into a database table specified.
-- The rows to be inserted are taken from a structure, an internal table, or the result set of an embedded subquery.
-- As mentioned above, structures and internal tables from which to insert content should be specified as host variables (with `@`) or host
-expressions (with `@( ... )`).
-- The system fields `sy-subrc` (0 = single row or all rows inserted successfully, 4 = row not or not all rows inserted) and `sy-dbcnt` (number of rows that are inserted) are set.
-
-``` abap
-"Inserting a single row into a database table
-
-INSERT dbtab FROM @row.
-
-"Alternative syntax, same effect
-INSERT INTO dbtab VALUES @row.
-
-"Line is created inline using the VALUE operator as part of a host expression
-
-INSERT dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
-
-"Inserting multiple lines from an internal table into a database table.
-"Make sure that the internal table does not contain a line having the same key
-"as an existing row in the database table. Otherwise, a runtime error occurs.
-
-INSERT dbtab FROM TABLE @itab.
-
-"Inserting lines from a table declared inline using the VALUE operator
-"as part of a host expression
-
-INSERT dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
- ( comp1 = ... comp2 = ... ) ) ).
-
-"ACCEPTING DUPLICATE KEYS addition: To avoid the runtime error mentioned above,
-"all lines that would produce duplicate entries in the database table
-"regarding the keys are discarded and sy-subrc is set to 4.
-
-INSERT dbtab FROM TABLE @itab ACCEPTING DUPLICATE KEYS.
-
-"Inserting the result set of an embedded subquery
-"Here, multiple result sets can be joined, e. g. using UNION.
-
-INSERT dbtab FROM ( SELECT ... ).
-```
-
-
-
-### Using [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapupdate.htm)
-- Changes the content of one or more rows of a database table specified.
-- Similar to `INSERT`, `sy-subrc` and `sy-dbcnt` are set.
-
-``` abap
-"Changing content by overwriting entire rows based on a structure
-
-UPDATE dbtab FROM @row.
-UPDATE dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ). "Using a host expression
-
-"Changing content by overwriting entire rows based on rows in an internal table
-
-UPDATE dbtab FROM TABLE @itab.
-
-"Using a host expression
-
-UPDATE dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
- ( comp1 = ... comp2 = ... ) ) ).
-
-"INDICATORS addition: Changing content of specific fields without overwriting
-"existing values of other fields
-"Example:
-"- Structured type is created with WITH INDICATORS addition
-"- Internal table from which to update dbtab is created;
-" it includes the indicator structure comp_ind
-"- Internal table is filled; only one component is flagged as to be updated
-"- Other fields remain unchanged; note that key fields must be included
-" in ind_tab (indicator setting for key fields has no effect)
-
-TYPES ind_wa TYPE dbtab WITH INDICATORS comp_ind TYPE abap_bool.
-
-DATA ind_tab TYPE TABLE OF ind_wa.
-
-ind_tab = VALUE #(
- ( comp1 = ... comp2 = ... comp_ind-comp2 = abap_true )
- ( comp1 = ... comp2 = ... comp_ind-comp2 = abap_true ) ).
-
-UPDATE dbtab FROM TABLE @ind_tab INDICATORS SET STRUCTURE comp_ind.
-
-"Reverses the logic
-
-UPDATE dbtab FROM TABLE @ind_tab INDICATORS NOT SET STRUCTURE comp_ind.
-
-"SET addition: Changing values of specific fields in all table rows
-"There are mutliple options for the value assignment. E. g. you can use
-"a literal, host variable/expression, SQL function, and so on.
-
-UPDATE dbtab SET comp2 = ... .
-```
-
-
-
-### Using [`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_dbtab.htm)
-- Inserts one or more rows into a database table specified or overwrites existing ones.
-- As above, `sy-subrc` and `sy-dbcnt` are set.
-
-``` abap
-"Inserting a single row into a database table or changing an existing row
-
-MODIFY dbtab FROM @row.
-
-"Using a host expression
-
-MODIFY dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
-
-"Inserting/Changing multiple rows
-
-MODIFY dbtab FROM TABLE @itab.
-
-"Using a host expression
-
-MODIFY dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
- ( comp1 = ... comp2 = ... ) ) ).
-
-"Inserting/Changing multiple rows based on a result set of an embedded subquery
-
-MODIFY dbtab FROM ( SELECT ... ).
-```
-
-
-
-### Using [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdelete_dbtab.htm)
-- Deletes one or more rows from a database table specified.
-- As above, `sy-subrc` and `sy-dbcnt` are set.
-
-``` abap
-"Variant DELETE FROM ...: Either all rows are deleted or restricted
-
-"All rows are deleted
-
-DELETE FROM dbtab.
-
-"Rows are deleted based on a condition
-
-DELETE FROM dbtab WHERE ....
-
-"Note that there are further options available, e. g. ORDER BY, UP TO
-"Variant DELETE ... FROM ...: Deleting a single row or multiple row
-
-DELETE dbtab FROM @row.
-
-"Using a host expression
-
-DELETE dbtab FROM @( VALUE #( comp1 = ... ) ).
-
-DELETE dbtab FROM TABLE @itab.
-
-"Using a host expression
-
-DELETE dbtab FROM TABLE @( VALUE #( ( comp1 = ... )
- ( comp1 = ... ) ) ).
-```
-
-
-
-## More Information
-- Note that ABAP SQL statements offer syntax options for dynamic programming. For example, you can specify the data source to read from dynamically. See more information in the ABAP Keyword Documentation or the [ABAP cheat sheet on dynamic programming](06_Dynamic_Programming.md).
- ```abap
- DATA(dbtab) = 'ZDEMO_ABAP_FLSCH'.
-
- "Selecting from a dynamically specified database table.
- SELECT *
- FROM (dbtab)
- WHERE ...
- INTO ...
- ```
-- [This topic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql.htm) serves as the entry point for topics about ABAP SQL in the ABAP Keyword Documentation. For the full details, check the subtopics there, especially topics not covered in this cheat sheet.
-- There are [RAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenarap_glosry.htm)-specific variants of ABAP SQL statements that use the `MAPPING FROM ENTITY` addition. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmapping_from_entity.htm).
-
-## Executable Example
-[zcl_demo_abap_sql](./src/zcl_demo_abap_sql.clas.abap)
-
-> **💡 Note**
-> - The executable example covers the following topics, among others:
-> - Reading from database tables using `SELECT`
-> - Various additions to `SELECT` statements
-> - Changing data in database tables using `INSERT`, `UPDATE`, `MODIFY` and `DELETE`
-> - Excursions: Operands and expressions in ABAP SQL statements
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
-> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
+
+
+# ABAP SQL
+
+- [ABAP SQL](#abap-sql)
+ - [Introduction](#introduction)
+ - [Excursion: Database Tables and Views](#excursion-database-tables-and-views)
+ - [Reading Data Using SELECT](#reading-data-using-select)
+ - [Basic Syntax](#basic-syntax)
+ - [Using SELECT for Multiple Purposes](#using-select-for-multiple-purposes)
+ - [Clause Variations and Additions in SELECT Statements](#clause-variations-and-additions-in-select-statements)
+ - [More Clauses](#more-clauses)
+ - [Operands and Expressions in ABAP SQL Statements](#operands-and-expressions-in-abap-sql-statements)
+ - [SQL operands](#sql-operands)
+ - [SQL Expressions](#sql-expressions)
+ - [Elementary Expressions](#elementary-expressions)
+ - [SQL Functions](#sql-functions)
+ - [More SQL Expressions](#more-sql-expressions)
+ - [Window Expressions](#window-expressions)
+ - [SQL Conditions](#sql-conditions)
+ - [Selecting Data by Evaluating the Content of Other Tables](#selecting-data-by-evaluating-the-content-of-other-tables)
+ - [Combining Data of Multiple Database Tables](#combining-data-of-multiple-database-tables)
+ - [Common Table Expressions (CTE)](#common-table-expressions-cte)
+ - [Changing Data in Database Tables](#changing-data-in-database-tables)
+ - [Using `INSERT`](#using-insert)
+ - [Using `UPDATE`](#using-update)
+ - [Using `MODIFY`](#using-modify)
+ - [Using `DELETE`](#using-delete)
+ - [More Information](#more-information)
+ - [Executable Example](#executable-example)
+
+## Introduction
+
+- [ABAP SQL](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_glosry.htm) is a subset of [SQL](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_glosry.htm "Glossary Entry")
+ which is the standardized language for accessing databases.
+- The main ABAP SQL keywords to read and change data are the
+ following:
+
+ | Keyword | Purpose |
+ | -------- | ------------------------------------------------------------------------- |
+ | `SELECT` | Reads data from database tables |
+ | `INSERT` | Adds rows to database tables |
+ | `UPDATE` | Changes the content of rows of database tables |
+ | `MODIFY` | Inserts rows into database tables or changes the content of existing rows |
+ | `DELETE` | Deletes rows from database tables |
+
+- ABAP SQL statements use the ABAP SQL interface. This interface transforms all ABAP SQL statements that access the standard database of an AS ABAP to platform-dependent SQL and forwards the results to the database system.
+- Generally bear in mind the [performance notes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql_perfo.htm) when using
+ ABAP SQL. The considerations there are not relevant for this cheat sheet since
+ the focus is on syntax options.
+
+## Excursion: Database Tables and Views
+
+
+ Expand to view the details
+
+
+This section provides bullet points on database tables and views which contain persisted data. Note that the code snippets in this cheat sheet focus on database tables as [data source](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_source_glosry.htm "Glossary Entry") for ABAP SQL statements.
+
+**Database tables in [AS ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenas_abap_glosry.htm "Glossary Entry") ...**
+
+- are objects of the [ABAP Dictionary (DDIC)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_dictionary_glosry.htm "Glossary Entry"). The term *database table* describes a physical database table in the current [standard database](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_db_glosry.htm).
+- are two-dimensional matrices consisting of rows and columns.
+- contain a [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm), i. e. a field or a combination of fields uniquely identifies every row in a table. A [primary key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_key_glosry.htm) must exist for every database table.
+ - Note the concept of [foreign keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenforeign_key_glosry.htm) in which one or more columns of a database table can be primary keys of another table. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_forkey.htm).
+- have a [flat structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenflat_structure_glosry.htm "Glossary Entry")
+ type. Plus, the definition of database tables consists of [technical](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_techstruc.htm) and [semantic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables_semastruc.htm) properties.
+- can be referenced as a data type and can be accessed using ABAP SQL.
+
+Find more information in the respective (sub)topics in the ABAP Keyword Documentation [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_database_tables.htm).
+
+
+**Views ...**
+
+- are further ABAP Dictionary objects for grouping columns from one or more database tables, among others.
+- usually realize a
+ [join](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenjoin_glosry.htm "Glossary Entry")
+ with defined [join
+ conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenjoin_condition_glosry.htm "Glossary Entry").
+- Note:
+ - Similar to database tables, the columns of such a view form a
+ flat structure. The view's name can be used, for example, as [data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_type_glosry.htm) to declare
+ [data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm), too.
+ - The views can be accessed by ABAP SQL, especially for reading
+ purposes using `SELECT`.
+
+**"Classic"** [DDIC
+Views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenddic_view_glosry.htm "Glossary Entry") ...
+
+- are the oldest form of views and are not available in [ABAP Cloud](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_cloud_glosry.htm).
+- can be accessed by ABAP SQL for read and write operations, however, writing is only supported if the view is created with only one database table.
+- can only be created in the [ABAP Workbench](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_workbench_glosry.htm).
+
+**"Modern" Views (since release 7.40)**
+
+- [External
+ views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexternal_view_glosry.htm "Glossary Entry")
+ as proxies for [SAP HANA
+ views](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenhana_view_glosry.htm "Glossary Entry")
+ (attribute view, analytic view, calculation view)
+ - SAP HANA Views are entities of the SAP HANA database that are
+ defined using the [SAP HANA
+ Studio](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenhana_studio_glosry.htm "Glossary Entry").
+ - They are based on HANA-specific data types.
+ - Using external views of the ABAP dictionary, you can make those
+ SAP HANA views "known" to the ABAP program. In doing so, the
+ external views can be used like classic DDIC views as structured
+ data types and as a source for reading operations with ABAP SQL.
+ - To be used only if the central database of the AS ABAP is an
+ [SAP HANA
+ database](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhana_database_glosry.htm "Glossary Entry").
+- [ABAP Core Data Services (ABAP
+ CDS)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_view_glosry.htm "Glossary Entry")
+ ...
+ - serve the purpose of defining semantically rich data models.
+ - have a lot more options than classic views, for example, they
+ support [annotations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_annotation_glosry.htm). Data sources can be combined using [associations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_association_glosry.htm), views can be defined with input parameters, and more.
+ - are used like a classic database view as structured data types
+ and used as a source for reading operations with ABAP SQL (using
+ [`SELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm)).
+ - are created using [Data Definition
+ Language (DDL)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddl_glosry.htm "Glossary Entry")
+ in the
+ [ADT](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenadt_glosry.htm "Glossary Entry")
+ (that is, a source code editor, in contrast to a form-based
+ editor).
+ - are, in contrast to external views, supported by all database
+ systems (that support the ABAP CDS characteristics).
+
+
+
+
+## Reading Data Using SELECT
+
+### Basic Syntax
+
+You use ABAP SQL `SELECT` statements to read data from one or more database tables (or views). This can be done to create a multirow or single row result set by assigning the result set to a suitable data object, i. e. you can store the multirow read result in an internal table or the single row result in a structure.
+The `SELECT` statement includes several clauses that serve
+different purposes. The following code snippet shows the basic syntax:
+``` abap
+SELECT FROM source "What database table or view to read from
+ FIELDS field_list "What columns should be read
+ WHERE condition "Specifies conditions on which a row/rows should be read
+ INTO @target. "Data object to which the result set is assigned (preceded by @)
+```
+> **💡 Note**
+>- There are further clauses available of which some are dealt with
+ further down. In general, the recommendation is to hit `F1` for the keywords and additions to get all the details in the ABAP Keyword Documentation.
+>- Especially in older ABAP programs, you will see other forms of the
+ `SELECT` syntax that you should no longer use. Strict syntax check modes might enforce the use
+ of specific ABAP SQL syntax. For example, the `INTO` clause should be placed after the other clauses. Furthermore, [host variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm "Glossary Entry") or [host expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_expression_glosry.htm "Glossary Entry") are required for data objects and expressions, i. e. they must be preceded by `@` or `@( ... )`. Further information: [Release-Dependent Syntax Check Modes (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_strict_modes.htm).
+>- Regarding host variables as in `SELECT ... INTO @target.` and since they are used in most examples below: A host variable is a data object that is
+> - declared in the ABAP program
+> - prefixed with the `@` character and
+> - specified in an [operand position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm) of an ABAP SQL statement.
+> See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm).
+>- The `SELECT` list, i. e. the fields that are specified, can also be specified following the `SELECT`
+ keyword before the `FROM` clause - without `FIELDS`. The
+ following two `SELECT` statements are basically the same but differently arranged:
+> ``` abap
+> SELECT FROM dbtab
+> FIELDS comp1, comp2, comp3
+> ...
+>
+> SELECT comp1, comp2, comp3
+> FROM dbtab
+> ...
+> ```
+>- Regarding the target into which data is read: Instead of using a
+ variable that is (extra) declared beforehand, you can also make use
+ of [inline
+ declarations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry"),
+ for example `... INTO TABLE @DATA(itab).`, to comfortably
+ create an appropriate variable in place. Note that in case of
+ internal tables as targets, the resulting table is a standard table
+ and has an empty key which might have an impact when further
+ processing the internal table entries. Find more information in the
+ ABAP cheat sheet [Internal Tables](01_Internal_Tables.md). In newer ABAP releases, the declaration operator [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm) can be used to declare immutable variables.
+
+
+
+### Using SELECT for Multiple Purposes
+
+**Reading a single row into a structure**
+``` abap
+"SINGLE addition
+"Here, all fields of a single row a read. Specifying an
+"asterisk * indicates that all fields are to be read.
+"Alternatively, you can list all the fields separated by comma.
+"Note that if the selection covers more than one row, e. g. in case
+"of a non-unique WHERE clause, one of these rows is included in
+"the result.
+SELECT SINGLE FROM dbtab
+ FIELDS *
+ WHERE ...
+ INTO @struc. "Existing structure of dbtab's row type
+
+"Reading a selected set of fields of a single row
+SELECT SINGLE FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE ...
+ INTO @DATA(struc2). "Structure declared inline
+
+"Alternative syntax without the FIELDS addition
+"Here, the CORRESPONDING FIELDS OF addition is used. Only the content of
+"columns that have identically named components in the target data object
+"is assigned.
+SELECT SINGLE comp1, comp2, comp3 "Selected set of fields
+ FROM dbtab
+ WHERE ...
+ INTO CORRESPONDING FIELDS OF @struc. "Existing structure
+```
+> **💡 Note**
+>- Although its use is optional, a `WHERE` clause should be specified to further restrict the read result.
+>- Regarding the addition `CORRESPONDING FIELDS OF` in the `INTO`
+ clause: As mentioned, only the content of columns for which there are identically named components in the target are assigned. However, if you want to read data into an existing data object and particular fields are specified in the `SELECT` list and if the addition is **not** specified, you might stumble on undesired results. The target data object must contain enough components and the content of the columns are assigned to the components of the target from left to right in the order specified after `SELECT`. The content of surplus components of the target is not changed. Plus, pay attention to [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm). Basic rule: Without `CORRESPONDING ...`, column names do not play a role but only the position. With `CORRESPONDING ...`, the position of the columns does not play a role but only the name.
+>- Find more information regarding the addition `INTO` [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm).
+
+**Reading multiple rows into an internal table**.
+``` abap
+SELECT FROM dbtab
+ FIELDS * "All fields
+ WHERE ...
+ INTO TABLE @itab. "itab has an appropriate row type
+
+"Alternative syntax without the FIELDS addition
+SELECT comp1, comp2, comp3 "Selected set of fields
+ FROM dbtab
+ WHERE ...
+ INTO TABLE @DATA(lv_itab). "Internal table declared inline
+
+"Selected set of fields, existing variable
+"See the note on CORRESPONDING FIELDS OF above
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3 "Selected set of fields
+ WHERE ...
+ INTO CORRESPONDING FIELDS OF TABLE @itab.
+```
+
+**`SELECT` loop: Sequentially reading multiple rows**.
+- A `SELECT` loop can be opened if the assignment is made to a structure and the addition `SINGLE` is not used.
+- If the row is found, the system field `sy-subrc` is set to `0`.
+- The loop must be closed using `ENDSELECT`.
+- To terminate the loop completely, you can use the statement [`EXIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapexit_loop.htm).
+- Note: As covered further down, when using the addition `PACKAGE SIZE` and storing the result in a table, a loop is opened, too.
+
+``` abap
+SELECT FROM dbtab
+ FIELDS *
+ WHERE ...
+ INTO @struc.
+
+ IF sy-subrc = 0.
+ ... "For example, making changes on data and adding the row to an internal table.
+
+ ENDIF.
+
+ENDSELECT.
+```
+
+
+### Clause Variations and Additions in SELECT Statements
+
+`SELECT`/`FROM` clauses:
+
+**Checking the existence of a row in a database table**
+``` abap
+"Instead of @abap_true, you could also use 'X'.
+SELECT SINGLE @abap_true
+ FROM dbtab
+ WHERE ...
+ INTO @DATA(exists).
+
+IF exists = abap_true.
+ ...
+ENDIF.
+```
+
+**Removing rows that occur more than once in a multirow result set** using the `DISTINCT` addition.
+- Cannot be used with the addition `SINGLE`.
+- See more information here [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_clause.htm).
+``` abap
+SELECT DISTINCT comp1
+ FROM dbtab
+ WHERE ...
+ INTO TABLE @itab.
+```
+
+**SELECT list variants** (some of them are already outlined above)
+
+The following specifications can also be combined:
+- `SELECT * ...`: As outlined above, the `*` character defines all columns to be read from a data source (in the order specified there).
+- `SELECT col1, col2, col3 ...`: A comma-separated list of individual column names.
+- `SELECT data_source~col1, data_source~col2, data_source~col3 ...`: A comma-separated list of individual column names. Here, the name of the data source is explicitly specified and precedes the column name, separated by a tilde.
+- `SELECT data_source~* ...`: In this case, the name of the data source is followed by a tilde and the `*` character to specify all columns. Note that there are [special conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_list.htm#!ABAP_VARIANT_1@1@) when using this variant.
+- `SELECT col1 AS al1, col2 AS al2, col3 AS al3 ...`:
+ - Defining alias names for individual columns of the result set with [`AS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_list.htm).
+ - Make sure that you use an alias name only once here. In the statement, the alias name can only be used after an `ORDER BY` clause.
+ - As shown further down, in some cases (e. g. when using SQL expressions) the specification of an alias name is required. Setting an alias name for the data source is also possible (`SELECT FROM dbtab AS alias_name ...`). See the section on joins further down.
+
+> **💡 Note**
+> You have plenty of options regarding the specification of the columns in the `SELECT` list, among them, the outlined direct specification of the column name. SQL expressions can be specified, too. See more details [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_clause_col_spec.htm) and in the sections on SQL expressions further down.
+
+
+``` abap
+"All fields
+SELECT * FROM dbtab
+ WHERE ...
+ INTO ...
+
+"Comma-separated list
+SELECT col1, col2, col3
+ FROM dbtab
+ WHERE ...
+ INTO ...
+
+"Comma-separated list, data source explicitly specified
+SELECT dbtab~col1, dbtab~col2, col3
+ FROM dbtab
+ WHERE ...
+ INTO ...
+
+"Data source explicitly specified, all fields
+SELECT dbtab~*
+ FROM dbtab
+ WHERE ...
+ INTO ...
+
+"Alias names
+"Consider the following: You want to read data from a database table into a target data
+"object but, for example, a name in the target is different. Provided that there will
+"not be an issue regarding the type (conversion) when the values are assigned, you might
+"specify an alias name for the database column to match a component's name in the target data object.
+SELECT FROM dbtab
+ FIELDS comp1 AS comp_a, comp2 AS comp_b, comp3 AS comp_c
+ WHERE ...
+ INTO CORRESPONDING FIELDS OF TABLE @itab.
+
+"Alias name also possible for the data source
+SELECT ds~col1, ds~col2, ds~col3
+ FROM dbtab AS ds
+ WHERE ...
+ INTO ...
+```
+
+
+
+**Reading data from a database table in another client** ([classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm) only). Note that there are several variants of the `USING ...` addition for switching the [implicit client handling (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_sql_client_handling.htm) from the current client to other clients. See more information [here (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapselect_client.htm).
+``` abap
+"Some examples; not available in ABAP for Cloud Development
+
+"Replaces the current client with the specified client
+SELECT *
+ FROM dbtab USING CLIENT '000'
+ WHERE ...
+ INTO TABLE @itab.
+
+"Selects data of any number of clients
+SELECT *
+ FROM dbtab USING ALL CLIENTS
+ WHERE ...
+ INTO TABLE @itab.
+```
+
+**Reading data from an internal table as data source** using `SELECT`. Note that an alias name must be specified for the internal table used as data source.
+Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_itab.htm).
+
+``` abap
+SELECT *
+ FROM @itab1 AS tab
+ WHERE ...
+ INTO TABLE @DATA(itab2).
+```
+
+
+
+`INTO` **clause**:
+
+**Limiting the number of returned table rows** using the optional addition [`UP TO n ROWS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm).
+
+``` abap
+"A maximum of five rows are to be returned
+"If the INTO clause is the last clause, the UP TO clause must be positioned after it.
+SELECT * FROM dbtab
+ WHERE ...
+ INTO TABLE @DATA(itab_upto)
+ UP TO 5 ROWS.
+```
+
+**Returning only the table rows after a row with a specified count from the result set** using the optional addition [`OFFSET n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_up_to_offset.htm#!ABAP_ADDITION_2@2@). You can only use the addition, if an `ORDER BY` clause is specified.
+
+``` abap
+"In the example, data of all flights are retrieved, except for the 2 flights
+"with the shortest flight time.
+SELECT *
+ FROM ztest_abap_flsch
+ WHERE carrid = 'LH'
+ ORDER BY fltime ASCENDING
+ INTO TABLE @DATA(itab)
+ OFFSET 2.
+```
+
+**Reading into individual elementary data objects**.
+Apart from reading into structures and internal tables outlined above, you can also read into individual elementary data objects.
+Here, the individual elementary data objects as target objects are specified in a comma-separated list (e. g. as existing host variables or declared inline with `@DATA(...)`) and put between a pair of parentheses.
+Note:
+- The comma-separated list must have the same number of elements as columns in the result set.
+- The content of the columns in the result set is assigned to the data objects specified in the list from left to right in accordance with the order specified in the `SELECT` list.
+- Note the [assignment rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenselect_into_conversion.htm) also in this context.
+- More information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ALTERNATIVE_1@1@).
+
+
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE ...
+ INTO (@res1,@res2,@res3).
+ "INTO (@DATA(res1),@DATA(res2),@DATA(res3)). "Using inline declarations
+```
+
+**Appending the result set to an existing internal table**.
+The addition `INTO` initializes the target object. When using the addition `APPENDING`, you can retain existing lines in internal tables. `APPENDING` is also possible with the addition `CORRESPONDING FIELDS OF TABLE`.
+
+``` abap
+SELECT * FROM dbtab
+ WHERE ...
+ APPENDING TABLE @itab.
+
+SELECT * FROM dbtab
+ WHERE ...
+ APPENDING CORRESPONDING FIELDS OF TABLE @diff_itab.
+```
+
+**Reading into packages of a specified number of rows** when reading into internal tables. The addition [`PACKAGE SIZE n`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinto_clause.htm#!ABAP_ONE_ADD@1@) can be specified after `INTO TABLE` and `APPENDING TABLE`. A `SELECT` loop ist opened. After `PACKAGE SIZE`, the number of rows is specified (which can be a host variable, host expression or a literal of type `i`) denoting the number of rows to be inserted in the target object per iteration.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE ...
+ INTO TABLE @DATA(itab_pack) PACKAGE SIZE n.
+...
+ENDSELECT.
+```
+
+**Specifying an [anonymous data object](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm) as target object** using the addition [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_into_target.htm#!ABAP_ALTERNATIVE_3@3@). Only to be used after `INTO` and not `APPENDING`.
+
+``` abap
+"Here, the target object is an anonymous data object declared inline.
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE ...
+ INTO TABLE NEW @DATA(dref).
+```
+
+
+
+### More Clauses
+
+[`GROUP BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapgroupby_clause.htm)
+clause: Combining groups of table rows in the result set. You
+might also use [SQL expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm "Glossary Entry")
+here. Multiple clause elements are separated by a comma. Find more
+information on SQL expressions further down.
+
+Note that the `GROUP BY` clause requires all columns that are
+directly specified in the `SELECT` list or specified there as an
+argument of an SQL expression to be specified. An exception to this is
+[aggregate
+functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
+in [aggregate
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_expression_glosry.htm "Glossary Entry")
+(except [grouping
+functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengrouping_glosry.htm "Glossary Entry"))
+as shown in the following example.
+
+In the example below, the database table rows that have the same content in column `comp1` are combined. The lowest and highest values in column `comp2` are determined for each of these groups and placed into the combined row.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, MIN( comp2 ) AS min, MAX( comp2 ) AS max
+ WHERE ...
+ GROUP BY comp1
+ INTO ...
+```
+
+[`HAVING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaphaving_clause.htm)
+clause: Limiting the number of table rows in groups in the
+result by setting conditions on these rows. The rows for which a
+logical expression is true are inserted in the target variable. Note
+that `HAVING` can only be used together with `GROUP BY`.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, MIN( comp2 ) AS min, MAX( comp3 ) AS max
+ WHERE ...
+ GROUP BY comp1
+ HAVING comp1 LIKE '%XYZ%' AND SUM( comp4 ) > 100
+ INTO ...
+```
+
+[`ORDER BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaporderby_clause.htm)
+clause: Sorting the result set by specified columns.
+
+The following example shows the ordering of the result set based on the
+content of the primary key of the [data
+source](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_source_glosry.htm "Glossary Entry").
+You can also order by any columns and by explicitly specifying the sort
+order. There are more ordering options, for example, by using SQL
+expressions.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE ...
+ ORDER BY PRIMARY KEY
+ "comp2 ASCENDING
+ "comp2 DESCENDING
+ INTO ...
+```
+
+> **💡 Note**
+>- Not specifying `ORDER BY` means that the order of entries in the result set is undefined.
+>- If `ORDER BY` and `GROUP BY` clauses are used, all columns specified after `ORDER BY` must also be specified after `GROUP BY`.
+>- If aggregate functions are specified after `SELECT`, all columns that are specified after `ORDER BY` and that do not have an alias name for an aggregate function must also be specified after `SELECT` and after the `GROUP BY` clause which is required in this case, too.
+
+[`WHERE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwhere.htm) clause: Restricts the number of rows that are included in the result set using logical expressions. See further information on them in the following sections.
+``` abap
+SELECT FROM dbtab
+ FIELDS comp1, comp2, comp3
+ WHERE comp1 = 'abc'
+ AND comp2 < 123
+ INTO ...
+```
+
+
+
+### Operands and Expressions in ABAP SQL Statements
+
+ABAP offers plenty of [SQL
+operands](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operand_glosry.htm "Glossary Entry")
+and
+[expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_expression_glosry.htm "Glossary Entry")
+that are possible in ABAP SQL statements, not only in the context of
+`SELECT` statements and the `SELECT` lists which are
+mainly used for the following demonstration examples. Questions about
+when to use what, what is possible in which contexts and positions, is
+beyond the scope of this cheat sheet. Check the details in the
+respective topics in the ABAP Keyword Documentation. Find a general
+overview of important operand positions in ABAP SQL
+[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operand_positions_oview.htm).
+Due to the rich variety of options, the cheat sheet covers a selection.
+
+#### SQL operands
+
+- Are elementary operands in an ABAP SQL statement
+- Can be database table or view columns, a
+ [literal](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_glosry.htm "Glossary Entry"),
+ [host
+ variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_variable_glosry.htm "Glossary Entry")
+ (i. e. global or local data objects escaped using `@`:
+ `@dobj`) or [host
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenhost_expression_glosry.htm "Glossary Entry")
+ (`@( ... )`)
+ - Regarding literals: They are not prefixed with the escape
+ character `@`. The literals can be
+ [typed](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentyped_literal_glosry.htm "Glossary Entry")
+ (using the type name and content within a pair of backquotes:
+ char\`abc\`) with [built-in ABAP Dictionary
+ types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_builtin_types.htm)
+ or untyped. Typed literals are preferable for the following
+ reasons: Using untyped literals means extra cost in terms of
+ performance since they must be converted by the compiler. Plus,
+ their use can result in errors at runtime whereas typed literals
+ guarantee type compatibility at once.
+ - Regarding host expressions: Structures and internal tables are
+ possible as host expressions for statements modifying the
+ content of database tables as shown further down.
+- See more information
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_operands.htm).
+
+Example demonstrating possible operands:
+``` abap
+DATA upto TYPE i VALUE 3.
+
+SELECT FROM zdemo_abap_flsch
+ FIELDS
+ "Specifies a column of a data source directly using its name
+ cityfrom,
+
+ "Column selector ~ can be used to prefix every specified column.
+ "Here, it is optional. It is non-optional, e. g., if multiple data
+ "sources in an ABAP SQL statement are edited and the column name
+ "is not unique.
+ zdemo_abap_flsch~cityto,
+
+ 'Lufthansa' AS name, "Untyped literal
+
+ char`X` AS flag, "Typed literal
+
+ @upto AS num, "Host variable
+
+ @( cl_abap_context_info=>get_system_date( ) ) as date "Host expression
+
+ WHERE carrid = 'LH' "Untyped literal
+ AND countryfr = char`DE` "Typed literal
+
+ "Data object created inline and escaped with @
+ INTO TABLE @DATA(it)
+
+ "The following clause shows all options having the same effect
+ UP TO 3 ROWS. "Untyped numeric literal
+ "UP TO int4`3` ROWS. "Typed numeric literal
+ "UP TO @upto ROWS. "Host variable
+ "UP TO @( 10 - 7 ) ROWS. "Host expression
+```
+
+
+
+#### SQL Expressions
+
+- Expressions in an ABAP SQL statement that are passed to the database
+ system for evaluation.
+- For example, SQL expressions can be specified as columns in the
+ `SELECT` list as demonstrated in most of the following examples.
+ Find information on more possible positions and general information
+ on SQL expressions
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsql_expr.htm)
+ and the subtopics there.
+
+##### Elementary Expressions
+
+- An elementary expression represents one of the four mentioned
+ operands above: A value from the database (the column name) or
+ values from an ABAP program passed to the database (literal, host
+ variable or host expression).
+- As an example, see the `SELECT` list in the example above.
+- See more information
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_elem.htm).
+
+##### SQL Functions
+
+- You can use built-in functions in ABAP SQL.
+- Result: Value with the associated dictionary type.
+- Arguments of the functions: Cover one or more SQL expressions.
+- See more information
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql_builtin_functions.htm).
+
+Example: [Numeric functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_arith_func.htm)
+``` abap
+SELECT SINGLE
+ carrname,
+
+ "Division, result rounded to an integer
+ "Result: 2
+ div( 4, 2 ) AS div,
+
+ "Division, 3rd argument: result is rounded to the specified
+ "number of decimals
+ "Result: 0.33
+ division( 1, 3, 2 ) AS division,
+
+ "Result is rounded to first greater integer
+ "Result: 2
+ ceil( decfloat34`1.333` ) AS ceil,
+
+ "Result is the remainder of division
+ "Result: 1
+ mod( 3, 2 ) AS mod,
+
+ "Result: Largest integer value not greater than the specified value
+ "Result: 1
+ floor( decfloat34`1.333` ) AS floor,
+
+ "Returns the absolute number
+ "Result: 2
+ abs( int4`-2` ) AS abs,
+
+ "Result is rounded to the specified position after the decimal separator
+ "Result: 1.34
+ round( decfloat34`1.337`, 2 ) AS round
+
+ FROM zdemo_abap_carr
+ WHERE carrid = 'AA'
+ INTO @DATA(numeric_functions).
+```
+
+
+
+Example: [String functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_string_func.htm)
+
+``` abap
+SELECT SINGLE
+ carrid, "LH
+ carrname, "Lufthansa
+ url, "http://www.lufthansa.com
+
+ "Concatenates strings, ignores trailing blanks
+ "Result: LHLufthansa
+ concat( carrid, carrname ) AS concat,
+
+ "Concatenates strings, number denotes the blanks that are inserted
+ "Result: LH Lufthansa
+ concat_with_space( carrid, carrname, 1 ) AS concat_with_space,
+
+ "First letter of a word -> uppercase, all other letters -> lowercase;
+ "note that a space and other special characters means a new word.
+ "Result: Http://Www.Lufthansa.Com
+ initcap( url ) AS initcap,
+
+ "Position of the first occurrence of the substring specified
+ "Result: 6
+ instr( carrname,'a' ) AS instr,
+
+ "String of length n starting from the left of an expression;
+ "trailing blanks are ignored
+ "Result: Luft
+ left( carrname, 4 ) AS left,
+
+ "Number of characters in an expression, trailing blanks are ignored
+ "Result: 24
+ length( url ) AS length,
+
+ "Checks if expression contains a PCRE expression;
+ "case-sensitive by default (case_sensitive parameter can be specified)
+ "Notes on the result: 1 = found, 0 = not found
+ "Result: 1
+ like_regexpr( pcre = '\..', "Period that is followed by any character
+ value = url ) AS like_regex,
+
+ "Returns position of a substring in an expression,
+ "3rd parameter = specifies offset (optional)
+ "4th parameter = determines the number of occurrences (optional)
+ "Result: 9
+ locate( carrname, 'a', 0, 2 ) AS locate,
+
+ "Searches a PCRE pattern, returns offset of match;
+ "many optional parameters: occurrence, case_sensitive, start, group
+ "Result: 21
+ locate_regexpr( pcre = '\..', "Period followed by any character
+ value = url,
+ occurrence = 2 ) "2nd occurrence in the string
+ AS locate_regexpr,
+
+ "Searches a PCRE pattern, returns offset of match + 1;
+ "many optional parameters: occurrence, case_sensitive, start, group
+ "Result: 2
+ locate_regexpr_after( pcre = '.', "Any character
+ value = url,
+ occurrence = 1 ) AS locate_regexpr_after,
+
+ "Removes leading characters as specified in the 2nd argument,
+ "trailing blanks are removed
+ "Result: ufthansa
+ ltrim( carrname, 'L' ) AS ltrim,
+
+ "Counts all occurrences of found PCRE patterns
+ "Result: 2
+ occurrences_regexpr( pcre = '\..', "Period that is followed by any character
+ value = url ) AS occ_regex,
+
+ "Replaces the 2nd argument with the 3rd in an expression
+ "Result: Lufth#ns#
+ replace( carrname, 'a', '#' ) AS replace,
+
+ "Replaces a found PCRE expression;
+ "more parameters possible: occurrence, case_sensitive, start
+ "Result: http://www#ufthansa#om
+ replace_regexpr( pcre = '\..', "Period that is followed by any character
+ value = url,
+ with = '#' ) AS replace_regex,
+
+ "Extracts a string with the length specified starting from the right
+ "Result: hansa
+ right( carrname, 5 ) AS right,
+
+ "Expands string to length n (2nd argument); trailing blanks produced
+ "are replaced by the characters from the (3rd) argument
+ "Note that if n is less than the string, the expression is truncated
+ "on the right.
+ "Result: Lufthansa###
+ rpad( carrname, 12, '#' ) AS rpad,
+
+ "All trailing characters that match the character of the 2nd argument
+ "are removed; trailing blanks are removed, too
+ "Result: Lufthans
+ rtrim( carrname, 'a' ) AS rtrim,
+
+ "Returns a substring; 2nd argument = position from where to start;
+ "3rd argument: length of the extracted substring
+ "Result: fth
+ substring( carrname, 3, 3 ) AS substring,
+
+ "Searches for a PCRE expression and returns the matched substring
+ "More parameters possible: occurrence, case_sensitive, start, group
+ "Result: .lu
+ substring_regexpr( pcre = '\...', "Period that is followed by any two characters
+ value = url ) AS substring_regexpr,
+
+ "All lower case letters are transformed to upper case letters
+ "Result: LUFTHANSA
+ upper( carrname ) AS upper
+
+ FROM zdemo_abap_carr
+ WHERE carrid = 'LH'
+ INTO @DATA(string_functions).
+```
+
+
+
+[Aggregate expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_aggregate.htm)
+
+- Consist of [aggregate
+ functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
+ and aggregate the values of multiple rows of the result set of a
+ [query](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenquery_glosry.htm "Glossary Entry")
+ into a single value
+- See more information
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_aggregate.htm).
+
+Example:
+``` abap
+"The example shows a selection of available functions
+SELECT
+ carrid,
+
+ "Average value of the content of a column in a row set
+ AVG( fltime ) AS fltime1,
+
+ "AVG with data type specification for the result
+ AVG( fltime AS DEC( 14,4 ) ) AS fltime2,
+
+ "Maximum value of the results in a row set
+ MAX( fltime ) AS max,
+
+ "Minimum value
+ MIN( fltime ) AS min,
+
+ "Sum of the results in a row set.
+ SUM( fltime ) AS sum,
+
+ "Returns the number of rows in a row set.
+ "The following two have the same meaning.
+ COUNT( * ) AS count2,
+ COUNT(*) AS count3,
+
+ "Chains the results in a row set.
+ "An optional separator can be specified
+ STRING_AGG( airpfrom, ', ' ) AS string_agg
+
+ FROM zdemo_abap_flsch
+ WHERE carrid = 'LH'
+ GROUP BY carrid
+ INTO TABLE @DATA(agg_exp).
+```
+
+
+
+##### More SQL Expressions
+
+- [Arithmetic
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_arith.htm)
+ to perform arithmetic calculations using the operators `+`,
+ `-`, `*`, `/`,
+- [Cast
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_cast.htm)
+ to convert the value of operands to a dedicated dictionary type.
+ Note that there are special [conversion
+ rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_cast_rules.htm).
+- [String
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_string.htm)
+ using the operator `&&` to concatenate character strings.
+- [Case
+ distinctions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_case.htm)
+ to carry out either a simple (comparison of the values of a
+ dedicated operand) or complex (searched case; evaluation of multiple
+ logical expressions) case distinction.
+
+The following example demonstrates the expressions mentioned above:
+``` abap
+SELECT SINGLE
+ carrid,
+
+ "Arithmethic expressions
+ "operators + - *
+ "Note that / is not allowed in integer expressions as the one below
+ ( 1 + 2 ) * 3 AS calc,
+
+ "/ used in an expression using type adjustment in ABAP SQL.
+ "A cast expression converts the value of the operands to the
+ "specified dictionary type. The result is a representation of the
+ "source value in the specified type.
+ CAST( 1 AS D34N ) / CAST( 2 AS D34N ) AS ratio,
+
+ "String expression using && to concatenate two character strings;
+ "the result of the concatenation must not be longer than
+ "255 characters.
+ carrid && carrname AS concat,
+
+ "Case distinction
+ "Simple case distinction
+ "The expression compares the values of an operand with other
+ "operands. Result: The first operand after THEN for which the
+ "comparison is true. If no matches are found, the result specified
+ "after ELSE is selected.
+ CASE currcode
+ WHEN 'EUR' THEN 'A'
+ WHEN 'USD' THEN 'B'
+ ELSE 'C'
+ END AS case_simple,
+
+ "Complex case distinction
+ "The expression evaluates logical expressions. Result: The first
+ "operand after THEN for which the logical expression is true. If no
+ "logical expressions are true, the result specified after ELSE is
+ "selected.
+ CASE WHEN length( carrname ) <= 5 THEN 'small'
+ WHEN length( carrname ) BETWEEN 6 AND 10 THEN 'mid'
+ WHEN length( carrname ) BETWEEN 11 AND 15 THEN 'large'
+ ELSE 'huge'
+ END AS case_complex
+
+FROM zdemo_abap_carr
+WHERE carrid = 'AA'
+INTO @DATA(more_sql_expr).
+```
+
+
+
+##### Window Expressions
+
+How [window expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_expression_glosry.htm "Glossary Entry") work:
+
+- Define a subset of the result set (i. e. the
+ "[window](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_glosry.htm "Glossary Entry")")
+ of a database query that implements ABAP SQL
+- Apply a [window
+ function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwindow_function_glosry.htm "Glossary Entry") -
+ which evaluates the rows of the window and which can, for example,
+ be an [aggregate
+ function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenaggregate_function_glosry.htm "Glossary Entry")
+ like
+ [`AVG`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_agg_func&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_VARIANT_1@1@&tree=X)
+ to determine the average value - to the result set
+- I. e. a window is constructed by the rows of the result set for
+ which all the window functions have the same result; a value is then
+ determined for the rows of a window
+
+Setup of a statement with window expressions:
+
+- Window function, e. g. an aggregate function like `AVG`,
+ followed by `OVER( ... )` (the content in the parentheses
+ defines the "window")
+- The content in the parentheses can contain the following additions:
+ - Optional `PARTITION BY`: Defines the windows using a
+ comma-separated list of [SQL
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsql_expr.htm);
+ the window function is calculated for the rows of this window;
+ note that if the addition is not specified, the window comprises
+ all rows of the result set
+ - Optional `ORDER BY`: Introduces both an order (you can
+ use `ASCENDING` and `DESCENDING`) and a frame
+ (as outlined below) within the current window, which further
+ restricts the rows for which the window function is calculated
+ - A window frame, which stands for a subset of rows inside a
+ window, can optionally be defined if `ORDER BY` is
+ specified; there are 3 options to define the starting and ending
+ frame boundaries (see the example)
+
+See more information on window expressions and the syntax
+[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect_over.htm).
+
+Examples:
+``` abap
+"Example 1: A simple window is constructed in the OVER clause;
+"window functions - here aggregate functions - are applied
+SELECT carrid, currency,
+ SUM( paymentsum ) OVER( PARTITION BY carrid ) AS sum,
+ AVG( price AS DEC( 14,2 ) ) OVER( PARTITION BY carrid ) AS avg,
+ MAX( price ) OVER( PARTITION BY carrid ) AS max
+ FROM zdemo_abap_fli
+ ORDER BY carrid
+ INTO TABLE @DATA(win).
+
+"Example 2:
+SELECT carrid, currency, fldate,
+ "Sorts the rows by some columns and counts the number of rows from
+ "the first row of the window to the current row.
+ COUNT( * ) OVER( ORDER BY currency, fldate
+ ROWS BETWEEN
+ "UNBOUNDED PRECEDING: frame starts at the first row of the window
+ UNBOUNDED PRECEDING
+ "CURRENT ROW: determines starting or ending at the current row; here, it ends
+ AND CURRENT ROW ) AS count1,
+
+ "If no window frame is used, the default window frame is
+ "BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,
+ "i. e. the result of count1 equals the result of count2.
+ COUNT( * ) OVER( ORDER BY currency, fldate ) AS count2,
+
+ "Sorts the rows by some columns and counts the number of rows from
+ "the current row to the last row of the window.
+ "The result is reverse numbering.
+ COUNT( * ) OVER( ORDER BY currency, fldate
+ ROWS BETWEEN CURRENT ROW
+ UNBOUND FOLLOWING:
+ "Determines the ending frame boundary, this addition specifies the last row of the window
+ AND UNBOUNDED FOLLOWING ) AS count_reverse,
+
+ "Sorts the rows by some columns and calculates the rolling averages
+ "of a subset of rows from column price. The subset consists of the
+ "current row plus one preceding and one following row. Another use
+ "case as below example that uses prices would be that, for example,
+ "you can calculate the 3-day-average temperature for every day from
+ "a list of temperature data.
+ AVG( price AS DEC( 14,2 ) ) OVER( ORDER BY currency, fldate
+ ROWS BETWEEN
+ "n PRECEDING: for both start and end of frame; frame to start/end n rows above the current row
+ 1 PRECEDING
+ "n FOLLOWING: for both start and end of frame; frame to start/end n rows beneath the current row
+ AND 1 FOLLOWING ) AS avg
+
+ FROM zdemo_abap_fli
+ INTO TABLE @DATA(result).
+```
+
+
+
+### SQL Conditions
+
+You can formulate conditions in ABAP SQL statements, i. e. [logical
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm "Glossary Entry"),
+especially in the `WHERE` clause to restrict the result. Note
+that without a `WHERE` clause, all rows are respected for the
+operation.
+
+See below a selection of the operators that are possible when specifying
+conditions. For more information, see the subtopics of the [SQL
+Conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenasql_cond.htm)
+topic.
+
+| Operator | Meaning |
+|----------|:-------------:|
+| `=`, `EQ` | The content of two operands is equal.|
+| `<>`, `NE` | The content of two operands is not equal.|
+| `<`, `LT` | The content of one operand is less than the content of the other operand.|
+| `>`, `GT` | The content of one operand is greater than the content of the other operand.|
+| `<=`, `LE` | The content of one operand is less than or equal to the content of the other operand.|
+| `>=`, `GE` | The content of one operand is greater than or equal to the content of the other operand.|
+| `... [NOT] BETWEEN ... AND ...` | The value of an operand is (not) between the value of the two other operands.|
+| `... [NOT] LIKE ...` | The content of an operand matches (does not match) a specified pattern. The pattern can be specified by using wildcard characters. `%` stands for any character string, including an empty string. `_` stands for any character.|
+| `... IS [NOT] INITIAL ...` | The value of an operand is (not) the initial value of its built-in dictionary type.|
+| `... EXISTS ...` | Checks the result set of a [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry"). The expression is true if the result set contains at least one row. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_subquery.htm).|
+| `... [NOT] IN ...` | Checks whether the operands on the left side match a value from a set of values specified in parentheses. On the left side, a single operand or an operand list are possible. On the right side, a comma-separated lists or subqueries can be specified. It is also possible to specify a [ranges table](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_table_glosry.htm) to evaluate [ranges conditions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenranges_condition_glosry.htm).|
+| `... IS [NOT] NULL ...` | Checks whether the value of an operand is (not) the [null value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennull_value_glosry.htm). Find more information in the code snippet and in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_null.htm). |
+
+> **💡 Note**
+>You can combine multiple logical expressions into one
+logical expression using `AND` or `OR`. To further
+detail out the desired condition, expressions within parentheses are
+possible.
+
+Examples:
+
+``` abap
+"---- SQL conditions demonstrated with the WHERE clause ----
+"Note:
+"- For most of the self-contained examples, an internal table is used as the
+" data source of SELECT statements to work with simple data.
+"- For some examples that are covered, such as subqueries, demo database tables
+" from the cheat sheet repository are used in addition.
+"- Dynamic specifications are also possible. They are not covered here. See
+" the Dynamic Programming cheat sheet.
+
+"---- Types and internal table to work with in the examples ----
+"Note: You cannot use type string columns in WHERE conditions.
+TYPES: BEGIN OF demo_struc,
+ id TYPE i,
+ name TYPE c LENGTH 15,
+ "name TYPE string,
+ END OF demo_struc.
+DATA itab TYPE SORTED TABLE OF demo_struc WITH UNIQUE KEY id.
+"Populating internal table with data to work with in the examples
+itab = VALUE #( ( id = 1 name = 'bear' )
+ ( id = 2 name = 'camel' )
+ ( id = 3 name = 'rabbit' )
+ ( id = 4 name = 'zebra' )
+ ( id = 5 name = 'dog' )
+ ( id = 6 name = 'deer' )
+ ( id = 7 name = 'squirrel' )
+ ( id = 8 name = 'cheetah' )
+ ( id = 9 name = 'elephant' )
+ ( id = 10 name = 'donkey' )
+ ( id = 11 name = 'fish' )
+ ( id = 12 name = 'sheep' ) ).
+
+"---- =, <>, >, >= (as a selection of possible comparison operators) ----
+SELECT id FROM @itab AS tab WHERE name = 'bear' INTO TABLE @DATA(it). "1
+SELECT id FROM @itab AS tab WHERE name <> 'bear' INTO TABLE @it. "2-12
+SELECT id FROM @itab AS tab WHERE id > 10 INTO TABLE @it. "11,12
+SELECT id FROM @itab AS tab WHERE id >= 10 INTO TABLE @it. "10,11,12
+
+"---- Combining logical expressions using AND, OR and parentheses ----
+SELECT id FROM @itab AS tab WHERE id = 1 AND name = 'bear' INTO TABLE @it. "1
+SELECT id FROM @itab AS tab WHERE name = 'bear' OR name = 'sheep' INTO TABLE @it. "1,12
+
+"In the following example, the resulting table is initial. One of the expressions
+"in parentheses is false (AND is used between the expressions in parentheses).
+"In contrast, the example below returns an entry because of using OR.
+SELECT id FROM @itab AS tab
+ WHERE ( id = 1 AND name = 'bear' )
+ AND ( id = 20 AND name = 'camel' )
+ INTO TABLE @it.
+
+SELECT id FROM @itab AS tab
+ WHERE ( id = 1 AND name = 'bear' )
+ OR ( id = 20 AND name = 'camel' )
+ INTO TABLE @it. "1
+
+"------------------------ [NOT] BETWEEN ------------------------
+SELECT id FROM @itab AS tab WHERE id BETWEEN 1 AND 4 INTO TABLE @it. "1,2,3,4
+"The condition with BETWEEN above corresponds to the following condition.
+"The example makes use of a condition specified in parentheses to combine multiple
+"expressions.
+SELECT id FROM @itab AS tab WHERE ( id >= 1 AND id <= 4 ) INTO TABLE @it. "1,2,3,4
+"Negation with NOT
+SELECT id FROM @itab AS tab WHERE id NOT BETWEEN 1 AND 4 INTO TABLE @it. "5-12
+
+"------------------------ IS [NOT] INITIAL ------------------------
+SELECT id FROM @itab AS tab WHERE id IS NOT INITIAL INTO TABLE @it. "1-12
+
+"------------------------ [NOT] LIKE ------------------------
+"For (not) matching a specified pattern
+"Note: % (any character string), _ (any character).
+SELECT name FROM @itab AS tab
+ WHERE name LIKE '%ee%'
+ OR name LIKE '_o%'
+ INTO TABLE @DATA(names). "dog,deer,cheetah,donkey,sheep
+
+"ESCAPE addition for defining a single-character escape character
+"In the following example, this character is #. It is placed before
+"the % character in the specification after LIKE. In this case, %
+"is escaped and does then not stand for any character string in the
+"evaluation.
+"Adding a table entry for this syntax example.
+itab = VALUE #( BASE itab ( id = 13 name = '100%' ) ).
+"Any character sequence followed by the % character
+SELECT name FROM @itab AS tab
+ WHERE name LIKE '%#%' ESCAPE '#'
+ INTO TABLE @names. "100%
+
+"Deleting the entry because it is not relevant for the further examples.
+DELETE itab INDEX 13.
+
+"------------------------ [NOT] IN (using a value set) ------------------------
+"For (not) matching a value in a set of values specified in parentheses.
+
+"Single operands on the left side of IN
+SELECT id FROM @itab AS tab
+ WHERE name IN ( 'camel', 'rabbit', 'dog', 'snake' )
+ INTO TABLE @it. "2,3,5
+
+"Negation NOT IN; note to use host variables/expressions for local/global data objects
+DATA(animal) = 'sheep'.
+SELECT id FROM @itab AS tab
+ WHERE name NOT IN ( 'fish', @animal )
+ INTO TABLE @it. "1-10
+
+"Operand list (a parenthesized comma-separated list) on the left side of IN
+"For (not) matching value tuples from a set of value tuples specified in parentheses on the right side.
+"In the following example, two values are specified in the operand list on the left. Consequently,
+"two values with appropriate types must be specified in parentheses on the right.
+SELECT id FROM @itab AS tab
+ WHERE ( id, name ) IN ( ( 1, 'bear' ), ( 3, 'rabbit' ), ( 8, 'zebra' ), ( 20, 'dog' ) )
+ INTO TABLE @it. "1,3
+
+
+"------------------------ [NOT] IN (using a subquery) ------------------------
+"[NOT] IN for matching a value contained in the result set of a subquery
+
+"In the following example, the subquery reads data from a demo database table.
+"For a representative result, the table is cleared, and then filled with 'suitable'
+"data sets.
+DELETE FROM zdemo_abap_tab1.
+MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 11 num1 = 11 )
+ ( key_field = 12 num1 = 12 )
+ ( key_field = 13 num1 = 13 )
+ ( key_field = 14 num1 = 14 ) ) ).
+
+SELECT id FROM @itab AS tab
+ WHERE id IN ( SELECT key_field FROM zdemo_abap_tab1 ) INTO TABLE @it. "11,12
+
+"------------------------ [NOT] IN (using a ranges table) ------------------------
+"[NOT] IN for checking whether the operands on the left side match a ranges condition in a ranges table
+
+"Declaring a ranges table
+DATA rangestab TYPE RANGE OF i.
+"Populating a ranges table using the VALUE operator
+rangestab = VALUE #( ( sign = 'I' option = 'BT' low = 1 high = 3 )
+ ( sign = 'I' option = 'GE' low = 10 ) ).
+
+SELECT id FROM @itab AS tab WHERE id IN @rangestab INTO TABLE @it. "1,2,3,10,11,12
+
+
+"You cannot use logical operators such as CP (conforms to pattern) in the WHERE clause.
+"In a ranges table, they are possible.
+"Note:
+"- Regarding CP: * (any character sequence), + (any character), # (escape character)
+"- An equivalent example above uses the LIKE addition.
+DATA rt TYPE RANGE OF demo_struc-name.
+rt = VALUE #( ( sign = 'I' option = 'CP' low = '*ee*' ) "ee in a string
+ ( sign = 'I' option = 'CP' low = '+o*' ) ). "o in second position
+SELECT name FROM @itab AS tab
+ WHERE name IN @rt
+ INTO TABLE @names. "dog,deer,cheetah,donkey,sheep
+
+"------------------------ EXISTS ------------------------
+"For checking the result set of a subquery.
+"The following example reads all entries from the internal table if entries having
+"the same key also exist in the database table.
+"Note: The SELECT list in the subquery only contains a literal to determine that
+"the entry exists. Specifying explicit column names is not relevant.
+SELECT id FROM @itab AS tab WHERE
+ EXISTS ( SELECT @abap_true FROM zdemo_abap_tab1 WHERE key_field = tab~id )
+ INTO TABLE @it. "11,12
+
+"------------------------ IS [NOT] NULL ------------------------
+"The null value is a special value that is returned by a database. It indicates an
+"undefined value or result. Note that, in ABAP, there are no special null values. Do
+"not confuse the null value with a type-dependent initial value. When using SELECT
+"statements to read data, null values can be produced by, for example, outer joins.
+"When the null values are passed to a data object, they are transformed to the
+"type-dependent initial values. For more information, refer to the ABAP Keyword Documentation.
+"The following example uses a left outer join to intentionally create null values. For
+"this purpose, two demo database tables of the cheat sheet repository are cleared and
+"populated with specific values to visulaize null values.
+DELETE FROM zdemo_abap_tab1.
+DELETE FROM zdemo_abap_tab2.
+MODIFY zdemo_abap_tab1 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' char2 = 'y' )
+ ( key_field = 2 char1 = 'b' char2 = 'z' ) ) ).
+MODIFY zdemo_abap_tab2 FROM TABLE @( VALUE #( ( key_field = 1 char1 = 'a' )
+ ( key_field = 2 char1 = 'a' )
+ ( key_field = 3 char1 = 'b' )
+ ( key_field = 4 ) ) ).
+"Note that for the entry 'key_field = 4' no char1 value was passed.
+"char1 is a shared column of the two database tables, and which is used in
+"the ON condition of the join. Since there is no entry in char1 for 'key_field = 4',
+"the joined values are null in that case. The WHERE clause uses the addition IS NULL.
+"Therefore, the result only contains this entry. char2 is assigned the type-initial
+"value in the result.
+SELECT tab2~key_field, tab1~char2
+ FROM zdemo_abap_tab2 AS tab2
+ LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
+ WHERE tab1~char1 IS NULL
+ INTO TABLE @DATA(joined_tab).
+*KEY_FIELD CHAR2
+*4
+
+"The following example visualizes the null values. The INDICATORS addition of the
+"INTO clause is used to specify indicators such as the null indicator. In the
+"example, an appropriate target table is defined to also store information about
+"which columns of the result set contain the null value and which do not.
+"For more information on the syntax, refer to the ABAP Keyword Documentation.
+TYPES: BEGIN OF st4null,
+ BEGIN OF s2,
+ key_field TYPE zdemo_abap_tab2-key_field,
+ char2 TYPE zdemo_abap_tab1-char2,
+ END OF s2,
+ BEGIN OF nulls,
+ key_field TYPE c LENGTH 1,
+ char2 TYPE c LENGTH 1,
+ END OF nulls,
+ END OF st4null.
+DATA joined_tab_w_null_ind TYPE TABLE OF st4null WITH EMPTY KEY.
+
+SELECT tab2~key_field, tab1~char2
+ FROM zdemo_abap_tab2 AS tab2
+ LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
+ INTO TABLE @joined_tab_w_null_ind INDICATORS NULL STRUCTURE nulls.
+*S2 NULLS
+*KEY_FIELD CHAR2 KEY_FIELD CHAR2
+*1 y
+*KEY_FIELD CHAR2 KEY_FIELD CHAR2
+*2 y
+*KEY_FIELD CHAR2 KEY_FIELD CHAR2
+*3 z
+*KEY_FIELD CHAR2 KEY_FIELD CHAR2
+*4 X
+
+"Negation IS NOT NULL
+SELECT tab2~key_field, tab1~char2
+ FROM zdemo_abap_tab2 AS tab2
+ LEFT OUTER JOIN zdemo_abap_tab1 AS tab1 ON tab1~char1 = tab2~char1
+ WHERE tab1~char1 IS NOT NULL
+ INTO TABLE @joined_tab.
+*KEY_FIELD CHAR2
+*1 y
+*2 y
+*3 z
+```
+
+
+
+### Selecting Data by Evaluating the Content of Other Tables
+
+[`FOR ALL ENTRIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm)
+addition:
+- Components of an internal table can be used in the `WHERE` clause in logical expressions for comparisons with a column of the data source.
+- The logical expression is evaluated for each individual row of the internal table.
+- The result set of the `SELECT` statement is the union set of the result sets produced by the individual evaluations. Rows that occur more than once are removed from the result set automatically. The entire content of a row is respected.
+- If `FOR ALL ENTRIES` is specified, there must be at least one comparison with a column of the internal table.
+- For more information, especially restricitions and things to pay attention to (e. g. making sure that the internal table is not initial), see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_all_entries.htm).
+
+``` abap
+"Checking that table is not initial
+IF ( 0 < lines( itab2 ) ).
+
+ SELECT comp1, comp2, comp3
+ FROM dbtab
+ FOR ALL ENTRIES IN @itab2 "Host variable before internal table
+ WHERE comp1 = @itab2-comp1 ... "Relational expression on the right side of a comparison
+ INTO TABLE @itab1
+
+ENDIF.
+```
+
+**Checking the result set of a subquery** with the addition [`EXISTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_exists.htm)
+
+See possible clauses and additions of a [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm) in a condition in ABAP SQL [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwhere_logexp_subquery.htm).
+
+The following code snippet includes a parenthesized subquery following `EXISTS`. Data is only selected from `dbtab1` if the relational expression (`WHERE EXISTS ...`) is true, i. e. if the result set of the subquery contains at least one row. Note the components of the table that are referenced using a tilde.
+
+``` abap
+SELECT comp1, comp2, comp3
+ FROM dbtab1 AS tab1
+ WHERE EXISTS
+ ( SELECT comp1 FROM dbtab2
+ WHERE comp1 = tab1~comp1 AND comp2 = tab1~comp2 )
+ INTO ...
+```
+
+
+
+### Combining Data of Multiple Database Tables
+
+**Using an [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.
+ - Contains all combinations of rows for whose columns the join condition is true.
+- 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
+ INNER JOIN dbtab2 AS b ON a~comp1 = b~comp1 AND a~comp2 = b~comp2
+ INNER JOIN dbtab3 AS c ON a~comp1 = c~comp1
+ WHERE ...
+ INTO ...
+```
+
+**Using an [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,
+ FROM dbtab1 AS a
+ LEFT OUTER JOIN dbtab2 AS b ON a~comp1 = b~comp1
+ WHERE ...
+ INTO ...
+```
+> **💡 Note**
+> There are more join variants 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`](http://ldcialx.wdf.sap.corp:50018/sap/public/bc/abap/docu?object=abapunion&sap-language=EN&sap-client=000&version=A&tree=X). 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
+ FIELDS ...
+ WHERE ...
+UNION
+ SELECT FROM dbtab2
+ FIELDS ...
+ WHERE ...
+ INTO ...
+```
+
+
+
+#### Common Table Expressions (CTE)
+
+When to use [Common Table Expressions (CTE)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencommon_table_expression_glosry.htm):
+
+- Whenever you need intermediate results in a `SELECT`
+ statement and especially if you need them more than once.
+- You get the option of selecting directly from a subquery (`SELECT FROM subquery`), which is not possible in ABAP SQL.
+
+How it works:
+
+- The ABAP SQL keyword
+ [`WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwith.htm)
+ introduces the definition of CTEs.
+- Each CTE creates a tabular result set in a
+ [subquery](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubquery_glosry.htm "Glossary Entry").
+- The result set of such a CTE can then be used in subsequent queries
+ as data source; CTEs can be considered as temporary views, which
+ only exist for the duration of the database access.
+- The CTEs (at least one) are then used in a final [main
+ query](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmainquery_glosry.htm "Glossary Entry"), i.
+ e. a `SELECT` statement accesses the result of the
+ expressions.
+
+Setup of a statement with CTE:
+
+- Introductory keyword `WITH`
+- A comma-separated list with at least one definition of a CTE
+ - Each CTE has a unique name with an initial `+` character
+ - An optional list of column names, which should be used in the
+ result set, within parentheses
+ - `AS` followed by a subquery with `SELECT` which
+ creates the tabular result set of the CTE
+- A closing main query with `SELECT` in which the previous
+ CTEs are to be used as data source
+- If a `SELECT` loop is opened and data is written into a work
+ area in the closing main query, the loop must be closed with
+ `ENDWITH.` (which fulfills the same task as
+ `ENDSELECT.`).
+
+> **💡 Note**
+>- Each CTE must be used at least once, either in another CTE or in the
+ main query. The main query must access at least one CTE.
+>- The result set of a CTE never has a [client
+ column](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclient_column_glosry.htm "Glossary Entry").
+>- See more information in [this topic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapwith.htm)
+and further options and additions when using CTEs in the subtopics.
+
+Example: The result sets of both common table expressions
+`+connections` and `+sum_seats` are merged in the
+subquery of the CTE `+result` in a join expression. An explicit
+name list assigns names to the resulting columns. These names are used
+in the main query to sort the results. For each flight connection of the
+selected airline, the total number of occupied seats is stored in the
+internal table.
+``` abap
+WITH
++connections AS (
+ SELECT zdemo_abap_flsch~carrid, carrname, connid, cityfrom, cityto
+ FROM zdemo_abap_flsch
+ INNER JOIN zdemo_abap_carr
+ ON zdemo_abap_carr~carrid = zdemo_abap_flsch~carrid
+ WHERE zdemo_abap_flsch~carrid BETWEEN 'AA' AND 'JL' ),
++sum_seats AS (
+ SELECT carrid, connid, SUM( seatsocc ) AS sum_seats
+ FROM zdemo_abap_fli
+ WHERE carrid BETWEEN 'AA' AND 'JL'
+ GROUP BY carrid, connid ),
++result( name, connection, departure, arrival, occupied ) AS (
+ SELECT carrname, c~connid, cityfrom, cityto, sum_seats
+ FROM +connections AS c
+ INNER JOIN +sum_seats AS s
+ ON c~carrid = s~carrid AND c~connid = s~connid )
+SELECT *
+ FROM +result
+ ORDER BY name, connection
+ INTO TABLE @DATA(result).
+```
+
+
+
+## Changing Data in Database Tables
+
+### Using [`INSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinsert_dbtab.htm)
+
+- Inserts one or more rows into a database table specified.
+- The rows to be inserted are taken from a structure, an internal table, or the result set of an embedded subquery.
+- As mentioned above, structures and internal tables from which to insert content should be specified as host variables (with `@`) or host
+expressions (with `@( ... )`).
+- The system fields `sy-subrc` (0 = single row or all rows inserted successfully, 4 = row not or not all rows inserted) and `sy-dbcnt` (number of rows that are inserted) are set.
+
+``` abap
+"Inserting a single row into a database table
+INSERT dbtab FROM @row.
+
+"Alternative syntax, same effect
+INSERT INTO dbtab VALUES @row.
+
+"Line is created inline using the VALUE operator as part of a host expression
+INSERT dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
+
+"Inserting multiple lines from an internal table into a database table.
+"Make sure that the internal table does not contain a line having the same key
+"as an existing row in the database table. Otherwise, a runtime error occurs.
+INSERT dbtab FROM TABLE @itab.
+
+"Inserting lines from a table declared inline using the VALUE operator
+"as part of a host expression
+INSERT dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
+ ( comp1 = ... comp2 = ... ) ) ).
+
+"ACCEPTING DUPLICATE KEYS addition: To avoid the runtime error mentioned above,
+"all lines that would produce duplicate entries in the database table
+"regarding the keys are discarded and sy-subrc is set to 4.
+INSERT dbtab FROM TABLE @itab ACCEPTING DUPLICATE KEYS.
+
+"Inserting the result set of an embedded subquery
+"Here, multiple result sets can be joined, e. g. using UNION.
+INSERT dbtab FROM ( SELECT ... ).
+```
+
+
+
+### Using [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapupdate.htm)
+- Changes the content of one or more rows of a database table specified.
+- Similar to `INSERT`, `sy-subrc` and `sy-dbcnt` are set.
+
+``` abap
+"Changing content by overwriting entire rows based on a structure
+UPDATE dbtab FROM @row.
+UPDATE dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ). "Using a host expression
+
+"Changing content by overwriting entire rows based on rows in an internal table
+UPDATE dbtab FROM TABLE @itab.
+
+"Using a host expression
+UPDATE dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
+ ( comp1 = ... comp2 = ... ) ) ).
+
+"INDICATORS addition: Changing content of specific fields without overwriting
+"existing values of other fields
+"Example:
+"- Structured type is created with WITH INDICATORS addition
+"- Internal table from which to update dbtab is created;
+" it includes the indicator structure comp_ind
+"- Internal table is filled; only one component is flagged as to be updated
+"- Other fields remain unchanged; note that key fields must be included
+" in ind_tab (indicator setting for key fields has no effect)
+TYPES ind_wa TYPE dbtab WITH INDICATORS comp_ind TYPE abap_bool.
+
+DATA ind_tab TYPE TABLE OF ind_wa.
+
+ind_tab = VALUE #(
+ ( comp1 = ... comp2 = ... comp_ind-comp2 = abap_true )
+ ( comp1 = ... comp2 = ... comp_ind-comp2 = abap_true ) ).
+
+UPDATE dbtab FROM TABLE @ind_tab INDICATORS SET STRUCTURE comp_ind.
+
+"In the following example, the logic is reversed using NOT.
+UPDATE dbtab FROM TABLE @ind_tab INDICATORS NOT SET STRUCTURE comp_ind.
+
+"SET addition: Changing values of specific fields in all table rows
+"There are mutliple options for the value assignment. E.g. you can use
+"a literal, host variable/expression, SQL function, and so on.
+UPDATE dbtab SET comp2 = ... .
+```
+
+
+
+### Using [`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_dbtab.htm)
+- Inserts one or more rows into a database table specified or overwrites existing ones.
+- As above, `sy-subrc` and `sy-dbcnt` are set.
+
+``` abap
+"Inserting a single row into a database table or changing an existing row
+MODIFY dbtab FROM @row.
+
+"Using a host expression
+MODIFY dbtab FROM @( VALUE #( comp1 = ... comp2 = ... ) ).
+
+"Inserting/Changing multiple rows
+MODIFY dbtab FROM TABLE @itab.
+
+"Using a host expression
+MODIFY dbtab FROM TABLE @( VALUE #( ( comp1 = ... comp2 = ... )
+ ( comp1 = ... comp2 = ... ) ) ).
+
+"Inserting/Changing multiple rows based on a result set of an embedded subquery
+MODIFY dbtab FROM ( SELECT ... ).
+```
+
+
+
+### Using [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdelete_dbtab.htm)
+- Deletes one or more rows from a database table specified.
+- As above, `sy-subrc` and `sy-dbcnt` are set.
+
+``` abap
+"Variant DELETE FROM ...: Either all rows are deleted or restricted
+
+"All rows are deleted
+DELETE FROM dbtab.
+
+"Rows are deleted based on a condition
+DELETE FROM dbtab WHERE ....
+
+"Note that there are further options available, e. g. ORDER BY, UP TO
+"Variant DELETE ... FROM ...: Deleting a single row or multiple row
+DELETE dbtab FROM @row.
+
+"Using a host expression
+DELETE dbtab FROM @( VALUE #( comp1 = ... ) ).
+DELETE dbtab FROM TABLE @itab.
+
+"Using a host expression
+DELETE dbtab FROM TABLE @( VALUE #( ( comp1 = ... )
+ ( comp1 = ... ) ) ).
+```
+
+
+
+## More Information
+- Note that ABAP SQL statements offer syntax options for dynamic programming. For example, you can specify the data source to read from dynamically. See more information in the ABAP Keyword Documentation or the [ABAP cheat sheet on dynamic programming](06_Dynamic_Programming.md).
+ ```abap
+ DATA(dbtab) = 'ZDEMO_ABAP_FLSCH'.
+
+ "Selecting from a dynamically specified database table.
+ SELECT *
+ FROM (dbtab)
+ WHERE ...
+ INTO ...
+ ```
+- [This topic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_sql.htm) serves as the entry point for topics about ABAP SQL in the ABAP Keyword Documentation. For the full details, check the subtopics there, especially topics not covered in this cheat sheet.
+- There are [RAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenarap_glosry.htm)-specific variants of ABAP SQL statements that use the `MAPPING FROM ENTITY` addition. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmapping_from_entity.htm).
+
+## Executable Example
+[zcl_demo_abap_sql](./src/zcl_demo_abap_sql.clas.abap)
+
+> **💡 Note**
+> - The executable example covers the following topics, among others:
+> - Reading from database tables using `SELECT`
+> - Various additions to `SELECT` statements
+> - Changing data in database tables using `INSERT`, `UPDATE`, `MODIFY` and `DELETE`
+> - Excursions: Operands and expressions in ABAP SQL statements
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
diff --git a/04_ABAP_Object_Orientation.md b/04_ABAP_Object_Orientation.md
index 54a5e73..86320b0 100644
--- a/04_ABAP_Object_Orientation.md
+++ b/04_ABAP_Object_Orientation.md
@@ -1,1329 +1,1329 @@
-
-
-# ABAP Object Orientation
-
-> **💡 Note**
-> This ABAP cheat sheet provides an overview on selected syntax options and concepts related to ABAP object orientation. It is supported by code snippets and an executable example. They are **not** suitable as role models for object-oriented design. Their primary focus is on the syntax and functionality. For more details, refer to the respective topics in the ABAP Keyword Documentation. Find an overview in the topic [ABAP Objects - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_objects_oview.htm).
-
-- [ABAP Object Orientation](#abap-object-orientation)
- - [Classes and Objects](#classes-and-objects)
- - [Creating Classes](#creating-classes)
- - [Creating a Local Class](#creating-a-local-class)
- - [Creating a Global Class](#creating-a-global-class)
- - [Visibility of Components](#visibility-of-components)
- - [Creating the Visibility Sections](#creating-the-visibility-sections)
- - [Defining Components](#defining-components)
- - [Working with Objects and Components](#working-with-objects-and-components)
- - [Declaring Reference Variables](#declaring-reference-variables)
- - [Creating Objects](#creating-objects)
- - [Assigning Reference Variables](#assigning-reference-variables)
- - [Accessing Attributes](#accessing-attributes)
- - [Calling Methods](#calling-methods)
- - [Method Chaining](#method-chaining)
- - [Self-Reference me](#self-reference-me)
- - [Notes on Inheritance](#notes-on-inheritance)
- - [Notes on Polymorphism and Casting](#notes-on-polymorphism-and-casting)
- - [Notes on Interfaces](#notes-on-interfaces)
- - [Excursions](#excursions)
- - [Friendship](#friendship)
- - [Events](#events)
- - [Factory Methods and Singletons as Design Patterns](#factory-methods-and-singletons-as-design-patterns)
- - [More Information](#more-information)
- - [Executable Example](#executable-example)
-
-## Classes and Objects
-
-Object-oriented programming in ABAP means dealing with
-[classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry")
-and
-[objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_glosry.htm "Glossary Entry").
-
-Objects ...
-
-- are
- [instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_glosry.htm "Glossary Entry")
- of a
- [type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_glosry.htm "Glossary Entry").
- In this context, they are instances of a
- [class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry").
- The terms *object* and *instance* are used synonymously.
-- exist in the [internal
- session](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninternal_session_glosry.htm "Glossary Entry")
- of an [ABAP
- program](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm "Glossary Entry").
-
-
-Classes ...
-- are templates for objects, i. e. they determine how
- all instances of a class are set up. All instances are created (i.e they are [instantiated](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstantiation_glosry.htm "Glossary Entry")) based on this template and, thus, have the same setup.
- - To give an example: If, for example, a vehicle represents a class, then the
- instances of the class `vehicle` have the same setup.
- That means they all share the same kind of components like a brand, model and color or the same functionality like the acceleration or braking distance.
- However, the values of these components are different from instance to instance. For example, one
- instance is a red sedan of brand A having a certain
- acceleration; another instance is a black SUV of brand B and so on. You can create an object (or instance respectively) that stands
- for an actual vehicle with which you can work with. You might create any number of objects that are based on such a class - if instantiation is allowed.
-- contain
- [components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_glosry.htm "Glossary Entry"):
- - [Attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenattribute_glosry.htm "Glossary Entry")
- of the objects (the data object declarations)
- - [Methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmethod_glosry.htm "Glossary Entry")
- that determine the behavior of an object
- - [Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry") to trigger the processing of ABAP code
-
-
are defined as
- global types, i. e. they are visible as a repository object - in contrast to local classes. As a global type, they can be used - as the name implies - globally in other ABAP programs or global classes
-
-> **💡 Note**
-> - If a class is only used in one ABAP program, creating a local class is enough. However, if you choose to create a global class, you must bear in mind that such a class can be used everywhere. Consider the impact on the users of the global class when you change, for example, the visibility section of a component or you delete it.
-> - Apart from ADT, global classes can also be created in the ABAP Workbench (`SE80`) or with transaction `SE24` in [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).
-
-Basic structure of classes:
-- [Declaration part](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeclaration_part_glosry.htm "Glossary Entry") that includes declarations of the class components.
-- [Implementation part](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenimplementation_part_glosry.htm "Glossary Entry") that includes method implementations.
-- Both are introduced by `CLASS` and ended by `ENDCLASS`.
-
-#### Creating a Local Class
-
-``` abap
-"Declaration part
-CLASS local_class DEFINITION.
-
- ... "Here go the declarations for all components and visibility sections.
- "You should place the declarations at the beginning of the program.
-
-ENDCLASS.
-
-"Implementation part
-CLASS local_class IMPLEMENTATION.
-
- ... "Here go the method implementations.
- "Only required if you declare methods in the declaration part.
-
-ENDCLASS.
-```
-
-#### Creating a Global Class
-The code snippet shows a basic skeleton of a global class. There are [further
-additions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm)
-possible for the declaration part.
-
-``` abap
-"Declaration part
-CLASS global_class DEFINITION
- PUBLIC "Makes the class a global class in the class library.
- FINAL "Means that no subclasses can be derived from this class.
- CREATE PUBLIC. "This class can be instantiated anywhere it is visible.
-
- ... "Here go the declarations for all components and visibility sections.
-
-ENDCLASS.
-
-"Implementation part
-CLASS global_class IMPLEMENTATION.
-
- ... "Here go the method implementations.
- "Only required if you declare methods in the DEFINITION part.
-
-ENDCLASS.
-```
-> **💡 Note**
-> - Addition `... CREATE PROTECTED.`: The class can only be instantiated in methods of its
-[subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"),
-of the class itself, and of its
-[friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry").
-> - Addition `... CREATE PRIVATE`: The class can only
-be instantiated in methods of the class itself or of its friends. Hence,
-it cannot be instantiated as an inherited component of subclasses.
-
-
-
-### Visibility of Components
-
-In the class declaration part, you must specify (at least one of the) three
-[visibility
-sections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm "Glossary Entry")
-and include class components to define their visibility. These visibility sections serve the purpose of encapsulation in ABAP Objects. For example, you do not want to make certain components publicly available for all users. The visibility sections are as follows:
-
-
-
-
PUBLIC SECTION.
-
Components declared in this section can be accessed from within the class and from all users of the class.
-
-
-
PROTECTED SECTION.
-
Components declared in this section can be
- accessed from within the class and subclasses as well as friends
- - concepts related to inheritance.
-
-
-
PRIVATE SECTION.
-
Components declared in this section can only be accessed from within the class in which they are declared and its friends.
-
-
-
-Summary:
-
-| Visible for | PUBLIC SECTION | PROTECTED SECTION | PRIVATE SECTION |
-|---|---|---|---|
-| Same class and its friends | X | X | X |
-| Any subclasses | X | X | - |
-| Any repository objects | X | - | - |
-
-
-#### Creating the Visibility Sections
-At least one section must be specified.
-``` abap
-CLASS local_class DEFINITION.
- PUBLIC SECTION.
- "Here go the components.
- PROTECTED SECTION.
- "Here go the components.
- PRIVATE SECTION.
- "Here go the components.
-ENDCLASS.
-```
-
-
-
-### Defining Components
-
-All components, i. e.
-- attributes (using `TYPES`, `DATA`, `CLASS-DATA`, and `CONSTANTS` for data types and data
-objects),
-- methods (using `METHODS` and `CLASS-METHODS`),
-- events (using `EVENTS` and `CLASS-EVENTS`) as well as
-- interfaces,
-
-are declared in the declaration part of the class. There, they must be
-assigned to a visibility section.
-
-Two
-kinds of components are to be distinguished when, for example, looking at declarations using `DATA` and `CLASS-DATA` having a preceding `CLASS-`:
-
-- [Instance components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_component_glosry.htm "Glossary Entry"):
- Components that exist separately for each instance and can only be accessed in instances of a class.
-- [Static components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_component_glosry.htm "Glossary Entry") (the declarations with `CLASS-`):
- Components that exist only once per class. They do no not exclusively exist for specific instances. They can be addressed using the name of the class.
-
-**Attributes**
-
-- The attributes of a class (or interface) mean the data objects declared within a
- class (or interface).
-- [Instance
- attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_attribute_glosry.htm "Glossary Entry")
- (`DATA`): Determine the state of a objects of a class. The data
- is only valid in the context of an instance. As shown further down,
- instance attributes can only be accessed via an [object reference
- variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry").
-- [Static
- attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_attribute_glosry.htm "Glossary Entry")
- (`CLASS-DATA`): Their content is independent of instances of
- a class and, thus, valid for all instances. That means that if you change such a static
- attribute, the change is visible in all instances. As shown further down,
- static attributes can be accessed by using the class name without a
- prior creation of an instance.
-
-
-> **💡 Note**
-> - You can declare constant data objects that should not be
-changed using
-[`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm)
-statements. You specify the values for the constants (which are also static attributes) when you declare
-them in the declaration part of a class.
-> - The addition
-[`READ-ONLY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_options.htm#!ABAP_ADDITION_2@2@)
-can be used in the public visibility section. Effect:
-> - Can be read from outside of the class
-> - Cannot be changed from outside
-> - Can only be changed using methods of the class or its subclasses
-
-Declaring attributes in visibility sections. In the code snippet below, all attributes are declared in the public section of a local class.
-``` abap
-CLASS local_class DEFINITION.
-
- PUBLIC SECTION.
- TYPES some_type TYPE c LENGTH 3. "Type declaration
-
- DATA: inst_number TYPE i, "Instance attributes
- inst_string TYPE string,
- dobj_r_only TYPE c LENGTH 5 READ-ONLY. "Read-only attribute
-
- CLASS-DATA: stat_number TYPE i, "Static attributes
- stat_char TYPE c LENGTH 3.
-
- CONSTANTS const_num TYPE i VALUE 123. "Non-changeable constant
-
- PROTECTED SECTION.
- "Here go more attributes if needed.
-
- PRIVATE SECTION.
- "Here go more attributes if needed.
-
-ENDCLASS.
-
-CLASS local_class IMPLEMENTATION.
-
- ... "Here go all method implementations.
-
-ENDCLASS.
-```
-
-
-
-**Methods**
-
-- Are internal
- [procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm "Glossary Entry")
- determining the behavior of the class.
-- Can access all of the attributes of a class and, if not defined
- otherwise, change their content.
-- Have a [parameter
- interface](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparameter_interface_glosry.htm "Glossary Entry")
- (also known as
- [signature](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensignature_glosry.htm "Glossary Entry"))
- with which methods can get values to work with when being called and pass values
- back to the caller (see the notes on formal and actual parameters below).
-- [Static
- methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_method_glosry.htm "Glossary Entry")
- can only access static attributes of a class and trigger static
- events. You declare them using `CLASS-METHODS` statements in
- a visibility section.
-- [Instance
- methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_method_glosry.htm "Glossary Entry")
- can access all of the attributes of a class and trigger all events.
- You declare them using `METHODS` statements in a visibility
- section. Note that you must create an instance of a class first before using instance methods.
-
-**Parameter Interface**
-
-In the simplest form, methods can have no parameter at all. Apart from that, methods can be defined with the following parameters:
-
-| Addition | Details |
-|---|---|
-|`IMPORTING`|Defines one or more input parameters to be imported by the method. |
-|`EXPORTING`|Defines one or more output parameters to be exported by the method. |
-|`CHANGING`|Defines one or more input or output parameters, i. e. that can be both imported and exported. |
-|`RETURNING`|For [functional methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunctional_method_glosry.htm "Glossary Entry"), i. e. such methods have only one `RETURNING` parameter that can be defined. As an output parameter like the `EXPORTING` parameter, `RETURNING` parameters pass back values (note that the formal parameters of returning parameters must be passed by value as covered below). In contrast to `EXPORTING` for which multiple parameters can be specified, only one `RETURNING` parameter can be specified in a method. If you only need one output parameter, you can benefit from using a `RETURNING` parameter by shortening the method call and enabling method chaining. Another big plus is that such functional methods can, for example, be used in expressions. In case of standalone method calls, the returned value can be accessed using the addition `RECEIVING`. |
-|`RAISING` | Used to declare the [class-based exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_based_exception_glosry.htm "Glossary Entry") that can be propagated from the method to the caller. |
-
-
-> **💡 Note**
-> - You may find the addition `EXCEPTIONS` especially in definitions of older classes. They are for non-class-based exceptions. This addition should not be used in ABAP for Cloud Development.
-> - Notes on [formal
- parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenformal_parameter_glosry.htm "Glossary Entry")
- versus [actual
- parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenactual_parameter_glosry.htm "Glossary Entry"):
-> - You define method parameters by specifying a name with a type which
- can be a
- [generic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengeneric_data_type_glosry.htm "Glossary Entry")
- or
- [complete](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplete_data_type_glosry.htm "Glossary Entry")
- type. Examples:
-> - `fp` is the formal parameter that has a complete type: `... meth IMPORTING fp TYPE string ...`
-> - `gen` is the formal parameter that has a generic type: `... meth IMPORTING gen TYPE any ...`
-> - Find more information about generic types also in the [Data Types and Data Objects](16_Data_Types_and_Objects.md#generic-types) cheat sheet.
-> - This formal parameter includes the specification of how the
- value passing should happen. Parameters can be [passed by
- reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_reference_glosry.htm "Glossary Entry")
- (`... REFERENCE(param) ...`; note that just specifying the
- parameter name `... param ...` - as a shorter syntax -
- means passing by reference by default) or [by
- value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_value_glosry.htm "Glossary Entry")
- (`... VALUE(param) ...`).
-> - The actual parameter represents
- the data object whose content is passed to or copied from a formal
- parameter as an argument when a procedure is called. If
- passing by reference is used, a local data object is not created for
- the actual parameter. Instead, the procedure is given a
- [reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry")
- to the actual parameter during the call and works with the actual
- parameter itself. Note that parameters that are input and passed by
- reference cannot be modified in the procedure. However, the use of a
- reference is beneficial regarding the performance compared to
- creating a local data object.
->- Parameters can be defined as optional using the
- [`OPTIONAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters.htm#!ABAP_ONE_ADD@1@)
- addition. In doing so, it is not mandatory to pass an actual
- parameter. The
- [`DEFAULT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters.htm#!ABAP_ONE_ADD@1@)
- addition also makes the passing of an actual parameter optional.
- However, when using this addition, as the name implies, a default
- value is set.
-
-
-
-**Constructors**
-
-- [Constructors](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_glosry.htm "Glossary Entry")
- are special methods that are usually used for setting a defined
- initial value for attributes of the class or its objects.
-- A class has exactly one [instance
- constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_constructor_glosry.htm "Glossary Entry")
- and one [static
- constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_constructor_glosry.htm "Glossary Entry").
-- The declaration and use of constructors is optional.
-- Static constructor:
- - Declared using the predefined name `class_constructor` as part of a
- `CLASS-METHODS` statement in the public visibility section.
- - Has no parameters.
- - Automatically and immediately called once for each class when calling a class for
- the first time in an internal session, i. e. when, for example, an instance of a class is created or a component is used. Note: If it is not explicitly declared and implemented, it is merely an empty method.
-- Instance constructor:
- - Declared using the predefined name `constructor` as part of a
- `METHODS` statement. In case of global classes, it can only be declared in the public visibility section.
- - Automatically called when a class is
- instantiated and an instance is created.
- - Can have `IMPORTING` parameters and raise exceptions.
-
-Example for method definitions: The following snippet shows
-multiple method definitions in the public section of a local class. Most of the formal
-parameters of the demo methods below are defined by just using the
-parameter name. This means passing by reference (returning parameters
-require to be passed by value).
-``` abap
-CLASS local_class DEFINITION.
- PUBLIC.
- METHODS: inst_meth1, "instance methods
-
- inst_meth2 IMPORTING a TYPE string,
-
- inst_meth3 IMPORTING b TYPE i
- EXPORTING c TYPE i,
-
- inst_meth4 IMPORTING d TYPE string
- RETURNING VALUE(e) TYPE string,
-
- inst_meth5 IMPORTING f TYPE i
- EXPORTING g TYPE i
- CHANGING h TYPE string
- RETURNING VALUE(i) TYPE i
- RAISING cx_sy_zerodivide,
-
- constructor IMPORTING j TYPE i. "instance constructor with importing parameter
-
- CLASS-METHODS: stat_meth1, "static methods
-
- stat_meth2 IMPORTING k TYPE i
- EXPORTING l TYPE i,
-
- class_constructor, "static constructor
-
- "Options of formal parameter definitions
- stat_meth3 IMPORTING VALUE(m) TYPE i, "pass by value
- stat_meth4 IMPORTING REFERENCE(n) TYPE i, "pass by reference
- stat_meth5 IMPORTING o TYPE i, "same as n; the specification of REFERENCE(...) is optional
- stat_meth6 RETURNING VALUE(p) TYPE i, "pass by value once more (note: it's the only option for returning parameters)
-
- "OPTIONAL/DEFAULT additions
- stat_meth7 IMPORTING q TYPE i DEFAULT 123
- r TYPE i OPTIONAL,
-
- "The examples above use a complete type for
- "the parameter specification. Generic types
- "are possible.
- stat_meth8 IMPORTING s TYPE any "Any data type
- t TYPE any table "Any internal table type
- u TYPE clike. "Character-like types (c, n, string, d, t and character-like flat structures)
-
-ENDCLASS.
-
-CLASS local_class IMPLEMENTATION.
- METHOD inst_meth1.
- ...
- ENDMETHOD.
-
- ... "Further method implementations. Note that all declared methods must go here.
-ENDCLASS.
-```
-
-
-
-## Working with Objects and Components
-
-### Declaring Reference Variables
-- To create an object, a [reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm "Glossary Entry")
-must be declared.
-- Such an [object reference
-variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry")
-is also necessary for accessing objects and their components. That means objects are not directly accessed but only via references that point to
-those objects. This object reference variable contains the reference to the object - after assigning the reference to the object (see further down).
-``` abap
-"Declaring object reference variables
-DATA: ref1 TYPE REF TO local_class,
- ref2 TYPE REF TO global_class,
- ref3 LIKE ref1.
-```
-
-
-
-### Creating Objects
-
-- Using the instance operator
- [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_new.htm),
- you can create objects of a class (and [anonymous data
- objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm "Glossary Entry"), too, that are not dealt with here). As a result,
- you get a [reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm "Glossary Entry")
- that points to the created object.
-- Regarding the type specifications before and parameters within the
- parentheses:
- - Right before the first parenthesis after `NEW`, the type, i. e. the class, must be specified. The `#` character - instead of the class name -
-means that the type (`TYPE REF TO ...`) can be derived from the context (in this case from the type of the reference variable). You can
-also omit the explicit declaration of a reference variable by declaring a new reference variable
-[inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm),
-for example, using `DATA`. In this case, the name of the class must be placed after `NEW` and before the first parenthesis.
- - No parameter specified within the parentheses: No values are
- passed to the instance constructor of an object. However, non-optional input parameters of the
- instance constructor of the instantiated class must be filled.
- No parameters are passed for a class without an explicitly declared
- instance constructor. See more information:
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennew_constructor_params_class.htm).
-- The operator
- basically replaces the syntax [`CREATE OBJECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcreate_object.htm) you might stumble on.
-
-``` abap
-"Declaring object reference variable
-DATA: ref1 TYPE REF TO some_class.
-
-"Creating objects
-ref1 = NEW #( ). "Type derived from already declared ref1
-
-DATA(ref2) = NEW some_class( ). "Reference variable declared inline, explicit type
- "(class) specification
-
-"Old syntax. Do not use.
-"CREATE OBJECT ref3. "Type derived from already declared ref3
-"CREATE OBJECT ref4 TYPE some_class. "Corresponds to the result of the expression above
-```
-
-
-
-### Assigning Reference Variables
-To assign or copy
-reference variables, use the [assignment
-operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
-`=`. In the example below, both object reference variables have the same
-type.
-
-``` abap
-DATA: ref1 TYPE REF TO some_class,
- ref2 TYPE REF TO some_class.
-
-ref1 = NEW #( ).
-
-"Assigning existing reference
-ref2 = ref1.
-```
-
-More examples for dealing with object reference variables:
-
-**Overwriting reference variables**: An [object
-reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_reference_glosry.htm "Glossary Entry")
-is overwritten when a new object is created with a reference variable
-already pointing to an instance.
-``` abap
-ref1 = NEW #( ).
-
-"Existing reference is overwritten
-ref1 = NEW #( ).
-```
-
-**Retaining object references**:
-- If your use case is to retain the object references, for example, if you create multiple objects using the same object reference variable, you can put the reference variables in internal tables that are declared using `... TYPE TABLE OF REF TO ...`.
-- The following code snippet just visualizes that the object references are not overwritten. Three objects are created with the same reference variable. The internal table includes all object references and, thus, their values are retained.
-``` abap
-DATA: ref TYPE REF TO some_class,
- itab TYPE TABLE OF REF TO some_class.
-
-DO 3 TIMES.
- ref = NEW #( ).
- itab = VALUE #( BASE itab ( ref ) ). "Adding the reference to itab
-ENDDO.
-```
-
-**Clearing object references**: You can use
-[`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm)
-statements to explicitly clear a reference variable.
-```abap
-CLEAR ref.
-```
-
-> **💡 Note**
-> Objects use up space in the memory and should therefore be
-cleared if they are no longer needed. However, the [garbage collector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengarbage_collector_glosry.htm "Glossary Entry") is called periodically and automatically by the [ABAP runtime framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm "Glossary Entry") and clears all objects without any reference.
-
-
-
-### Accessing Attributes
-- Instance attributes: Accessed using
-the [object component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm "Glossary Entry")
-`->` via a reference variable.
-- Static attributes: Accessed (if the attributes are visible) using the [class component
-selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_component_select_glosry.htm "Glossary Entry")
-`=>` via the class name. You can also declare data objects and
-types by referring to static attributes.
-``` abap
-"Accessing instance attribute via an object reference variable
-
-... ref->some_attribute ...
-
-"Accessing static attributes via the class name
-
-... some_class=>static_attribute ...
-
-"Without the class name only within the class itself
-... static_attribute ...
-
-"Type and data object declarations
-
-TYPES some_type LIKE some_class=>some_static_attribute.
-DATA dobj1 TYPE some_class=>some_type.
-DATA dobj2 LIKE some_class=>some_static_attribute.
-```
-
-
-
-### Calling Methods
-- Similar to accessing attributes, instance
-methods are called using `->` via a reference variable.
-- Static
-methods are called using `=>` via the class name. When used
-within the class in which it is declared, the static method can also be
-called without `class_name=>...`.
-- When methods are called, the (non-optional) parameters must be specified within parentheses.
-- You might also stumble on method calls with [`CALL METHOD`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcall_method_static.htm)
-statements. These statements should no longer be used. Note that `CALL METHOD` statements are the only option in the context of [dynamic programming](06_Dynamic_Programming.md). Therefore, `CALL METHOD` statements should be reserved for dynamic method calls.
-
-
-Examples for instance method calls and static method calls:
-``` abap
-"Calling instance methods via reference variable;
-"within the parentheses, the parameters must be specified and assigned - if required
-
-ref->inst_meth( ... ).
-
-"Calling static methods via/without the class name
-
-class_name=>stat_meth( ... ).
-
-"Only within the program in which it is declared.
-stat_meth( ... ).
-
-"Calling (static) method having no parameter
-
-class_name=>stat_meth( ).
-
-"Calling (static) methods having a single importing parameter:
-
-"Note that in the method call, the caller exports values to the
-"method having importing parameters defined; hence, the addition
-"EXPORTING is relevant for the caller. The following three method calls are the same
-
-"Explicit use of EXPORTING.
-class_name=>meth( EXPORTING a = b ).
-
-"Only importing parameters in the method signature: explicit EXPORTING not needed
-
-class_name=>meth( a = b ).
-
-"If only a single value must be passed:
-"the formal parameter name (a) and EXPORTING not needed
-
-stat_meth( b ).
-
-"Calling (static) methods having importing/exporting parameters
-"Parameters must be specified if they are not marked as optional
-
-class_name=>meth( EXPORTING a = b c = d "a/c: importing parameters in the method signature
- IMPORTING e = f ). "e: exporting parameter in the method signature
-
-"To store the value of the parameter, you may also declare it inline.
-
-class_name=>meth( EXPORTING a = b c = d
- IMPORTING e = DATA(z) ).
-
-"Calling (static) methods having a changing parameter;
-"should be reserved for changing an existing local variable and value
-
-DATA h TYPE i VALUE 123.
-class_name=>meth( CHANGING g = h ).
-
-"Calling (static) methods having a returning parameter.
-"Basically, they do the same as methods with exporting parameters
-"but they are way more versatile, and you can save lines of code.
-
-"They do not need temporary variables.
-"In the example, the return value is stored in a variable declared inline.
-
-"i and k are importing parameters
-DATA(result) = class_name=>meth( i = j k = l ).
-
-"They can be used with other statements, e. g. logical expressions.
-"In the example below, the assumption is that the returning parameter is of type i.
-IF class_name=>meth( i = j k = l ) > 100.
- ...
-ENDIF.
-
-"They enable method chaining.
-"The example shows a method to create random integer values.
-"The methods have a returning parameter.
-DATA(random_no) = cl_abap_random_int=>create( )->get_next( ).
-
-"RECEIVING parameter: Available in methods defined with a returning parameter;
-"used in standalone method calls only.
-"In the snippet, m is the returning parameter; n stores the result.
-class_name=>meth( EXPORTING i = j k = l RECEIVING m = DATA(n) ).
-```
-
-
-
-### Method Chaining
-
-As shown in the previous example, method chaining is possible for functional method calls (i.e. methods that have exactly one return value declared with `RETURNING`) at appropriate read positions. In this case, the method's return value is used as an ABAP operand.
-A chained method call can consist of multipled functional methods that are linked using component selectors `->`. The return values of each method are references to the next method.
-
-```abap
-"The following example demonstrates method chaining
-"The following class creates random integers. Find more information in the
-"class documentation.
-"Both methods have returning parameters specified.
-DATA(some_int1) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
- min = 1
- max = 10 )->get_next( ).
-
-"Getting to the result as above - not using method chaining and inline declarations.
-DATA some_int2 TYPE i.
-DATA dref TYPE REF TO cl_abap_random_int.
-
-dref = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
- min = 1
- max = 10 ).
-
-some_int2 = dref->get_next( ).
-
-"Using the RECEIVING parameter in a standalone method call
-DATA some_int3 TYPE i.
-dref->get_next( RECEIVING value = some_int3 ).
-
-"IF statement that uses the return value in a read position
-IF cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
- min = 1
- max = 10 )->get_next( ) < 5.
- ... "The random number is lower than 5.
-ELSE.
- ... "The random number is greater than 5.
-ENDIF.
-
-"Examples using classes of the XCO library (see more information in the
-"ABAP for Cloud Development and Misc ABAP Classes cheat sheets), in which
-"multiple chained method calls can be specified. Each of the methods
-"has a returning parameter specified.
-
-"In the following example, 1 hour is added to the current time.
-DATA(add1hour) = xco_cp=>sy->time( xco_cp_time=>time_zone->user )->add( iv_hour = 1 )->as( xco_cp_time=>format->iso_8601_extended )->value.
-
-"In the following example, a string is converted to xstring using a codepage
-DATA(xstr) = xco_cp=>string( `Some string` )->as_xstring( xco_cp_character=>code_page->utf_8 )->value.
-
-"In the following example, JSON data is created. First, a JSON data builder
-"is created. Then, using different methods, JSON data is added. Finally,
-"the JSON data is turned to a string.
-DATA(json) = xco_cp_json=>data->builder( )->begin_object(
- )->add_member( 'CarrierId' )->add_string( 'DL'
- )->add_member( 'ConnectionId' )->add_string( '1984'
- )->add_member( 'CityFrom' )->add_string( 'San Francisco'
- )->add_member( 'CityTo' )->add_string( 'New York'
- )->end_object( )->get_data( )->to_string( ).
-```
-
-
-
-### Self-Reference me
-
-When implementing instance methods, you can optionally make use of the implicitly available object reference variable [`me`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenme.htm) which is always available at runtime and points to the respective object itself. You can use it to refer to components of the instance of a particular class:
-``` abap
-... some_method( ... ) ...
-
-... me->some_method( ... ) ...
-```
-
-The following code snippet shows a method implementation. In this case, a local data object from within the method and an instance attribute that is declared in the declaration part of the class in which this method is implemented have identical names. `me` is used to access the non-local data object.
-
-``` abap
-METHOD me_ref.
-
- DATA str TYPE string VALUE `Local string`.
-
- DATA(local_string) = str.
-
- "Assuming there is a variable str declared in the class declaration part.
- DATA(other_string) = me->str.
-
-ENDMETHOD.
-```
-
-
-
-## Notes on Inheritance
-
-- Concept: Deriving a new class (i. e.
- [subclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"))
- from an existing one
- ([superclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperclass_glosry.htm "Glossary Entry")).
-- In doing so, you create a hierarchical relationship between superclasses and subclasses
- (an [inheritance hierarchy](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_hierarchy_glosry.htm "Glossary Entry")) to form an [inheritance
- tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_tree_glosry.htm "Glossary Entry"). This is relevant for a class that can have multiple subclasses and one direct superclass.
-- Subclasses ...
- - inherit and thus adopt all components from superclasses.
- - can be made more specific by declaring new components and
- redefining instance methods (i. e. you can alter the implementation of inherited methods). In case a subclass has no further components, it contains exactly the components of the superclass - but the ones of the private visibility section are not visible there.
- - can redefine the public and protected instance methods of all preceding superclasses. Note: Regarding the static components of superclasses, accessing them is possible but not redefining them.
- - can themselves have multiple direct subclasses but only one direct superclass.
-- Components that are changed or added to subclasses are not visible to superclasses, hence, these changes are only relevant for the class itself and its subclasses.
-- Classes can rule out derivation: classes cannot inherit from classes that are specified with the addition
- [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_abstract_final.htm#!ABAP_ADDITION_2@2@)
- (e. g. `CLASS global_class DEFINITION PUBLIC FINAL CREATE PUBLIC. ...`).
-
-
-
-**Excursion: Additions `ABSTRACT` and `FINAL`**
-- Both classes and methods can be defined with the additions `ABSTRACT` and `FINAL`.
-- `FINAL` with ...:
- - Classes: These classes cannot be inherited. All methods are automatically and implicitly `FINAL`. In this case, the addition `FINAL` cannot be used for methods.
- - Methods: These methods cannot be redefined in subclasses.
-- `ABSTRACT` with ...:
- - Classes: Defines abstract classes. You cannot create an instance of an abstract class. To use instance components of an abstract class, you must create an instance of a subclass of such classes.
- - Methods: Defines abstract methods. The addition is only allowed in abstract classes (and not for private methods). These methods cannot be implemented in the implementation part of the class where they are declared. They must be redefined in subclasses. Note that you can also have non-abstract methods in abstract classes.
-- See [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm) more information on class options.
-
-``` abap
-"Declaration of an abstract method of an abstract superclass
-"and its implementation in a concrete subclass.
-CLASS cls1 DEFINITION ABSTRACT.
- PROTECTED SECTION.
- METHODS meth ABSTRACT.
-ENDCLASS.
-
-CLASS cls2 DEFINITION INHERITING FROM cls1.
- PROTECTED SECTION.
- METHODS meth REDEFINITION.
-ENDCLASS.
-
-CLASS cls2 IMPLEMENTATION.
- METHOD meth.
- ...
- ENDMETHOD.
-ENDCLASS.
-```
-
-
-
-**Redefining Methods**
-
-- Redefining methods is possible for the public and protected instance (not the static) methods of all preceding superclasses in a subclass (but only if the methods are not specified with `FINAL`).
-- In the declaration part of the subclass, you must specify the method as follows (and using the same method name):
- `METHODS meth REDEFINITION.`
-- This must be done in the same
- visibility section of the subclass as in the superclass.
-- You cannot change the parameters of the method.
-- Redefined methods work with private attributes of the subclass and cannot access private attributes of the superclass with the same name.
-- If you want to access the identically named method implementation in a superclass from within
- the method implementation of the subclass, use the [pseudo
- reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpseudo_reference_glosry.htm "Glossary Entry")
- [`super->meth`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcall_method_meth_super.htm).
-
-> **💡 Note**
-> Inheritance and constructors:
-> - Constructors cannot be redefined.
-> - If the instance constructor is implemented in a subclass, the instance constructor of the superclass must be called explicitly using `super->constructor`, even if the latter is not explicitly declared. An exception to this: Direct subclasses of the root node `OBJECT`.
-> - Regarding the static constructor: When calling a subclass for the first time, the preceding static constructors of all of the entire inheritance tree must have been called first.
-> - More information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_constructors.htm).
-
-
-
-## Notes on Polymorphism and Casting
-
-The object orientation concept
-[polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry")
-means you can address differently implemented methods belonging to different objects of different classes using one and the
-same reference variable, for example,
-object reference variables pointing to a superclass can point to objects of a subclass.
-
-Note the concept of static and dynamic type in this context:
-
-- Object reference variables (and also interface reference variables) have both a
- [static](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_type_glosry.htm "Glossary Entry")
- and a [dynamic
- type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_type_glosry.htm "Glossary Entry").
-- When declaring an object reference variable, e. g. `DATA oref TYPE REF TO cl`, you determine the static type, i. e.
- `cl` - a class - is used to declare the reference variable that is statically defined in the code. This is the class of an object to which the reference variable points to.
-- Similarly, the dynamic type also defines the class of an object which the reference variable points to. However, the dynamic type is determined at runtime, i. e. the class of an object which the reference variable points to can change.
-- Relevant for? This differentiation enters the picture in polymorphism when a reference variable typed with reference to a subclass can always be assigned to reference variables typed with reference to one of its superclasses or their interfaces. That's what is called [upcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenup_cast_glosry.htm "Glossary Entry") (or widening cast). Or the assignment is done the other way round. That's what is called [downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry") (or narrowing cast).
-
-> **✔️ Hints**
-> - The following basic rule applies: The static type is always more general than or the same as the dynamic type. The other way round: The dynamic type is always more special than or equal to the static type.
->- That means:
-> - If the static type is a class, the dynamic type must be the same class or one of its subclasses.
-> - If the static type is an interface, the dynamic type must implement the interface.
-
-- Regarding assignments: If it can be statically checked that an assignment is possible
- although the types are different, the assignment is done using the
- [assignment
- operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
- `=` that triggers an upcast automatically.
-- Otherwise, it is a
- [downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry").
- Here, the assignability is not checked until runtime. The downcast - in contrast to upcasts -
- must be triggered explicitly using the [casting
- operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencasting_operator_glosry.htm "Glossary Entry")
- [`CAST`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_cast.htm). You might see code using the older
- operator [`?=`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove_cast.htm).
-- See more information in the topic [Assignment Rules for Reference
- Variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_references.htm).
-
-As an example, assume there is an inheritance tree with `lcl_super` as the superclass and `lcl_sub` as a direct subclass. `lcl_sub2` is a direct subclass of `lcl_sub`.
-
-In the following code snippet, the rule is met since the superclass is either the same as or more generic than the subclass (the subclass has, for example, redefined methods and is, thus, more specific). Hence, the assignment of an object reference variable pointing to the subclass to a variable pointing to a superclass works. An upcast is triggered. After this casting, the type of `oref_super` has changed and the methods of `lcl_sub` can be accessed via `oref_super`.
-
-``` abap
-"Creating object references
-DATA(oref_super) = NEW lcl_super( ).
-
-DATA(oref_sub) = NEW lcl_sub( ).
-
-"Upcast
-oref_super = oref_sub.
-
-"The casting might be done when creating the object.
-DATA super_ref TYPE REF TO lcl_super.
-
-super_ref = NEW lcl_sub( ).
-```
-
-- As mentioned above, a downcast must be triggered
-manually. Just an assignment like `oref_sub = oref_super.`
-does not work. A syntax error occurs saying the right-hand variable's type cannot be converted to the left-hand variable's type.
-- If you indeed want to carry out this casting, you must use
-`CAST` (or you might see code using the older operator `?=`) to overcome this syntax error (but just the syntax error!). Note: You might also use these casting operators for the upcasts. That means `oref_super = oref_sub.` has the same effect as `oref_super = CAST #( oref_sub ).`. Using the casting operator for upcasts is usually not necessary.
-- At runtime, the assignment is checked and if the conversion does not work, you face a (catchable) exception. Even more so, the assignment `oref_sub = CAST #( oref_super ).` does not throw a syntax error but it does not work in this example either because it violates the rule mentioned above (`oref_sub` is more specific than `oref_super`).
-- To check whether such an assignment is possible
-on specific classes, you can use the predicate expression [`IS INSTANCE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_instance_of.htm)
-or the case distinction [`CASE TYPE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase_type.htm). Carrying out an upcast before the downcast ensures that the left-hand variable's type is compatible to the right-hand variable's type.
-
-``` abap
-DATA(oref_super) = NEW lcl_super( ).
-DATA(oref_sub) = NEW lcl_sub( ).
-DATA(oref_sub2) = NEW lcl_sub2( ).
-
-"Downcast impossible (oref_sub is more specific than oref_super);
-"the exception is caught here
-
-TRY.
- oref_sub = CAST #( oref_super ).
- CATCH CX_SY_MOVE_CAST_ERROR INTO DATA(e).
- ...
-ENDTRY.
-
-"Working downcast with a prior upcast
-
-oref_super = oref_sub2.
-
-"Due to the prior upcast, the following check is actually not necessary.
-
-IF oref_super IS INSTANCE OF lcl_sub.
- oref_sub = CAST #( oref_super ).
- ...
-ENDIF.
-
-"Excursion RTTI: Downcasts, CAST and method chaining
-"Downcasts particularly play, for example, a role in the context of
-"retrieving type information using RTTI. Method chaining is handy
-"because it reduces the lines of code in this case.
-"The example below shows the retrieval of type information
-"regarding the components of a structure.
-"Due to the method chaining in the second example, the three
-"statements in the first example are reduced to one statement.
-
-DATA struct4cast TYPE zdemo_abap_carr.
-
-DATA(rtti_a) = cl_abap_typedescr=>describe_by_data( struct4cast ).
-DATA(rtti_b) = CAST cl_abap_structdescr( rtti_a ).
-DATA(rtti_c) = rtti_b->components.
-
-DATA(rtti_d) = CAST cl_abap_structdescr(
- cl_abap_typedescr=>describe_by_data( struct4cast )
- )->components.
-```
-
-
-
-## Notes on Interfaces
-
-Interfaces ...
-
-- represent a template for the components in the public visibility
- section of classes.
-- enhance classes by adding interface components.
-- are possible as both
- [local](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_interface_glosry.htm "Glossary Entry")
- and [global
- interfaces](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_interface_glosry.htm "Glossary Entry").
-- support
- [polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry") in classes. Each class that implements an interface can implement its methods differently. [Interface reference variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_ref_variable_glosry.htm "Glossary Entry") can point to objects of all classes that implement the associated interface.
-- can be implemented by classes of an inheritance tree. It can be any number of interfaces. However, each interface can be implemented only once in an inheritance tree.
-- are different from classes in the following ways:
- - They only consist of a part declaring the components without an
- implementation part. The implementation is done in classes that use the interface.
- - There are no visibility sections. All components of an interface are visible.
- - No instances can be created from interfaces.
- - Declarations as mentioned for classes, e. g. `DATA`,
- `CLASS-DATA`, `METHODS`,
- `CLASS-METHODS`, are possible. Constructors are not
- possible.
-
-
-
-Defining interfaces:
-- Can be done either globally in the repository or locally in an ABAP program.
-
-``` abap
-INTERFACE intf.
-"The addition PUBLIC is for global interfaces:
-"INTERFACE intf_g PUBLIC.
-
- DATA ...
- CLASS-DATA ...
- METHODS ...
- CLASS-METHODS ...
-
-ENDINTERFACE.
-```
-
-Implementing interfaces:
-- A class can implement multiple interfaces.
-- Interfaces must be specified in the
- declaration part of a class using the statement
- [`INTERFACES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces.htm).
-- Since all interface components are public, you must include this
- statement and the interfaces in the public visibility section of a class. When an interface is implemented in a class, all interface components are added to the other components of the class in the public visibility section.
-- Interface components can be addressed using the [interface component
- selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_comp_selector_glosry.htm "Glossary Entry"): `... intf~comp ...`.
-- You can specify alias names for the interface components using the statement [`ALIASES ... FOR ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapaliases.htm). The components can then be addressed using the alias name.
-- The class must implement the methods of all implemented interfaces in it unless the methods are flagged as abstract or final. You can adapt some interface components to requirements of your class.
- - You can specify the additions [`ABSTRACT METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS ABSTRACT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of
- classes. In this case, the class(es) need not
- implement the methods of the interface. The implementation is then relevant for a subclass inheriting from a superclass that includes
- such an interface declaration. Note that the whole class must be abstract.
- - The additions [`FINAL METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of classes flag the method(s) as final.
-- In the interface, methods can mark their implementation as optional using the additions [`DEFAULT
- IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm)
- or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm).
-
-
-Syntax for using interfaces in classes:
-``` abap
-CLASS class DEFINITION.
- PUBLIC SECTION.
- "Multiple interface implementations possible
- INTERFACES intf.
- ALIASES meth_alias FOR intf~some_method.
-ENDCLASS.
-
-CLASS class IMPLEMENTATION.
- METHOD intf~some_meth. "Method implementation using the original name
- ...
- ENDMETHOD.
-
- "Just for demo purposes: Method implementation using the alias name
- "METHOD meth_alias.
- " ...
- "ENDMETHOD.
-
- ...
-ENDCLASS.
-
-"Abstract class
-CLASS cl_super DEFINITION ABSTRACT.
- PUBLIC SECTION.
- INTERFACES intf ALL METHODS ABSTRACT.
- ALIASES:
- meth1 FOR intf~meth1,
- meth2 FOR intf~meth2.
-ENDCLASS.
-
-"Subclass inheriting from abstract class and implementing interface methods
-CLASS cl_sub DEFINITION INHERITING FROM cl_super.
- PUBLIC SECTION.
- METHODS:
- meth1 REDEFINITION,
- meth2 REDEFINITION.
-ENDCLASS.
-
-CLASS cl_sub IMPLEMENTATION.
- METHOD meth1.
- ...
- ENDMETHOD.
- METHOD meth2.
- ...
- ENDMETHOD.
-ENDCLASS.
-```
-
-Interface reference variables and accessing objects:
-- As mentioned above, addressing an object happens via an object reference variable with reference to a class.
-- An interface variable can contain references to objects of classes that implement the corresponding interface.
-- You create an interface reference variable like this: `DATA i_ref TYPE REF TO intf.`
-
-Addressing interface components:
-- Addressing instance components using interface reference variable
- - attribute: `i_ref->attr`
- - instance method: `i_ref->meth( )`
-- Addressing instance components using an object reference variable (Note: The type is a class that implements the interface) is also possible but it's not the recommended way:
- - attribute: `cl_ref->intf~attr`
- - instance method: `cl_ref->intf~meth`
-- Addressing static components:
- - static attribute: `class=>intf~attr`,
- - static method: `class=>intf~meth( )`
- - constant: `intf=>const`
-
-
-``` abap
-"Addressing instance interface components using interface reference variable
-DATA i_ref TYPE REF TO intf.
-
-DATA cl_ref TYPE REF TO class.
-
-"Creating an instance of a class that implements the interface intf
-cl_ref = NEW #( ).
-
-"If the class class implements an interface intf,
-"the class reference variable cl_ref can be assigned
-"to the interface reference variable i_ref.
-"The reference in i_ref then points to the same object
-"as the reference in cl_ref.
-i_ref = cl_ref.
-
-"Can also be done directly, i. e. directly creating an object to which the interface reference variable points
-i_ref = NEW class( ).
-
-"Instance interface method via interface reference variable
-... i_ref->inst_method( ... ) ...
-
-"Instance interface attribute via interface reference variable
-... i_ref->inst_attr ...
-
-"Addressing instance components using the class reference variable
-"is also possible but it's not the recommended way.
-... cl_ref->intf~inst_method( ... ) ...
-... cl_ref->intf~inst_attr ...
-
-"Addressing static interface components
-"class=> can be dropped if the method is called in the same class that implements the interface
-... class=>intf~stat_method( ... ) ...
-... class=>intf~stat_attr ...
-
-"Just for the record: Static interface components can be called via reference variables, too.
-... i_ref->stat_method( ... ) ...
-... i_ref->stat_attr ...
-... cl_ref->intf~stat_method( ... ) ...
-
-"Constants
-"A constant can be addressed using the options mentioned above.
-"Plus, it can be addressed using the following pattern
-... intf=>const ...
-```
-
-
-
-## Excursions
-
-### Friendship
-
-- The concept of friendship enters the picture if your use case for your classes is to work together very closely. This is true, for example, for [unit
-tests](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunit_test_glosry.htm "Glossary Entry") if you want to test private methods.
-- Classes can grant access to invisible components for their [friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry").
-- The friends can be other classes and interfaces. In case of interfaces, friendship is granted to all classes that implement the interface.
-- Impact of friendship:
- - Access is granted to all components, regardless of the visibility section or the addition `READ-ONLY`.
- - Friends of a class can create instances of the class without restrictions.
- - Friendship is a one-way street, i. e. a class granting friendship to another class is not granded friendship the other way round. If class `a` grants friendship to class `b`, class `b` must also explicitly grant friendship to class `a` so that `a` can access the invisible components of class `b`.
- - Friendship and inheritance: Heirs of friends and interfaces that contain a friend as a component interface also become friends. However, granting friendship is not inherited, i. e. a friend of a superclass is not automatically a friend of its subclasses.
-
-
-You specify the befriended class in the definition part using a `FRIENDS` addition:
-``` abap
-"For local classes. Friendship can be granted to all classes/interfaces
-"of the same program and the class library.
-"Multiple classes can be specified as friends.
-CLASS lo_class DEFINITION FRIENDS other_class ... .
-...
-
-CLASS lo_class DEFINITION CREATE PRIVATE FRIENDS other_class ... .
-
-"Addition GLOBAL only allowed for global classes, i. e. if the addition PUBLIC is also used
-"Other global classes and interfaces from the class library can be specified after GLOBAL FRIENDS.
-CLASS global_class DEFINITION CREATE PUBLIC FRIENDS other_global_class ... .
-```
-
-
-
-### Events
-
-- [Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry")
-can trigger the processing of [processing blocks](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocessing_block_glosry.htm "Glossary Entry").
-- Declaring events: Can be declared in a visibility section of the declaration part of a class or in an interface, e. g. as
- - instance event using an [`EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapevents.htm) statement. Note that they can only be raised in instance methods of the same class.
- - static event using [`CLASS-EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass-events.htm). They can be raised in all methods of the same class or of a class that implements the interface. Static event handlers can be called by the event independently of an instance of the class.
-
-``` abap
-"Declaration part of a class/interface
-"Instance events
-EVENTS: i_evt1,
-
-"Events can only have output parameters that are passed by value
- i_evt2 EXPORTING VALUE(num) TYPE i ...
-...
-"Static events
-CLASS-EVENTS: st_evt1,
- st_evt2 EXPORTING VALUE(num) TYPE i ...
-
-```
-
-- Event handlers:
- - An event is raised by a [`RAISE EVENT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_event.htm) statement in another method or in the same method.
- - Raising an event means that [event handlers](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_handler_glosry.htm "Glossary Entry") are called.
- - This event handler must be declared with the following syntax (see more information and more additions [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_event_handler.htm)):
-
-``` abap
-"Event handlers for instance events
-METHODS: handler_meth1 FOR EVENT i_evt1 OF some_class,
-
- "Parameter names must be the same as declared;
- "no further additions possible for the parameter (e.g. TYPE);
- "the predefined, implicit parameter sender as another formal parameter is possible with instance events,
- "it is typed as a reference variable, which itself has the class/interface as a static type,
- "If the event handler is called by an instance event, it is passed a reference to the raising object in sender.
- handler_meth2 FOR EVENT i_evt2 OF some_class IMPORTING num sender,
-...
-```
-
-- To make sure that an event handler handles a raised event, it must be registered with the statement [`SET HANDLER`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapset_handler.htm). See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapset_handler.htm) (for example, events can also be deregistered).
-
-```abap
-"Registering event for a specific instance
-SET HANDLER handler1 FOR ref.
-
-"Registering event for all instances
-SET HANDLER handler2 FOR ALL INSTANCES.
-
-"Registering static event for the whole class/interface
-SET HANDLER handler3.
-"Note that multiple handler methods can be specified.
-```
-
-
-
-### Factory Methods and Singletons as Design Patterns
-
-In object-oriented programming, there a plenty of design patterns. Covering these ones here to get a rough idea: factory methods and singletons. Both are relevant if you want to restrict or control the instantiation of a class by external users of this class.
-
-A singleton is a design pattern in which it is only up to the class to create objects. In doing so, the class ensures that only one object exists for every internal session that is made available to consumers.
-
-The following code snippet shows an implementation of the singleton design pattern. The `get_instance` method is used to return the object reference to the object created. Only one instance can be created.
-
-```abap
-"Using the addition CREATE PRIVATE, objects can only be created by the class itself.
-CLASS singleton_class DEFINITION CREATE PRIVATE.
- PUBLIC SECTION.
- CLASS-METHODS get_instance RETURNING VALUE(ret) TYPE REF TO singleton_class.
-
- PRIVATE SECTION.
- CLASS-DATA inst TYPE REF TO singleton_class.
-ENDCLASS.
-
-CLASS singleton_class IMPLEMENTATION.
- METHOD get_instance.
- IF inst IS NOT BOUND.
- inst = NEW #( ).
- ENDIF.
- ret = inst.
- ENDMETHOD.
-ENDCLASS.
-```
-
-Controlling the creation of objects - the instantiation of a class - can be realized using a factory method. For example, certain checks might be required before a class can be instantiated. If a check is not successful, the instantiation is denied.
-You might create a (static) factory method as follows:
-- A check is carried out in the factory method, for example, by evaluating importing parameters.
-- If the check is successful, an object of the class is created.
-- The method signature includes an output parameter that returns an object reference to the caller.
-
-This is rudimentarily demonstrated in the following snippet:
-
-``` abap
-CLASS class DEFINITION CREATE PRIVATE.
- PUBLIC SECTION.
- CLASS-METHODS
- factory_method IMPORTING par ...,
- RETURNING VALUE(obj) TYPE REF TO class.
- ...
-ENDCLASS.
-
-CLASS class IMPLEMENTATION.
- METHOD factory_method.
- IF par = ...
- obj = NEW class( ).
- ELSE.
- ...
- ENDIF.
-
- ENDMETHOD.
- ...
-ENDCLASS.
-...
-
-"Calling a factory method.
-DATA obj_factory TYPE REF TO class.
-
-obj_factory = class=>factory_method( par = ... ).
-```
-
-
-
-## More Information
-You can check the subtopics of
-
-- [ABAP Objects - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_objects_oview.htm)
-- [Programming Guidlines - Object-Oriented Programming (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenobj_oriented_gdl.htm)
-
-in the ABAP Keyword Documentation.
-
-## Executable Example
-[zcl_demo_abap_objects](./src/zcl_demo_abap_objects.clas.abap)
-
-> **💡 Note**
-> - The executable example covers the following topics, among others:
-> - Working with objects and components
-> - Redefining methods, inheritance
-> - Working with interfaces
-> - Upcast and downcast
-> - Concepts such as factory methods, singleton and abstract classes
-> - Events
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
-> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
+
+
+# ABAP Object Orientation
+
+> **💡 Note**
+> This ABAP cheat sheet provides an overview on selected syntax options and concepts related to ABAP object orientation. It is supported by code snippets and an executable example. They are **not** suitable as role models for object-oriented design. Their primary focus is on the syntax and functionality. For more details, refer to the respective topics in the ABAP Keyword Documentation. Find an overview in the topic [ABAP Objects - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_objects_oview.htm).
+
+- [ABAP Object Orientation](#abap-object-orientation)
+ - [Classes and Objects](#classes-and-objects)
+ - [Creating Classes](#creating-classes)
+ - [Creating a Local Class](#creating-a-local-class)
+ - [Creating a Global Class](#creating-a-global-class)
+ - [Visibility of Components](#visibility-of-components)
+ - [Creating the Visibility Sections](#creating-the-visibility-sections)
+ - [Defining Components](#defining-components)
+ - [Working with Objects and Components](#working-with-objects-and-components)
+ - [Declaring Reference Variables](#declaring-reference-variables)
+ - [Creating Objects](#creating-objects)
+ - [Assigning Reference Variables](#assigning-reference-variables)
+ - [Accessing Attributes](#accessing-attributes)
+ - [Calling Methods](#calling-methods)
+ - [Method Chaining](#method-chaining)
+ - [Self-Reference me](#self-reference-me)
+ - [Notes on Inheritance](#notes-on-inheritance)
+ - [Notes on Polymorphism and Casting](#notes-on-polymorphism-and-casting)
+ - [Notes on Interfaces](#notes-on-interfaces)
+ - [Excursions](#excursions)
+ - [Friendship](#friendship)
+ - [Events](#events)
+ - [Factory Methods and Singletons as Design Patterns](#factory-methods-and-singletons-as-design-patterns)
+ - [More Information](#more-information)
+ - [Executable Example](#executable-example)
+
+## Classes and Objects
+
+Object-oriented programming in ABAP means dealing with
+[classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry")
+and
+[objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_glosry.htm "Glossary Entry").
+
+Objects ...
+
+- are
+ [instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_glosry.htm "Glossary Entry")
+ of a
+ [type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_glosry.htm "Glossary Entry").
+ In this context, they are instances of a
+ [class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_glosry.htm "Glossary Entry").
+ The terms *object* and *instance* are used synonymously.
+- exist in the [internal
+ session](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninternal_session_glosry.htm "Glossary Entry")
+ of an [ABAP
+ program](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm "Glossary Entry").
+
+
+Classes ...
+- are templates for objects, i. e. they determine how
+ all instances of a class are set up. All instances are created (i.e they are [instantiated](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstantiation_glosry.htm "Glossary Entry")) based on this template and, thus, have the same setup.
+ - To give an example: If, for example, a vehicle represents a class, then the
+ instances of the class `vehicle` have the same setup.
+ That means they all share the same kind of components like a brand, model and color or the same functionality like the acceleration or braking distance.
+ However, the values of these components are different from instance to instance. For example, one
+ instance is a red sedan of brand A having a certain
+ acceleration; another instance is a black SUV of brand B and so on. You can create an object (or instance respectively) that stands
+ for an actual vehicle with which you can work with. You might create any number of objects that are based on such a class - if instantiation is allowed.
+- contain
+ [components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_glosry.htm "Glossary Entry"):
+ - [Attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenattribute_glosry.htm "Glossary Entry")
+ of the objects (the data object declarations)
+ - [Methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmethod_glosry.htm "Glossary Entry")
+ that determine the behavior of an object
+ - [Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry") to trigger the processing of ABAP code
+
+
are defined as
+ global types, i. e. they are visible as a repository object - in contrast to local classes. As a global type, they can be used - as the name implies - globally in other ABAP programs or global classes
+
+> **💡 Note**
+> - If a class is only used in one ABAP program, creating a local class is enough. However, if you choose to create a global class, you must bear in mind that such a class can be used everywhere. Consider the impact on the users of the global class when you change, for example, the visibility section of a component or you delete it.
+> - Apart from ADT, global classes can also be created in the ABAP Workbench (`SE80`) or with transaction `SE24` in [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).
+
+Basic structure of classes:
+- [Declaration part](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeclaration_part_glosry.htm "Glossary Entry") that includes declarations of the class components.
+- [Implementation part](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenimplementation_part_glosry.htm "Glossary Entry") that includes method implementations.
+- Both are introduced by `CLASS` and ended by `ENDCLASS`.
+
+#### Creating a Local Class
+
+``` abap
+"Declaration part
+CLASS local_class DEFINITION.
+
+ ... "Here go the declarations for all components and visibility sections.
+ "You should place the declarations at the beginning of the program.
+
+ENDCLASS.
+
+"Implementation part
+CLASS local_class IMPLEMENTATION.
+
+ ... "Here go the method implementations.
+ "Only required if you declare methods in the declaration part.
+
+ENDCLASS.
+```
+
+#### Creating a Global Class
+The code snippet shows a basic skeleton of a global class. There are [further
+additions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm)
+possible for the declaration part.
+
+``` abap
+"Declaration part
+CLASS global_class DEFINITION
+ PUBLIC "Makes the class a global class in the class library.
+ FINAL "Means that no subclasses can be derived from this class.
+ CREATE PUBLIC. "This class can be instantiated anywhere it is visible.
+
+ ... "Here go the declarations for all components and visibility sections.
+
+ENDCLASS.
+
+"Implementation part
+CLASS global_class IMPLEMENTATION.
+
+ ... "Here go the method implementations.
+ "Only required if you declare methods in the DEFINITION part.
+
+ENDCLASS.
+```
+> **💡 Note**
+> - Addition `... CREATE PROTECTED.`: The class can only be instantiated in methods of its
+[subclasses](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"),
+of the class itself, and of its
+[friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry").
+> - Addition `... CREATE PRIVATE`: The class can only
+be instantiated in methods of the class itself or of its friends. Hence,
+it cannot be instantiated as an inherited component of subclasses.
+
+
+
+### Visibility of Components
+
+In the class declaration part, you must specify (at least one of the) three
+[visibility
+sections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm "Glossary Entry")
+and include class components to define their visibility. These visibility sections serve the purpose of encapsulation in ABAP Objects. For example, you do not want to make certain components publicly available for all users. The visibility sections are as follows:
+
+
+
+
PUBLIC SECTION.
+
Components declared in this section can be accessed from within the class and from all users of the class.
+
+
+
PROTECTED SECTION.
+
Components declared in this section can be
+ accessed from within the class and subclasses as well as friends
+ - concepts related to inheritance.
+
+
+
PRIVATE SECTION.
+
Components declared in this section can only be accessed from within the class in which they are declared and its friends.
+
+
+
+Summary:
+
+| Visible for | PUBLIC SECTION | PROTECTED SECTION | PRIVATE SECTION |
+|---|---|---|---|
+| Same class and its friends | X | X | X |
+| Any subclasses | X | X | - |
+| Any repository objects | X | - | - |
+
+
+#### Creating the Visibility Sections
+At least one section must be specified.
+``` abap
+CLASS local_class DEFINITION.
+ PUBLIC SECTION.
+ "Here go the components.
+ PROTECTED SECTION.
+ "Here go the components.
+ PRIVATE SECTION.
+ "Here go the components.
+ENDCLASS.
+```
+
+
+
+### Defining Components
+
+All components, i. e.
+- attributes (using `TYPES`, `DATA`, `CLASS-DATA`, and `CONSTANTS` for data types and data
+objects),
+- methods (using `METHODS` and `CLASS-METHODS`),
+- events (using `EVENTS` and `CLASS-EVENTS`) as well as
+- interfaces,
+
+are declared in the declaration part of the class. There, they must be
+assigned to a visibility section.
+
+Two
+kinds of components are to be distinguished when, for example, looking at declarations using `DATA` and `CLASS-DATA` having a preceding `CLASS-`:
+
+- [Instance components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_component_glosry.htm "Glossary Entry"):
+ Components that exist separately for each instance and can only be accessed in instances of a class.
+- [Static components](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_component_glosry.htm "Glossary Entry") (the declarations with `CLASS-`):
+ Components that exist only once per class. They do no not exclusively exist for specific instances. They can be addressed using the name of the class.
+
+**Attributes**
+
+- The attributes of a class (or interface) mean the data objects declared within a
+ class (or interface).
+- [Instance
+ attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_attribute_glosry.htm "Glossary Entry")
+ (`DATA`): Determine the state of a objects of a class. The data
+ is only valid in the context of an instance. As shown further down,
+ instance attributes can only be accessed via an [object reference
+ variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry").
+- [Static
+ attributes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_attribute_glosry.htm "Glossary Entry")
+ (`CLASS-DATA`): Their content is independent of instances of
+ a class and, thus, valid for all instances. That means that if you change such a static
+ attribute, the change is visible in all instances. As shown further down,
+ static attributes can be accessed by using the class name without a
+ prior creation of an instance.
+
+
+> **💡 Note**
+> - You can declare constant data objects that should not be
+changed using
+[`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm)
+statements. You specify the values for the constants (which are also static attributes) when you declare
+them in the declaration part of a class.
+> - The addition
+[`READ-ONLY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata_options.htm#!ABAP_ADDITION_2@2@)
+can be used in the public visibility section. Effect:
+> - Can be read from outside of the class
+> - Cannot be changed from outside
+> - Can only be changed using methods of the class or its subclasses
+
+Declaring attributes in visibility sections. In the code snippet below, all attributes are declared in the public section of a local class.
+``` abap
+CLASS local_class DEFINITION.
+
+ PUBLIC SECTION.
+ TYPES some_type TYPE c LENGTH 3. "Type declaration
+
+ DATA: inst_number TYPE i, "Instance attributes
+ inst_string TYPE string,
+ dobj_r_only TYPE c LENGTH 5 READ-ONLY. "Read-only attribute
+
+ CLASS-DATA: stat_number TYPE i, "Static attributes
+ stat_char TYPE c LENGTH 3.
+
+ CONSTANTS const_num TYPE i VALUE 123. "Non-changeable constant
+
+ PROTECTED SECTION.
+ "Here go more attributes if needed.
+
+ PRIVATE SECTION.
+ "Here go more attributes if needed.
+
+ENDCLASS.
+
+CLASS local_class IMPLEMENTATION.
+
+ ... "Here go all method implementations.
+
+ENDCLASS.
+```
+
+
+
+**Methods**
+
+- Are internal
+ [procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm "Glossary Entry")
+ determining the behavior of the class.
+- Can access all of the attributes of a class and, if not defined
+ otherwise, change their content.
+- Have a [parameter
+ interface](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparameter_interface_glosry.htm "Glossary Entry")
+ (also known as
+ [signature](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensignature_glosry.htm "Glossary Entry"))
+ with which methods can get values to work with when being called and pass values
+ back to the caller (see the notes on formal and actual parameters below).
+- [Static
+ methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_method_glosry.htm "Glossary Entry")
+ can only access static attributes of a class and trigger static
+ events. You declare them using `CLASS-METHODS` statements in
+ a visibility section.
+- [Instance
+ methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_method_glosry.htm "Glossary Entry")
+ can access all of the attributes of a class and trigger all events.
+ You declare them using `METHODS` statements in a visibility
+ section. Note that you must create an instance of a class first before using instance methods.
+
+**Parameter Interface**
+
+In the simplest form, methods can have no parameter at all. Apart from that, methods can be defined with the following parameters:
+
+| Addition | Details |
+|---|---|
+|`IMPORTING`|Defines one or more input parameters to be imported by the method. |
+|`EXPORTING`|Defines one or more output parameters to be exported by the method. |
+|`CHANGING`|Defines one or more input or output parameters, i. e. that can be both imported and exported. |
+|`RETURNING`|For [functional methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunctional_method_glosry.htm "Glossary Entry"), i. e. such methods have only one `RETURNING` parameter that can be defined. As an output parameter like the `EXPORTING` parameter, `RETURNING` parameters pass back values (note that the formal parameters of returning parameters must be passed by value as covered below). In contrast to `EXPORTING` for which multiple parameters can be specified, only one `RETURNING` parameter can be specified in a method. If you only need one output parameter, you can benefit from using a `RETURNING` parameter by shortening the method call and enabling method chaining. Another big plus is that such functional methods can, for example, be used in expressions. In case of standalone method calls, the returned value can be accessed using the addition `RECEIVING`. |
+|`RAISING` | Used to declare the [class-based exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_based_exception_glosry.htm "Glossary Entry") that can be propagated from the method to the caller. |
+
+
+> **💡 Note**
+> - You may find the addition `EXCEPTIONS` especially in definitions of older classes. They are for non-class-based exceptions. This addition should not be used in ABAP for Cloud Development.
+> - Notes on [formal
+ parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenformal_parameter_glosry.htm "Glossary Entry")
+ versus [actual
+ parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenactual_parameter_glosry.htm "Glossary Entry"):
+> - You define method parameters by specifying a name with a type which
+ can be a
+ [generic](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengeneric_data_type_glosry.htm "Glossary Entry")
+ or
+ [complete](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplete_data_type_glosry.htm "Glossary Entry")
+ type. Examples:
+> - `fp` is the formal parameter that has a complete type: `... meth IMPORTING fp TYPE string ...`
+> - `gen` is the formal parameter that has a generic type: `... meth IMPORTING gen TYPE any ...`
+> - Find more information about generic types also in the [Data Types and Data Objects](16_Data_Types_and_Objects.md#generic-types) cheat sheet.
+> - This formal parameter includes the specification of how the
+ value passing should happen. Parameters can be [passed by
+ reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_reference_glosry.htm "Glossary Entry")
+ (`... REFERENCE(param) ...`; note that just specifying the
+ parameter name `... param ...` - as a shorter syntax -
+ means passing by reference by default) or [by
+ value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpass_by_value_glosry.htm "Glossary Entry")
+ (`... VALUE(param) ...`).
+> - The actual parameter represents
+ the data object whose content is passed to or copied from a formal
+ parameter as an argument when a procedure is called. If
+ passing by reference is used, a local data object is not created for
+ the actual parameter. Instead, the procedure is given a
+ [reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry")
+ to the actual parameter during the call and works with the actual
+ parameter itself. Note that parameters that are input and passed by
+ reference cannot be modified in the procedure. However, the use of a
+ reference is beneficial regarding the performance compared to
+ creating a local data object.
+>- Parameters can be defined as optional using the
+ [`OPTIONAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters.htm#!ABAP_ONE_ADD@1@)
+ addition. In doing so, it is not mandatory to pass an actual
+ parameter. The
+ [`DEFAULT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_parameters.htm#!ABAP_ONE_ADD@1@)
+ addition also makes the passing of an actual parameter optional.
+ However, when using this addition, as the name implies, a default
+ value is set.
+
+
+
+**Constructors**
+
+- [Constructors](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_glosry.htm "Glossary Entry")
+ are special methods that are usually used for setting a defined
+ initial value for attributes of the class or its objects.
+- A class has exactly one [instance
+ constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_constructor_glosry.htm "Glossary Entry")
+ and one [static
+ constructor](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_constructor_glosry.htm "Glossary Entry").
+- The declaration and use of constructors is optional.
+- Static constructor:
+ - Declared using the predefined name `class_constructor` as part of a
+ `CLASS-METHODS` statement in the public visibility section.
+ - Has no parameters.
+ - Automatically and immediately called once for each class when calling a class for
+ the first time in an internal session, i. e. when, for example, an instance of a class is created or a component is used. Note: If it is not explicitly declared and implemented, it is merely an empty method.
+- Instance constructor:
+ - Declared using the predefined name `constructor` as part of a
+ `METHODS` statement. In case of global classes, it can only be declared in the public visibility section.
+ - Automatically called when a class is
+ instantiated and an instance is created.
+ - Can have `IMPORTING` parameters and raise exceptions.
+
+Example for method definitions: The following snippet shows
+multiple method definitions in the public section of a local class. Most of the formal
+parameters of the demo methods below are defined by just using the
+parameter name. This means passing by reference (returning parameters
+require to be passed by value).
+``` abap
+CLASS local_class DEFINITION.
+ PUBLIC.
+ METHODS: inst_meth1, "instance methods
+
+ inst_meth2 IMPORTING a TYPE string,
+
+ inst_meth3 IMPORTING b TYPE i
+ EXPORTING c TYPE i,
+
+ inst_meth4 IMPORTING d TYPE string
+ RETURNING VALUE(e) TYPE string,
+
+ inst_meth5 IMPORTING f TYPE i
+ EXPORTING g TYPE i
+ CHANGING h TYPE string
+ RETURNING VALUE(i) TYPE i
+ RAISING cx_sy_zerodivide,
+
+ constructor IMPORTING j TYPE i. "instance constructor with importing parameter
+
+ CLASS-METHODS: stat_meth1, "static methods
+
+ stat_meth2 IMPORTING k TYPE i
+ EXPORTING l TYPE i,
+
+ class_constructor, "static constructor
+
+ "Options of formal parameter definitions
+ stat_meth3 IMPORTING VALUE(m) TYPE i, "pass by value
+ stat_meth4 IMPORTING REFERENCE(n) TYPE i, "pass by reference
+ stat_meth5 IMPORTING o TYPE i, "same as n; the specification of REFERENCE(...) is optional
+ stat_meth6 RETURNING VALUE(p) TYPE i, "pass by value once more (note: it's the only option for returning parameters)
+
+ "OPTIONAL/DEFAULT additions
+ stat_meth7 IMPORTING q TYPE i DEFAULT 123
+ r TYPE i OPTIONAL,
+
+ "The examples above use a complete type for
+ "the parameter specification. Generic types
+ "are possible.
+ stat_meth8 IMPORTING s TYPE any "Any data type
+ t TYPE any table "Any internal table type
+ u TYPE clike. "Character-like types (c, n, string, d, t and character-like flat structures)
+
+ENDCLASS.
+
+CLASS local_class IMPLEMENTATION.
+ METHOD inst_meth1.
+ ...
+ ENDMETHOD.
+
+ ... "Further method implementations. Note that all declared methods must go here.
+ENDCLASS.
+```
+
+
+
+## Working with Objects and Components
+
+### Declaring Reference Variables
+- To create an object, a [reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm "Glossary Entry")
+must be declared.
+- Such an [object reference
+variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_refer_variable_glosry.htm "Glossary Entry")
+is also necessary for accessing objects and their components. That means objects are not directly accessed but only via references that point to
+those objects. This object reference variable contains the reference to the object - after assigning the reference to the object (see further down).
+``` abap
+"Declaring object reference variables
+DATA: ref1 TYPE REF TO local_class,
+ ref2 TYPE REF TO global_class,
+ ref3 LIKE ref1.
+```
+
+
+
+### Creating Objects
+
+- Using the instance operator
+ [`NEW`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_new.htm),
+ you can create objects of a class (and [anonymous data
+ objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenanonymous_data_object_glosry.htm "Glossary Entry"), too, that are not dealt with here). As a result,
+ you get a [reference variable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm "Glossary Entry")
+ that points to the created object.
+- Regarding the type specifications before and parameters within the
+ parentheses:
+ - Right before the first parenthesis after `NEW`, the type, i. e. the class, must be specified. The `#` character - instead of the class name -
+means that the type (`TYPE REF TO ...`) can be derived from the context (in this case from the type of the reference variable). You can
+also omit the explicit declaration of a reference variable by declaring a new reference variable
+[inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm),
+for example, using `DATA`. In this case, the name of the class must be placed after `NEW` and before the first parenthesis.
+ - No parameter specified within the parentheses: No values are
+ passed to the instance constructor of an object. However, non-optional input parameters of the
+ instance constructor of the instantiated class must be filled.
+ No parameters are passed for a class without an explicitly declared
+ instance constructor. See more information:
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennew_constructor_params_class.htm).
+- The operator
+ basically replaces the syntax [`CREATE OBJECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcreate_object.htm) you might stumble on.
+
+``` abap
+"Declaring object reference variable
+DATA: ref1 TYPE REF TO some_class.
+
+"Creating objects
+ref1 = NEW #( ). "Type derived from already declared ref1
+
+DATA(ref2) = NEW some_class( ). "Reference variable declared inline, explicit type
+ "(class) specification
+
+"Old syntax. Do not use.
+"CREATE OBJECT ref3. "Type derived from already declared ref3
+"CREATE OBJECT ref4 TYPE some_class. "Corresponds to the result of the expression above
+```
+
+
+
+### Assigning Reference Variables
+To assign or copy
+reference variables, use the [assignment
+operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
+`=`. In the example below, both object reference variables have the same
+type.
+
+``` abap
+DATA: ref1 TYPE REF TO some_class,
+ ref2 TYPE REF TO some_class.
+
+ref1 = NEW #( ).
+
+"Assigning existing reference
+ref2 = ref1.
+```
+
+More examples for dealing with object reference variables:
+
+**Overwriting reference variables**: An [object
+reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_reference_glosry.htm "Glossary Entry")
+is overwritten when a new object is created with a reference variable
+already pointing to an instance.
+``` abap
+ref1 = NEW #( ).
+
+"Existing reference is overwritten
+ref1 = NEW #( ).
+```
+
+**Retaining object references**:
+- If your use case is to retain the object references, for example, if you create multiple objects using the same object reference variable, you can put the reference variables in internal tables that are declared using `... TYPE TABLE OF REF TO ...`.
+- The following code snippet just visualizes that the object references are not overwritten. Three objects are created with the same reference variable. The internal table includes all object references and, thus, their values are retained.
+``` abap
+DATA: ref TYPE REF TO some_class,
+ itab TYPE TABLE OF REF TO some_class.
+
+DO 3 TIMES.
+ ref = NEW #( ).
+ itab = VALUE #( BASE itab ( ref ) ). "Adding the reference to itab
+ENDDO.
+```
+
+**Clearing object references**: You can use
+[`CLEAR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclear.htm)
+statements to explicitly clear a reference variable.
+```abap
+CLEAR ref.
+```
+
+> **💡 Note**
+> Objects use up space in the memory and should therefore be
+cleared if they are no longer needed. However, the [garbage collector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengarbage_collector_glosry.htm "Glossary Entry") is called periodically and automatically by the [ABAP runtime framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm "Glossary Entry") and clears all objects without any reference.
+
+
+
+### Accessing Attributes
+- Instance attributes: Accessed using
+the [object component selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_component_select_glosry.htm "Glossary Entry")
+`->` via a reference variable.
+- Static attributes: Accessed (if the attributes are visible) using the [class component
+selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_component_select_glosry.htm "Glossary Entry")
+`=>` via the class name. You can also declare data objects and
+types by referring to static attributes.
+``` abap
+"Accessing instance attribute via an object reference variable
+
+... ref->some_attribute ...
+
+"Accessing static attributes via the class name
+
+... some_class=>static_attribute ...
+
+"Without the class name only within the class itself
+... static_attribute ...
+
+"Type and data object declarations
+
+TYPES some_type LIKE some_class=>some_static_attribute.
+DATA dobj1 TYPE some_class=>some_type.
+DATA dobj2 LIKE some_class=>some_static_attribute.
+```
+
+
+
+### Calling Methods
+- Similar to accessing attributes, instance
+methods are called using `->` via a reference variable.
+- Static
+methods are called using `=>` via the class name. When used
+within the class in which it is declared, the static method can also be
+called without `class_name=>...`.
+- When methods are called, the (non-optional) parameters must be specified within parentheses.
+- You might also stumble on method calls with [`CALL METHOD`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcall_method_static.htm)
+statements. These statements should no longer be used. Note that `CALL METHOD` statements are the only option in the context of [dynamic programming](06_Dynamic_Programming.md). Therefore, `CALL METHOD` statements should be reserved for dynamic method calls.
+
+
+Examples for instance method calls and static method calls:
+``` abap
+"Calling instance methods via reference variable;
+"within the parentheses, the parameters must be specified and assigned - if required
+
+ref->inst_meth( ... ).
+
+"Calling static methods via/without the class name
+
+class_name=>stat_meth( ... ).
+
+"Only within the program in which it is declared.
+stat_meth( ... ).
+
+"Calling (static) method having no parameter
+
+class_name=>stat_meth( ).
+
+"Calling (static) methods having a single importing parameter:
+
+"Note that in the method call, the caller exports values to the
+"method having importing parameters defined; hence, the addition
+"EXPORTING is relevant for the caller. The following three method calls are the same
+
+"Explicit use of EXPORTING.
+class_name=>meth( EXPORTING a = b ).
+
+"Only importing parameters in the method signature: explicit EXPORTING not needed
+
+class_name=>meth( a = b ).
+
+"If only a single value must be passed:
+"the formal parameter name (a) and EXPORTING not needed
+
+stat_meth( b ).
+
+"Calling (static) methods having importing/exporting parameters
+"Parameters must be specified if they are not marked as optional
+
+class_name=>meth( EXPORTING a = b c = d "a/c: importing parameters in the method signature
+ IMPORTING e = f ). "e: exporting parameter in the method signature
+
+"To store the value of the parameter, you may also declare it inline.
+
+class_name=>meth( EXPORTING a = b c = d
+ IMPORTING e = DATA(z) ).
+
+"Calling (static) methods having a changing parameter;
+"should be reserved for changing an existing local variable and value
+
+DATA h TYPE i VALUE 123.
+class_name=>meth( CHANGING g = h ).
+
+"Calling (static) methods having a returning parameter.
+"Basically, they do the same as methods with exporting parameters
+"but they are way more versatile, and you can save lines of code.
+
+"They do not need temporary variables.
+"In the example, the return value is stored in a variable declared inline.
+
+"i and k are importing parameters
+DATA(result) = class_name=>meth( i = j k = l ).
+
+"They can be used with other statements, e. g. logical expressions.
+"In the example below, the assumption is that the returning parameter is of type i.
+IF class_name=>meth( i = j k = l ) > 100.
+ ...
+ENDIF.
+
+"They enable method chaining.
+"The example shows a method to create random integer values.
+"The methods have a returning parameter.
+DATA(random_no) = cl_abap_random_int=>create( )->get_next( ).
+
+"RECEIVING parameter: Available in methods defined with a returning parameter;
+"used in standalone method calls only.
+"In the snippet, m is the returning parameter; n stores the result.
+class_name=>meth( EXPORTING i = j k = l RECEIVING m = DATA(n) ).
+```
+
+
+
+### Method Chaining
+
+As shown in the previous example, method chaining is possible for functional method calls (i.e. methods that have exactly one return value declared with `RETURNING`) at appropriate read positions. In this case, the method's return value is used as an ABAP operand.
+A chained method call can consist of multiple functional methods that are linked using component selectors `->`. The return values of each method are references to the next method.
+
+```abap
+"The following example demonstrates method chaining
+"The following class creates random integers. Find more information in the
+"class documentation.
+"Both methods have returning parameters specified.
+DATA(some_int1) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
+ min = 1
+ max = 10 )->get_next( ).
+
+"Getting to the result as above - not using method chaining and inline declarations.
+DATA some_int2 TYPE i.
+DATA dref TYPE REF TO cl_abap_random_int.
+
+dref = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
+ min = 1
+ max = 10 ).
+
+some_int2 = dref->get_next( ).
+
+"Using the RECEIVING parameter in a standalone method call
+DATA some_int3 TYPE i.
+dref->get_next( RECEIVING value = some_int3 ).
+
+"IF statement that uses the return value in a read position
+IF cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
+ min = 1
+ max = 10 )->get_next( ) < 5.
+ ... "The random number is lower than 5.
+ELSE.
+ ... "The random number is greater than 5.
+ENDIF.
+
+"Examples using classes of the XCO library (see more information in the
+"ABAP for Cloud Development and Misc ABAP Classes cheat sheets), in which
+"multiple chained method calls can be specified. Each of the methods
+"has a returning parameter specified.
+
+"In the following example, 1 hour is added to the current time.
+DATA(add1hour) = xco_cp=>sy->time( xco_cp_time=>time_zone->user )->add( iv_hour = 1 )->as( xco_cp_time=>format->iso_8601_extended )->value.
+
+"In the following example, a string is converted to xstring using a codepage
+DATA(xstr) = xco_cp=>string( `Some string` )->as_xstring( xco_cp_character=>code_page->utf_8 )->value.
+
+"In the following example, JSON data is created. First, a JSON data builder
+"is created. Then, using different methods, JSON data is added. Finally,
+"the JSON data is turned to a string.
+DATA(json) = xco_cp_json=>data->builder( )->begin_object(
+ )->add_member( 'CarrierId' )->add_string( 'DL'
+ )->add_member( 'ConnectionId' )->add_string( '1984'
+ )->add_member( 'CityFrom' )->add_string( 'San Francisco'
+ )->add_member( 'CityTo' )->add_string( 'New York'
+ )->end_object( )->get_data( )->to_string( ).
+```
+
+
+
+### Self-Reference me
+
+When implementing instance methods, you can optionally make use of the implicitly available object reference variable [`me`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenme.htm) which is always available at runtime and points to the respective object itself. You can use it to refer to components of the instance of a particular class:
+``` abap
+... some_method( ... ) ...
+
+... me->some_method( ... ) ...
+```
+
+The following code snippet shows a method implementation. In this case, a local data object from within the method and an instance attribute that is declared in the declaration part of the class in which this method is implemented have identical names. `me` is used to access the non-local data object.
+
+``` abap
+METHOD me_ref.
+
+ DATA str TYPE string VALUE `Local string`.
+
+ DATA(local_string) = str.
+
+ "Assuming there is a variable str declared in the class declaration part.
+ DATA(other_string) = me->str.
+
+ENDMETHOD.
+```
+
+
+
+## Notes on Inheritance
+
+- Concept: Deriving a new class (i. e.
+ [subclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubclass_glosry.htm "Glossary Entry"))
+ from an existing one
+ ([superclass](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensuperclass_glosry.htm "Glossary Entry")).
+- In doing so, you create a hierarchical relationship between superclasses and subclasses
+ (an [inheritance hierarchy](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_hierarchy_glosry.htm "Glossary Entry")) to form an [inheritance
+ tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_tree_glosry.htm "Glossary Entry"). This is relevant for a class that can have multiple subclasses and one direct superclass.
+- Subclasses ...
+ - inherit and thus adopt all components from superclasses.
+ - can be made more specific by declaring new components and
+ redefining instance methods (i. e. you can alter the implementation of inherited methods). In case a subclass has no further components, it contains exactly the components of the superclass - but the ones of the private visibility section are not visible there.
+ - can redefine the public and protected instance methods of all preceding superclasses. Note: Regarding the static components of superclasses, accessing them is possible but not redefining them.
+ - can themselves have multiple direct subclasses but only one direct superclass.
+- Components that are changed or added to subclasses are not visible to superclasses, hence, these changes are only relevant for the class itself and its subclasses.
+- Classes can rule out derivation: classes cannot inherit from classes that are specified with the addition
+ [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_abstract_final.htm#!ABAP_ADDITION_2@2@)
+ (e. g. `CLASS global_class DEFINITION PUBLIC FINAL CREATE PUBLIC. ...`).
+
+
+
+**Excursion: Additions `ABSTRACT` and `FINAL`**
+- Both classes and methods can be defined with the additions `ABSTRACT` and `FINAL`.
+- `FINAL` with ...:
+ - Classes: These classes cannot be inherited. All methods are automatically and implicitly `FINAL`. In this case, the addition `FINAL` cannot be used for methods.
+ - Methods: These methods cannot be redefined in subclasses.
+- `ABSTRACT` with ...:
+ - Classes: Defines abstract classes. You cannot create an instance of an abstract class. To use instance components of an abstract class, you must create an instance of a subclass of such classes.
+ - Methods: Defines abstract methods. The addition is only allowed in abstract classes (and not for private methods). These methods cannot be implemented in the implementation part of the class where they are declared. They must be redefined in subclasses. Note that you can also have non-abstract methods in abstract classes.
+- See [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_options.htm) more information on class options.
+
+``` abap
+"Declaration of an abstract method of an abstract superclass
+"and its implementation in a concrete subclass.
+CLASS cls1 DEFINITION ABSTRACT.
+ PROTECTED SECTION.
+ METHODS meth ABSTRACT.
+ENDCLASS.
+
+CLASS cls2 DEFINITION INHERITING FROM cls1.
+ PROTECTED SECTION.
+ METHODS meth REDEFINITION.
+ENDCLASS.
+
+CLASS cls2 IMPLEMENTATION.
+ METHOD meth.
+ ...
+ ENDMETHOD.
+ENDCLASS.
+```
+
+
+
+**Redefining Methods**
+
+- Redefining methods is possible for the public and protected instance (not the static) methods of all preceding superclasses in a subclass (but only if the methods are not specified with `FINAL`).
+- In the declaration part of the subclass, you must specify the method as follows (and using the same method name):
+ `METHODS meth REDEFINITION.`
+- This must be done in the same
+ visibility section of the subclass as in the superclass.
+- You cannot change the parameters of the method.
+- Redefined methods work with private attributes of the subclass and cannot access private attributes of the superclass with the same name.
+- If you want to access the identically named method implementation in a superclass from within
+ the method implementation of the subclass, use the [pseudo
+ reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpseudo_reference_glosry.htm "Glossary Entry")
+ [`super->meth`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcall_method_meth_super.htm).
+
+> **💡 Note**
+> Inheritance and constructors:
+> - Constructors cannot be redefined.
+> - If the instance constructor is implemented in a subclass, the instance constructor of the superclass must be called explicitly using `super->constructor`, even if the latter is not explicitly declared. An exception to this: Direct subclasses of the root node `OBJECT`.
+> - Regarding the static constructor: When calling a subclass for the first time, the preceding static constructors of all of the entire inheritance tree must have been called first.
+> - More information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninheritance_constructors.htm).
+
+
+
+## Notes on Polymorphism and Casting
+
+The object orientation concept
+[polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry")
+means you can address differently implemented methods belonging to different objects of different classes using one and the
+same reference variable, for example,
+object reference variables pointing to a superclass can point to objects of a subclass.
+
+Note the concept of static and dynamic type in this context:
+
+- Object reference variables (and also interface reference variables) have both a
+ [static](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatic_type_glosry.htm "Glossary Entry")
+ and a [dynamic
+ type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_type_glosry.htm "Glossary Entry").
+- When declaring an object reference variable, e. g. `DATA oref TYPE REF TO cl`, you determine the static type, i. e.
+ `cl` - a class - is used to declare the reference variable that is statically defined in the code. This is the class of an object to which the reference variable points to.
+- Similarly, the dynamic type also defines the class of an object which the reference variable points to. However, the dynamic type is determined at runtime, i. e. the class of an object which the reference variable points to can change.
+- Relevant for? This differentiation enters the picture in polymorphism when a reference variable typed with reference to a subclass can always be assigned to reference variables typed with reference to one of its superclasses or their interfaces. That's what is called [upcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenup_cast_glosry.htm "Glossary Entry") (or widening cast). Or the assignment is done the other way round. That's what is called [downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry") (or narrowing cast).
+
+> **✔️ Hints**
+> - The following basic rule applies: The static type is always more general than or the same as the dynamic type. The other way round: The dynamic type is always more special than or equal to the static type.
+>- That means:
+> - If the static type is a class, the dynamic type must be the same class or one of its subclasses.
+> - If the static type is an interface, the dynamic type must implement the interface.
+
+- Regarding assignments: If it can be statically checked that an assignment is possible
+ although the types are different, the assignment is done using the
+ [assignment
+ operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry")
+ `=` that triggers an upcast automatically.
+- Otherwise, it is a
+ [downcast](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendown_cast_glosry.htm "Glossary Entry").
+ Here, the assignability is not checked until runtime. The downcast - in contrast to upcasts -
+ must be triggered explicitly using the [casting
+ operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencasting_operator_glosry.htm "Glossary Entry")
+ [`CAST`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_cast.htm). You might see code using the older
+ operator [`?=`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove_cast.htm).
+- See more information in the topic [Assignment Rules for Reference
+ Variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconversion_references.htm).
+
+As an example, assume there is an inheritance tree with `lcl_super` as the superclass and `lcl_sub` as a direct subclass. `lcl_sub2` is a direct subclass of `lcl_sub`.
+
+In the following code snippet, the rule is met since the superclass is either the same as or more generic than the subclass (the subclass has, for example, redefined methods and is, thus, more specific). Hence, the assignment of an object reference variable pointing to the subclass to a variable pointing to a superclass works. An upcast is triggered. After this casting, the type of `oref_super` has changed and the methods of `lcl_sub` can be accessed via `oref_super`.
+
+``` abap
+"Creating object references
+DATA(oref_super) = NEW lcl_super( ).
+
+DATA(oref_sub) = NEW lcl_sub( ).
+
+"Upcast
+oref_super = oref_sub.
+
+"The casting might be done when creating the object.
+DATA super_ref TYPE REF TO lcl_super.
+
+super_ref = NEW lcl_sub( ).
+```
+
+- As mentioned above, a downcast must be triggered
+manually. Just an assignment like `oref_sub = oref_super.`
+does not work. A syntax error occurs saying the right-hand variable's type cannot be converted to the left-hand variable's type.
+- If you indeed want to carry out this casting, you must use
+`CAST` (or you might see code using the older operator `?=`) to overcome this syntax error (but just the syntax error!). Note: You might also use these casting operators for the upcasts. That means `oref_super = oref_sub.` has the same effect as `oref_super = CAST #( oref_sub ).`. Using the casting operator for upcasts is usually not necessary.
+- At runtime, the assignment is checked and if the conversion does not work, you face a (catchable) exception. Even more so, the assignment `oref_sub = CAST #( oref_super ).` does not throw a syntax error but it does not work in this example either because it violates the rule mentioned above (`oref_sub` is more specific than `oref_super`).
+- To check whether such an assignment is possible
+on specific classes, you can use the predicate expression [`IS INSTANCE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_instance_of.htm)
+or the case distinction [`CASE TYPE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase_type.htm). Carrying out an upcast before the downcast ensures that the left-hand variable's type is compatible to the right-hand variable's type.
+
+``` abap
+DATA(oref_super) = NEW lcl_super( ).
+DATA(oref_sub) = NEW lcl_sub( ).
+DATA(oref_sub2) = NEW lcl_sub2( ).
+
+"Downcast impossible (oref_sub is more specific than oref_super);
+"the exception is caught here
+
+TRY.
+ oref_sub = CAST #( oref_super ).
+ CATCH CX_SY_MOVE_CAST_ERROR INTO DATA(e).
+ ...
+ENDTRY.
+
+"Working downcast with a prior upcast
+
+oref_super = oref_sub2.
+
+"Due to the prior upcast, the following check is actually not necessary.
+
+IF oref_super IS INSTANCE OF lcl_sub.
+ oref_sub = CAST #( oref_super ).
+ ...
+ENDIF.
+
+"Excursion RTTI: Downcasts, CAST and method chaining
+"Downcasts particularly play, for example, a role in the context of
+"retrieving type information using RTTI. Method chaining is handy
+"because it reduces the lines of code in this case.
+"The example below shows the retrieval of type information
+"regarding the components of a structure.
+"Due to the method chaining in the second example, the three
+"statements in the first example are reduced to one statement.
+
+DATA struct4cast TYPE zdemo_abap_carr.
+
+DATA(rtti_a) = cl_abap_typedescr=>describe_by_data( struct4cast ).
+DATA(rtti_b) = CAST cl_abap_structdescr( rtti_a ).
+DATA(rtti_c) = rtti_b->components.
+
+DATA(rtti_d) = CAST cl_abap_structdescr(
+ cl_abap_typedescr=>describe_by_data( struct4cast )
+ )->components.
+```
+
+
+
+## Notes on Interfaces
+
+Interfaces ...
+
+- represent a template for the components in the public visibility
+ section of classes.
+- enhance classes by adding interface components.
+- are possible as both
+ [local](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlocal_interface_glosry.htm "Glossary Entry")
+ and [global
+ interfaces](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_interface_glosry.htm "Glossary Entry").
+- support
+ [polymorphism](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpolymorphism_glosry.htm "Glossary Entry") in classes. Each class that implements an interface can implement its methods differently. [Interface reference variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_ref_variable_glosry.htm "Glossary Entry") can point to objects of all classes that implement the associated interface.
+- can be implemented by classes of an inheritance tree. It can be any number of interfaces. However, each interface can be implemented only once in an inheritance tree.
+- are different from classes in the following ways:
+ - They only consist of a part declaring the components without an
+ implementation part. The implementation is done in classes that use the interface.
+ - There are no visibility sections. All components of an interface are visible.
+ - No instances can be created from interfaces.
+ - Declarations as mentioned for classes, e. g. `DATA`,
+ `CLASS-DATA`, `METHODS`,
+ `CLASS-METHODS`, are possible. Constructors are not
+ possible.
+
+
+
+Defining interfaces:
+- Can be done either globally in the repository or locally in an ABAP program.
+
+``` abap
+INTERFACE intf.
+"The addition PUBLIC is for global interfaces:
+"INTERFACE intf_g PUBLIC.
+
+ DATA ...
+ CLASS-DATA ...
+ METHODS ...
+ CLASS-METHODS ...
+
+ENDINTERFACE.
+```
+
+Implementing interfaces:
+- A class can implement multiple interfaces.
+- Interfaces must be specified in the
+ declaration part of a class using the statement
+ [`INTERFACES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces.htm).
+- Since all interface components are public, you must include this
+ statement and the interfaces in the public visibility section of a class. When an interface is implemented in a class, all interface components are added to the other components of the class in the public visibility section.
+- Interface components can be addressed using the [interface component
+ selector](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninterface_comp_selector_glosry.htm "Glossary Entry"): `... intf~comp ...`.
+- You can specify alias names for the interface components using the statement [`ALIASES ... FOR ...`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapaliases.htm). The components can then be addressed using the alias name.
+- The class must implement the methods of all implemented interfaces in it unless the methods are flagged as abstract or final. You can adapt some interface components to requirements of your class.
+ - You can specify the additions [`ABSTRACT METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS ABSTRACT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of
+ classes. In this case, the class(es) need not
+ implement the methods of the interface. The implementation is then relevant for a subclass inheriting from a superclass that includes
+ such an interface declaration. Note that the whole class must be abstract.
+ - The additions [`FINAL METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of classes flag the method(s) as final.
+- In the interface, methods can mark their implementation as optional using the additions [`DEFAULT
+ IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm)
+ or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm).
+
+
+Syntax for using interfaces in classes:
+``` abap
+CLASS class DEFINITION.
+ PUBLIC SECTION.
+ "Multiple interface implementations possible
+ INTERFACES intf.
+ ALIASES meth_alias FOR intf~some_method.
+ENDCLASS.
+
+CLASS class IMPLEMENTATION.
+ METHOD intf~some_meth. "Method implementation using the original name
+ ...
+ ENDMETHOD.
+
+ "Just for demo purposes: Method implementation using the alias name
+ "METHOD meth_alias.
+ " ...
+ "ENDMETHOD.
+
+ ...
+ENDCLASS.
+
+"Abstract class
+CLASS cl_super DEFINITION ABSTRACT.
+ PUBLIC SECTION.
+ INTERFACES intf ALL METHODS ABSTRACT.
+ ALIASES:
+ meth1 FOR intf~meth1,
+ meth2 FOR intf~meth2.
+ENDCLASS.
+
+"Subclass inheriting from abstract class and implementing interface methods
+CLASS cl_sub DEFINITION INHERITING FROM cl_super.
+ PUBLIC SECTION.
+ METHODS:
+ meth1 REDEFINITION,
+ meth2 REDEFINITION.
+ENDCLASS.
+
+CLASS cl_sub IMPLEMENTATION.
+ METHOD meth1.
+ ...
+ ENDMETHOD.
+ METHOD meth2.
+ ...
+ ENDMETHOD.
+ENDCLASS.
+```
+
+Interface reference variables and accessing objects:
+- As mentioned above, addressing an object happens via an object reference variable with reference to a class.
+- An interface variable can contain references to objects of classes that implement the corresponding interface.
+- You create an interface reference variable like this: `DATA i_ref TYPE REF TO intf.`
+
+Addressing interface components:
+- Addressing instance components using interface reference variable
+ - attribute: `i_ref->attr`
+ - instance method: `i_ref->meth( )`
+- Addressing instance components using an object reference variable (Note: The type is a class that implements the interface) is also possible but it's not the recommended way:
+ - attribute: `cl_ref->intf~attr`
+ - instance method: `cl_ref->intf~meth`
+- Addressing static components:
+ - static attribute: `class=>intf~attr`,
+ - static method: `class=>intf~meth( )`
+ - constant: `intf=>const`
+
+
+``` abap
+"Addressing instance interface components using interface reference variable
+DATA i_ref TYPE REF TO intf.
+
+DATA cl_ref TYPE REF TO class.
+
+"Creating an instance of a class that implements the interface intf
+cl_ref = NEW #( ).
+
+"If the class class implements an interface intf,
+"the class reference variable cl_ref can be assigned
+"to the interface reference variable i_ref.
+"The reference in i_ref then points to the same object
+"as the reference in cl_ref.
+i_ref = cl_ref.
+
+"Can also be done directly, i. e. directly creating an object to which the interface reference variable points
+i_ref = NEW class( ).
+
+"Instance interface method via interface reference variable
+... i_ref->inst_method( ... ) ...
+
+"Instance interface attribute via interface reference variable
+... i_ref->inst_attr ...
+
+"Addressing instance components using the class reference variable
+"is also possible but it's not the recommended way.
+... cl_ref->intf~inst_method( ... ) ...
+... cl_ref->intf~inst_attr ...
+
+"Addressing static interface components
+"class=> can be dropped if the method is called in the same class that implements the interface
+... class=>intf~stat_method( ... ) ...
+... class=>intf~stat_attr ...
+
+"Just for the record: Static interface components can be called via reference variables, too.
+... i_ref->stat_method( ... ) ...
+... i_ref->stat_attr ...
+... cl_ref->intf~stat_method( ... ) ...
+
+"Constants
+"A constant can be addressed using the options mentioned above.
+"Plus, it can be addressed using the following pattern
+... intf=>const ...
+```
+
+
+
+## Excursions
+
+### Friendship
+
+- The concept of friendship enters the picture if your use case for your classes is to work together very closely. This is true, for example, for [unit
+tests](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunit_test_glosry.htm "Glossary Entry") if you want to test private methods.
+- Classes can grant access to invisible components for their [friends](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfriend_glosry.htm "Glossary Entry").
+- The friends can be other classes and interfaces. In case of interfaces, friendship is granted to all classes that implement the interface.
+- Impact of friendship:
+ - Access is granted to all components, regardless of the visibility section or the addition `READ-ONLY`.
+ - Friends of a class can create instances of the class without restrictions.
+ - Friendship is a one-way street, i. e. a class granting friendship to another class is not granded friendship the other way round. If class `a` grants friendship to class `b`, class `b` must also explicitly grant friendship to class `a` so that `a` can access the invisible components of class `b`.
+ - Friendship and inheritance: Heirs of friends and interfaces that contain a friend as a component interface also become friends. However, granting friendship is not inherited, i. e. a friend of a superclass is not automatically a friend of its subclasses.
+
+
+You specify the befriended class in the definition part using a `FRIENDS` addition:
+``` abap
+"For local classes. Friendship can be granted to all classes/interfaces
+"of the same program and the class library.
+"Multiple classes can be specified as friends.
+CLASS lo_class DEFINITION FRIENDS other_class ... .
+...
+
+CLASS lo_class DEFINITION CREATE PRIVATE FRIENDS other_class ... .
+
+"Addition GLOBAL only allowed for global classes, i. e. if the addition PUBLIC is also used
+"Other global classes and interfaces from the class library can be specified after GLOBAL FRIENDS.
+CLASS global_class DEFINITION CREATE PUBLIC FRIENDS other_global_class ... .
+```
+
+
+
+### Events
+
+- [Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_glosry.htm "Glossary Entry")
+can trigger the processing of [processing blocks](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocessing_block_glosry.htm "Glossary Entry").
+- Declaring events: Can be declared in a visibility section of the declaration part of a class or in an interface, e. g. as
+ - instance event using an [`EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapevents.htm) statement. Note that they can only be raised in instance methods of the same class.
+ - static event using [`CLASS-EVENTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass-events.htm). They can be raised in all methods of the same class or of a class that implements the interface. Static event handlers can be called by the event independently of an instance of the class.
+
+``` abap
+"Declaration part of a class/interface
+"Instance events
+EVENTS: i_evt1,
+
+"Events can only have output parameters that are passed by value
+ i_evt2 EXPORTING VALUE(num) TYPE i ...
+...
+"Static events
+CLASS-EVENTS: st_evt1,
+ st_evt2 EXPORTING VALUE(num) TYPE i ...
+
+```
+
+- Event handlers:
+ - An event is raised by a [`RAISE EVENT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_event.htm) statement in another method or in the same method.
+ - Raising an event means that [event handlers](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenevent_handler_glosry.htm "Glossary Entry") are called.
+ - This event handler must be declared with the following syntax (see more information and more additions [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_event_handler.htm)):
+
+``` abap
+"Event handlers for instance events
+METHODS: handler_meth1 FOR EVENT i_evt1 OF some_class,
+
+ "Parameter names must be the same as declared;
+ "no further additions possible for the parameter (e.g. TYPE);
+ "the predefined, implicit parameter sender as another formal parameter is possible with instance events,
+ "it is typed as a reference variable, which itself has the class/interface as a static type,
+ "If the event handler is called by an instance event, it is passed a reference to the raising object in sender.
+ handler_meth2 FOR EVENT i_evt2 OF some_class IMPORTING num sender,
+...
+```
+
+- To make sure that an event handler handles a raised event, it must be registered with the statement [`SET HANDLER`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapset_handler.htm). See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapset_handler.htm) (for example, events can also be deregistered).
+
+```abap
+"Registering event for a specific instance
+SET HANDLER handler1 FOR ref.
+
+"Registering event for all instances
+SET HANDLER handler2 FOR ALL INSTANCES.
+
+"Registering static event for the whole class/interface
+SET HANDLER handler3.
+"Note that multiple handler methods can be specified.
+```
+
+
+
+### Factory Methods and Singletons as Design Patterns
+
+In object-oriented programming, there a plenty of design patterns. Covering these ones here to get a rough idea: factory methods and singletons. Both are relevant if you want to restrict or control the instantiation of a class by external users of this class.
+
+A singleton is a design pattern in which it is only up to the class to create objects. In doing so, the class ensures that only one object exists for every internal session that is made available to consumers.
+
+The following code snippet shows an implementation of the singleton design pattern. The `get_instance` method is used to return the object reference to the object created. Only one instance can be created.
+
+```abap
+"Using the addition CREATE PRIVATE, objects can only be created by the class itself.
+CLASS singleton_class DEFINITION CREATE PRIVATE.
+ PUBLIC SECTION.
+ CLASS-METHODS get_instance RETURNING VALUE(ret) TYPE REF TO singleton_class.
+
+ PRIVATE SECTION.
+ CLASS-DATA inst TYPE REF TO singleton_class.
+ENDCLASS.
+
+CLASS singleton_class IMPLEMENTATION.
+ METHOD get_instance.
+ IF inst IS NOT BOUND.
+ inst = NEW #( ).
+ ENDIF.
+ ret = inst.
+ ENDMETHOD.
+ENDCLASS.
+```
+
+Controlling the creation of objects - the instantiation of a class - can be realized using a factory method. For example, certain checks might be required before a class can be instantiated. If a check is not successful, the instantiation is denied.
+You might create a (static) factory method as follows:
+- A check is carried out in the factory method, for example, by evaluating importing parameters.
+- If the check is successful, an object of the class is created.
+- The method signature includes an output parameter that returns an object reference to the caller.
+
+This is rudimentarily demonstrated in the following snippet:
+
+``` abap
+CLASS class DEFINITION CREATE PRIVATE.
+ PUBLIC SECTION.
+ CLASS-METHODS
+ factory_method IMPORTING par ...,
+ RETURNING VALUE(obj) TYPE REF TO class.
+ ...
+ENDCLASS.
+
+CLASS class IMPLEMENTATION.
+ METHOD factory_method.
+ IF par = ...
+ obj = NEW class( ).
+ ELSE.
+ ...
+ ENDIF.
+
+ ENDMETHOD.
+ ...
+ENDCLASS.
+...
+
+"Calling a factory method.
+DATA obj_factory TYPE REF TO class.
+
+obj_factory = class=>factory_method( par = ... ).
+```
+
+
+
+## More Information
+You can check the subtopics of
+
+- [ABAP Objects - Overview](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_objects_oview.htm)
+- [Programming Guidlines - Object-Oriented Programming (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenobj_oriented_gdl.htm)
+
+in the ABAP Keyword Documentation.
+
+## Executable Example
+[zcl_demo_abap_objects](./src/zcl_demo_abap_objects.clas.abap)
+
+> **💡 Note**
+> - The executable example covers the following topics, among others:
+> - Working with objects and components
+> - Redefining methods, inheritance
+> - Working with interfaces
+> - Upcast and downcast
+> - Concepts such as factory methods, singleton and abstract classes
+> - Events
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
diff --git a/07_String_Processing.md b/07_String_Processing.md
index a43b173..36719da 100644
--- a/07_String_Processing.md
+++ b/07_String_Processing.md
@@ -1,2006 +1,2168 @@
-
-
-# String Processing
-
-- [String Processing](#string-processing)
- - [Introduction](#introduction)
- - [Data Types for Character Strings](#data-types-for-character-strings)
- - [Declaring Character-Like Data Objects](#declaring-character-like-data-objects)
- - [Assigning Values](#assigning-values)
- - [String Templates](#string-templates)
- - [Determining the Length of Strings](#determining-the-length-of-strings)
- - [Concatenating Strings](#concatenating-strings)
- - [Splitting Strings](#splitting-strings)
- - [Modifying Strings](#modifying-strings)
- - [Processing Substrings](#processing-substrings)
- - [Searching and Replacing](#searching-and-replacing)
- - [Searching for Specific Characters](#searching-for-specific-characters)
- - [Replacing Specific Characters in Strings](#replacing-specific-characters-in-strings)
- - [Searching for Substrings in Strings (and Tables)](#searching-for-substrings-in-strings-and-tables)
- - [Replacing Substrings in Strings (and Tables)](#replacing-substrings-in-strings-and-tables)
- - [Pattern-Based Searching and Replacing in Strings](#pattern-based-searching-and-replacing-in-strings)
- - [Simple Pattern-Based Searching Using Comparison Operators](#simple-pattern-based-searching-using-comparison-operators)
- - [Complex Searching and Replacing Using Regular Expressions](#complex-searching-and-replacing-using-regular-expressions)
- - [Excursion: Common Regular Expressions](#excursion-common-regular-expressions)
- - [Searching Using Regular Expressions](#searching-using-regular-expressions)
- - [Excursion: System Classes for Regular Expressions](#excursion-system-classes-for-regular-expressions)
- - [Replacing Using Regular Expressions](#replacing-using-regular-expressions)
- - [More String Functions](#more-string-functions)
- - [Checking the Similarity of Strings](#checking-the-similarity-of-strings)
- - [Repeating Strings](#repeating-strings)
- - [Returning the Smallest/Biggest of a Set of Character-Like Arguments](#returning-the-smallestbiggest-of-a-set-of-character-like-arguments)
- - [Escaping Special Characters](#escaping-special-characters)
- - [Excursion: String Processing Using the XCO Library](#excursion-string-processing-using-the-xco-library)
- - [Executable Example](#executable-example)
-
-
-## Introduction
-
-ABAP offers plenty of options for processing [character strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencharacter_string_glosry.htm "Glossary Entry").
-The options include ABAP statements (e. g. [`FIND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)),
-[character string expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_expression_glosry.htm "Glossary Entry")
-([concatenations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_glosry.htm) and [string templates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_template_glosry.htm "Glossary Entry"))
-and built-in [string functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_function_glosry.htm "Glossary Entry")
-(e. g. [`strlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm)).
-
-> **💡 Note**
->- Compared to statements, expressions and string functions can help make your ABAP code more
- concise and straightforward. For example, you can perform string operations directly in [operand
- position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry"),
- allowing you to avoid temporary variables.
->- In ABAP statements, modification operations on strings are often performed in read/write positions, meaning that the source and target
- fields of an operation are the same. When working with string functions, the source field is passed as an input parameter and the modified value is returned as a [return value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreturn_value_glosry.htm "Glossary Entry"), meaning that the function itself does not modify the source field. Of course, you can assign the function to the source field to achieve its modification.
->- In most cases, string functions provide the same functionality as the
- corresponding ABAP statements, or even more. The return value of string functions
- that return character strings is always of type `string`.
-
-
-
-## Data Types for Character Strings
-
-ABAP provides the following built-in data types for data objects that contain character strings. They are distinguished as follows:
-
-| Type | Details | Length | Value Range | Initial Value |
-|---|---|---|---|---|
-| `string` | For variable length character strings. [Data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm "Glossary Entry") of this type are [dynamic data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_data_object_glosry.htm "Glossary Entry"), i. e. the length of a variable can change during the execution of an ABAP program and thus it can contain character strings of different lengths. A data object of type `string` is called *text string* or, in short, just *string*. | No standard length; length is variable | Any [Unicode](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunicode_glosry.htm) characters that can be encoded in ABAP language's code page [UCS-2](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenucs2_glosry.htm). The most common content are alphanumeric characters or special characters. | Empty string with length 0 |
-| `c` | For fixed length character strings. Data objects of this type are [static data objects](http://ldcialx.wdf.sap.corp:50018/sap/public/bc/abap/docu?sap-language=EN&object=abenstatic_data_object_glosry&version=X&sap-client=000), i. e. the length of a variable must be defined during its declaration and does not change during the execution of an ABAP program. Thus, it always contains character strings of the same length. A data object of type `c` is called *text field*.|Data objects of this type can contain a string of fixed length (between 1 and 262143 characters); standard length: 1 | Same as for `string` | A blank for each position |
-
-In addition to these main data types for character strings, there are several other fixed length data types with special meanings:
-
-- `n` for fixed length numerical character strings
- - Data objects of this type are technically almost the same as text fields. However, the only valid characters are the digits 0 to 9. Validity is not checked for assigning values in a regular way but only for [lossless assignments](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlossless_assignment_glosry.htm). Thus, such numeric text fields can contain invalid data, but should only be used for digits that are not intended for arithmetic calculations, such as zip codes or article numbers. The initial value for each position is 0.
-- `d` and `t` for date and time fields
- - These data types have a predefiend length of 6 and 8. Data objects of these types are used for character representations of dates and times in a predefined format. You can use them directly in date and time calculations. However, these fields can also contain invalid values.
-
-These data types are not covered further in this cheat sheet. The same is true for the [byte-like data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_like_data_typ_glosry.htm "Glossary Entry") `x` and `xstring` that are closely related to `c` and `string` but contain raw [byte strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_string_glosry.htm).
-
-> **⚡ Differences between text strings (variable length) and text fields (fixed length)**
->- **Initial value**: The initial value of a text string is an
- empty string of length 0. The initial value of text field is represented by blanks at each position.
->- **Internal representation**: Data objects of type `c` and `string` are both [elementary data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_object_glosry.htm "Glossary Entry").
- However, while text fields occupy a block of memory according to their length, text strings are so-called [deep](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_glosry.htm "Glossary Entry") data objects. Internally, they are managed by a [reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry") that points to the actual character. This fact has restrictive consequences for the use of strings as components of structures, but can also improve the performance of assignments due to the concept of [sharing](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensharing_glosry.htm "Glossary Entry") of deep data objects.
->- **Length**: Theoretically, a text string can use up to 2 GB (one character occupies 2 bytes).
- The maximum length of a text field is 262143 characters.
->- **Trailing blanks**: For text strings, trailing blanks are preserved in all operations. For text fields, it depends on the [operand
- position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry") whether trailing blanks are respected or not. In most operand positions, trailing blanks are truncated when working with text fields, even when using [text field literals](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentext_field_literal_glosry.htm). For example, if a text field is assigned to a text string, the resulting target string will never contain trailing blanks. See the *Condensing Strings* section in this context.
->- **Flexibility**: Text strings are more flexible than text fields
- because you can easily shorten or lengthen them without
- worrying that, for example, parts of the character string will be
- truncated during processing. On the other hand, when accessing substrings of a string, you have to make sure that the string is long enough, whereas with text fields you always know their length.
-
-So, when to use what? Text fields are useful when
-actually specifying a maximum or mandatory length, e.g. a country code
-that must be a maximum of two characters, or for input fields in
-forms that should not exceed a certain length. If limiting a string
-is not relevant, text strings are a good choice.
-
-
-
-## Declaring Character-Like Data Objects
-
-- To work with character strings, you need character-like data objects based on the character-like types mentioned above.
-- The simplest way of producing text in an ABAP program are [character literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencharacter_literal_glosry.htm).
-The following code snippet shows a global class implementing the interface `if_oo_adt_classrun`.
- - Using the `write` method, you can display output in the ADT console. In the example, two [untyped literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuntyped_literal_glosry.htm) without a dedicated name ([unnamed data object](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunnamed_data_object_glosry.htm)) are included.
- - In the case below, the data type of the character literals are defined by the delimiters.
-- Text string literals are enclosed in backquotes (\`...\`) and have the data type `string`.
-- Text field literals are enclosed in single quotes (`'...'`) and have the data type `c`.
-- The literals can be (but should not according to the [programming guidelines on literals (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenliterals_guidl.htm)) used like constants of these types in [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm). They should be only used for start values when declaring [named data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm).
-
-```abap
-CLASS zcl_some_test_class DEFINITION PUBLIC FINAL CREATE PUBLIC.
- PUBLIC SECTION.
- INTERFACES if_oo_adt_classrun.
-ENDCLASS.
-
-CLASS zcl_some_test_class IMPLEMENTATION.
- METHOD if_oo_adt_classrun~main.
- out->write( `I am a text string literal` ). "text string literal of type string
- out->write( 'I am a text field literal' ). "text field literal of type c
- ENDMETHOD.
-ENDCLASS.
-```
-
-- [Named](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm) character-like data types and objects can be declared like other types and objects using [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm), [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) [`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm) and by referring to a character-like data type.
-- In addition, character-like data objects can be declared inline with the operators `DATA` and [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm).
-
-Syntax examples:
-``` abap
-"Type declarations using built-in types
-
-TYPES: c_type TYPE c LENGTH 3, "Explicit length specification
- str_type TYPE string.
-
-"Data object declarations using built-in, local and DDIC types
-
-DATA: flag TYPE c LENGTH 1, "Built-in type
- str1 TYPE string, "Built-in type
- char1 TYPE c_type, "Local type
- str2 LIKE str1, "Deriving type from a local data object
- str3 TYPE str_type, "Local type
- char2 TYPE s_toairp, "DDIC type (used e. g. for a field in a demo table)
- char3 TYPE zdemo_abap_flsch-carrid. "Using the type of a DDIC table component
-
-"You may also encounter declarations with type c and the length
-"specified in parentheses. This is not recommended, to avoid confusion
-"with the use of parentheses in dynamic programming.
-
-DATA char(4) TYPE c.
-
-"Just a TYPE c specification without length means LENGTH 1.
-DATA char_len_one TYPE c.
-"No type and length specification: TYPE c LENGTH 1 by default
-DATA char_no_type_len.
-```
-
-
-
-## Assigning Values
-
-- When you declare character-like data objects, you can specify start values directly with the `VALUE` addition, e.g. `DATA chars TYPE c LENGTH 3 VALUE 'abc'.`.
-- You can do value assignments to data objects using the the [assignment operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry") `=`.
-- As mentioned above, you can declare character-like data objects inline using the operators `DATA` or `FINAL`.
-- You can use the operators at many [write positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwrite_position_glosry.htm "Glossary Entry").
-- Unlike the `VALUE` addition of the declaration statements, inline declarations allow you to declare variables for the results of expressions or at other positions where character strings are returned.
-- In the case below, a variable specified in parentheses preceded by `DATA` (or `FINAL`) on the left side of the assignment operator automatically derives a data type from the operand on the right. This helps to make your
-programs leaner.
-
-Syntax examples:
-``` abap
-"Data object declarations including default values with VALUE
-"Note the chained statement: DATA followed by a colon, listing the data object declarations,
-"separated by a comma.
-DATA: flag TYPE c LENGTH 1 VALUE 'X',
- str1 TYPE string VALUE `Hallo!`.
-
-"Examples for type n
-DATA zip_code TYPE n LENGTH 5 VALUE '12345'.
-DATA isbn_number TYPE n LENGTH 13 VALUE '1234567890123'.
-
-"Constant; content cannot be changed at runtime
-CONSTANTS pi TYPE p LENGTH 8 DECIMALS 14 VALUE '3.14159265358979'.
-
-"More data object declarations
-DATA: char1 TYPE c LENGTH 5,
- html TYPE string,
- str2 LIKE html.
-
-"Value assignments
-char1 = 'ab123'.
-html = `
hallo
`.
-
-"Escaping backquotes in text string literals with another one
-str1 = `This is a backquote: ``.`.
-
-"If possible, avoid unnecessary type conversion; in principle, every
-"convertible type can be specified
-str2 = 'abc'. "Fixed length string assigned to data object of type string
-DATA str3 TYPE string VALUE 'X'. "type c length 1
-DATA str4 TYPE string VALUE -1. "type i
-
-"Inline declarations
-DATA(char2) = 'abcd'. "Type c length 4
-DATA(str5) = `efgh`.
-
-"You can use FINAL to create immutable variables.
-FINAL(final_string) = `zyx`.
-
-"Since char2 is of type c length 4 (the length is also derived),
-"characters are truncated in the following example assignment
-char2 = 'ijklmnopq'. "ijkl
-
-"Trailing blanks after assigning fixed length to variable length string
-DATA(char3) = 'ab '.
-DATA(str6) = `cdefgh`.
-str6 = char3. "'ab' (trailing blanks are not respected due to conversion rule)
-```
-
-- When assigning strings, not only data objects can be placed on the right
-side. Various expressions and strings can be concatenated using the
-[concatenation
-operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_operator_glosry.htm "Glossary Entry")
-`&&`.
-- Alternatively, you can concatenate strings using [string
-templates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_template_glosry.htm "Glossary Entry"), as described in the *Concatenating Strings* section.
-``` abap
-str5 = str3 && ` ` && str4 && `!`. "X 1-!
-"Note the output for str4 that includes the conversion of type i to
-"string above demonstrating a possibly inadvertent specification
-"of an integer value for str4 that is of type string.
-```
-
-Note that there is also the [literal
-operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator_glosry.htm "Glossary Entry")
-`&` that joins [text string
-literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentext_string_literal_glosry.htm "Glossary Entry"),
-however, with [significant
-differences](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator.htm)
-to `&&`.
-
-
-
-## String Templates
-- Using string templates, you can construct strings very elegantly from
-literal text and - which is the primary use case - by including
-embedded ABAP
-[expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexpression_glosry.htm "Glossary Entry")
-within a pair of delimiters (`|...|`) if these expressions can be converted to `string`.
-- To embed expressions, you enclose them in curly brackets: `{ ... }`.
-
-> **💡 Note**
-> String templates form a [string
-expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_expression_glosry.htm "Glossary Entry")
-that is compiled at runtime. Therefore, a string template that contains only
-literal text is treated as an expression, which has a performance impact. In such a case, it is preferable to use a text string literal with backquotes.
-
-Syntax examples:
-``` abap
-"Value assignment with string templates
-"The expression must be convertible to a string. A blank (not within the curly brackets)
-"means a blank in the resulting string.
-DATA(s1) = |Hallo { cl_abap_context_info=>get_user_technical_name( ) }!|.
-
-DATA(s2) = `How are you?`. "Literal text only with backquotes
-DATA(s3) = |{ s1 } { s2 }|. "Hallo NAME! How are you?
-
-"Chaining of string templates using &&
-DATA(s4) = |{ s1 }| && ` ` && |{ s2 }|. "Hallo NAME! How are you?
-```
-
-- String templates interpret certain character combinations as [control
-characters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_templates_separators.htm).
-- For example, `\n` is interpreted as a newline. A new line is
-started.
-- String templates also support various [formatting
-options](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcompute_string_format_options.htm).
-- Refer to the ABAP Keyword Documentation for all options.
-
-The following syntax examples demonstrate a selection:
-```abap
-"Control characters
-s4 = |{ s1 }\n{ s2 }\nSee you.|. "\n is interpreted as a line feed
-
-"Excursion: Class CL_ABAP_CHAR_UTILITIES provides attributes and methods as utilities for string processing.
-"See the class documentation
-"The following examples demonstrate that attributes that contain control characters can be replaced by
-"a representation of control characters in a string template.
-ASSERT cl_abap_char_utilities=>newline = |\n|.
-ASSERT cl_abap_char_utilities=>horizontal_tab = |\t|.
-ASSERT cl_abap_char_utilities=>cr_lf = |\r\n|.
-
-"Various formatting options
-"DATE: Defining the format of a date
-"The output is just an example and depends on your settings.
-DATA(d) = |The date is { cl_abap_context_info=>get_system_date( ) DATE = USER }.|. "The date is 01/01/2024.
-d = |{ cl_abap_context_info=>get_system_date( ) DATE = RAW }|. "20240101
-d = |{ cl_abap_context_info=>get_system_date( ) DATE = ISO }|. "2024-01-01
-d = |{ cl_abap_context_info=>get_system_date( ) DATE = ENVIRONMENT }|. "01/01/2024
-
-"TIME: Defining the format of a time
-"The output is just an example and depends on your settings.
-DATA(tm) = |The time is { cl_abap_context_info=>get_system_time( ) TIME = ISO }.|. "The time is 14:37:24.
-tm = |{ cl_abap_context_info=>get_system_time( ) TIME = RAW }|. "143724
-tm = |{ cl_abap_context_info=>get_system_time( ) TIME = USER }|. "14:37:24
-tm = |{ cl_abap_context_info=>get_system_time( ) TIME = ENVIRONMENT }|. "14:37:24
-
-"TIMESTAMP: Defining the format of a time stamp
-"The output is just an example and depends on your settings.
-DATA(ts) = |{ utclong_current( ) TIMESTAMP = SPACE }|. "2024-01-01 14:39:50.4069170
-ts = |{ utclong_current( ) TIMESTAMP = ISO }|. "2024-01-01T14:39:50,4071110
-ts = |{ utclong_current( ) TIMESTAMP = USER }|. "01/01/2024 14:39:50.4072010
-ts = |{ utclong_current( ) TIMESTAMP = ENVIRONMENT }|. "01/01/2024 14:39:50.4073230
-ts = |{ utclong_current( ) }|. "2024-01-01 14:39:50.4074060
-
-"TIMEZONE: Defining the format of a time stamp using the rules for time zones
-DATA(tz) = |{ utclong_current( ) TIMEZONE = 'UTC' }|. "2024-12-30 14:43:20.6534640
-tz = |{ utclong_current( ) TIMEZONE = 'CET' COUNTRY = 'DE ' }|. "30.12.2024 15:43:20,6536320
-tz = |{ utclong_current( ) TIMEZONE = 'EST' COUNTRY = 'US ' }|. "12/30/2024 09:43:20.6889180 AM
-
-"CASE: Lowercase and uppercase
-s1 = |AbCdEfG|.
-s2 = |{ s1 CASE = LOWER }|. "abcdefg
-s2 = |{ s1 CASE = UPPER }|. "ABCDEFG
-
-"WIDTH/ALIGN
-s1 = `##`.
-s2 = |{ s1 WIDTH = 10 ALIGN = LEFT }<---|. "'## <---'
-s2 = |{ s1 WIDTH = 10 ALIGN = CENTER }<---|. "' ## <---'
-
-"PAD: Used to pad any surplus places in the result with the specified character.
-s2 = |{ s1 WIDTH = 10 ALIGN = RIGHT PAD = `.` }<---|. "'........##<---'
-
-"DECIMALS
-s1 = |{ CONV decfloat34( - 1 / 3 ) DECIMALS = 3 }|. "'-0.333'
-
-"SIGN: Defining the format of the +/- sign when the string represented
-"by the embedded expression represents a numeric value
-"- left without space, no +
-s1 = |{ +1 SIGN = LEFT }|. "1
-"- and + left without space
-s1 = |{ 1 SIGN = LEFTPLUS }|. "+1
-"- left without space, blank left for +
-s1 = |{ 1 SIGN = LEFTSPACE }|. " 1
-"- right without space, no +
-s1 = |{ -1 SIGN = RIGHT }|. "1-
-"- and + right without space
-s1 = |{ 1 SIGN = RIGHTPLUS }|. "1+
-"- left without space, blank right for +
-s1 = |{ +1 SIGN = RIGHTSPACE }|. "1
-
-"ZERO: Defining the format of the numeric value zero.
-"Only to be specified if the embedded expression has a numeric data type.
-s1 = |'{ 0 ZERO = NO }' and '{ 0 ZERO = YES }'|. "'' and '0'
-
-"XSD: Formatting is applied to an embedded expression (elementary data types) in asXML format that is
-"assigned to its data type. Check the information in the ABAP Keyword Documentation about the asXML
-"mapping of elementary ABAP types.
-DATA xstr TYPE xstring VALUE `41424150`.
-DATA dat type d value '20240101'.
-DATA tim type t value '123456'.
-DATA(utc) = utclong_current( ). "e.g. 2024-01-01 13:51:38.5708800
-
-s1 = |{ xstr XSD = YES }|. "QUJBUA==
-s1 = |{ dat XSD = YES }|. "2024-01-01
-s1 = |{ tim XSD = YES }|. "12:34:56
-s1 = |{ utc XSD = YES }|. "2024-01-01T13:51:38.57088Z
-
-"STYLE: Defining the style of decimal floating point numbers;
-"see the details in the ABAP Keyword Documentation.
-DATA(dcfl34) = CONV decfloat34( '-123.45600' ).
-s1 = |{ dcfl34 }|. "-123.456
-"Creates the predefined format
-s1 = |{ dcfl34 STYLE = SIMPLE }|. "-123.456
-"+/- added to the right, removes trailing zeros
-s1 = |{ dcfl34 STYLE = SIGN_AS_POSTFIX }|. "123.456-
-"Retains trailing zeros
-s1 = |{ dcfl34 STYLE = SCALE_PRESERVING }|. "-123.45600
-"Scientific notation; at least a two digit exponent with a plus/minus sign
-s1 = |{ dcfl34 STYLE = SCIENTIFIC }|. "-1.23456E+02
-"Scientific notation; only one integer digit with the value 0
-s1 = |{ dcfl34 STYLE = SCIENTIFIC_WITH_LEADING_ZERO }|. "-0.123456E+03
-"Scientific notation; exponent has 3 digits for decfloat16 and 4 digits for decfloat34
-s1 = |{ dcfl34 STYLE = SCALE_PRESERVING_SCIENTIFIC }|. "-1.2345600E+0002
-"Technical format
-s1 = |{ dcfl34 STYLE = ENGINEERING }|. "-123.456E+00
-
-"ALPHA: Adds or removes leading zeros from strings of digits; the data type
-"must be string, c, or n
-"Adding leading zeros
-"Additionally specifying WIDTH
-"Note: The specified length is only used if it is greater than
-"the length of provided string (without leading zeros)
-s1 = |{ '1234' ALPHA = IN WIDTH = 10 }|. "0000001234
-s1 = |{ '00000000000000000000000012' ALPHA = IN WIDTH = 10 }|. "0000000012
-"Fixed-length string provided, WIDTH not specified
-s1 = |{ ' 12' ALPHA = IN }|. "00012
-"Removing leading zeros
-s1 = |{ '00001234' ALPHA = OUT }|. "1234
-"Do not apply formatting
-s1 = |{ '00001234' ALPHA = RAW }|. "00001234
-```
-
-> **💡 Note**
-> Escape `\|{}` in string templates using `\`, i. e. `\\` means `\`.
-
-
-
-## Determining the Length of Strings
-
-- To determine the length of a string, you can use the string function
-[`strlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm).
-- Note that the result depends on the type of the string, i. e. the result for a data object of type `string` includes trailing blanks. A
-fixed-length string does not include them.
-- To exclude trailing blanks in all cases, regardless of the data type, you can use the built-in
-[`numofchar`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm) function.
-
-Syntax examples:
-``` abap
-"strlen
-DATA(len_c) = strlen( 'abc ' ). "3
-DATA(len_str) = strlen( `abc ` ). "6
-
-"numofchar
-len_c = numofchar( 'abc ' ). "3
-len_str = numofchar( `abc ` ). "3
-```
-
-
-
-## Concatenating Strings
-
-- Two or more strings can be concatenated using the concatenation operator
-`&&` and string templates. Alternatively, you can use
-[`CONCATENATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconcatenate.htm)
-statements.
-- It is also possible to concatenate lines from internal tables
-into a string to avoid a loop.
-- A more modern way is to use
-the string function
-[`concat_lines_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_functions.htm).
-
-Syntax examples:
-``` abap
-"&& and string template
-DATA(s1) = `AB` && `AP`. "ABAP
-DATA(s2) = `ab` && `ap` && ` ` && s1. "abap ABAP
-DATA(s3) = |{ s1 }. { s2 }!|. "ABAP. abap ABAP!
-
-"CONCATENATE statements
-CONCATENATE s1 s2 INTO s3. "ABAPabap ABAP
-
-"Multiple data objects and target declared inline
-CONCATENATE s1 ` ` s2 INTO DATA(s5). "ABAP abap ABAP
-
-CONCATENATE s1 s2 s5 INTO DATA(s6). "ABAPabap ABAPABAP abap ABAP
-
-"You can also add a separation sign using the addition SEPARATED BY
-CONCATENATE s1 s2 INTO s3 SEPARATED BY ` `. "ABAP abap ABAP
-
-CONCATENATE s1 s2 INTO s3 SEPARATED BY `#`. "ABAP#abap ABAP
-
-"Keeping trailing blanks in the result when concatenating fixed length
-"strings. The ones of variable length strings are respected by default.
-CONCATENATE 'a ' 'b ' 'c ' INTO DATA(ch) RESPECTING BLANKS. "'a b c '
-
-"Concatenating lines of internal tables into a string
-CONCATENATE LINES OF itab INTO t SEPARATED BY ` `.
-
-"Using concat_lines_of
-s1 = concat_lines_of( table = itab ). "Without separator
-s1 = concat_lines_of( table = itab sep = ` ` ). "With separator
-```
-
-
-
-## Splitting Strings
-
-- You can use
-[`SPLIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsplit.htm)
-statements to split strings in multiple segments.
-- The result of the
-split can be stored in separate data objects or internal tables that
-have a character-like line type.
-- Note that if the number of specified targets is
-less than the number of segments returned by the split, the last target receives the remaining unsplit segements. If more targets are specified, the targets that do not receive a segment are
-initialized.
-- Therefore, specifying individual targets with `SPLIT`
-statements is useful if the number of expected segments is known.
-Otherwise, splitting into tables is a good choice.
-- If you want to get the value of a particular segment, you can use the
-string function
-[`segment`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensegment_functions.htm).
-
-Syntax examples:
-``` abap
-DATA(s1) = `Hallo,world,123`.
-DATA: s2 TYPE string,
- s3 TYPE string,
- s4 TYPE string.
-
-SPLIT s1 AT `,` INTO s2 s3 s4. "s2 = Hallo / s3 = world / s4 = 123
-
-"Less data objects than possible splittings
-SPLIT s1 AT `,` INTO s2 s3. "s2 = Hallo / s3 = world,123
-
-"Splitting into internal table
-DATA itab TYPE TABLE OF string.
-SPLIT s1 AT ',' INTO TABLE itab. "Strings are added to itab in individual lines without comma
-
-"String function segment returning the occurrence of a segment
-"index parameter: number of segment
-s2 = segment( val = s1 index = 2 sep = `,` ). "world
-```
-
-
-
-## Modifying Strings
-**Transforming to Lowercase and Uppercase**
-
-- The string functions
-[`to_lower`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm)
-and
-[`to_upper`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm)
-transform characters of a string to either lowercase or uppercase and
-store the result in a target variable.
-- If you want to apply the transformation to the source directly, you can use
-[`TRANSLATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptranslate.htm)
-statements.
-
-Syntax examples:
-``` abap
-"String functions
-DATA(s1) = to_upper( `abap` ). "ABAP
-s1 = to_lower( `SOME_FILE.Txt` ). "some_file.txt
-
-"TRANSLATE statements
-s1 = `Hallo`.
-TRANSLATE s1 TO UPPER CASE. "HALLO
-TRANSLATE s1 TO LOWER CASE. "hallo
-```
-
-**Shifting Content**
-
-- You can shift content within a string to a specific position on the left
-or right of a string.
-[`SHIFT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapshift.htm)
-statements have various additions for specific use cases.
-- In a more modern way, you can use the string functions
-[`shift_left`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm)
-and
-[`shift_right`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm), which store the result in a variable.
- - These functions provide additional
-functionality. The `sub` parameter can be used to specify a
-substring. All substrings in the string that match the value specified
-in `sub` on either the left or right side of the string are
-removed.
-
-Syntax examples:
-``` abap
-"SHIFT statements
-"Note that all results below refer to s1 = `hallo`.
-DATA(s1) = `hallo`. "Type string
-
-SHIFT s1. "No addition; string shifted one place to the left: allo
-SHIFT s1 BY 2 PLACES. "Without direction, left by default: llo
-SHIFT s1 BY 3 PLACES RIGHT. "With direction, variable length strings are extended: ' hallo'
-
-"Note that all results below refer to ch4 = 'hallo'.
-DATA(ch4) = 'hallo'. "Type c length 5
-
-SHIFT ch4 BY 3 PLACES RIGHT. "Fixed length string: ' ha'
-
-"CIRCULAR addition: characters that are moved out of the string are
-"added at the other end again
-SHIFT ch4 BY 3 PLACES LEFT CIRCULAR. "lohal
-SHIFT ch4 UP TO `ll`. "Shift characters up to a specific character set: llo
-
-"Deleting leading and trailing characters
-DATA(s2) = ` hallo `.
-DATA(s3) = s2.
-
-SHIFT s2 LEFT DELETING LEADING ` `. "'hallo '
-SHIFT s3 RIGHT DELETING TRAILING ` `. "' hallo' (length is kept)
-
-"Removing trailing blanks in strings without leading blanks;
-"you can use the following sequence of statements
-DATA(s4) = `hallo `.
-SHIFT s4 RIGHT DELETING TRAILING ` `. "' hallo'
-SHIFT s4 LEFT DELETING LEADING ` `. "'hallo'
-
-"String functions with parameters
-s1 = `hallo`.
-
-s2 = shift_left( val = s1 places = 3 ). "lo
-s2 = shift_left( val = s1 circular = 2 ). "lloha
-
-"Note that shift_right does not extend a variable length string.
-s2 = shift_right( val = s1 places = 3 ). "ha
-s2 = shift_right( val = `abc ` sub = ` ` ). "'abc'
-s2 = shift_right( val = `abc ` ). "'abc' (same result as above)
-```
-
-**Condensing Strings**
-
-- You can use
-[`CONDENSE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcondense.htm)
-statements or the string function
-[`condense`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencondense_functions.htm)
-to remove blanks from strings.
-- The advantage of using the string function
-is that you can specify any character to remove, not just blanks.
-
-Syntax examples:
-``` abap
-"CONDENSE statements
-DATA(s1) = ` ab cd `.
-DATA(s2) = ` ef gh ij `.
-DATA(s3) = ` kl mn op `.
-
-CONDENSE s1. "Trailing and leading blanks are removed: 'ab cd'
-CONDENSE s2. "It also replaces sequences of multiple blanks with a single blank: 'ef gh ij'
-CONDENSE s3 NO-GAPS. "Removes all blanks: 'klmnop'
-
-"String function condense
-s1 = ` ab cd `.
-
-"No parameters specified, i. e. their default values are provided.
-"Works like CONDENSE statement without the NO-GAPS addition.
-s2 = condense( s1 ). "ab cd
-
-"Parameters del/to not specified. from parameter with initial string
-"(could also be a text field literal: from = ' '). This way, leading and
-"trailing blanks are removed.
-s2 = condense( val = s1 from = `` ). "ab cd
-
-"Parameter to specified with an initial string. No other parameters.
-"Works like CONDENSE statement with the NO-GAPS addition.
-s2 = condense( val = s1 to = `` ). "abcd
-
-"Parameter del specifies the leading/trailing characters to be removed.
-s2 = condense( val = `##see###you##` del = `#` ). "see###you
-
-"If from and to are specified along with del, leading/trailing
-"characters specified in del are first removed. Then, in the remaining string, all
-"substrings composed of characters specified in from are replaced with
-"the first character of the string specified in the to parameter
-s2 = condense( val = ` Rock'xxx'Roller`
- del = `re `
- from = `x`
- to = `n` ). "Rock'n'Roll
-```
-
-**Reversing Strings**
-
-The string function
-[`reverse`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreverse_functions.htm)
-reverses a string:
-``` abap
-"Result: 'abap'
-DATA(s1) = reverse( `paba` ).
-```
-
-**Inserting Substrings into Strings**
-
-- The string function
-[`insert`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninsert_functions.htm)
-inserts a substring at any position within a given string. You can use various parameters to construct the string you want:
- - `val`: Original string.
- - `sub`: Substring.
- - `off`: Optionally sets the offset, i.e. the position where the substring should be added. The default value is 0. When using the function with the default value, the result is like concatenating a string with `&&` (like `res = sub && text`).
-- Inserting substrings can also be accomplished using the string function `replace` or `REPLACE` statements, which are are covered below.
-
-Syntax examples:
-``` abap
-"Result: 'abcdefghi'
-DATA(s1) = insert( val = `abcghi` sub = `def` off = 3 ).
-
-"Result: 'defabcghi'
-s1 = insert( val = `abcghi` sub = `def` ).
-```
-
-**Overlaying Content**
-
-You can use [`OVERLAY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapoverlay.htm) statements to replace characters in one variable with characters in another variable that are in the same place there.
-
-Syntax examples:
-``` abap
-DATA(incl) = '==============================CP'.
-DATA(cl_name) = 'CL_SOME_CLASS '.
-
-"Addition ONLY is not specified: All blanks are replaced
-OVERLAY cl_name WITH incl.
-"cl_name: CL_SOME_CLASS=================CP
-
-DATA(txt1) = 'a.b.c.a.b.c.A'.
-DATA(txt2) = 'z.x.y.Z.x.y.z'.
-
-"Addition ONLY is specified: All characters that are specified after ONLY and that
-"occur in the operand are replaced. Note that this is case-sensitive.
-OVERLAY txt1 WITH txt2 ONLY 'ab'.
-"txt1: z.x.c.Z.x.c.A
-```
-
-
-
-## Processing Substrings
-
-- The string function
-[`substring`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm) allows you to specify the position (parameter `off`) and the length
-(`len`) of a substring to be extracted from a given
-string (`val`).
- - At least one of the two parameters `off`
-or `len` must be specified. The default value of `off`
-is 0, i.e. when using the default value, the substring is extracted
-from the beginning of the string.
- - If `len` is not specified, the rest of the remaining characters are respected. If the offset
-and length are greater than the actual length of the string, the
-exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised.
-- You may also encounter the syntax for accessing substrings by specifying the offset
-and length using the `+` character after a variable.
- - The length is specified in parentheses. Specifying an asterisk (`*`) means
-that the rest of the remaining string is respected.
- - This syntax option
-even allows write access to substrings for fixed-length strings. Read
-access is possible for both fixed-length and variable-length strings.
- - However, this syntax can be confused with the use of tokens in the
-context of dynamic programming.
-- There are other string functions available for dealing with substrings, such as
-[`substring_after`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm),
-[`substring_before`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm),
-[`substring_from`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm)
-and
-[`substring_to`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm).
- - These functions offer more options in terms of parameters, such as the use of [PCRE regular
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry"),
-which are covered below.
-
-Syntax examples:
-``` abap
-DATA(s1) = `Lorem ipsum dolor sit amet`. "Type string
-
-"Extracting substring starting at a specific position
-"'len' not specified means the rest of the remaining characters are
-"respected
-DATA(s2) = substring( val = s1 off = 6 ). "ipsum dolor sit amet
-
-"Extracting substring with a specific length
-"'off' is not specified and has the default value 0.
-s2 = substring( val = s1 len = 5 ). "Lorem
-
-"Specifying both off and len parameters
-s2 = substring( val = s1 off = 6 len = 5 ). "ipsum
-
-DATA(txt) = 'Lorem ipsum dolor sit amet'. "Type c
-
-"Offset and length specification using the + sign after a variable
-DATA(ch6) = txt+0(5). "Lorem
-
-"* means respecting the rest of the remaining string
-DATA(ch7) = txt+12(*). "dolor sit amet
-
-CLEAR txt+11(*). "Lorem ipsum
-
-txt+0(5) = 'Hallo'. "Hallo ipsum dolor sit amet
-
-"Further string functions
-s1 = `aa1bb2aa3bb4`.
-
-"Extracting a substring ...
-"... after a specified substring
-s2 = substring_after( val = s1 sub = `aa` ). "1bb2aa3bb4 (only the first occurrence is respected)
-
-"... after a specified substring specifying the occurence in a string
-"and restricting the length
-s2 = substring_after( val = s1 sub = `aA` occ = 2 len = 4 case = abap_false ). "3bb4
-
-"... before a specified substring
-s2 = substring_before( val = s1 sub = `b2` ). "aa1b
-
-"... from a specified substring on. It includes the substring specified
-"in sub. len/off and other parameters are possible.
-s2 = substring_from( val = s1 sub = `a3` ). "a3bb4
-
-"... up to a specified substring. It includes the substring specified
-"in sub. len/off and other parameters are possible.
-s2 = substring_to( val = s1 sub = `3b` ). "aa1bb2aa3b
-```
-
-
-
-## Searching and Replacing
-
-- In ABAP, there are many ways to perform search and replace
-operations on strings. These include the use of [comparison
-operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
-or the ABAP statements
-[`FIND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)
-and
-[`REPLACE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace.htm),
-or the more modern built-in string functions
-[`find`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
-and
-[`replace`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreplace_functions.htm),
-among others, with their considerable number of additions and parameters.
-- Many of these options support rather simple operations
-on single characters only or more complex, pattern-based
-operations on character sequences using [PCRE regular
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry").
-
-
-
-### Searching for Specific Characters
-
-- You can use the [comparison
- operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
- [`CA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains any) or its negation
- [`NA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains not any) in [comparison
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry")
- to determine whether any character of a given character set is contained
- in a string. Such an expression is true if at least one character is
- found.
- - The search is case-sensitive.
- - The system variable `sy-fdpos` contains the offset of
- the first character found. If nothing is found,
- `sy-fdpos` contains the length of the string.
- - Note that offset 0 represents the very first position.
-- The string functions
- [`find_any_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
- and its negation
- [`find_any_not_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
- return the offset of the occurrence of any character contained in a
- substring. They are special variants of the string function `find`, which is shown below.
- - If nothing is found, the value -1 is returned.
- - Other optional parameters are possible. For example, the
- specification of `occ` determines the search
- direction, i.e. a positive value means that the search is performed
- from left to right. A negative value means to search from right
- to left.
-- If you are not interested in the position of characters, but rather how
- often they occur in a string, you can use the string function
- [`count`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencount_functions.htm), as well as the special variants `count_any_of` and its negation `count_any_not_of`.
-- To determine whether a string contains only a certain set of characters,
- you can use the comparison operators
- [`CO`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains only) or its negation
- [`CN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains not only) in comparison expressions.
- - For `CO`, a comparison is true if the left operand
- contains only characters that are also contained in the right
- operand. If the comparison returns false, you can use `sy-fdpos` to get the position
- of the first character from text that is not contained in the
- character.
- - For `CN`, a
- comparison is true if a string contains characters other than those in the character set.
-
-Syntax examples:
-``` abap
-DATA(s1) = `cheers`.
-IF s1 CA `aeiou` ... "true, sy-fdpos = 2
-IF s1 NA `xyz`... "true, sy-fdpos = 6
-
-IF s1 CO `rs` ... "false, sy-fdpos = 0
-IF s1 CN `cheers` ... "false, sy-fdpos = 6
-```
-
-Built-in functions:
-
-``` abap
-"Note that the functions may contain more parameters than those covered in the snippet.
-DATA(str) = `Pieces of cakes.`.
-DATA res TYPE i.
-
-"find_end returns the sum of the offset of the occurrence
-res = find_end( val = str sub = `of` ). "9
-
-"find_any_of returns the offset of the occurrence of any character contained in substring
-"The search is always case-sensitive.
-res = find_any_of( val = str sub = `x523z4e` ). "2 (character e is found)
-res = find_any_of( val = str sub = `zwq85t` ). "-1
-
-"find_any_not_of: Negation of the one above
-"The search is always case-sensitive.
-res = find_any_not_of( val = str sub = `ieces` ). "0 (very first character in the searched string)
-res = find_any_not_of( val = str sub = `P` ). "1
-
-"count returns the number of all occurrences
-res = count( val = str sub = `e` ). "3
-res = count( val = str sub = `x` ). "0
-
-"count_any_of
-res = count_any_of( val = str sub = `x523z4e` ). "3
-res = count_any_of( val = str sub = `eco` ). "6
-
-"count_any_not_of
-res = count_any_not_of( val = str sub = `fP` ). "14
-res = count_any_not_of( val = str sub = `Piecs ofak.` ). "0
-```
-
-
-
-
-### Replacing Specific Characters in Strings
-
-- You can use the string function
-[`translate`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentranslate_functions.htm)
-to replace certain characters with others.
- - The
-`from` parameter specifies the characters to be placed in a string, and
-the `to` parameter specifies the target characters.
- - Note: The
-replacement is performed as follows: Each character specified in
-`from` is replaced by the character in `to` that is at
-the same position, i.e. the second character in `from` is
-replaced by the second character specified in `to`. If there is
-no equivalent in `to`, the character in `from` is
-removed from the result.
-- You can use
-[`TRANSLATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptranslate.htm)
-statements to perform replacements directly on the source field.
-
-Syntax examples:
-``` abap
-DATA(s1) = `___abc_def_____ghi_`.
-DATA(s2) = translate( val = s1 from = `hi_` to = `##` ). "abcdefg##
-s2 = translate( val = s1 from = `_` to = `##` ). "###abc#def#####ghi#
-
-"TRANSLATE statement. The value after USING is interpreted as a string composed of character pairs.
-"Starting with the first pair, a search is performed in text for the
-"first character in every pair and each occurrence is replaced with the
-"second character of the pair.
-TRANSLATE s1 USING `_.a#g+`. "...#bc.def.....+hi.
-```
-
-
-
-### Searching for Substrings in Strings (and Tables)
-
-- For simple substring searches, you can use the [comparison
- operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
- [`CS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains string) or its negation
- [`NS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
- (contains no string) in [comparison
- expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry").
- The search is not case-sensitive.
-- The system variable
- `sy-fdpos` contains the offset of the found substring. If
- the substring is not found, `sy-fdpos` contains the length
- of the searched string.
-
-``` abap
-DATA(s3) = `cheers`.
-
-IF s3 CS `rs` ... "true, sy-fdpos = 4 (offset)
-
-IF s3 CS `xy`... "false, sy-fdpos = 6 (length of string)
-
-IF s3 NS `ee`... "false, sy-fdpos = 2 (offset)
-
-IF s3 NS `xy`... "true, sy-fdpos = 6 (length of string)
-```
-
-For more complex and iterative searches, you may want to use `FIND` statements or the string functions below.
-
-- `FIND`
- - Used to search for a character sequence.
- - Has a rich set of additions, a selection of which is covered in this cheat sheet. See [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm) for more information. Byte string processing is not included (there are special additions).
- - Sets the system fields `sy-subrc`: 0 (search pattern found at least once) or 4 (search pattern not found).
-
-Syntax Overview (see the syntax diagram in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)):
-
-``` abap
-FIND
- FIRST OCCURRENCE OF "(or) ALL OCCURRENCES OF
- "1. Only the first occurrence is searched
- "2. All occurrences are searched
- "Note: If none of these two additions is specified, only the first occurrence is searched for.
-
- SUBSTRING some_substring "(or) PCRE some_regex
- "1. Searching for exactly one string, specifying SUBSTRING is optional (e.g. for emphasis);
- " some_substring is a character-like operand; note: Trailing blanks are not ignored if it is of type string
- "2. Searching for a substring matching a regular expression; only the PCRE addition should be used;
- " some_regex = character-like operand; note: PCRE syntax is compiled in an extended mode, i.e. unescaped whitespaces
- " are ignored; if the regex is too complex, a catchable exception of the class CX_SY_REGEX_TOO_COMPLEX is raised
-
-IN
- SECTION
- OFFSET off
- LENGTH len
- OF
- "- Restricting the search to a specific section from an offset specified in off with the length len
- "- When using SECTION, at least one of the two options must be specified
- " - No OFFSET specification: offset 0 is used implicitly
- " - No LENGTH specification: search from specified offset to end of string
- " - Note: off and len are of type i; it must be a positive integer value;
- " exception: len = -1 (same effect as not using the LENGTH addition)
- "- Without the addition SECTION ... OF, the entire data object dobj is searched
-
-"Character-like data object
-dobj
-
- "Further additional options for advanced evaluation options:
- "Specifying whether the search is case-sensitive; not specified means RESEPECTING CASE by default
- RESPECTING CASE "(or) IGNORING CASE
-
- "Determining the number of sequences found, number stored in cnt that is of type i (e.g. a variable declared inline)
- "When searching for the first occurrence, the value is always 1 (not found -> 0)
- MATCH COUNT cnt
-
- "Determining position of sequences found
- "Note: off holds the position of the last occurrence when searching for all occurrences and if
- "there are multiple occurrences (not found -> 0 or the previous value of a finding is retained).
- MATCH OFFSET off
-
- "Determining the length of sequences found
- "Note: Similar to above, not finding an occurrence means 0 for len or the previous value of a finding is retained
- MATCH LENGTH len
-
- "Storing offset, length, submatches (only relevant for regular expressions) information in a table or a structure
- "tab: of type MATCH_RESULT_TAB; especially for using with ALL OCCURRENCES
- "struc: of type MATCH_RESULT; especially for using with FIRST OCCURRENCE
- "Note on submatches: table of type SUBMATCH_RESULT_TAB; holds offset and length information of substrings of occurrences
- "that are stored in subgroup registers of regular expressions; in FIND IN TABLE statements, the additional component LINE
- "is available
- RESULTS tab "(or) RESULTS struc
-
- "Storing content of subgroup register of a regular expression in character-like data objects;
- "only to be used if a regular expression pattern is specified.
- "Note: Only the last occurrence is evaluated when using ALL OCCURRENCES; the number of the operands specified should match
- "the number of subgroups specified
- SUBMATCHES sub1 sub2 ...
-.
-```
-
-Examples:
-
-``` abap
-"Note: The code snippets mainly use inline declarations.
-
-DATA(str) = `She sells seashells by the seashore.`.
-
-"Determining if a substring is found
-"Simple find statement
-FIND `se` IN str.
-
-IF sy-subrc = 0.
- "found
-ELSE.
- "not found
-ENDIF.
-
-"Addition SUBSTRING is optional
-FIND SUBSTRING `hi` IN str.
-
-IF sy-subrc = 0.
- "found
-ELSE.
- "not found
-ENDIF.
-
-"The following examples use the additions MATCH COUNT and MATCH OFFSET to determine
-"the number of occurrences and offset
-
-"Addition FIRST OCCURRENCE OF: Explicit specification to search for the first occurrence
-FIND FIRST OCCURRENCE OF `se` IN str
- MATCH COUNT DATA(cnt2) "1 (always 1 when searching and finding the first occurrence)
- MATCH OFFSET DATA(off2). "4
-
-"Omitting FIRST OCCURRENCE OF and ALL OCCURRENCES OF addition means searching for the
-"first occurrence by default; same effect as the previous statement
-FIND `se` IN str
- MATCH COUNT DATA(cnt1) "1
- MATCH OFFSET DATA(off1). "4
-
-"Addition ALL OCCURRENCES: Searching for all occurrences
-FIND ALL OCCURRENCES OF `se` IN str
- MATCH COUNT DATA(cnt3) "3
- MATCH OFFSET DATA(off3). "27 (value for the last occurrence)
-
-"Addition IN SECTION ... OF:
-"Searching in a specified section; both additions OFFSET and LENGTH are specified
-FIND ALL OCCURRENCES OF `se`
- IN SECTION OFFSET 9 LENGTH 5 OF str
- MATCH COUNT DATA(cnt4) "1
- MATCH OFFSET DATA(off4). "10
-
-"Only LENGTH specified (OFFSET is 0 by default)
-FIND ALL OCCURRENCES OF `se`
- IN SECTION LENGTH 7 OF str
- MATCH COUNT DATA(cnt5) "1
- MATCH OFFSET DATA(off5). "4
-
-"Only OFFSET specified (LENGTH: up to end of string)
-FIND ALL OCCURRENCES OF `se`
- IN SECTION OFFSET 7 OF str
- MATCH COUNT DATA(cnt6). "2
-
-"Another string to be searched
-DATA(str_abap) = `abap ABAP abap`.
-
-"Further additional options for advanced evaluation options
-
-"Specifying the case-sensitivity of the search
-"Not specifying the CASE addition means RESPECTING CASE is used by default.
-"Here, it is explicitly specified.
-FIND FIRST OCCURRENCE OF `A` IN str_abap
- MATCH OFFSET DATA(off7) "5
- RESPECTING CASE.
-
-"Making search case-insensitive
-FIND FIRST OCCURRENCE OF `A` IN str_abap
- MATCH OFFSET DATA(off8) "0
- IGNORING CASE.
-
-"MATCH LENGTH addition
-"The example uses a regular expression: Non-greedy search for
-"a substring starting with lower case a up to an upper case P
-FIND FIRST OCCURRENCE OF PCRE `a.*?P` IN str_abap
- MATCH LENGTH DATA(len8) "9
- RESPECTING CASE.
-
-"RESULTS addition
-"Example: Because of using ALL OCCURRENCES, the data object declared inline automatically
-"has the type match_result_tab
-FIND ALL OCCURRENCES OF `ab` IN str_abap
- RESULTS DATA(res9)
- IGNORING CASE.
-
-"3 entries in table res9 (tables in SUBMATCHES are initial since no regular expression is used)
-"line: always 0 (it's not a table); length: always 2 (search for concrete occurrence of `se`)
-"1. line: 0, offset: 0, length: 2, submatches: (initial)
-"2. line: 0, offset: 5, length: 2, ...
-"3. line: 0, offset: 10, length: 2, ...
-
-"Example: Because of using FIRST OCCURRENCE, the data object declared inline automatically
-"has the type match_result
-FIND FIRST OCCURRENCE OF `ab` IN str_abap
- RESULTS DATA(res10)
- IGNORING CASE.
-
-"res10: line: 0, offset: 0, length: 2, submatches: (initial)
-```
-
-You can use [`FIND ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_itab.htm) statements to search for substrings in internal tables (standard tables without secondary table keys; with character-like line type) line by line.
-
-``` abap
-DATA(str_table) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
-
-"Finding all occurrences in a table
-"Note: res_tab is of type match_result_tab
-"You can also restrict the search range in an internal table; see an example in REPLACE ... IN TABLE
-FIND ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- RESULTS DATA(res_tab)
- RESPECTING CASE.
-
-"4 entries in table res_tab (tables in SUBMATCHES are initial since no regular expression is used)
-"1. line: 1, offset: 1, length: 1, submatches: (initial)
-"2. line: 1, offset: 4, length: 1, ...
-"3. line: 2, offset: 2, length: 1, ...
-"4. line: 3, offset: 0, length: 1, ...
-
-"Finding the first occurrence in a table
-"Note: res_struc, which is declared inline here, is of type match_result
-FIND FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- RESULTS DATA(res_struc)
- RESPECTING CASE.
-
-"Entries in structure res_struc
-"line: 1, offset: 1, length: 1, submatches: (initial)
-
-"Alternative to the statement above (storing the information in individual data objects)
-FIND FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- MATCH LINE DATA(line) "1
- MATCH OFFSET DATA(off) "1
- MATCH LENGTH DATA(len) "1
- RESPECTING CASE.
-```
-
-**Built-in search functions**
-- Built-in search functions, such as `find`, are available for searching strings.
-- They return a return value of type i and contain multiple (optional) parameters.
-- `FIND` covers the same functionality and more with the many addition options.
-- For more information, see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
-
-Parameters of the `find` function:
-- `val`:
- - Character-like data object
- - Note: If a fixed length string is specified, any trailing blanks are ignored.
-- `sub`:
- - Contains what is searched for
- - A character like expression position; expects arguments with elementary types
- - Similar to above, trailing blanks are ignored in fixed length strings
-- `case`:
- - Search is case-sensitive by default
-- `occ`:
- - Specifies the occurrence of a match
- - Must be of type `i`
- - Values:
- - 1: default value, searches for the first occurrence from the left
- - any positive value: searches for the nth occurrence from the left
- - any negative value: searches for the nth occurrence from the right
- - 0: raises an exception (`CX_SY_STRG_PAR_VAL`), note: in the context of the `replace` function, 0 means replace all occurrences
- - Note: Specifying `occ` affects the default values of `off` and `len`
-- `off`:
- - Specifies the offset
- - Must be of type `i`
- - The default value is 0 (search from the beginning of the string)
- - Exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised for a negative offset specified and an offset that is longer than the searched string
-- `len`:
- - Specifies the length
- - Must be of type `i`
- - The default value is the length of the string (minus a defined offset in `off`)
- - The exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised if the offset is negative and a range is not contained in the searched string
-- `pcre`: Regular expression
-
-``` abap
-DATA(str) = `Pieces of cakes.`.
-DATA res TYPE i.
-
-"Searching for substring
-"Returns offset of substring found
-res = find( val = str sub = `ca` ). "10
-
-"Substring not found returns -1
-res = find( val = str sub = `xy` ). "-1
-
-"Actual parameter of sub must not be initial when using the find function
-TRY.
- res = find( val = str sub = `` ).
- CATCH cx_sy_strg_par_val.
- ...
-ENDTRY.
-
-"The search is case-sensitive by default
-res = find( val = str sub = `OF` ). "-1
-"Making search case-insensitive
-res = find( val = str sub = `OF` case = abap_false ). "7
-
-"Specifying occ
-res = find( val = str sub = `c` ). "3
-res = find( val = str sub = `c` occ = 2 ). "10
-res = find( val = str sub = `e` occ = -1 ). "13
-res = find( val = str sub = `e` occ = -3 ). "2
-
-"Specifying off and len
-"Specifying a subarea in which a string is searched
-res = find( val = str sub = `e` off = 5 ). "13
-res = find( val = str sub = `e` off = 5 len = 7 ). "-1
-res = find( val = str sub = `e` len = 2 ). "-1
-
-TRY.
- res = find( val = str sub = `e` off = 5 len = 15 ).
- CATCH cx_sy_range_out_of_bounds.
- ...
-ENDTRY.
-```
-
-
-
-### Replacing Substrings in Strings (and Tables)
-
-- [`REPLACE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace.htm) and [`REPLACE ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace_itab.htm) statements have a similar syntax as `FIND` and `FIND ... IN TABLE` statements. Refer to the ABAP Keyword Documentation for all possible additions. The following code snippets cover a selection.
-- `sy-subrc` is set: 0 (search pattern or section was replaced by the specified content, result was not truncated on the right), 2 (search pattern or section was replaced, result was truncated on the right), 4 (search pattern was not found).
-- `REPLACE` statements can be used to directly replace strings (including substrings, which is not possible with the string function).
-
-``` abap
-"Examples for pattern-based replacements in which data objects are searched for character strings
-"specified in a pattern and the occurrences are replaced
-
-DATA(str_original) = `abap ABAP abap`.
-DATA(str) = str_original.
-
-"Simple REPLACE statement
-"Omitting the FIRST OCCURRENCE and ALL OCCURRENCES OF additions means
-"replacing the first occurrence by default.
-REPLACE `ab` IN str WITH `##`. "##ap ABAP abap
-
-str = str_original.
-
-"Addition SUBSTRING is optional
-REPLACE SUBSTRING `ab` IN str WITH `##`. "##ap ABAP abap
-
-str = str_original.
-
-"Addition FIRST OCCURRENCE OF: Explicit specification to replace the
-"first occurrence; same effect as the statements above
-REPLACE FIRST OCCURRENCE OF `ab` IN str WITH `##`. "##ap ABAP abap
-
-str = str_original.
-
-"Addition ALL OCCURRENCES OF: All occurrences are replaced
-"Note that the replacement is case-sensitive by default.
-REPLACE ALL OCCURRENCES OF `ab` IN str WITH `##`. "##ap ABAP ##ap
-
-str = str_original.
-
-"Further additional options for advanced evaluation options
-
-"IGNORING CASE addition: Making replacements case-insensitive
-REPLACE ALL OCCURRENCES OF `ab`
- IN str WITH `##`
- IGNORING CASE. "##ap ##AP ##ap
-
-str = str_original.
-
-"REPLACEMENT COUNT addition
-REPLACE ALL OCCURRENCES OF `ab`
- IN str WITH `##`
- REPLACEMENT COUNT DATA(cnt1) "3
- IGNORING CASE.
-
-str = str_original.
-
-"REPLACEMENT OFFSET and LENGTH additions
-REPLACE FIRST OCCURRENCE OF `ap`
- IN str WITH `##`
- REPLACEMENT COUNT DATA(cnt2) "1 (always 1 for replaced first occurrence)
- REPLACEMENT OFFSET DATA(off2) "2
- REPLACEMENT LENGTH DATA(len2) "2
- IGNORING CASE. "ab## ABAP abap
-
-str = str_original.
-
-"SECTION ... OF addition: Replacing within a specified area
-REPLACE ALL OCCURRENCES OF `ap`
- IN SECTION OFFSET 4 LENGTH 5
- OF str WITH `##`
- REPLACEMENT COUNT DATA(cnt3) "1
- REPLACEMENT OFFSET DATA(off3) "2
- REPLACEMENT LENGTH DATA(len3) "2
- IGNORING CASE. "abap AB## abap
-
-str = str_original.
-
-"RESULTS additions with ...
-"... ALL OCCURRENCES OF
-"Note: repl_tab, which is declared inline here, is of type repl_result_tab
-REPLACE ALL OCCURRENCES OF `ap`
- IN str WITH `##`
- RESULTS DATA(repl_tab)
- IGNORING CASE. "ab## AB## ab##
-
-"repl_tab:
-"LINE OFFSET LENGTH
-"0 2 2
-"0 7 2
-"0 12 2
-
-str = str_original.
-
-"... FIRST OCCURRENCE OF
-"Note: repl_struc, which is declared inline here, is of type repl_result
-REPLACE FIRST OCCURRENCE OF `ap`
- IN str WITH `##`
- RESULTS DATA(repl_struc)
- IGNORING CASE.
-
-"repl_struc:
-"LINE OFFSET LENGTH
-"0 2 2
-```
-
-You can use [`REPLACE SECTION ... OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_section_of.htm) statements for position-based replacements, that is, to replace a section in a string starting at a specified offset for a specified length.
-
-``` abap
-DATA(str_original) = `abap ABAP abap`.
-DATA(str) = str_original.
-
-"OFFSET + LENGTH specified
-REPLACE SECTION OFFSET 5 LENGTH 4 OF str WITH `#`. "abap # abap
-
-str = str_original.
-
-"Only OFFSET (LENGTH: up to the end of the string)
-REPLACE SECTION OFFSET 5 OF str WITH `#`. "abap #
-
-str = str_original.
-
-"Only LENGTH (OFFSET: starting from the leftmost position)
-REPLACE SECTION LENGTH 6 OF str WITH `#`. "#BAP abap
-```
-
-Replacements in internal tables with `REPLACE ... IN TABLE`:
-``` abap
-DATA(str_table_original) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
-DATA(str_table) = str_table_original.
-
-"Replacing all occurrences in a table
-"RESULTS addition: Storing information in an internal table of type repl_result_tab
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- WITH `#`
- RESULTS DATA(res_table)
- RESPECTING CASE.
-
-"str_table: a#bz# / cd#ze / #zzf / ghz
-"res_table:
-"LINE OFFSET LENGTH
-"1 1 1
-"1 4 1
-"2 2 1
-"3 0 1
-
-str_table = str_table_original.
-
-"Replacing the first occurrence in a table
-"RESULTS addition: Storing information in a structure of type repl_result
-REPLACE FIRST OCCURRENCE OF `Z`
- IN TABLE str_table
- WITH `#`
- RESULTS DATA(res_structure)
- RESPECTING CASE.
-
-"str_table: a#bzZ / cdZze / Zzzf / ghz
-"res_structure:
-"LINE OFFSET LENGTH
-"1 1 1
-
-str_table = str_table_original.
-
-"Restricting the search range in an internal table
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- FROM 1 TO 2
- WITH `#`
- RESPECTING CASE.
-
-"str_table: a#bz# / cd#ze / Zzzf / ghz
-
-str_table = str_table_original.
-
-"Offsets can be optionally specified (also only the offset of start or end line possible)
-REPLACE ALL OCCURRENCES OF `Z`
- IN TABLE str_table
- FROM 1 OFFSET 3 TO 2 OFFSET 2
- WITH `#`
- RESPECTING CASE.
-
-"str_table: aZbz# / cdZze / Zzzf / ghz
-```
-
-- The string function
-[`replace`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreplace_functions.htm),
-allows you to store the result of a substring replacement in a separate
-variable.
-- What makes it especially powerful is that it
-returns a value, so it can be used at almost any [read
-positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenread_position_glosry.htm "Glossary Entry").
-- The parameters of the `replace` string functions are similar to those of the `find` function. In addition, there is the `with` parameter for the replacement. Setting `occ` to `0` means that all occurrences are respected for the replacement.
-
-Syntax examples:
-``` abap
-DATA(str) = `abap ABAP abap`.
-DATA res TYPE string.
-
-"Note that here only the first occurrence is replaced.
-res = replace( val = str sub = `ap` with = `#` ). "ab# ABAP abap
-
-"Making the search case-insensitive
-res = replace( val = str sub = `AB` with = `#` case = abap_false ). "#ap ABAP abap
-
-"Setting occ
-res = replace( val = str sub = `ab` with = `#` occ = 2 case = abap_false ). "abap #AP abap
-
-"Replacing all occurrences: Setting occ to 0
-res = replace( val = str sub = `ab` with = `#` occ = 0 case = abap_false ). "#ap #AP #ap
-
-"Negative value for occ: Occurrences are counted from the right
-res = replace( val = str sub = `ab` with = `#` occ = -1 ). "abap ABAP #ap
-
-"Setting off and len for determining a subarea for replacements
-"Note: When using off/len, sub and occ cannot be specified.
-"Specifying both off and len
-res = replace( val = str with = `#` off = 5 len = 3 ). "abap #P abap
-
-"Specifying only off (len is 0 by default)
-res = replace( val = str with = `#` off = 2 ). "ab#ap ABAP abap
-
-"Note: When specifying only off and not specifying len or len = 0,
-"replace works like insert
-res = insert( val = str sub = `#` off = 2 ). "ab#ap ABAP abap
-
-"Specifying only len (off is 0 by default): First segment of length in len is replaced
-res = replace( val = str with = `#` len = 3 ). "#p ABAP abap
-
-"Special case
-"- off: equal to the length of the string
-"- len: not specified or 0
-"- Result: Value specified for 'with' is appended to the end of the string
-res = replace( val = str with = `#` off = strlen( str ) ). "abap ABAP abap#
-```
-
-## Pattern-Based Searching and Replacing in Strings
-
-You can perform complex search and replace operations based on
-patterns. [PCRE regular
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry")
-help you process strings effectively.
-> **💡 Note**
-> Do not use [POSIX
-regular
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenposix_regex_glosry.htm "Glossary Entry")
-anymore, they are obsolete.
-
-
-
-### Simple Pattern-Based Searching Using Comparison Operators
-
-For simple patterns, you can use the [comparison
-operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
-[`CP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
-(conforms to pattern) or its negation
-[`NP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
-(does not conform to pattern) in [comparison
-expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry")
-to determine whether a set of characters is contained in a string that
-matches a particular pattern. You can use the following
-special characters as patterns:
-
-| Special Character | Details |
-|---|---|
-| `*` | Any character sequence (including blanks). |
-| `+` | Any character (only one character, including blanks). |
-| `#` | Escape character. The following character is marked for an exact comparison. |
-
-Patterns are not case-sensitive except for characters marked with
-`#`. If a pattern is found, the system variable
-`sy-fdpos` returns the offset of the first occurrence.
-Otherwise, it contains the length of the searched string.
-``` abap
-DATA(s1) = `abc_def_ghi`.
-
-"Pattern: f is preceded by any character sequence, must be followed
-"by '_' and then followed by any character sequence
-IF s1 CP `*f#_*`. ... "true; sy-fdpos = 6
-
-"Pattern: 'i' is not followed by another character
-IF s1 NP `i+`. ... "true; sy-fdpos = 11 (length of searched string)
-```
-
-
-
-### Complex Searching and Replacing Using Regular Expressions
-
-#### Excursion: Common Regular Expressions
-
-There are several ways to perform complex searches in strings using PCRE expressions. They can be quite complex. The following overview shows common PCRE expressions with simple examples.
-For more information, see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenregex_pcre_syntax_specials.htm).
-
-Characters and character types
-
-| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
-|---|---|---|---|---|---|
-| `x` | Specific character | `a` | abcdef | a | Anything else |
-| `.` | Anything except a line break | `.` | ab 1# | a, b, the blank, 1, # | ab, 1# |
-| `\d` | Any digit (0-9), alternative: `[0-9]` | `\d` | a1-b2 3-4c9 | 1, 2, 3, 4, 9 | a, b, c, the blank and hyphens |
-| `\D` | Any non-digit, alternative: `[^0-9]` | `\D` | a1-b2 3-4c9 | a, b, c, the blank and hyphens | 1, 2, 3, 4, 9 |
-| `\s` | Any whitespace character such as a blank, tab and new line | `\s` | (hi X ) | The blanks | h, i, X, (, ) |
-| `\S` | Any character that is not a whitespace | `\S` | (hi X ) | h, i, X, (, ) | The blanks |
-| `\w` | Any word character (letter, digit or the underscore), alternative: `[a-zA-Z0-9_]` | `\w` | (ab 12_c) | a, b, c, 1, 2, _ | (, ), the blank |
-| `\W` | Any character that is not a word character, alternative: `[^a-zA-Z0-9_]` | `\W` | (ab 12_c) | (, ), the blank | a, b, c, 1, 2, _ |
-| `\` | To include special characters like `[] \ / ^`, use `\` to escape them. Use `\.` to match a period ("."). | `.\.` | ab.cd.ef | a**b.**c**d.**ef | ab**.c**d**.e**f |
-
-Repetitions and Alternatives
-
-| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
-|---|---|---|---|---|---|
-| `x*` | Zero or more repetitions of `x` | `ab*` | abc abbc abbbc a ac | **ab**c **abb**c **abbb**c **a** **a**c | **abc** **abbc** **abbbc** a **ac** |
-| `x+` | One or more repetitions of `x` | `ab+` | abc abbc abbbc a ac | **ab**c **abb**c **abbb**c a ac | ... **a** **a**c |
-| `x{m,n}` | Between `m` and `n` repetitions of `x` | `ab{2,3}` | abc abbc abbbc a ac | abc **abb**c **abbb**c a ac | **ab**c ... |
-| `x{m}` | Exactly `m` repetitions | `ab{3}` | abc abbc abbbc a ac | abc abbc **abbb**c a ac | abc **abb**c ... |
-| `x{m,}` | Exactly `m` or more repetitions | `ab{2,}` | abc abbc abbbc a ac | abc **abb**c **abbb**c a ac | **ab**c ... |
-| `x?` | Optional `x`, i.e. zero or one time | `ab?` | abc abbc abbbc a ac | **ab**c **ab**bc **ab**bbc **a** **a**c | ... **ac** |
-| `x\|y` | Matching alternatives, i. e. `x` or `y` | 1. `b\|2` 2. `b(a\|u)t` | 1. abc 123 2. bit bat but bet | 1. b, 2 2. bat, but | 1. a, c, 1, 3 2. bit, bet |
-| `x*?` | `x*` captures greedily, i.e. as much as possible, while `x*?` captures non-greedily, i.e. as few as possible | 1. `bc*?` 2. `a.*?#` | 1. abcd abccccd ab 2. abc#defgh#i | 1. a**b**cd a**b**ccccd a**b** 2. **abc#**defgh#i | 1. a**bc**d a**bcccc**d a**b** (result for `bc*`) 2. **abc#defgh#**i (result for `a.*#`) |
-| `x+?` | Same as above: `x+` (greedy), `x+?` (non-greedy) | 1. `bc+?` 2. `<.+?>` | 1. abcd abccccd ab 2. <span>Hallo</span> html. | 1. a**bc**d a**bc**cccd ab 2. **<span>**Hallo**</span>** html. | 1. a**bc**d a**bcccc**d ab (result for `bc+`) 2. **<span>Hallo</span>** html. (result for `<.+>`) |
-
-Character Sets, Ranges, Subgroups and Lookarounds
-| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
-|---|---|---|---|---|---|
-| `[xy]` | Character set, matches a single character present in the list | `b[iu]` | bit bat but bet | **bi**t bat **bu**t bet | bit **ba**t but **be**t |
-| `[x-y]` | Character range, matches a single character in the specified range, note that ranges may be locale-dependent | `a[a-c0-5]` | aa1 ab2 ba3 cac4 da56 a7 |**aa**1 **ab**2 b**a3** c**ac**4 d**a5**6 a7 | aa1 ab2 ba3 cac4 da56 **a7** |
-| `[^xy]` | Negation, matches any single character not present in the list | `[^Ap]` | ABap | B, a | A, p |
-| `[^x-y]` | Negation, matches any single character not within the range | `[^A-Ca-c1-4]` | ABCDabcd123456 | D, d, 5, 6 | A, B, C, a, b, c, 1, 2, 3, 4 |
-| `(...)` | Capturing group to group parts of patterns together | `b(a\|u)t` | bit bat but bet | bat, but | bit, bet |
-| `(?=...)` | Positive lookahead, returns characters that are followed by a specified pattern without including this pattern | `a(?=b)` | abc ade | **a**bc ade | abc **a**de |
-| `(?!...)` | Negative lookahead, returns characters that are not followed by a specified pattern without including this pattern | `a(?!b)` | abc ade | abc **a**de | **a**bc ade |
-| `(?<=...)` | Positive lookbehind, returns characters that are preceded by a specified pattern without including this pattern | `(?<=\s)c` | ab c abcd | ab **c** abcd (it is preceded by a blank) | ab c ab**c**d |
-| `(?**c**d (it is not preceded by a blank) | ab **c** abcd |
-| `\n` | Backreference, refers to a previous capturing group; n represents the number of the group index that starts with 1 | `(a.)(\w*)\1` | abcdefabghij | **abcdefab**ghij Note: Capturing group 1 holds `ab` in the example. The second capturing group captures all word characters until `ab` is found. | **ab**cdefabghij |
-| `\K` | Resets the starting point of a match, i.e. findings are excluded from the final match | `a.\Kc` | abcd | ab**c**d | **abc**d |
-
-> **💡 Note**
-> - Subgroups are useful in replacements. By using an expression with `$` and a number, such as `$1`, you can refer to a specific group. For example, you have a string `abcde`. A PCRE expression might be
-`(ab|xy)c(d.)`, where two subgroups are specified within two pairs of parentheses. In a replacement pattern, you can refer to the first group with `$1` and the second group with `$2`. Thus, the replacement pattern `$2Z$1` results in `deZab`.
-> - `(?:x)` creates a group but it is not captured. Example regular expression: `(?:ab)(ap)`. Example string: 'abap'. It matches 'abap', but `$1` will only contain 'ap'.
-
-Anchors and Positions
-
-| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
-|---|---|---|---|---|---|
-| `^` | Start of line, alternative: `\A` | `^.` or `\A.` | abc def | **a**bc def | abc **d**ef |
-| `$` | End of line, alternative: `\Z` | `.$` or `.\Z` | abc def | abc de**f** | **a**bc def |
-| `\b` | Start or end of word | 1. `\ba.` 2. `\Dd\b` 3. `\b.d\b` | abcd a12d ed | 1. **ab**cd **a1**2d ed 2. ab**cd** a12d **ed** 3. abcd a12d **ed** | 1. ab**cd** a1**2d** ed 2. abcd a1**2d** ed 3. **abcd** **a12d** ed |
-| `\B` | Negation of `\b`, not at the start or end of words | `\Be\B` | see an elefant | s**e**e an el**e**fant | s**ee** an **e**lefant |
-
-
-
-#### Searching Using Regular Expressions
-
-- Multiple string functions support PCRE expressions by offering the
- `pcre` parameter, which you can use to specify such an expression.
-`FIND` and `REPLACE` statements support regular
-expressions with the `PCRE` addition.
-- The string function
-[`match`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmatch_functions.htm)
-works only with regular expressions. It returns a substring that
-matches a regular expression within a string.
-- For comparisons, you can
-also use the [predicate
-function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_function_glosry.htm "Glossary Entry")
-[`matches`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmatches_functions.htm), which returns true or false if a string matches a given pattern or not.
-
-Syntax examples:
-``` abap
-DATA(s1) = `Cathy's black cat on the mat played with Matt.`.
-
-"Determining the position of the first occurrence
-"Here, the parameter occ is 1 by default.
-DATA(int) = find( val = s1 pcre = `at.` ). "1
-
-"Determining the number of all occurrences.
-"Respects all 'a' characters not followed by 't', all 'at' plus 'att'
-int = count( val = s1 pcre = `at*` ). "6
-
-"Respects all 'at' plus 'att'
-int = count( val = s1 pcre = `at+` ). "4
-
-"Extracting a substring matching a given pattern
-DATA(s2) = match( val = `The email address is jon.doe@email.com.`
- pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ). "jon.doe@email.com
-
-"Predicate function matches
-"Checking the validitiy of an email address
-IF matches( val = `jon.doe@email.com`
- pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ). "true
-...
-ENDIF.
-
-"Examples with the FIND statement
-"SUBMATCHES addition: Storing submatches in variables
-"Pattern: anything before and after ' on '
-FIND PCRE `(.*)\son\s(.*)` IN s1 IGNORING CASE SUBMATCHES DATA(a) DATA(b).
-"a: 'Cathy's black cat' / b: 'the mat played with Matt.'.
-
-"Determining the number of letters in a string
-FIND ALL OCCURRENCES OF PCRE `[A-Za-z]` IN s1 MATCH COUNT DATA(c). "36
-
-"Searching in an internal table and retrieving line, offset, length information
-DATA(itab) = value string_table( ( `Cathy's black cat on the mat played with the friend of Matt.` ) ).
-"Pattern: 't' at the beginning of a word followed by another character
-FIND FIRST OCCURRENCE OF PCRE `\bt.` IN TABLE itab
- IGNORING CASE MATCH LINE DATA(d) MATCH OFFSET DATA(e) MATCH LENGTH DATA(f). "d: 1, e: 21, f: 2
-```
-
-
-##### Excursion: System Classes for Regular Expressions
-
-- You can create an object-oriented representation of regular expressions using the `CL_ABAP_REGEX` system class.
-- For example, the `CREATE_PCRE` method creates instances of regular expressions with PCRE syntax.
-- The instances can be used, for example, with the `CL_ABAP_MATCHER` class, which applies the regular expressions.
-- A variety of methods and parameters can be specified to accomplish various things and to further specify the handling of the regular expression.
-- More information can be found [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenregex_system_classes.htm) and in the class documentation (choose F2 on the class in ADT).
-
-
-``` abap
-DATA(str) = `a1 # B2 ? cd . E3`.
-
-"Creating a regex instance for PCRE regular expressions
-"In the example, regex_inst has the type ref to cl_abap_regex.
-DATA(regex_inst) = cl_abap_regex=>create_pcre( pattern = `\D\d` "any-non digit followed by a digit
- ignore_case = abap_true ).
-
-"Creating an instance of CL_ABAP_MATCHER using the method CREATE_MATCHER of the class CL_ABAP_REGEX
-"You can also specify internal tables with the 'table' parameter and more.
-DATA(matcher) = regex_inst->create_matcher( text = str ).
-
-"Finding all results using the 'find_all' method
-"In the example, result has the type match_result_tab containing the findings.
-DATA(result) = matcher->find_all( ).
-
-"Using method chaining
-DATA(res) = cl_abap_regex=>create_pcre( pattern = `\s\w` "any blank followed by any word character
- ignore_case = abap_true )->create_matcher( text = str )->find_all( ).
-```
-
-
-
-#### Replacing Using Regular Expressions
-
-- To perform replacement operations using regular expressions, you can use both
-the string function `replace` and `REPLACE` statements with the `pcre` parameter or the `PCRE` addition.
-- Like the `find` function, among others, and
-`FIND` statements, the `replace` function and
-`REPLACE` statements offer a number of parameters and additions that you can use to further restrict the area to be replaced.
-- For more detailed information, refer to the ABAP
-Keyword Documentation.
-- The executable example covers many of the PCRE expressions listed above.
-
-Syntax examples:
-``` abap
-DATA(s1) = `ab apppc app`.
-DATA s2 TYPE string.
-
-"Replaces 'p' with 2 - 4 repetitions, all occurences
-s2 = replace( val = s1 pcre = `p{2,4}` with = `#` occ = 0 ). "ab a#c a#
-
-"Replaces any single character not present in the list, all occurences
-s2 = replace( val = s1 pcre = `[^ac]` with = `#` occ = 0 ). " "a##a###c#a##
-
-"Replaces first occurence of a blank
-s2 = replace( val = s1 pcre = `\s` with = `#` ). "ab#apppc app
-
-"Greedy search
-"The pattern matches anything before 'p'. The matching is carried out as
-"often as possible. Hence, in this example the search stretches until the
-"end of the string since 'p' is the final character, i. e. this 'p' and
-"anything before is replaced.
-s2 = replace( val = s1 pcre = `.*p` with = `#` ). "#
-
-"Non-greedy search
-"The pattern matches anything before 'p'. The matching proceeds until
-"the first 'p' is found and does not go beyond. It matches as few as
-"possible. Hence, the first found 'p' including the content before
-"is replaced.
-s2 = replace( val = s1 pcre = `.*?p` with = `#` ). "#ppc app
-
-"Replacements with subgroups
-"Replaces 'pp' (case-insensitive here) with '#', the content before and after 'pp' is switched
-s2 = replace( val = s1
- pcre = `(.*?)PP(.*)`
- with = `$2#$1`
- case = abap_false ). "pc app#ab a
-
-"Changing the source field directly with a REPLACE statement; same as above
-REPLACE PCRE `(.*?)PP(.*)` IN s1 WITH `$2#$1` IGNORING CASE. "pc app#ab a
-```
-
-
-
-## More String Functions
-
-### Checking the Similarity of Strings
-
-- [`distance`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendistance_functions.htm) returns the Levenshtein distance between two strings, which reflects their similarity.
-- Unlike other string functions, the return value has the type `i`.
-- Optional addition `max`: Positive integer. The calculation of the Levenshtein distance will stop if the calculated value is greater than this integer.
-
-```abap
-DATA(str_to_check) = `abap`.
-DATA(dist1) = distance( val1 = str_to_check val2 = `abap` ). "0
-DATA(dist2) = distance( val1 = str_to_check val2 = `axbap` ). "1
-DATA(dist3) = distance( val1 = str_to_check val2 = `yabyyapy` ). "4
-DATA(dist4) = distance( val1 = str_to_check val2 = `zabapzzzzzzzzzzzz` max = 5 ). "5
-
-"If the value of max is 0 or less, an exception is raised.
-TRY.
- DATA(dist5) = distance( val1 = str_to_check val2 = `#ab#ap#` max = 0 ).
- CATCH cx_sy_strg_par_val.
- ...
-ENDTRY.
-```
-
-### Repeating Strings
-- [`repeat`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrepeat_functions.htm) returns a string that contains the content of a specified string for parameter `val` as many times as specified in the parameter `occ`.
-- An empty string is returned when `occ` has the value 0 or `val` is empty.
-
-```abap
-DATA(repeat1) = repeat( val = `abap` occ = 5 ). "abapabapabapabapabap
-DATA(repeat2) = |#{ repeat( val = ` ` occ = 10 ) }#|. "# #
-DATA(repeat3) = COND #( WHEN repeat( val = `a` occ = 0 ) = `` THEN `Y` ELSE `Z` ). "Y (initial value returned)
-
-"If occ has a negative value, an exception is raised.
-TRY.
- DATA(repeat4) = repeat( val = `X` occ = -3 ).
- CATCH cx_sy_strg_par_val.
- ...
-ENDTRY.
-```
-
-
-
-### Returning the Smallest/Biggest of a Set of Character-Like Arguments
-- [`cmin/cmax`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencmax_cmin_functions.htm) returns a string that contains the content of the smallest or biggest of a set of character-like arguments
-- 'Set' means at least two arguments and a maximum of nine argeuments are passed (`valn` operators) for comparison.
-- The comparison is made from left to right, and the first different character found determines the smaller or bigger argument.
-
-```abap
-DATA(min) = cmin( val1 = `zzzzzzz`
- val2 = `zzazzzzzzzz` "smallest argument
- val3 = `zzzzabc` ).
-
-DATA(max) = cmax( val1 = `abcdef` "biggest argument
- val2 = `aaghij`
- val3 = `aaaaklmn`
- val4 = `aaaaaaopqrs`
- val5 = `aaaaaaaaaatuvwxy`
- val6 = `aaaaaaaaaaaaaz` ).
-```
-
-
-
-### Escaping Special Characters
-- [`escape`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm) returns a string that is provided for the `val` parameter by escaping special characters according to the specification in the `format` parameter.
-- Suitable values for the `format` parameter (which expects a data object of type `i`) are available in the `CL_ABAP_FORMAT` class (the constants starting with `E_`).
-- Special rules apply to different contexts, such as URLS and JSON. Also note the prevention of Cross Site Scripting (XSS) attacks on web applications. For more information, refer to the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm).
-
-```abap
-"Context: URLs
-DATA(esc1) = escape( val = '...test: 5@8...'
- format = cl_abap_format=>e_url_full ).
-"...test%3A%205%408...
-
-"Context: JSON
-DATA(esc2) = escape( val = 'some "test" json \ with backslash and double quotes'
- format = cl_abap_format=>e_json_string ).
-"some \"test\" json \\ with backslash and double quotes
-
-
-"Context: String templates
-DATA(esc3) = escape( val = 'Special characters in string templates: |, \, {, }'
- format = cl_abap_format=>e_string_tpl ).
-"Special characters in string templates: \|, \\, \{, \}
-
-"Invalid value for the format parameter
-TRY.
- DATA(esc4) = escape( val = 'This will raise an exception due to an invalid format value.'
- format = 123 ).
- CATCH cx_sy_strg_par_val.
-ENDTRY.
-```
-
-
-
-## Excursion: String Processing Using the XCO Library
-The Extension Components Library (XCO) library provides [released APIs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreleased_api_glosry.htm) and offers various development utilities. Find more information [here](https://help.sap.com/docs/btp/sap-business-technology-platform/overview-of-xco-modules). The following code snippet demonstrates several methods of the `XCO_CP` class that deal with string processing.
-
-```abap
-"--------- Extracting a substring from a string ---------
-DATA(some_string) = `abcdefghijklmnopqrstuvwxyz`.
-
-"Creating an encapsulation of a string using XCO
-DATA(str) = xco_cp=>string( some_string ).
-
-"Using the FROM and TO methods, you can determine
-"the character position. Note that the value includes the
-"character at the position specified.
-"The character index pattern for the example string above
-"is (the string has 26 characters in total):
-"a = 1, b = 2, c = 3 ... z = 26
-"a = -26, b = -25, c = -24 ... z = -1
-"Providing a value that is out of bounds means that
-"the first (or the last) character of the string is used
-"by default.
-"Note: When combining FROM and TO, e.g. with method
-"chaining ...->from( ...)->to( ... ), note that another
-"instance is created with the first 'from', and another
-"character index pattern is created based on the new
-"and adjusted string value.
-
-"bcdefghijklmnopqrstuvwxyz
-DATA(sub1) = str->from( 2 )->value.
-
-"defghijklmnopqrstuvwxyz
-DATA(sub2) = str->from( -23 )->value.
-
-"vwxyz
-DATA(sub3) = str->from( -5 )->value.
-
-"abcde
-DATA(sub4) = str->to( 5 )->value.
-
-"ab
-DATA(sub5) = str->to( -25 )->value.
-
-"Result of 1st 'from' method call: bcdefghijklmnopqrstuvwxyz
-"Based on this result, the 'to' method call is
-"applied.
-"bcdefg
-DATA(sub6) = str->from( 2 )->to( 6 )->value.
-
-"Result of 1st 'to' method call: abcdefghijklmnopq
-"Based on this result, the 'from' method call is
-"applied.
-"defghijklmnopq
-DATA(sub7) = str->to( -10 )->from( 4 )->value.
-
-"Values that are out of bounds.
-"In the example, the first and last character of the
-"string are used.
-"abcdefghijklmnopqrstuvwxyz
-DATA(sub8) = str->from( 0 )->to( 100 )->value.
-
-"--------- Splitting and joining ---------
-
-"Splitting a string into a string table
-DATA(str_table) = xco_cp=>string( `Hello.World.ABAP` )->split( `.` )->value.
-"Hello
-"World
-"ABAP
-
-"Concatenating a string table into a string; specifying a delimiter
-str_table = VALUE #( ( `a` ) ( `b` ) ( `c` ) ).
-"a, b, c
-DATA(conc_str1) = xco_cp=>strings( str_table )->join( `, ` )->value.
-
-"Concatenating a string table into a string; specifying a delimiter and
-"reversing the table order
-"c / b / a
-DATA(conc_str2) = xco_cp=>strings( str_table )->reverse( )->join( ` / ` )->value.
-
-"--------- Prepending and appending strings ---------
-DATA(name) = xco_cp=>string( `Max Mustermann` ).
-
-"Max Mustermann, Some Street 1, 12345 Someplace
-DATA(address) = name->append( `, Some Street 1, 12345 Someplace` )->value.
-
-"Mr. Max Mustermann
-DATA(title) = name->prepend( `Mr. ` )->value.
-
-"--------- Transforming to lowercase and uppercase ---------
-"ABAP
-DATA(to_upper) = xco_cp=>string( `abap` )->to_upper_case( )->value.
-
-"hallo world
-DATA(to_lower) = xco_cp=>string( `HALLO WORLD` )->to_lower_case( )->value.
-
-"--------- Checking if a string starts/ends with a specific string ---------
-DATA check TYPE string.
-DATA(str_check) = xco_cp=>string( `Max Mustermann` ).
-
-"yes
-IF str_check->ends_with( `mann` ).
- check = `yes`.
-ELSE.
- check = `no`.
-ENDIF.
-
-"no
-IF str_check->starts_with( `John` ).
- check = `yes`.
-ELSE.
- check = `no`.
-ENDIF.
-
-"--------- Converting strings to xstrings using a codepage ---------
-"536F6D6520737472696E67
-DATA(xstr) = xco_cp=>string( `Some string` )->as_xstring( xco_cp_character=>code_page->utf_8 )->value.
-
-"--------- Camel case compositions and decompositions with split and join operations ---------
-"Pascal case is also possible
-"someValue
-DATA(comp) = xco_cp=>string( `some_value` )->split( `_` )->compose( xco_cp_string=>composition->camel_case )->value.
-
-"Camel case decomposition
-"some_value
-DATA(decomp) = xco_cp=>string( `someValue` )->decompose( xco_cp_string=>decomposition->camel_case )->join( `_` )->value.
-
-"--------- Matching string against regular expression ---------
-DATA match TYPE string.
-
-"yes
-IF xco_cp=>string( ` 1` )->matches( `\s\d` ).
- match = 'yes'.
-ELSE.
- match = 'no'.
-ENDIF.
-
-"no
-IF xco_cp=>string( ` X` )->matches( `\s\d` ).
- match = 'yes'.
-ELSE.
- match = 'no'.
-ENDIF.
-```
-
-
-
-## Executable Example
-
-[zcl_demo_abap_string_proc](./src/zcl_demo_abap_string_proc.clas.abap)
-
-> **💡 Note**
-> - The executable example ...
-> - covers the following topics:
-> - Creating strings and assigning values
-> - String templates
-> - Operations with strings operations: chaining, concatenating, splitting, modifying
-> - Searching and replacing
-> - Regular expressions
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
-> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
+
+
+# String Processing
+
+- [String Processing](#string-processing)
+ - [Introduction](#introduction)
+ - [Data Types for Character Strings](#data-types-for-character-strings)
+ - [Declaring Character-Like Data Objects](#declaring-character-like-data-objects)
+ - [Assigning Values](#assigning-values)
+ - [String Templates](#string-templates)
+ - [Determining the Length of Strings](#determining-the-length-of-strings)
+ - [Concatenating Strings](#concatenating-strings)
+ - [Splitting Strings](#splitting-strings)
+ - [Modifying Strings](#modifying-strings)
+ - [Transforming to Lowercase and Uppercase](#transforming-to-lowercase-and-uppercase)
+ - [Shifting Content](#shifting-content)
+ - [Condensing Strings](#condensing-strings)
+ - [Reversing Strings](#reversing-strings)
+ - [Inserting Substrings into Strings](#inserting-substrings-into-strings)
+ - [Overlaying Content](#overlaying-content)
+ - [Processing Substrings](#processing-substrings)
+ - [Searching and Replacing](#searching-and-replacing)
+ - [Searching for Specific Characters](#searching-for-specific-characters)
+ - [Replacing Specific Characters in Strings](#replacing-specific-characters-in-strings)
+ - [Searching for Substrings in Strings](#searching-for-substrings-in-strings)
+ - [Searching for Substrings in Tables](#searching-for-substrings-in-tables)
+ - [String Function find](#string-function-find)
+ - [Replacing Substrings in Strings](#replacing-substrings-in-strings)
+ - [Replacing Substrings in Tables](#replacing-substrings-in-tables)
+ - [String Function replace](#string-function-replace)
+ - [Pattern-Based Searching and Replacing in Strings](#pattern-based-searching-and-replacing-in-strings)
+ - [Simple Pattern-Based Searching Using Comparison Operators](#simple-pattern-based-searching-using-comparison-operators)
+ - [Complex Searching and Replacing Using Regular Expressions](#complex-searching-and-replacing-using-regular-expressions)
+ - [Excursion: Common Regular Expressions](#excursion-common-regular-expressions)
+ - [Searching Using Regular Expressions](#searching-using-regular-expressions)
+ - [System Classes for Regular Expressions](#system-classes-for-regular-expressions)
+ - [Replacing Using Regular Expressions](#replacing-using-regular-expressions)
+ - [More String Functions](#more-string-functions)
+ - [Checking the Similarity of Strings](#checking-the-similarity-of-strings)
+ - [Repeating Strings](#repeating-strings)
+ - [Returning the Smallest/Biggest of a Set of Character-Like Arguments](#returning-the-smallestbiggest-of-a-set-of-character-like-arguments)
+ - [Escaping Special Characters](#escaping-special-characters)
+ - [Excursions](#excursions)
+ - [Comparison Operators for Character-Like Data Types in a Nutshell](#comparison-operators-for-character-like-data-types-in-a-nutshell)
+ - [String Processing Using the XCO Library](#string-processing-using-the-xco-library)
+ - [Executable Example](#executable-example)
+
+
+## Introduction
+
+ABAP offers plenty of options for processing [character strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencharacter_string_glosry.htm "Glossary Entry").
+The options include ABAP statements (e. g. [`FIND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)),
+[character string expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_expression_glosry.htm "Glossary Entry")
+([concatenations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_glosry.htm) and [string templates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_template_glosry.htm "Glossary Entry"))
+and built-in [string functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_function_glosry.htm "Glossary Entry")
+(e. g. [`strlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm)).
+
+> **💡 Note**
+>- Compared to statements, expressions and string functions can help make your ABAP code more
+ concise and straightforward. For example, you can perform string operations directly in [operand
+ position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry"),
+ allowing you to avoid temporary variables.
+>- In ABAP statements, modification operations on strings are often performed in read/write positions, meaning that the source and target
+ fields of an operation are the same. When working with string functions, the source field is passed as an input parameter and the modified value is returned as a [return value](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreturn_value_glosry.htm "Glossary Entry"), meaning that the function itself does not modify the source field. Of course, you can assign the function to the source field to achieve its modification.
+>- In most cases, string functions provide the same functionality as the
+ corresponding ABAP statements, or even more. The return value of string functions
+ that return character strings is always of type `string`.
+
+
+
+## Data Types for Character Strings
+
+ABAP provides the following built-in data types for data objects that contain character strings. They are distinguished as follows:
+
+| Type | Details | Length | Value Range | Initial Value |
+|---|---|---|---|---|
+| `string` | For variable length character strings. [Data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm "Glossary Entry") of this type are [dynamic data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendynamic_data_object_glosry.htm "Glossary Entry"), i. e. the length of a variable can change during the execution of an ABAP program and thus it can contain character strings of different lengths. A data object of type `string` is called *text string* or, in short, just *string*. | No standard length; length is variable | Any [Unicode](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunicode_glosry.htm) characters that can be encoded in ABAP language's code page [UCS-2](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenucs2_glosry.htm). The most common content are alphanumeric characters or special characters. | Empty string with length 0 |
+| `c` | For fixed length character strings. Data objects of this type are [static data objects](http://ldcialx.wdf.sap.corp:50018/sap/public/bc/abap/docu?sap-language=EN&object=abenstatic_data_object_glosry&version=X&sap-client=000), i. e. the length of a variable must be defined during its declaration and does not change during the execution of an ABAP program. Thus, it always contains character strings of the same length. A data object of type `c` is called *text field*.|Data objects of this type can contain a string of fixed length (between 1 and 262143 characters); standard length: 1 | Same as for `string` | A blank for each position |
+
+In addition to these main data types for character strings, there are several other fixed length data types with special meanings:
+
+- `n` for fixed length numerical character strings
+ - Data objects of this type are technically almost the same as text fields. However, the only valid characters are the digits 0 to 9. Validity is not checked for assigning values in a regular way but only for [lossless assignments](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlossless_assignment_glosry.htm). Thus, such numeric text fields can contain invalid data, but should only be used for digits that are not intended for arithmetic calculations, such as zip codes or article numbers. The initial value for each position is 0.
+- `d` and `t` for date and time fields
+ - These data types have a predefiend length of 6 and 8. Data objects of these types are used for character representations of dates and times in a predefined format. You can use them directly in date and time calculations. However, these fields can also contain invalid values.
+
+These data types are not covered further in this cheat sheet. The same is true for the [byte-like data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_like_data_typ_glosry.htm "Glossary Entry") `x` and `xstring` that are closely related to `c` and `string` but contain raw [byte strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_string_glosry.htm).
+
+> **⚡ Differences between text strings (variable length) and text fields (fixed length)**
+>- **Initial value**: The initial value of a text string is an
+ empty string of length 0. The initial value of text field is represented by blanks at each position.
+>- **Internal representation**: Data objects of type `c` and `string` are both [elementary data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_object_glosry.htm "Glossary Entry").
+ However, while text fields occupy a block of memory according to their length, text strings are so-called [deep](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_glosry.htm "Glossary Entry") data objects. Internally, they are managed by a [reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry") that points to the actual character. This fact has restrictive consequences for the use of strings as components of structures, but can also improve the performance of assignments due to the concept of [sharing](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensharing_glosry.htm "Glossary Entry") of deep data objects.
+>- **Length**: Theoretically, a text string can use up to 2 GB (one character occupies 2 bytes).
+ The maximum length of a text field is 262143 characters.
+>- **Trailing blanks**: For text strings, trailing blanks are preserved in all operations. For text fields, it depends on the [operand
+ position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm "Glossary Entry") whether trailing blanks are respected or not. In most operand positions, trailing blanks are truncated when working with text fields, even when using [text field literals](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentext_field_literal_glosry.htm). For example, if a text field is assigned to a text string, the resulting target string will never contain trailing blanks. See the *Condensing Strings* section in this context.
+>- **Flexibility**: Text strings are more flexible than text fields
+ because you can easily shorten or lengthen them without
+ worrying that, for example, parts of the character string will be
+ truncated during processing. On the other hand, when accessing substrings of a string, you have to make sure that the string is long enough, whereas with text fields you always know their length.
+
+So, when to use what? Text fields are useful when
+actually specifying a maximum or mandatory length, e.g. a country code
+that must be a maximum of two characters, or for input fields in
+forms that should not exceed a certain length. If limiting a string
+is not relevant, text strings are a good choice.
+
+
+
+## Declaring Character-Like Data Objects
+
+- To work with character strings, you need character-like data objects based on the character-like types mentioned above.
+- The simplest way of producing text in an ABAP program are [character literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencharacter_literal_glosry.htm).
+The following code snippet shows a global class implementing the interface `if_oo_adt_classrun`.
+ - Using the `write` method, you can display output in the ADT console. In the example, two [untyped literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuntyped_literal_glosry.htm) without a dedicated name ([unnamed data object](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunnamed_data_object_glosry.htm)) are included.
+ - In the case below, the data type of the character literals are defined by the delimiters.
+- Text string literals are enclosed in backquotes (\`...\`) and have the data type `string`.
+- Text field literals are enclosed in single quotes (`'...'`) and have the data type `c`.
+- The literals can be (but should not according to the [programming guidelines on literals (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenliterals_guidl.htm)) used like constants of these types in [operand positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm). They should be only used for start values when declaring [named data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm).
+
+```abap
+CLASS zcl_some_test_class DEFINITION PUBLIC FINAL CREATE PUBLIC.
+ PUBLIC SECTION.
+ INTERFACES if_oo_adt_classrun.
+ENDCLASS.
+
+CLASS zcl_some_test_class IMPLEMENTATION.
+ METHOD if_oo_adt_classrun~main.
+ out->write( `I am a text string literal` ). "text string literal of type string
+ out->write( 'I am a text field literal' ). "text field literal of type c
+ ENDMETHOD.
+ENDCLASS.
+```
+
+- [Named](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennamed_data_object_glosry.htm) character-like data types and objects can be declared like other types and objects using [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm), [`DATA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapdata.htm) [`CONSTANTS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconstants.htm) and by referring to a character-like data type.
+- In addition, character-like data objects can be declared inline with the operators `DATA` and [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm).
+
+Syntax examples:
+``` abap
+"Type declarations using built-in types
+
+TYPES: c_type TYPE c LENGTH 3, "Explicit length specification
+ str_type TYPE string.
+
+"Data object declarations using built-in, local and DDIC types
+
+DATA: flag TYPE c LENGTH 1, "Built-in type
+ str1 TYPE string, "Built-in type
+ char1 TYPE c_type, "Local type
+ str2 LIKE str1, "Deriving type from a local data object
+ str3 TYPE str_type, "Local type
+ char2 TYPE s_toairp, "DDIC type (used e. g. for a field in a demo table)
+ char3 TYPE zdemo_abap_flsch-carrid. "Using the type of a DDIC table component
+
+"You may also encounter declarations with type c and the length
+"specified in parentheses. This is not recommended, to avoid confusion
+"with the use of parentheses in dynamic programming.
+
+DATA char(4) TYPE c.
+
+"Just a TYPE c specification without length means LENGTH 1.
+DATA char_len_one TYPE c.
+"No type and length specification: TYPE c LENGTH 1 by default
+DATA char_no_type_len.
+```
+
+
+
+## Assigning Values
+
+- When you declare character-like data objects, you can specify start values directly with the `VALUE` addition, e.g. `DATA chars TYPE c LENGTH 3 VALUE 'abc'.`.
+- You can do value assignments to data objects using the the [assignment operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenassignment_operator_glosry.htm "Glossary Entry") `=`.
+- As mentioned above, you can declare character-like data objects inline using the operators `DATA` or `FINAL`.
+- You can use the operators at many [write positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwrite_position_glosry.htm "Glossary Entry").
+- Unlike the `VALUE` addition of the declaration statements, inline declarations allow you to declare variables for the results of expressions or at other positions where character strings are returned.
+- In the case below, a variable specified in parentheses preceded by `DATA` (or `FINAL`) on the left side of the assignment operator automatically derives a data type from the operand on the right. This helps to make your
+programs leaner.
+
+Syntax examples:
+``` abap
+"Data object declarations including default values with VALUE
+"Note the chained statement: DATA followed by a colon, listing the data object declarations,
+"separated by a comma.
+DATA: flag TYPE c LENGTH 1 VALUE 'X',
+ str1 TYPE string VALUE `Hallo!`.
+
+"Examples for type n
+DATA zip_code TYPE n LENGTH 5 VALUE '12345'.
+DATA isbn_number TYPE n LENGTH 13 VALUE '1234567890123'.
+
+"Constant; content cannot be changed at runtime
+CONSTANTS pi TYPE p LENGTH 8 DECIMALS 14 VALUE '3.14159265358979'.
+
+"More data object declarations
+DATA: char1 TYPE c LENGTH 5,
+ html TYPE string,
+ str2 LIKE html.
+
+"Value assignments
+char1 = 'ab123'.
+html = `
hallo
`.
+
+"Escaping backquotes in text string literals with another one
+str1 = `This is a backquote: ``.`.
+
+"If possible, avoid unnecessary type conversion; in principle, every
+"convertible type can be specified
+str2 = 'abc'. "Fixed length string assigned to data object of type string
+DATA str3 TYPE string VALUE 'X'. "type c length 1
+DATA str4 TYPE string VALUE -1. "type i
+
+"Inline declarations
+DATA(char2) = 'abcd'. "Type c length 4
+DATA(str5) = `efgh`.
+
+"You can use FINAL to create immutable variables.
+FINAL(final_string) = `zyx`.
+
+"Since char2 is of type c length 4 (the length is also derived),
+"characters are truncated in the following example assignment
+char2 = 'ijklmnopq'. "ijkl
+
+"Trailing blanks after assigning fixed length to variable length string
+DATA(char3) = 'ab '.
+DATA(str6) = `cdefgh`.
+str6 = char3. "'ab' (trailing blanks are not respected due to conversion rule)
+```
+
+- When assigning strings, not only data objects can be placed on the right
+side. Various expressions and strings can be concatenated using the
+[concatenation
+operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_operator_glosry.htm "Glossary Entry")
+`&&`.
+- Alternatively, you can concatenate strings using [string
+templates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_template_glosry.htm "Glossary Entry"), as described in the *Concatenating Strings* section.
+``` abap
+str5 = str3 && ` ` && str4 && `!`. "X 1-!
+"Note the output for str4 that includes the conversion of type i to
+"string above demonstrating a possibly inadvertent specification
+"of an integer value for str4 that is of type string.
+```
+
+Note that there is also the [literal
+operator](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator_glosry.htm "Glossary Entry")
+`&` that joins [text string
+literals](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentext_string_literal_glosry.htm "Glossary Entry"),
+however, with [significant
+differences](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenliteral_operator.htm)
+to `&&`.
+
+
+
+## String Templates
+- Using string templates, you can construct strings very elegantly from
+literal text and - which is the primary use case - by including
+embedded ABAP
+[expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexpression_glosry.htm "Glossary Entry")
+within a pair of delimiters (`|...|`) if these expressions can be converted to `string`.
+- To embed expressions, you enclose them in curly brackets: `{ ... }`.
+
+> **💡 Note**
+> String templates form a [string
+expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_expression_glosry.htm "Glossary Entry")
+that is compiled at runtime. Therefore, a string template that contains only
+literal text is treated as an expression, which has a performance impact. In such a case, it is preferable to use a text string literal with backquotes.
+
+Syntax examples:
+``` abap
+"Value assignment with string templates
+"The expression must be convertible to a string. A blank (not within the curly brackets)
+"means a blank in the resulting string.
+DATA(s1) = |Hallo { cl_abap_context_info=>get_user_technical_name( ) }!|.
+
+DATA(s2) = `How are you?`. "Literal text only with backquotes
+DATA(s3) = |{ s1 } { s2 }|. "Hallo NAME! How are you?
+
+"Chaining of string templates using &&
+DATA(s4) = |{ s1 }| && ` ` && |{ s2 }|. "Hallo NAME! How are you?
+```
+
+- String templates interpret certain character combinations as [control
+characters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstring_templates_separators.htm).
+- For example, `\n` is interpreted as a newline. A new line is
+started.
+- String templates also support various [formatting
+options](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcompute_string_format_options.htm).
+- Refer to the ABAP Keyword Documentation for all options.
+
+The following syntax examples demonstrate a selection:
+```abap
+"Control characters
+s4 = |{ s1 }\n{ s2 }\nSee you.|. "\n is interpreted as a line feed
+
+"Excursion: Class CL_ABAP_CHAR_UTILITIES provides attributes and methods as utilities for string processing.
+"See the class documentation
+"The following examples demonstrate that attributes that contain control characters can be replaced by
+"a representation of control characters in a string template.
+ASSERT cl_abap_char_utilities=>newline = |\n|.
+ASSERT cl_abap_char_utilities=>horizontal_tab = |\t|.
+ASSERT cl_abap_char_utilities=>cr_lf = |\r\n|.
+
+"Various formatting options
+"DATE: Defining the format of a date
+"The output is just an example and depends on your settings.
+DATA(d) = |The date is { cl_abap_context_info=>get_system_date( ) DATE = USER }.|. "The date is 01/01/2024.
+d = |{ cl_abap_context_info=>get_system_date( ) DATE = RAW }|. "20240101
+d = |{ cl_abap_context_info=>get_system_date( ) DATE = ISO }|. "2024-01-01
+d = |{ cl_abap_context_info=>get_system_date( ) DATE = ENVIRONMENT }|. "01/01/2024
+
+"TIME: Defining the format of a time
+"The output is just an example and depends on your settings.
+DATA(tm) = |The time is { cl_abap_context_info=>get_system_time( ) TIME = ISO }.|. "The time is 14:37:24.
+tm = |{ cl_abap_context_info=>get_system_time( ) TIME = RAW }|. "143724
+tm = |{ cl_abap_context_info=>get_system_time( ) TIME = USER }|. "14:37:24
+tm = |{ cl_abap_context_info=>get_system_time( ) TIME = ENVIRONMENT }|. "14:37:24
+
+"TIMESTAMP: Defining the format of a time stamp
+"The output is just an example and depends on your settings.
+DATA(ts) = |{ utclong_current( ) TIMESTAMP = SPACE }|. "2024-01-01 14:39:50.4069170
+ts = |{ utclong_current( ) TIMESTAMP = ISO }|. "2024-01-01T14:39:50,4071110
+ts = |{ utclong_current( ) TIMESTAMP = USER }|. "01/01/2024 14:39:50.4072010
+ts = |{ utclong_current( ) TIMESTAMP = ENVIRONMENT }|. "01/01/2024 14:39:50.4073230
+ts = |{ utclong_current( ) }|. "2024-01-01 14:39:50.4074060
+
+"TIMEZONE: Defining the format of a time stamp using the rules for time zones
+DATA(tz) = |{ utclong_current( ) TIMEZONE = 'UTC' }|. "2024-12-30 14:43:20.6534640
+tz = |{ utclong_current( ) TIMEZONE = 'CET' COUNTRY = 'DE ' }|. "30.12.2024 15:43:20,6536320
+tz = |{ utclong_current( ) TIMEZONE = 'EST' COUNTRY = 'US ' }|. "12/30/2024 09:43:20.6889180 AM
+
+"CASE: Lowercase and uppercase
+s1 = |AbCdEfG|.
+s2 = |{ s1 CASE = LOWER }|. "abcdefg
+s2 = |{ s1 CASE = UPPER }|. "ABCDEFG
+
+"WIDTH/ALIGN
+s1 = `##`.
+s2 = |{ s1 WIDTH = 10 ALIGN = LEFT }<---|. "'## <---'
+s2 = |{ s1 WIDTH = 10 ALIGN = CENTER }<---|. "' ## <---'
+
+"PAD: Used to pad any surplus places in the result with the specified character.
+s2 = |{ s1 WIDTH = 10 ALIGN = RIGHT PAD = `.` }<---|. "'........##<---'
+
+"DECIMALS
+s1 = |{ CONV decfloat34( - 1 / 3 ) DECIMALS = 3 }|. "'-0.333'
+
+"SIGN: Defining the format of the +/- sign when the string represented
+"by the embedded expression represents a numeric value
+"- left without space, no +
+s1 = |{ +1 SIGN = LEFT }|. "1
+"- and + left without space
+s1 = |{ 1 SIGN = LEFTPLUS }|. "+1
+"- left without space, blank left for +
+s1 = |{ 1 SIGN = LEFTSPACE }|. " 1
+"- right without space, no +
+s1 = |{ -1 SIGN = RIGHT }|. "1-
+"- and + right without space
+s1 = |{ 1 SIGN = RIGHTPLUS }|. "1+
+"- left without space, blank right for +
+s1 = |{ +1 SIGN = RIGHTSPACE }|. "1
+
+"ZERO: Defining the format of the numeric value zero.
+"Only to be specified if the embedded expression has a numeric data type.
+s1 = |'{ 0 ZERO = NO }' and '{ 0 ZERO = YES }'|. "'' and '0'
+
+"XSD: Formatting is applied to an embedded expression (elementary data types) in asXML format that is
+"assigned to its data type. Check the information in the ABAP Keyword Documentation about the asXML
+"mapping of elementary ABAP types.
+DATA xstr TYPE xstring VALUE `41424150`.
+DATA dat type d value '20240101'.
+DATA tim type t value '123456'.
+DATA(utc) = utclong_current( ). "e.g. 2024-01-01 13:51:38.5708800
+
+s1 = |{ xstr XSD = YES }|. "QUJBUA==
+s1 = |{ dat XSD = YES }|. "2024-01-01
+s1 = |{ tim XSD = YES }|. "12:34:56
+s1 = |{ utc XSD = YES }|. "2024-01-01T13:51:38.57088Z
+
+"STYLE: Defining the style of decimal floating point numbers;
+"see the details in the ABAP Keyword Documentation.
+DATA(dcfl34) = CONV decfloat34( '-123.45600' ).
+s1 = |{ dcfl34 }|. "-123.456
+"Creates the predefined format
+s1 = |{ dcfl34 STYLE = SIMPLE }|. "-123.456
+"+/- added to the right, removes trailing zeros
+s1 = |{ dcfl34 STYLE = SIGN_AS_POSTFIX }|. "123.456-
+"Retains trailing zeros
+s1 = |{ dcfl34 STYLE = SCALE_PRESERVING }|. "-123.45600
+"Scientific notation; at least a two digit exponent with a plus/minus sign
+s1 = |{ dcfl34 STYLE = SCIENTIFIC }|. "-1.23456E+02
+"Scientific notation; only one integer digit with the value 0
+s1 = |{ dcfl34 STYLE = SCIENTIFIC_WITH_LEADING_ZERO }|. "-0.123456E+03
+"Scientific notation; exponent has 3 digits for decfloat16 and 4 digits for decfloat34
+s1 = |{ dcfl34 STYLE = SCALE_PRESERVING_SCIENTIFIC }|. "-1.2345600E+0002
+"Technical format
+s1 = |{ dcfl34 STYLE = ENGINEERING }|. "-123.456E+00
+
+"ALPHA: Adds or removes leading zeros from strings of digits; the data type
+"must be string, c, or n
+"Adding leading zeros
+"Additionally specifying WIDTH
+"Note: The specified length is only used if it is greater than
+"the length of provided string (without leading zeros)
+s1 = |{ '1234' ALPHA = IN WIDTH = 10 }|. "0000001234
+s1 = |{ '00000000000000000000000012' ALPHA = IN WIDTH = 10 }|. "0000000012
+"Fixed-length string provided, WIDTH not specified
+s1 = |{ ' 12' ALPHA = IN }|. "00012
+"Removing leading zeros
+s1 = |{ '00001234' ALPHA = OUT }|. "1234
+"Do not apply formatting
+s1 = |{ '00001234' ALPHA = RAW }|. "00001234
+```
+
+> **💡 Note**
+> Escape `\|{}` in string templates using `\`, i. e. `\\` means `\`.
+
+
+
+## Determining the Length of Strings
+
+- To determine the length of a string, you can use the string function
+[`strlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm).
+- Note that the result depends on the type of the string, i. e. the result for a data object of type `string` includes trailing blanks. A
+fixed-length string does not include them.
+- To exclude trailing blanks in all cases, regardless of the data type, you can use the built-in
+[`numofchar`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm) function.
+
+Syntax examples:
+``` abap
+"strlen
+DATA(len_c) = strlen( 'abc ' ). "3
+DATA(len_str) = strlen( `abc ` ). "6
+
+"numofchar
+len_c = numofchar( 'abc ' ). "3
+len_str = numofchar( `abc ` ). "3
+```
+
+
+
+## Concatenating Strings
+
+- Two or more strings can be concatenated using the concatenation operator
+`&&` and string templates. Alternatively, you can use
+[`CONCATENATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapconcatenate.htm)
+statements.
+- It is also possible to concatenate lines from internal tables
+into a string to avoid a loop.
+- A more modern way is to use
+the string function
+[`concat_lines_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconcatenation_functions.htm).
+
+Syntax examples:
+``` abap
+"&& and string template
+DATA(s1) = `AB` && `AP`. "ABAP
+DATA(s2) = `ab` && `ap` && ` ` && s1. "abap ABAP
+DATA(s3) = |{ s1 }. { s2 }!|. "ABAP. abap ABAP!
+
+"CONCATENATE statements
+CONCATENATE s1 s2 INTO s3. "ABAPabap ABAP
+
+"Multiple data objects and target declared inline
+CONCATENATE s1 ` ` s2 INTO DATA(s5). "ABAP abap ABAP
+
+CONCATENATE s1 s2 s5 INTO DATA(s6). "ABAPabap ABAPABAP abap ABAP
+
+"You can also add a separation sign using the addition SEPARATED BY
+CONCATENATE s1 s2 INTO s3 SEPARATED BY ` `. "ABAP abap ABAP
+
+CONCATENATE s1 s2 INTO s3 SEPARATED BY `#`. "ABAP#abap ABAP
+
+"Keeping trailing blanks in the result when concatenating fixed length
+"strings. The ones of variable length strings are respected by default.
+CONCATENATE 'a ' 'b ' 'c ' INTO DATA(ch) RESPECTING BLANKS. "'a b c '
+
+"Concatenating lines of internal tables into a string
+CONCATENATE LINES OF itab INTO t SEPARATED BY ` `.
+
+"Using concat_lines_of
+s1 = concat_lines_of( table = itab ). "Without separator
+s1 = concat_lines_of( table = itab sep = ` ` ). "With separator
+```
+
+
+
+## Splitting Strings
+
+- You can use
+[`SPLIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsplit.htm)
+statements to split strings in multiple segments.
+- The result of the
+split can be stored in separate data objects or internal tables that
+have a character-like line type.
+- Note that if the number of specified targets is
+less than the number of segments returned by the split, the last target receives the remaining unsplit segements. If more targets are specified, the targets that do not receive a segment are
+initialized.
+- Therefore, specifying individual targets with `SPLIT`
+statements is useful if the number of expected segments is known.
+Otherwise, splitting into tables is a good choice.
+- If you want to get the value of a particular segment, you can use the
+string function
+[`segment`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensegment_functions.htm).
+
+Syntax examples:
+``` abap
+DATA(s1) = `Hallo,world,123`.
+DATA: s2 TYPE string,
+ s3 TYPE string,
+ s4 TYPE string.
+
+SPLIT s1 AT `,` INTO s2 s3 s4. "s2 = Hallo / s3 = world / s4 = 123
+
+"Less data objects than possible splittings
+SPLIT s1 AT `,` INTO s2 s3. "s2 = Hallo / s3 = world,123
+
+"Splitting into internal table
+DATA itab TYPE TABLE OF string.
+SPLIT s1 AT ',' INTO TABLE itab. "Strings are added to itab in individual lines without comma
+
+"String function segment returning the occurrence of a segment
+"index parameter: number of segment
+s2 = segment( val = s1 index = 2 sep = `,` ). "world
+```
+
+
+
+## Modifying Strings
+### Transforming to Lowercase and Uppercase
+
+- The string functions
+[`to_lower`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm)
+and
+[`to_upper`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencase_functions.htm)
+transform characters of a string to either lowercase or uppercase and
+store the result in a target variable.
+- If you want to apply the transformation to the source directly, you can use
+[`TRANSLATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptranslate.htm)
+statements.
+
+Syntax examples:
+``` abap
+"String functions
+DATA(s1) = to_upper( `abap` ). "ABAP
+s1 = to_lower( `SOME_FILE.Txt` ). "some_file.txt
+
+"TRANSLATE statements
+s1 = `Hallo`.
+TRANSLATE s1 TO UPPER CASE. "HALLO
+TRANSLATE s1 TO LOWER CASE. "hallo
+```
+
+
+
+### Shifting Content
+
+- You can shift content within a string to a specific position on the left
+or right of a string.
+[`SHIFT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapshift.htm)
+statements have various additions for specific use cases.
+- In a more modern way, you can use the string functions
+[`shift_left`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm)
+and
+[`shift_right`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshift_functions.htm), which store the result in a variable.
+ - These functions provide additional
+functionality. The `sub` parameter can be used to specify a
+substring. All substrings in the string that match the value specified
+in `sub` on either the left or right side of the string are
+removed.
+
+Syntax examples:
+``` abap
+"SHIFT statements
+"Note that all results below refer to s1 = `hallo`.
+DATA(s1) = `hallo`. "Type string
+
+SHIFT s1. "No addition; string shifted one place to the left: allo
+SHIFT s1 BY 2 PLACES. "Without direction, left by default: llo
+SHIFT s1 BY 3 PLACES RIGHT. "With direction, variable length strings are extended: ' hallo'
+
+"Note that all results below refer to ch4 = 'hallo'.
+DATA(ch4) = 'hallo'. "Type c length 5
+
+SHIFT ch4 BY 3 PLACES RIGHT. "Fixed length string: ' ha'
+
+"CIRCULAR addition: characters that are moved out of the string are
+"added at the other end again
+SHIFT ch4 BY 3 PLACES LEFT CIRCULAR. "lohal
+SHIFT ch4 UP TO `ll`. "Shift characters up to a specific character set: llo
+
+"Deleting leading and trailing characters
+DATA(s2) = ` hallo `.
+DATA(s3) = s2.
+
+SHIFT s2 LEFT DELETING LEADING ` `. "'hallo '
+SHIFT s3 RIGHT DELETING TRAILING ` `. "' hallo' (length is kept)
+
+"Removing trailing blanks in strings without leading blanks;
+"you can use the following sequence of statements
+DATA(s4) = `hallo `.
+SHIFT s4 RIGHT DELETING TRAILING ` `. "' hallo'
+SHIFT s4 LEFT DELETING LEADING ` `. "'hallo'
+
+"String functions with parameters
+s1 = `hallo`.
+
+s2 = shift_left( val = s1 places = 3 ). "lo
+s2 = shift_left( val = s1 circular = 2 ). "lloha
+
+"Note that shift_right does not extend a variable length string.
+s2 = shift_right( val = s1 places = 3 ). "ha
+s2 = shift_right( val = `abc ` sub = ` ` ). "'abc'
+s2 = shift_right( val = `abc ` ). "'abc' (same result as above)
+```
+
+
+
+### Condensing Strings
+
+- You can use
+[`CONDENSE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcondense.htm)
+statements or the string function
+[`condense`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencondense_functions.htm)
+to remove blanks from strings.
+- The advantage of using the string function
+is that you can specify any character to remove, not just blanks.
+
+Syntax examples:
+``` abap
+"CONDENSE statements
+DATA(s1) = ` ab cd `.
+DATA(s2) = ` ef gh ij `.
+DATA(s3) = ` kl mn op `.
+
+CONDENSE s1. "Trailing and leading blanks are removed: 'ab cd'
+CONDENSE s2. "It also replaces sequences of multiple blanks with a single blank: 'ef gh ij'
+CONDENSE s3 NO-GAPS. "Removes all blanks: 'klmnop'
+
+"String function condense
+s1 = ` ab cd `.
+
+"No parameters specified, i. e. their default values are provided.
+"Works like CONDENSE statement without the NO-GAPS addition.
+s2 = condense( s1 ). "ab cd
+
+"Parameters del/to not specified. from parameter with initial string
+"(could also be a text field literal: from = ' '). This way, leading and
+"trailing blanks are removed.
+s2 = condense( val = s1 from = `` ). "ab cd
+
+"Parameter to specified with an initial string. No other parameters.
+"Works like CONDENSE statement with the NO-GAPS addition.
+s2 = condense( val = s1 to = `` ). "abcd
+
+"Parameter del specifies the leading/trailing characters to be removed.
+s2 = condense( val = `##see###you##` del = `#` ). "see###you
+
+"If from and to are specified along with del, leading/trailing
+"characters specified in del are first removed. Then, in the remaining string, all
+"substrings composed of characters specified in from are replaced with
+"the first character of the string specified in the to parameter
+s2 = condense( val = ` Rock'xxx'Roller`
+ del = `re `
+ from = `x`
+ to = `n` ). "Rock'n'Roll
+```
+
+
+
+### Inserting Substrings into Strings
+
+- The string function
+[`insert`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninsert_functions.htm)
+inserts a substring at any position within a given string. You can use various parameters to construct the string you want:
+ - `val`: Original string.
+ - `sub`: Substring.
+ - `off`: Optionally sets the offset, i.e. the position where the substring should be added. The default value is 0. When using the function with the default value, the result is like concatenating a string with `&&` (like `res = sub && text`).
+- Inserting substrings can also be accomplished using the string function `replace` or `REPLACE` statements, which are are covered below.
+
+Syntax examples:
+``` abap
+"Result: 'abcdefghi'
+DATA(s1) = insert( val = `abcghi` sub = `def` off = 3 ).
+
+"Result: 'defabcghi'
+s1 = insert( val = `abcghi` sub = `def` ).
+```
+
+
+
+### Overlaying Content
+
+You can use [`OVERLAY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapoverlay.htm) statements to replace characters in one variable with characters in another variable that are in the same place there.
+
+Syntax examples:
+``` abap
+DATA(incl) = '==============================CP'.
+DATA(cl_name) = 'CL_SOME_CLASS '.
+
+"Addition ONLY is not specified: All blanks are replaced
+OVERLAY cl_name WITH incl.
+"cl_name: CL_SOME_CLASS=================CP
+
+DATA(txt1) = 'a.b.c.a.b.c.A'.
+DATA(txt2) = 'z.x.y.Z.x.y.z'.
+
+"Addition ONLY is specified: All characters that are specified after ONLY and that
+"occur in the operand are replaced. Note that this is case-sensitive.
+OVERLAY txt1 WITH txt2 ONLY 'ab'.
+"txt1: z.x.c.Z.x.c.A
+```
+
+
+
+## Processing Substrings
+
+- The string function
+[`substring`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm) allows you to specify the position (parameter `off`) and the length
+(`len`) of a substring to be extracted from a given
+string (`val`).
+ - At least one of the two parameters `off`
+or `len` must be specified. The default value of `off`
+is 0, i.e. when using the default value, the substring is extracted
+from the beginning of the string.
+ - If `len` is not specified, the rest of the remaining characters is respected. If the offset
+and length are greater than the actual length of the string, the
+exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised.
+- You may also encounter the syntax for accessing substrings by specifying the offset
+and length using the `+` character after a variable.
+ - The length is specified in parentheses. Specifying an asterisk (`*`) means
+that the rest of the remaining string is respected.
+ - This syntax option
+even allows write access to substrings for fixed-length strings. Read
+access is possible for both fixed-length and variable-length strings.
+ - However, this syntax can be confused with the use of tokens in the
+context of dynamic programming.
+- There are other string functions available for dealing with substrings, such as
+[`substring_after`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm),
+[`substring_before`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm),
+[`substring_from`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm)
+and
+[`substring_to`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm).
+ - These functions offer more options in terms of parameters, such as the use of [PCRE regular
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry"),
+which are covered below.
+
+Syntax examples:
+``` abap
+DATA(s1) = `Lorem ipsum dolor sit amet`. "Type string
+
+"Extracting substring starting at a specific position
+"'len' not specified means the rest of the remaining characters is
+"respected
+DATA(s2) = substring( val = s1 off = 6 ). "ipsum dolor sit amet
+
+"Extracting substring with a specific length
+"'off' is not specified and has the default value 0.
+s2 = substring( val = s1 len = 5 ). "Lorem
+
+"Specifying both off and len parameters
+s2 = substring( val = s1 off = 6 len = 5 ). "ipsum
+
+DATA(txt) = 'Lorem ipsum dolor sit amet'. "Type c
+
+"Offset and length specification using the + sign after a variable
+DATA(ch6) = txt+0(5). "Lorem
+
+"* means respecting the rest of the remaining string
+DATA(ch7) = txt+12(*). "dolor sit amet
+
+CLEAR txt+11(*). "Lorem ipsum
+
+txt+0(5) = 'Hallo'. "Hallo ipsum dolor sit amet
+
+"Further string functions
+s1 = `aa1bb2aa3bb4`.
+
+"Extracting a substring ...
+"... after a specified substring
+s2 = substring_after( val = s1 sub = `aa` ). "1bb2aa3bb4 (only the first occurrence is respected)
+
+"... after a specified substring specifying the occurence in a string
+"and restricting the length
+s2 = substring_after( val = s1 sub = `aA` occ = 2 len = 4 case = abap_false ). "3bb4
+
+"... before a specified substring
+s2 = substring_before( val = s1 sub = `b2` ). "aa1b
+
+"... from a specified substring on. It includes the substring specified
+"in sub. len/off and other parameters are possible.
+s2 = substring_from( val = s1 sub = `a3` ). "a3bb4
+
+"... up to a specified substring. It includes the substring specified
+"in sub. len/off and other parameters are possible.
+s2 = substring_to( val = s1 sub = `3b` ). "aa1bb2aa3b
+```
+
+
+
+## Searching and Replacing
+
+- In ABAP, there are many ways to perform search and replace
+operations on strings. These include the use of [comparison
+operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
+or the ABAP statements
+[`FIND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)
+and
+[`REPLACE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace.htm),
+or the more modern built-in string functions
+[`find`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
+and
+[`replace`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreplace_functions.htm),
+among others, with their considerable number of additions and parameters.
+- Many of these options support rather simple operations
+on single characters only or more complex, pattern-based
+operations on character sequences using [PCRE regular
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry").
+
+
+
+### Searching for Specific Characters
+
+- You can use the [comparison
+ operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
+ [`CA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains any) or its negation
+ [`NA`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains not any) in [comparison
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry")
+ to determine whether any character of a given character set is contained
+ in a string. Such an expression is true if at least one character is
+ found.
+ - The search is case-sensitive.
+ - The system variable `sy-fdpos` contains the offset of
+ the first character found. If nothing is found,
+ `sy-fdpos` contains the length of the string.
+ - Note that offset 0 represents the very first position.
+- The string functions
+ [`find_any_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
+ and its negation
+ [`find_any_not_of`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
+ return the offset of the occurrence of any character contained in a
+ substring. They are special variants of the string function `find`, which is shown below.
+ - If nothing is found, the value -1 is returned.
+ - Other optional parameters are possible. For example, the
+ specification of `occ` determines the search
+ direction, i.e. a positive value means that the search is performed
+ from left to right. A negative value means to search from right
+ to left.
+- If you are not interested in the position of characters, but rather how
+ often they occur in a string, you can use the string function
+ [`count`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencount_functions.htm), as well as the special variants `count_any_of` and its negation `count_any_not_of`.
+- To determine whether a string contains only a certain set of characters,
+ you can use the comparison operators
+ [`CO`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains only) or its negation
+ [`CN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains not only) in comparison expressions.
+ - For `CO`, a comparison is true if the left operand
+ contains only characters that are also contained in the right
+ operand. If the comparison returns false, you can use `sy-fdpos` to get the position
+ of the first character from text that is not contained in the
+ character.
+ - For `CN`, a
+ comparison is true if a string contains characters other than those in the character set.
+
+Syntax examples:
+``` abap
+DATA(s1) = `cheers`.
+IF s1 CA `aeiou` ... "true, sy-fdpos = 2
+IF s1 NA `xyz`... "true, sy-fdpos = 6
+
+IF s1 CO `rs` ... "false, sy-fdpos = 0
+IF s1 CN `cheers` ... "false, sy-fdpos = 6
+```
+
+Built-in functions:
+
+``` abap
+"Note that the functions may contain more parameters than those covered in the snippet.
+DATA(str) = `Pieces of cakes.`.
+DATA res TYPE i.
+
+"find_end returns the sum of the offset of the occurrence
+res = find_end( val = str sub = `of` ). "9
+
+"find_any_of returns the offset of the occurrence of any character contained in substring
+"The search is always case-sensitive.
+res = find_any_of( val = str sub = `x523z4e` ). "2 (character e is found)
+res = find_any_of( val = str sub = `zwq85t` ). "-1
+
+"find_any_not_of: Negation of the one above
+"The search is always case-sensitive.
+res = find_any_not_of( val = str sub = `ieces` ). "0 (very first character in the searched string)
+res = find_any_not_of( val = str sub = `P` ). "1
+
+"count returns the number of all occurrences
+res = count( val = str sub = `e` ). "3
+res = count( val = str sub = `x` ). "0
+
+"count_any_of
+res = count_any_of( val = str sub = `x523z4e` ). "3
+res = count_any_of( val = str sub = `eco` ). "6
+
+"count_any_not_of
+res = count_any_not_of( val = str sub = `fP` ). "14
+res = count_any_not_of( val = str sub = `Piecs ofak.` ). "0
+```
+
+
+
+
+### Replacing Specific Characters in Strings
+
+- You can use the string function
+[`translate`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentranslate_functions.htm)
+to replace certain characters with others.
+ - The
+`from` parameter specifies the characters to be placed in a string, and
+the `to` parameter specifies the target characters.
+ - Note: The
+replacement is performed as follows: Each character specified in
+`from` is replaced by the character in `to` that is at
+the same position, i.e. the second character in `from` is
+replaced by the second character specified in `to`. If there is
+no equivalent in `to`, the character in `from` is
+removed from the result.
+- You can use
+[`TRANSLATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptranslate.htm)
+statements to perform replacements directly on the source field.
+
+Syntax examples:
+``` abap
+DATA(s1) = `___abc_def_____ghi_`.
+DATA(s2) = translate( val = s1 from = `hi_` to = `##` ). "abcdefg##
+s2 = translate( val = s1 from = `_` to = `##` ). "###abc#def#####ghi#
+
+"TRANSLATE statement. The value after USING is interpreted as a string composed of character pairs.
+"Starting with the first pair, a search is performed in text for the
+"first character in every pair and each occurrence is replaced with the
+"second character of the pair.
+TRANSLATE s1 USING `_.a#g+`. "...#bc.def.....+hi.
+```
+
+
+
+### Searching for Substrings in Strings
+
+- For simple substring searches, you can use the [comparison
+ operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
+ [`CS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains string) or its negation
+ [`NS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+ (contains no string) in [comparison
+ expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry").
+ The search is not case-sensitive.
+- The system variable
+ `sy-fdpos` contains the offset of the found substring. If
+ the substring is not found, `sy-fdpos` contains the length
+ of the searched string.
+
+``` abap
+DATA(s3) = `cheers`.
+
+IF s3 CS `rs` ... "true, sy-fdpos = 4 (offset)
+
+IF s3 CS `xy`... "false, sy-fdpos = 6 (length of string)
+
+IF s3 NS `ee`... "false, sy-fdpos = 2 (offset)
+
+IF s3 NS `xy`... "true, sy-fdpos = 6 (length of string)
+```
+
+For more complex and iterative searches, you may want to use `FIND` statements or the string functions below.
+
+- `FIND`
+ - Used to search for a character sequence.
+ - Has a rich set of additions, a selection of which is covered in this cheat sheet. See [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm) for more information. Byte string processing is not included (there are special additions).
+ - Sets the system fields `sy-subrc`: 0 (search pattern found at least once) or 4 (search pattern not found).
+
+Syntax Overview (see the syntax diagram in the [ABAP Keyword Documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind.htm)):
+
+``` abap
+FIND
+ FIRST OCCURRENCE OF "(or) ALL OCCURRENCES OF
+ "1. Only the first occurrence is searched
+ "2. All occurrences are searched
+ "Note: If none of these two additions is specified, only the first occurrence is searched for.
+
+ SUBSTRING some_substring "(or) PCRE some_regex
+ "1. Searching for exactly one string, specifying SUBSTRING is optional (e.g. for emphasis);
+ " some_substring is a character-like operand; note: Trailing blanks are not ignored if it is of type string
+ "2. Searching for a substring matching a regular expression; only the PCRE addition should be used;
+ " some_regex = character-like operand; note: PCRE syntax is compiled in an extended mode, i.e. unescaped whitespaces
+ " are ignored; if the regex is too complex, a catchable exception of the class CX_SY_REGEX_TOO_COMPLEX is raised
+
+IN
+ SECTION
+ OFFSET off
+ LENGTH len
+ OF
+ "- Restricting the search to a specific section from an offset specified in off with the length len
+ "- When using SECTION, at least one of the two options must be specified
+ " - No OFFSET specification: offset 0 is used implicitly
+ " - No LENGTH specification: search from specified offset to end of string
+ " - Note: off and len are of type i; it must be a positive integer value;
+ " exception: len = -1 (same effect as not using the LENGTH addition)
+ "- Without the addition SECTION ... OF, the entire data object dobj is searched
+
+"Character-like data object
+dobj
+
+ "Further additional options for advanced evaluation options:
+ "Specifying whether the search is case-sensitive; not specified means RESEPECTING CASE by default
+ RESPECTING CASE "(or) IGNORING CASE
+
+ "Determining the number of sequences found, number stored in cnt that is of type i (e.g. a variable declared inline)
+ "When searching for the first occurrence, the value is always 1 (not found -> 0)
+ MATCH COUNT cnt
+
+ "Determining position of sequences found
+ "Note: off holds the position of the last occurrence when searching for all occurrences and if
+ "there are multiple occurrences (not found -> 0 or the previous value of a finding is retained).
+ MATCH OFFSET off
+
+ "Determining the length of sequences found
+ "Note: Similar to above, not finding an occurrence means 0 for len or the previous value of a finding is retained
+ MATCH LENGTH len
+
+ "Storing offset, length, submatches (only relevant for regular expressions) information in a table or a structure
+ "tab: of type MATCH_RESULT_TAB; especially for using with ALL OCCURRENCES
+ "struc: of type MATCH_RESULT; especially for using with FIRST OCCURRENCE
+ "Note on submatches: table of type SUBMATCH_RESULT_TAB; holds offset and length information of substrings of occurrences
+ "that are stored in subgroup registers of regular expressions; in FIND IN TABLE statements, the additional component LINE
+ "is available
+ RESULTS tab "(or) RESULTS struc
+
+ "Storing content of subgroup register of a regular expression in character-like data objects;
+ "only to be used if a regular expression pattern is specified.
+ "Note: Only the last occurrence is evaluated when using ALL OCCURRENCES; the number of the operands specified should match
+ "the number of subgroups specified
+ SUBMATCHES sub1 sub2 ...
+.
+```
+
+Examples:
+
+``` abap
+"Note: The code snippets mainly use inline declarations.
+
+DATA(str) = `She sells seashells by the seashore.`.
+
+"Determining if a substring is found
+"Simple find statement
+FIND `se` IN str.
+
+IF sy-subrc = 0.
+ "found
+ELSE.
+ "not found
+ENDIF.
+
+"Addition SUBSTRING is optional
+FIND SUBSTRING `hi` IN str.
+
+IF sy-subrc = 0.
+ "found
+ELSE.
+ "not found
+ENDIF.
+
+"The following examples use the additions MATCH COUNT and MATCH OFFSET to determine
+"the number of occurrences and offset
+
+"Addition FIRST OCCURRENCE OF: Explicit specification to search for the first occurrence
+FIND FIRST OCCURRENCE OF `se` IN str
+ MATCH COUNT DATA(cnt2) "1 (always 1 when searching and finding the first occurrence)
+ MATCH OFFSET DATA(off2). "4
+
+"Omitting FIRST OCCURRENCE OF and ALL OCCURRENCES OF addition means searching for the
+"first occurrence by default; same effect as the previous statement
+FIND `se` IN str
+ MATCH COUNT DATA(cnt1) "1
+ MATCH OFFSET DATA(off1). "4
+
+"Addition ALL OCCURRENCES: Searching for all occurrences
+FIND ALL OCCURRENCES OF `se` IN str
+ MATCH COUNT DATA(cnt3) "3
+ MATCH OFFSET DATA(off3). "27 (value for the last occurrence)
+
+"Addition IN SECTION ... OF:
+"Searching in a specified section; both additions OFFSET and LENGTH are specified
+FIND ALL OCCURRENCES OF `se`
+ IN SECTION OFFSET 9 LENGTH 5 OF str
+ MATCH COUNT DATA(cnt4) "1
+ MATCH OFFSET DATA(off4). "10
+
+"Only LENGTH specified (OFFSET is 0 by default)
+FIND ALL OCCURRENCES OF `se`
+ IN SECTION LENGTH 7 OF str
+ MATCH COUNT DATA(cnt5) "1
+ MATCH OFFSET DATA(off5). "4
+
+"Only OFFSET specified (LENGTH: up to end of string)
+FIND ALL OCCURRENCES OF `se`
+ IN SECTION OFFSET 7 OF str
+ MATCH COUNT DATA(cnt6). "2
+
+"Another string to be searched
+DATA(str_abap) = `abap ABAP abap`.
+
+"Further additional options for advanced evaluation options
+
+"Specifying the case-sensitivity of the search
+"Not specifying the CASE addition means RESPECTING CASE is used by default.
+"Here, it is explicitly specified.
+FIND FIRST OCCURRENCE OF `A` IN str_abap
+ MATCH OFFSET DATA(off7) "5
+ RESPECTING CASE.
+
+"Making search case-insensitive
+FIND FIRST OCCURRENCE OF `A` IN str_abap
+ MATCH OFFSET DATA(off8) "0
+ IGNORING CASE.
+
+"MATCH LENGTH addition
+"The example uses a regular expression: Non-greedy search for
+"a substring starting with lower case a up to an upper case P
+FIND FIRST OCCURRENCE OF PCRE `a.*?P` IN str_abap
+ MATCH LENGTH DATA(len8) "9
+ RESPECTING CASE.
+
+"RESULTS addition
+"Example: Because of using ALL OCCURRENCES, the data object declared inline automatically
+"has the type match_result_tab
+FIND ALL OCCURRENCES OF `ab` IN str_abap
+ RESULTS DATA(res9)
+ IGNORING CASE.
+
+"3 entries in table res9 (tables in SUBMATCHES are initial since no regular expression is used)
+"line: always 0 (it's not a table); length: always 2 (search for concrete occurrence of `se`)
+"1. line: 0, offset: 0, length: 2, submatches: (initial)
+"2. line: 0, offset: 5, length: 2, ...
+"3. line: 0, offset: 10, length: 2, ...
+
+"Example: Because of using FIRST OCCURRENCE, the data object declared inline automatically
+"has the type match_result
+FIND FIRST OCCURRENCE OF `ab` IN str_abap
+ RESULTS DATA(res10)
+ IGNORING CASE.
+
+"res10: line: 0, offset: 0, length: 2, submatches: (initial)
+```
+
+### Searching for Substrings in Tables
+You can use [`FIND ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_itab.htm) statements to search for substrings in internal tables (standard tables without secondary table keys; with character-like line type) line by line.
+
+``` abap
+DATA(str_table) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
+
+"Finding all occurrences in a table
+"Note: res_tab is of type match_result_tab
+"You can also restrict the search range in an internal table; see an example in REPLACE ... IN TABLE
+FIND ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ RESULTS DATA(res_tab)
+ RESPECTING CASE.
+
+"4 entries in table res_tab (tables in SUBMATCHES are initial since no regular expression is used)
+"1. line: 1, offset: 1, length: 1, submatches: (initial)
+"2. line: 1, offset: 4, length: 1, ...
+"3. line: 2, offset: 2, length: 1, ...
+"4. line: 3, offset: 0, length: 1, ...
+
+"Finding the first occurrence in a table
+"Note: res_struc, which is declared inline here, is of type match_result
+FIND FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ RESULTS DATA(res_struc)
+ RESPECTING CASE.
+
+"Entries in structure res_struc
+"line: 1, offset: 1, length: 1, submatches: (initial)
+
+"Alternative to the statement above (storing the information in individual data objects)
+FIND FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ MATCH LINE DATA(line) "1
+ MATCH OFFSET DATA(off) "1
+ MATCH LENGTH DATA(len) "1
+ RESPECTING CASE.
+```
+
+### String Function find
+- Built-in search functions, such as `find`, are available for searching strings.
+- They return a return value of type i and contain multiple (optional) parameters.
+- `FIND` covers the same functionality and more with the many addition options.
+- For more information, see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensearch_functions.htm)
+
+Parameters of the `find` function:
+- `val`:
+ - Character-like data object
+ - Note: If a fixed length string is specified, any trailing blanks are ignored.
+- `sub`:
+ - Contains what is searched for
+ - A character like expression position; expects arguments with elementary types
+ - Similar to above, trailing blanks are ignored in fixed length strings
+- `case`:
+ - Search is case-sensitive by default
+- `occ`:
+ - Specifies the occurrence of a match
+ - Must be of type `i`
+ - Values:
+ - 1: default value, searches for the first occurrence from the left
+ - any positive value: searches for the nth occurrence from the left
+ - any negative value: searches for the nth occurrence from the right
+ - 0: raises an exception (`CX_SY_STRG_PAR_VAL`), note: in the context of the `replace` function, 0 means replace all occurrences
+ - Note: Specifying `occ` affects the default values of `off` and `len`
+- `off`:
+ - Specifies the offset
+ - Must be of type `i`
+ - The default value is 0 (search from the beginning of the string)
+ - Exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised for a negative offset specified and an offset that is longer than the searched string
+- `len`:
+ - Specifies the length
+ - Must be of type `i`
+ - The default value is the length of the string (minus a defined offset in `off`)
+ - The exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised if the offset is negative and a range is not contained in the searched string
+- `pcre`: Regular expression
+
+``` abap
+DATA(str) = `Pieces of cakes.`.
+DATA res TYPE i.
+
+"Searching for substring
+"Returns offset of substring found
+res = find( val = str sub = `ca` ). "10
+
+"Substring not found returns -1
+res = find( val = str sub = `xy` ). "-1
+
+"Actual parameter of sub must not be initial when using the find function
+TRY.
+ res = find( val = str sub = `` ).
+ CATCH cx_sy_strg_par_val.
+ ...
+ENDTRY.
+
+"The search is case-sensitive by default
+res = find( val = str sub = `OF` ). "-1
+"Making search case-insensitive
+res = find( val = str sub = `OF` case = abap_false ). "7
+
+"Specifying occ
+res = find( val = str sub = `c` ). "3
+res = find( val = str sub = `c` occ = 2 ). "10
+res = find( val = str sub = `e` occ = -1 ). "13
+res = find( val = str sub = `e` occ = -3 ). "2
+
+"Specifying off and len
+"Specifying a subarea in which a string is searched
+res = find( val = str sub = `e` off = 5 ). "13
+res = find( val = str sub = `e` off = 5 len = 7 ). "-1
+res = find( val = str sub = `e` len = 2 ). "-1
+
+TRY.
+ res = find( val = str sub = `e` off = 5 len = 15 ).
+ CATCH cx_sy_range_out_of_bounds.
+ ...
+ENDTRY.
+```
+
+
+
+### Replacing Substrings in Strings
+
+- [`REPLACE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace.htm) and [`REPLACE ... IN TABLE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreplace_itab.htm) statements have a similar syntax as `FIND` and `FIND ... IN TABLE` statements. Refer to the ABAP Keyword Documentation for all possible additions. The following code snippets cover a selection.
+- `sy-subrc` is set: 0 (search pattern or section was replaced by the specified content, result was not truncated on the right), 2 (search pattern or section was replaced, result was truncated on the right), 4 (search pattern was not found).
+- `REPLACE` statements can be used to directly replace strings (including substrings, which is not possible with the string function).
+
+``` abap
+"Examples for pattern-based replacements in which data objects are searched for character strings
+"specified in a pattern and the occurrences are replaced
+
+DATA(str_original) = `abap ABAP abap`.
+DATA(str) = str_original.
+
+"Simple REPLACE statement
+"Omitting the FIRST OCCURRENCE and ALL OCCURRENCES OF additions means
+"replacing the first occurrence by default.
+REPLACE `ab` IN str WITH `##`. "##ap ABAP abap
+
+str = str_original.
+
+"Addition SUBSTRING is optional
+REPLACE SUBSTRING `ab` IN str WITH `##`. "##ap ABAP abap
+
+str = str_original.
+
+"Addition FIRST OCCURRENCE OF: Explicit specification to replace the
+"first occurrence; same effect as the statements above
+REPLACE FIRST OCCURRENCE OF `ab` IN str WITH `##`. "##ap ABAP abap
+
+str = str_original.
+
+"Addition ALL OCCURRENCES OF: All occurrences are replaced
+"Note that the replacement is case-sensitive by default.
+REPLACE ALL OCCURRENCES OF `ab` IN str WITH `##`. "##ap ABAP ##ap
+
+str = str_original.
+
+"Further additional options for advanced evaluation options
+
+"IGNORING CASE addition: Making replacements case-insensitive
+REPLACE ALL OCCURRENCES OF `ab`
+ IN str WITH `##`
+ IGNORING CASE. "##ap ##AP ##ap
+
+str = str_original.
+
+"REPLACEMENT COUNT addition
+REPLACE ALL OCCURRENCES OF `ab`
+ IN str WITH `##`
+ REPLACEMENT COUNT DATA(cnt1) "3
+ IGNORING CASE.
+
+str = str_original.
+
+"REPLACEMENT OFFSET and LENGTH additions
+REPLACE FIRST OCCURRENCE OF `ap`
+ IN str WITH `##`
+ REPLACEMENT COUNT DATA(cnt2) "1 (always 1 for replaced first occurrence)
+ REPLACEMENT OFFSET DATA(off2) "2
+ REPLACEMENT LENGTH DATA(len2) "2
+ IGNORING CASE. "ab## ABAP abap
+
+str = str_original.
+
+"SECTION ... OF addition: Replacing within a specified area
+REPLACE ALL OCCURRENCES OF `ap`
+ IN SECTION OFFSET 4 LENGTH 5
+ OF str WITH `##`
+ REPLACEMENT COUNT DATA(cnt3) "1
+ REPLACEMENT OFFSET DATA(off3) "2
+ REPLACEMENT LENGTH DATA(len3) "2
+ IGNORING CASE. "abap AB## abap
+
+str = str_original.
+
+"RESULTS additions with ...
+"... ALL OCCURRENCES OF
+"Note: repl_tab, which is declared inline here, is of type repl_result_tab
+REPLACE ALL OCCURRENCES OF `ap`
+ IN str WITH `##`
+ RESULTS DATA(repl_tab)
+ IGNORING CASE. "ab## AB## ab##
+
+"repl_tab:
+"LINE OFFSET LENGTH
+"0 2 2
+"0 7 2
+"0 12 2
+
+str = str_original.
+
+"... FIRST OCCURRENCE OF
+"Note: repl_struc, which is declared inline here, is of type repl_result
+REPLACE FIRST OCCURRENCE OF `ap`
+ IN str WITH `##`
+ RESULTS DATA(repl_struc)
+ IGNORING CASE.
+
+"repl_struc:
+"LINE OFFSET LENGTH
+"0 2 2
+```
+
+You can use [`REPLACE SECTION ... OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapfind_section_of.htm) statements for position-based replacements, that is, to replace a section in a string starting at a specified offset for a specified length.
+
+``` abap
+DATA(str_original) = `abap ABAP abap`.
+DATA(str) = str_original.
+
+"OFFSET + LENGTH specified
+REPLACE SECTION OFFSET 5 LENGTH 4 OF str WITH `#`. "abap # abap
+
+str = str_original.
+
+"Only OFFSET (LENGTH: up to the end of the string)
+REPLACE SECTION OFFSET 5 OF str WITH `#`. "abap #
+
+str = str_original.
+
+"Only LENGTH (OFFSET: starting from the leftmost position)
+REPLACE SECTION LENGTH 6 OF str WITH `#`. "#BAP abap
+```
+
+### Replacing Substrings in Tables
+
+Replacements in internal tables with `REPLACE ... IN TABLE` (see the notes above for searching in internal tables):
+``` abap
+DATA(str_table_original) = VALUE string_table( ( `aZbzZ` ) ( `cdZze` ) ( `Zzzf` ) ( `ghz` ) ).
+DATA(str_table) = str_table_original.
+
+"Replacing all occurrences in a table
+"RESULTS addition: Storing information in an internal table of type repl_result_tab
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ WITH `#`
+ RESULTS DATA(res_table)
+ RESPECTING CASE.
+
+"str_table: a#bz# / cd#ze / #zzf / ghz
+"res_table:
+"LINE OFFSET LENGTH
+"1 1 1
+"1 4 1
+"2 2 1
+"3 0 1
+
+str_table = str_table_original.
+
+"Replacing the first occurrence in a table
+"RESULTS addition: Storing information in a structure of type repl_result
+REPLACE FIRST OCCURRENCE OF `Z`
+ IN TABLE str_table
+ WITH `#`
+ RESULTS DATA(res_structure)
+ RESPECTING CASE.
+
+"str_table: a#bzZ / cdZze / Zzzf / ghz
+"res_structure:
+"LINE OFFSET LENGTH
+"1 1 1
+
+str_table = str_table_original.
+
+"Restricting the search range in an internal table
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ FROM 1 TO 2
+ WITH `#`
+ RESPECTING CASE.
+
+"str_table: a#bz# / cd#ze / Zzzf / ghz
+
+str_table = str_table_original.
+
+"Offsets can be optionally specified (also only the offset of start or end line possible)
+REPLACE ALL OCCURRENCES OF `Z`
+ IN TABLE str_table
+ FROM 1 OFFSET 3 TO 2 OFFSET 2
+ WITH `#`
+ RESPECTING CASE.
+
+"str_table: aZbz# / cdZze / Zzzf / ghz
+```
+
+### String Function replace
+- The string function
+[`replace`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreplace_functions.htm),
+allows you to store the result of a substring replacement in a separate
+variable.
+- What makes it especially powerful is that it
+returns a value, so it can be used at almost any [read
+positions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenread_position_glosry.htm "Glossary Entry").
+- The parameters of the `replace` string functions are similar to those of the `find` function. In addition, there is the `with` parameter for the replacement. Setting `occ` to `0` means that all occurrences are respected for the replacement.
+
+Syntax examples:
+``` abap
+DATA(str) = `abap ABAP abap`.
+DATA res TYPE string.
+
+"Note that here only the first occurrence is replaced.
+res = replace( val = str sub = `ap` with = `#` ). "ab# ABAP abap
+
+"Making the search case-insensitive
+res = replace( val = str sub = `AB` with = `#` case = abap_false ). "#ap ABAP abap
+
+"Setting occ
+res = replace( val = str sub = `ab` with = `#` occ = 2 case = abap_false ). "abap #AP abap
+
+"Replacing all occurrences: Setting occ to 0
+res = replace( val = str sub = `ab` with = `#` occ = 0 case = abap_false ). "#ap #AP #ap
+
+"Negative value for occ: Occurrences are counted from the right
+res = replace( val = str sub = `ab` with = `#` occ = -1 ). "abap ABAP #ap
+
+"Setting off and len for determining a subarea for replacements
+"Note: When using off/len, sub and occ cannot be specified.
+"Specifying both off and len
+res = replace( val = str with = `#` off = 5 len = 3 ). "abap #P abap
+
+"Specifying only off (len is 0 by default)
+res = replace( val = str with = `#` off = 2 ). "ab#ap ABAP abap
+
+"Note: When specifying only off and not specifying len or len = 0,
+"replace works like insert
+res = insert( val = str sub = `#` off = 2 ). "ab#ap ABAP abap
+
+"Specifying only len (off is 0 by default): First segment of length in len is replaced
+res = replace( val = str with = `#` len = 3 ). "#p ABAP abap
+
+"Special case
+"- off: equal to the length of the string
+"- len: not specified or 0
+"- Result: Value specified for 'with' is appended to the end of the string
+res = replace( val = str with = `#` off = strlen( str ) ). "abap ABAP abap#
+```
+
+## Pattern-Based Searching and Replacing in Strings
+
+You can perform complex search and replace operations based on
+patterns. [PCRE regular
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpcre_regex_glosry.htm "Glossary Entry")
+help you process strings effectively.
+> **💡 Note**
+> Do not use [POSIX
+regular
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenposix_regex_glosry.htm "Glossary Entry")
+anymore, they are obsolete.
+
+
+
+### Simple Pattern-Based Searching Using Comparison Operators
+
+For simple patterns, you can use the [comparison
+operators](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomp_operator_glosry.htm "Glossary Entry")
+[`CP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+(conforms to pattern) or its negation
+[`NP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_strings.htm)
+(does not conform to pattern) in [comparison
+expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm "Glossary Entry")
+to determine whether a set of characters is contained in a string that
+matches a particular pattern. You can use the following
+special characters as patterns:
+
+| Special Character | Details |
+|---|---|
+| `*` | Any character sequence (including blanks). |
+| `+` | Any character (only one character, including blanks). |
+| `#` | Escape character. The following character is marked for an exact comparison. |
+
+Patterns are not case-sensitive except for characters marked with
+`#`. If a pattern is found, the system variable
+`sy-fdpos` returns the offset of the first occurrence.
+Otherwise, it contains the length of the searched string.
+``` abap
+DATA(s1) = `abc_def_ghi`.
+
+"Pattern: f is preceded by any character sequence, must be followed
+"by '_' and then followed by any character sequence
+IF s1 CP `*f#_*`. ... "true; sy-fdpos = 6
+
+"Pattern: 'i' is not followed by another character
+IF s1 NP `i+`. ... "true; sy-fdpos = 11 (length of searched string)
+```
+
+
+
+### Complex Searching and Replacing Using Regular Expressions
+
+#### Excursion: Common Regular Expressions
+
+There are several ways to perform complex searches in strings using PCRE expressions. They can be quite complex. The following overview shows common PCRE expressions with simple examples.
+For more information, see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenregex_pcre_syntax_specials.htm).
+
+Characters and character types
+
+| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
+|---|---|---|---|---|---|
+| `x` | Specific character | `a` | abcdef | a | Anything else |
+| `.` | Anything except a line break | `.` | ab 1# | a, b, the blank, 1, # | ab, 1# |
+| `\d` | Any digit (0-9), alternative: `[0-9]` | `\d` | a1-b2 3-4c9 | 1, 2, 3, 4, 9 | a, b, c, the blank and hyphens |
+| `\D` | Any non-digit, alternative: `[^0-9]` | `\D` | a1-b2 3-4c9 | a, b, c, the blank and hyphens | 1, 2, 3, 4, 9 |
+| `\s` | Any whitespace character such as a blank, tab and new line | `\s` | (hi X ) | The blanks | h, i, X, (, ) |
+| `\S` | Any character that is not a whitespace | `\S` | (hi X ) | h, i, X, (, ) | The blanks |
+| `\w` | Any word character (letter, digit or the underscore), alternative: `[a-zA-Z0-9_]` | `\w` | (ab 12_c) | a, b, c, 1, 2, _ | (, ), the blank |
+| `\W` | Any character that is not a word character, alternative: `[^a-zA-Z0-9_]` | `\W` | (ab 12_c) | (, ), the blank | a, b, c, 1, 2, _ |
+| `\` | To include special characters like `[] \ / ^`, use `\` to escape them. Use `\.` to match a period ("."). | `.\.` | ab.cd.ef | a**b.**c**d.**ef | ab**.c**d**.e**f |
+
+Repetitions and Alternatives
+
+| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
+|---|---|---|---|---|---|
+| `x*` | Zero or more repetitions of `x` | `ab*` | abc abbc abbbc a ac | **ab**c **abb**c **abbb**c **a** **a**c | **abc** **abbc** **abbbc** a **ac** |
+| `x+` | One or more repetitions of `x` | `ab+` | abc abbc abbbc a ac | **ab**c **abb**c **abbb**c a ac | ... **a** **a**c |
+| `x{m,n}` | Between `m` and `n` repetitions of `x` | `ab{2,3}` | abc abbc abbbc a ac | abc **abb**c **abbb**c a ac | **ab**c ... |
+| `x{m}` | Exactly `m` repetitions | `ab{3}` | abc abbc abbbc a ac | abc abbc **abbb**c a ac | abc **abb**c ... |
+| `x{m,}` | Exactly `m` or more repetitions | `ab{2,}` | abc abbc abbbc a ac | abc **abb**c **abbb**c a ac | **ab**c ... |
+| `x?` | Optional `x`, i.e. zero or one time | `ab?` | abc abbc abbbc a ac | **ab**c **ab**bc **ab**bbc **a** **a**c | ... **ac** |
+| `x\|y` | Matching alternatives, i. e. `x` or `y` | 1. `b\|2` 2. `b(a\|u)t` | 1. abc 123 2. bit bat but bet | 1. b, 2 2. bat, but | 1. a, c, 1, 3 2. bit, bet |
+| `x*?` | `x*` captures greedily, i.e. as much as possible, while `x*?` captures non-greedily, i.e. as few as possible | 1. `bc*?` 2. `a.*?#` | 1. abcd abccccd ab 2. abc#defgh#i | 1. a**b**cd a**b**ccccd a**b** 2. **abc#**defgh#i | 1. a**bc**d a**bcccc**d a**b** (result for `bc*`) 2. **abc#defgh#**i (result for `a.*#`) |
+| `x+?` | Same as above: `x+` (greedy), `x+?` (non-greedy) | 1. `bc+?` 2. `<.+?>` | 1. abcd abccccd ab 2. <span>Hallo</span> html. | 1. a**bc**d a**bc**cccd ab 2. **<span>**Hallo**</span>** html. | 1. a**bc**d a**bcccc**d ab (result for `bc+`) 2. **<span>Hallo</span>** html. (result for `<.+>`) |
+
+Character Sets, Ranges, Subgroups and Lookarounds
+| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
+|---|---|---|---|---|---|
+| `[xy]` | Character set, matches a single character present in the list | `b[iu]` | bit bat but bet | **bi**t bat **bu**t bet | bit **ba**t but **be**t |
+| `[x-y]` | Character range, matches a single character in the specified range, note that ranges may be locale-dependent | `a[a-c0-5]` | aa1 ab2 ba3 cac4 da56 a7 |**aa**1 **ab**2 b**a3** c**ac**4 d**a5**6 a7 | aa1 ab2 ba3 cac4 da56 **a7** |
+| `[^xy]` | Negation, matches any single character not present in the list | `[^Ap]` | ABap | B, a | A, p |
+| `[^x-y]` | Negation, matches any single character not within the range | `[^A-Ca-c1-4]` | ABCDabcd123456 | D, d, 5, 6 | A, B, C, a, b, c, 1, 2, 3, 4 |
+| `(...)` | Capturing group to group parts of patterns together | `b(a\|u)t` | bit bat but bet | bat, but | bit, bet |
+| `(?=...)` | Positive lookahead, returns characters that are followed by a specified pattern without including this pattern | `a(?=b)` | abc ade | **a**bc ade | abc **a**de |
+| `(?!...)` | Negative lookahead, returns characters that are not followed by a specified pattern without including this pattern | `a(?!b)` | abc ade | abc **a**de | **a**bc ade |
+| `(?<=...)` | Positive lookbehind, returns characters that are preceded by a specified pattern without including this pattern | `(?<=\s)c` | ab c abcd | ab **c** abcd (it is preceded by a blank) | ab c ab**c**d |
+| `(?**c**d (it is not preceded by a blank) | ab **c** abcd |
+| `\n` | Backreference, refers to a previous capturing group; n represents the number of the group index that starts with 1 | `(a.)(\w*)\1` | abcdefabghij | **abcdefab**ghij Note: Capturing group 1 holds `ab` in the example. The second capturing group captures all word characters until `ab` is found. | **ab**cdefabghij |
+| `\K` | Resets the starting point of a match, i.e. findings are excluded from the final match | `a.\Kc` | abcd | ab**c**d | **abc**d |
+
+> **💡 Note**
+> - Subgroups are useful in replacements. By using an expression with `$` and a number, such as `$1`, you can refer to a specific group. For example, you have a string `abcde`. A PCRE expression might be
+`(ab|xy)c(d.)`, where two subgroups are specified within two pairs of parentheses. In a replacement pattern, you can refer to the first group with `$1` and the second group with `$2`. Thus, the replacement pattern `$2Z$1` results in `deZab`.
+> - `(?:x)` creates a group but it is not captured. Example regular expression: `(?:ab)(ap)`. Example string: 'abap'. It matches 'abap', but `$1` will only contain 'ap'.
+
+Anchors and Positions
+
+| Expression | Represents | Example Regex | Example String | Matches | Does not Match |
+|---|---|---|---|---|---|
+| `^` | Start of line, alternative: `\A` | `^.` or `\A.` | abc def | **a**bc def | abc **d**ef |
+| `$` | End of line, alternative: `\Z` | `.$` or `.\Z` | abc def | abc de**f** | **a**bc def |
+| `\b` | Start or end of word | 1. `\ba.` 2. `\Dd\b` 3. `\b.d\b` | abcd a12d ed | 1. **ab**cd **a1**2d ed 2. ab**cd** a12d **ed** 3. abcd a12d **ed** | 1. ab**cd** a1**2d** ed 2. abcd a1**2d** ed 3. **abcd** **a12d** ed |
+| `\B` | Negation of `\b`, not at the start or end of words | `\Be\B` | see an elefant | s**e**e an el**e**fant | s**ee** an **e**lefant |
+
+
+
+#### Searching Using Regular Expressions
+
+- Multiple string functions support PCRE expressions by offering the
+ `pcre` parameter, which you can use to specify such an expression.
+`FIND` and `REPLACE` statements support regular
+expressions with the `PCRE` addition.
+- The string function
+[`match`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmatch_functions.htm)
+works only with regular expressions. It returns a substring that
+matches a regular expression within a string.
+- For comparisons, you can
+also use the [predicate
+function](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_function_glosry.htm "Glossary Entry")
+[`matches`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmatches_functions.htm), which returns true or false if a string matches a given pattern or not.
+
+Syntax examples:
+``` abap
+DATA(s1) = `Cathy's black cat on the mat played with Matt.`.
+
+"Determining the position of the first occurrence
+"Here, the parameter occ is 1 by default.
+DATA(int) = find( val = s1 pcre = `at.` ). "1
+
+"Determining the number of all occurrences.
+"Respects all 'a' characters not followed by 't', all 'at' plus 'att'
+int = count( val = s1 pcre = `at*` ). "6
+
+"Respects all 'at' plus 'att'
+int = count( val = s1 pcre = `at+` ). "4
+
+"Extracting a substring matching a given pattern
+DATA(s2) = match( val = `The email address is jon.doe@email.com.`
+ pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ). "jon.doe@email.com
+
+"Predicate function matches
+"Checking the validitiy of an email address
+IF matches( val = `jon.doe@email.com`
+ pcre = `\w+(\.\w+)*@(\w+\.)+(\w{2,4})` ). "true
+...
+ENDIF.
+
+"Examples with the FIND statement
+"SUBMATCHES addition: Storing submatches in variables
+"Pattern: anything before and after ' on '
+FIND PCRE `(.*)\son\s(.*)` IN s1 IGNORING CASE SUBMATCHES DATA(a) DATA(b).
+"a: 'Cathy's black cat' / b: 'the mat played with Matt.'.
+
+"Determining the number of letters in a string
+FIND ALL OCCURRENCES OF PCRE `[A-Za-z]` IN s1 MATCH COUNT DATA(c). "36
+
+"Searching in an internal table and retrieving line, offset, length information
+DATA(itab) = value string_table( ( `Cathy's black cat on the mat played with the friend of Matt.` ) ).
+"Pattern: 't' at the beginning of a word followed by another character
+FIND FIRST OCCURRENCE OF PCRE `\bt.` IN TABLE itab
+ IGNORING CASE MATCH LINE DATA(d) MATCH OFFSET DATA(e) MATCH LENGTH DATA(f). "d: 1, e: 21, f: 2
+```
+
+
+#### System Classes for Regular Expressions
+
+- You can create an object-oriented representation of regular expressions using the `CL_ABAP_REGEX` system class.
+- For example, the `CREATE_PCRE` method creates instances of regular expressions with PCRE syntax.
+- The instances can be used, for example, with the `CL_ABAP_MATCHER` class, which applies the regular expressions.
+- A variety of methods and parameters can be specified to accomplish various things and to further specify the handling of the regular expression.
+- More information can be found [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenregex_system_classes.htm) and in the class documentation (choose F2 on the class in ADT).
+
+
+``` abap
+DATA(str) = `a1 # B2 ? cd . E3`.
+
+"Creating a regex instance for PCRE regular expressions
+"In the example, regex_inst has the type ref to cl_abap_regex.
+DATA(regex_inst) = cl_abap_regex=>create_pcre( pattern = `\D\d` "any-non digit followed by a digit
+ ignore_case = abap_true ).
+
+"Creating an instance of CL_ABAP_MATCHER using the method CREATE_MATCHER of the class CL_ABAP_REGEX
+"You can also specify internal tables with the 'table' parameter and more.
+DATA(matcher) = regex_inst->create_matcher( text = str ).
+
+"Finding all results using the 'find_all' method
+"In the example, result has the type match_result_tab containing the findings.
+DATA(result) = matcher->find_all( ).
+
+"Using method chaining
+DATA(res) = cl_abap_regex=>create_pcre( pattern = `\s\w` "any blank followed by any word character
+ ignore_case = abap_true )->create_matcher( text = str )->find_all( ).
+```
+
+
+
+#### Replacing Using Regular Expressions
+
+- To perform replacement operations using regular expressions, you can use both
+the string function `replace` and `REPLACE` statements with the `pcre` parameter or the `PCRE` addition.
+- Like the `find` function, among others, and
+`FIND` statements, the `replace` function and
+`REPLACE` statements offer a number of parameters and additions that you can use to further restrict the area to be replaced.
+- For more detailed information, refer to the ABAP
+Keyword Documentation.
+- The executable example covers many of the PCRE expressions listed above.
+
+Syntax examples:
+``` abap
+DATA(s1) = `ab apppc app`.
+DATA s2 TYPE string.
+
+"Replaces 'p' with 2 - 4 repetitions, all occurences
+s2 = replace( val = s1 pcre = `p{2,4}` with = `#` occ = 0 ). "ab a#c a#
+
+"Replaces any single character not present in the list, all occurences
+s2 = replace( val = s1 pcre = `[^ac]` with = `#` occ = 0 ). " "a##a###c#a##
+
+"Replaces first occurence of a blank
+s2 = replace( val = s1 pcre = `\s` with = `#` ). "ab#apppc app
+
+"Greedy search
+"The pattern matches anything before 'p'. The matching is carried out as
+"often as possible. Hence, in this example the search stretches until the
+"end of the string since 'p' is the final character, i. e. this 'p' and
+"anything before is replaced.
+s2 = replace( val = s1 pcre = `.*p` with = `#` ). "#
+
+"Non-greedy search
+"The pattern matches anything before 'p'. The matching proceeds until
+"the first 'p' is found and does not go beyond. It matches as few as
+"possible. Hence, the first found 'p' including the content before
+"is replaced.
+s2 = replace( val = s1 pcre = `.*?p` with = `#` ). "#ppc app
+
+"Replacements with subgroups
+"Replaces 'pp' (case-insensitive here) with '#', the content before and after 'pp' is switched
+s2 = replace( val = s1
+ pcre = `(.*?)PP(.*)`
+ with = `$2#$1`
+ case = abap_false ). "pc app#ab a
+
+"Changing the source field directly with a REPLACE statement; same as above
+REPLACE PCRE `(.*?)PP(.*)` IN s1 WITH `$2#$1` IGNORING CASE. "pc app#ab a
+```
+
+
+
+## More String Functions
+
+### Checking the Similarity of Strings
+
+- [`distance`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendistance_functions.htm) returns the Levenshtein distance between two strings, which reflects their similarity.
+- Unlike other string functions, the return value has the type `i`.
+- Optional addition `max`: Positive integer. The calculation of the Levenshtein distance will stop if the calculated value is greater than this integer.
+
+```abap
+DATA(str_to_check) = `abap`.
+DATA(dist1) = distance( val1 = str_to_check val2 = `abap` ). "0
+DATA(dist2) = distance( val1 = str_to_check val2 = `axbap` ). "1
+DATA(dist3) = distance( val1 = str_to_check val2 = `yabyyapy` ). "4
+DATA(dist4) = distance( val1 = str_to_check val2 = `zabapzzzzzzzzzzzz` max = 5 ). "5
+
+"If the value of max is 0 or less, an exception is raised.
+TRY.
+ DATA(dist5) = distance( val1 = str_to_check val2 = `#ab#ap#` max = 0 ).
+ CATCH cx_sy_strg_par_val.
+ ...
+ENDTRY.
+```
+
+### Repeating Strings
+- [`repeat`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrepeat_functions.htm) returns a string that contains the content of a specified string for parameter `val` as many times as specified in the parameter `occ`.
+- An empty string is returned when `occ` has the value 0 or `val` is empty.
+
+```abap
+DATA(repeat1) = repeat( val = `abap` occ = 5 ). "abapabapabapabapabap
+DATA(repeat2) = |#{ repeat( val = ` ` occ = 10 ) }#|. "# #
+DATA(repeat3) = COND #( WHEN repeat( val = `a` occ = 0 ) = `` THEN `Y` ELSE `Z` ). "Y (initial value returned)
+
+"If occ has a negative value, an exception is raised.
+TRY.
+ DATA(repeat4) = repeat( val = `X` occ = -3 ).
+ CATCH cx_sy_strg_par_val.
+ ...
+ENDTRY.
+```
+
+
+
+### Returning the Smallest/Biggest of a Set of Character-Like Arguments
+- [`cmin/cmax`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencmax_cmin_functions.htm) returns a string that contains the content of the smallest or biggest of a set of character-like arguments
+- 'Set' means at least two arguments and a maximum of nine argeuments are passed (`valn` operators) for comparison.
+- The comparison is made from left to right, and the first different character found determines the smaller or bigger argument.
+
+```abap
+DATA(min) = cmin( val1 = `zzzzzzz`
+ val2 = `zzazzzzzzzz` "smallest argument
+ val3 = `zzzzabc` ).
+
+DATA(max) = cmax( val1 = `abcdef` "biggest argument
+ val2 = `aaghij`
+ val3 = `aaaaklmn`
+ val4 = `aaaaaaopqrs`
+ val5 = `aaaaaaaaaatuvwxy`
+ val6 = `aaaaaaaaaaaaaz` ).
+```
+
+
+
+### Escaping Special Characters
+- [`escape`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm) returns a string that is provided for the `val` parameter by escaping special characters according to the specification in the `format` parameter.
+- Suitable values for the `format` parameter (which expects a data object of type `i`) are available in the `CL_ABAP_FORMAT` class (the constants starting with `E_`).
+- Special rules apply to different contexts, such as URLS and JSON. Also note the prevention of Cross Site Scripting (XSS) attacks on web applications. For more information, refer to the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenescape_functions.htm).
+
+```abap
+"Context: URLs
+DATA(esc1) = escape( val = '...test: 5@8...'
+ format = cl_abap_format=>e_url_full ).
+"...test%3A%205%408...
+
+"Context: JSON
+DATA(esc2) = escape( val = 'some "test" json \ with backslash and double quotes'
+ format = cl_abap_format=>e_json_string ).
+"some \"test\" json \\ with backslash and double quotes
+
+
+"Context: String templates
+DATA(esc3) = escape( val = 'Special characters in string templates: |, \, {, }'
+ format = cl_abap_format=>e_string_tpl ).
+"Special characters in string templates: \|, \\, \{, \}
+
+"Invalid value for the format parameter
+TRY.
+ DATA(esc4) = escape( val = 'This will raise an exception due to an invalid format value.'
+ format = 123 ).
+ CATCH cx_sy_strg_par_val.
+ENDTRY.
+```
+
+
+
+## Excursions
+
+### Comparison Operators for Character-Like Data Types in a Nutshell
+
+The comparison operators have already been covered in different sections above. This is a summary of the operators.
+
+
+
+
Comparison Operator
+
Details
+
Example
+
+
+
CA
+
Contains any To determine whether any character of a given character set is contained
+in a string. Note: The search is case-sensitive. sy-fdpos contains the offset of the first character found, while 0 stands for the very first position. If nothing is found, sy-fdpos contains the length of the string.
Contains not only To determine whether a string does not only contain a certain set of characters, i.e. whether a string contains characters other than those in the character set. See the note above.
Contains string For simple substring searches and determining whether a string contains a substring. Note: The search is not case-sensitive. sy-fdpos contains the offset of the first substring found. If it is not found, sy-fdpos contains the length of the string searched.
Conforms to pattern For simple pattern searches and determining whether a set of characters is contained in a string that matches a particular pattern. You can use the following special characters as patterns:
*: Any character sequence (including blanks)
+: Any character (only one character, including blanks)
#: Escape character. The following character is marked for an exact comparison.
Patterns are not case-sensitive except for characters marked with
+#. If a pattern is found, sy-fdpos returns the offset of the first occurrence. Otherwise, it contains the length of the string searched.
+
+
+
+```abap
+DATA(s7) = `abc_def_ghi`.
+
+"Pattern: f is preceded by any character sequence, must be followed
+"by '_' and then followed by any character sequence
+IF s7 CP `*f#_*`. ... "true; sy-fdpos: 6
+
+"Pattern: i is preceded by any character sequence, must be followed
+"by any character or a blank
+IF s7 CP `*i+`. ... "false; sy-fdpos: 11
+```
+
+
+
+
+
NP
+
Does not conform to pattern Negation of CP. See the previous notes.
+
+
+```abap
+DATA(s8) = `abcDEFghi`.
+
+"Pattern: c is preceded by any character sequence, must be followed
+"by a small letter d, and then followed by any character sequence
+IF s8 NP `*c#d*`. ... "true; sy-fdpos: 9
+
+"Pattern: c is preceded by any character sequence, must be followed
+"by a capital letter D, and then followed by any character sequence
+IF s8 NP `*c#D*`. ... "false; sy-fdpos: 2
+```
+
+
+
+### String Processing Using the XCO Library
+The Extension Components Library (XCO) library provides [released APIs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreleased_api_glosry.htm) and offers various development utilities. Find more information [here](https://help.sap.com/docs/btp/sap-business-technology-platform/overview-of-xco-modules). The following code snippet demonstrates several methods of the `XCO_CP` class that deal with string processing.
+
+```abap
+"--------- Extracting a substring from a string ---------
+DATA(some_string) = `abcdefghijklmnopqrstuvwxyz`.
+
+"Creating an encapsulation of a string using XCO
+DATA(str) = xco_cp=>string( some_string ).
+
+"Using the FROM and TO methods, you can determine
+"the character position. Note that the value includes the
+"character at the position specified.
+"The character index pattern for the example string above
+"is (the string has 26 characters in total):
+"a = 1, b = 2, c = 3 ... z = 26
+"a = -26, b = -25, c = -24 ... z = -1
+"Providing a value that is out of bounds means that
+"the first (or the last) character of the string is used
+"by default.
+"Note: When combining FROM and TO, e.g. with method
+"chaining ...->from( ...)->to( ... ), note that another
+"instance is created with the first 'from', and another
+"character index pattern is created based on the new
+"and adjusted string value.
+
+"bcdefghijklmnopqrstuvwxyz
+DATA(sub1) = str->from( 2 )->value.
+
+"defghijklmnopqrstuvwxyz
+DATA(sub2) = str->from( -23 )->value.
+
+"vwxyz
+DATA(sub3) = str->from( -5 )->value.
+
+"abcde
+DATA(sub4) = str->to( 5 )->value.
+
+"ab
+DATA(sub5) = str->to( -25 )->value.
+
+"Result of 1st 'from' method call: bcdefghijklmnopqrstuvwxyz
+"Based on this result, the 'to' method call is
+"applied.
+"bcdefg
+DATA(sub6) = str->from( 2 )->to( 6 )->value.
+
+"Result of 1st 'to' method call: abcdefghijklmnopq
+"Based on this result, the 'from' method call is
+"applied.
+"defghijklmnopq
+DATA(sub7) = str->to( -10 )->from( 4 )->value.
+
+"Values that are out of bounds.
+"In the example, the first and last character of the
+"string are used.
+"abcdefghijklmnopqrstuvwxyz
+DATA(sub8) = str->from( 0 )->to( 100 )->value.
+
+"--------- Splitting and joining ---------
+
+"Splitting a string into a string table
+DATA(str_table) = xco_cp=>string( `Hello.World.ABAP` )->split( `.` )->value.
+"Hello
+"World
+"ABAP
+
+"Concatenating a string table into a string; specifying a delimiter
+str_table = VALUE #( ( `a` ) ( `b` ) ( `c` ) ).
+"a, b, c
+DATA(conc_str1) = xco_cp=>strings( str_table )->join( `, ` )->value.
+
+"Concatenating a string table into a string; specifying a delimiter and
+"reversing the table order
+"c / b / a
+DATA(conc_str2) = xco_cp=>strings( str_table )->reverse( )->join( ` / ` )->value.
+
+"--------- Prepending and appending strings ---------
+DATA(name) = xco_cp=>string( `Max Mustermann` ).
+
+"Max Mustermann, Some Street 1, 12345 Someplace
+DATA(address) = name->append( `, Some Street 1, 12345 Someplace` )->value.
+
+"Mr. Max Mustermann
+DATA(title) = name->prepend( `Mr. ` )->value.
+
+"--------- Transforming to lowercase and uppercase ---------
+"ABAP
+DATA(to_upper) = xco_cp=>string( `abap` )->to_upper_case( )->value.
+
+"hallo world
+DATA(to_lower) = xco_cp=>string( `HALLO WORLD` )->to_lower_case( )->value.
+
+"--------- Checking if a string starts/ends with a specific string ---------
+DATA check TYPE string.
+DATA(str_check) = xco_cp=>string( `Max Mustermann` ).
+
+"yes
+IF str_check->ends_with( `mann` ).
+ check = `yes`.
+ELSE.
+ check = `no`.
+ENDIF.
+
+"no
+IF str_check->starts_with( `John` ).
+ check = `yes`.
+ELSE.
+ check = `no`.
+ENDIF.
+
+"--------- Converting strings to xstrings using a codepage ---------
+"536F6D6520737472696E67
+DATA(xstr) = xco_cp=>string( `Some string` )->as_xstring( xco_cp_character=>code_page->utf_8 )->value.
+
+"--------- Camel case compositions and decompositions with split and join operations ---------
+"Pascal case is also possible
+"someValue
+DATA(comp) = xco_cp=>string( `some_value` )->split( `_` )->compose( xco_cp_string=>composition->camel_case )->value.
+
+"Camel case decomposition
+"some_value
+DATA(decomp) = xco_cp=>string( `someValue` )->decompose( xco_cp_string=>decomposition->camel_case )->join( `_` )->value.
+
+"--------- Matching string against regular expression ---------
+DATA match TYPE string.
+
+"yes
+IF xco_cp=>string( ` 1` )->matches( `\s\d` ).
+ match = 'yes'.
+ELSE.
+ match = 'no'.
+ENDIF.
+
+"no
+IF xco_cp=>string( ` X` )->matches( `\s\d` ).
+ match = 'yes'.
+ELSE.
+ match = 'no'.
+ENDIF.
+```
+
+
+
+## Executable Example
+
+[zcl_demo_abap_string_proc](./src/zcl_demo_abap_string_proc.clas.abap)
+
+> **💡 Note**
+> - The executable example ...
+> - covers the following topics:
+> - Creating strings and assigning values
+> - String templates
+> - Operations with strings operations: chaining, concatenating, splitting, modifying
+> - Searching and replacing
+> - Regular expressions
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
diff --git a/08_EML_ABAP_for_RAP.md b/08_EML_ABAP_for_RAP.md
index 1c67643..a089161 100644
--- a/08_EML_ABAP_for_RAP.md
+++ b/08_EML_ABAP_for_RAP.md
@@ -1,1719 +1,1719 @@
-
-
-# ABAP for RAP: Entity Manipulation Language (ABAP EML)
-
-- [ABAP for RAP: Entity Manipulation Language (ABAP EML)](#abap-for-rap-entity-manipulation-language-abap-eml)
- - [RAP Terms](#rap-terms)
- - [Excursion: RAP Behavior Definition (BDEF)](#excursion-rap-behavior-definition-bdef)
- - [ABAP Behavior Pools (ABP)](#abap-behavior-pools-abp)
- - [RAP Handler Classes and Methods](#rap-handler-classes-and-methods)
- - [RAP Saver Class and Saver Methods](#rap-saver-class-and-saver-methods)
- - [BDEF Derived Types](#bdef-derived-types)
- - [Components of BDEF Derived Types](#components-of-bdef-derived-types)
- - [EML Syntax](#eml-syntax)
- - [EML Syntax for Modifying Operations](#eml-syntax-for-modifying-operations)
- - [EML Syntax for Reading Operations](#eml-syntax-for-reading-operations)
- - [Dynamic Forms of EML Statements](#dynamic-forms-of-eml-statements)
- - [Persisting to the Database](#persisting-to-the-database)
- - [Raising RAP Business Events](#raising-rap-business-events)
- - [Additions to EML Statements in ABAP Behavior Pools](#additions-to-eml-statements-in-abap-behavior-pools)
- - [RAP Excursions](#rap-excursions)
- - [Using Keys and Identifying RAP BO Instances in a Nutshell](#using-keys-and-identifying-rap-bo-instances-in-a-nutshell)
- - [RAP Concepts](#rap-concepts)
- - [Ensuring Data Consistency in a RAP Transaction](#ensuring-data-consistency-in-a-rap-transaction)
- - [More Information](#more-information)
- - [Executable Examples](#executable-examples)
-
-## RAP Terms
-
-[ABAP Entity Manipulation Language](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenaeml_glosry.htm) (or EML for short) is a subset of ABAP that allows you to access the data of [RAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenarap_glosry.htm) business objects in an ABAP program.
-The following points cover RAP-related terms such as *RAP business objects* and others for setting the context:
-
-- RAP business objects (RAP BO)
- - A RAP BO is based on a special, tree-like hierarchical structure
- of [CDS
- entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_glosry.htm "Glossary Entry")
- of a data model
- - Such a structure of entities consists of [parent
- entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparent_entity_glosry.htm "Glossary Entry")
- and [child
- entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenchild_entity_glosry.htm "Glossary Entry")
- that are themselves defined using [CDS
- compositions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_composition_glosry.htm "Glossary Entry")
- and [to-parent
- associations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abento_parent_association_glosry.htm "Glossary Entry").
- - The top parent entity of a [CDS composition
- tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_composition_tree_glosry.htm "Glossary Entry")
- is the root entity that represents the business object. With a
- large composition tree, RAP BOs can be fairly complex. Or they
- can be very simple by just consisting of one root entity alone.
- - Note: There is a special syntax for the [CDS root entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenroot_entity_glosry.htm) of a RAP BO: [`define root view entity`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_define_root_view_v2.htm)
-- [RAP behavior
- definition](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_behavior_definition_glosry.htm "Glossary Entry")
- (BDEF)
- - RAP BOs are described by the definitions specified in a special
- [DDIC](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_glosry.htm "Glossary Entry")
- artifact: RAP behavior definition (BDEF)
- - A BDEF defines the [RAP business object
- behavior](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_behavior_glosry.htm "Glossary Entry")
- (i. e. the transactional behavior of a RAP BO)
- - Transactional behavior means a BDEF defines [behavior
- characteristics](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_properties_glosry.htm "Glossary Entry")
- and [RAP BO
- operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_operation_glosry.htm "Glossary Entry") i.
- e. [RAP BO standard
- operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_standard_operation_glosry.htm "Glossary Entry")
- ([CRUD
- operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencrud_glosry.htm "Glossary Entry")),
- [non-standard
- operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_nstandard_operation_glosry.htm "Glossary Entry")
- like specific [RAP
- actions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_action_glosry.htm "Glossary Entry")
- and
- [functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_function_glosry.htm "Glossary Entry"),
- and more.
- - There are many other things that can be included impacting the
- RAP BO behavior like [RAP feature
- control](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_feature_control_glosry.htm "Glossary Entry"),
- for example, defining which data is mandatory and which is
- read-only, or
- [determinations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_determination_glosry.htm "Glossary Entry")
- and
- [validations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_validation_glosry.htm "Glossary Entry").
- - BDEFs use [Behavior Definition
- Language](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_glosry.htm "Glossary Entry")
- (BDL) for the definitions. Find more information on the topic
- and various options to define the transactional behavior in
- section [BDL for Behavior
- Definitions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl.htm)
- in the ABAP Keyword Documentation.
-- Transactional buffer and implementation types
- - A BDEF defines the behavior of a RAP BO and, thus, how to handle
- its data. This data is available in the [RAP transactional
- buffer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentransactional_buffer_glosry.htm "Glossary Entry").
- - It is a storage for a RAP BO's data that is used and worked on
- during an [SAP LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensap_luw_glosry.htm).
- - This data includes [RAP BO
- instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_instance_glosry.htm "Glossary Entry")
- (i. e. concrete data sets of an entity). This is where EML
- enters the picture: EML is used, among others, to access this data in the transactional buffer.
- - Currently, there are two kinds of RAP BOs:
- [managed](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmanaged_rap_bo_glosry.htm "Glossary Entry")
- and [unmanaged RAP
- BOs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunmanaged_rap_bo_glosry.htm "Glossary Entry").
- - Managed and unmanaged are implementation types that are also
- specified in the BDEF.
- - The implementation type determines the [RAP BO
- provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_provider_glosry.htm "Glossary Entry"), i.
- e. how the transactional buffer is provided and how the behavior
- of a RAP BO is implemented.
-- Managed RAP BOs:
- - The managed RAP BO provider fully or partly provides the
- transactional buffer and RAP BO behavior (for standard
- operations only). In this case, the developers need not cater
- for the transactional buffer and implement the standard
- operations. This implementation is mostly relevant for
- greenfield scenarios when starting from scratch.
- - Example: Regarding CRUD operations in managed RAP BOs,
- developers need not cater for an implementation at all. The
- standard operations work out of the box. For example, in case of
- an update operation, RAP BO instance data that is to be updated
- is automatically read into the transactional buffer, and then
- updated accordingly there. Finally, when triggering the saving,
- the updated instance in the transactional buffer is
- automatically saved to the database without any custom
- development needed.
- - The transactional buffer is provided, too. You do not need to
- create the buffer yourself.
- - Note: Usually, the behavior of a RAP BO requires some
- additional implementations also in the context of managed RAP
- BOs. For example, non-standard operations or feature controls
- must be self-implemented in [ABAP behavior
- pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm "Glossary Entry")
- (see the details further down).
-- Unmanaged RAP BOs:
- - Everything must be provided by the [unmanaged RAP BO
- provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunmanaged_rap_bo_prov_glosry.htm "Glossary Entry"), i.
- e. the transactional buffer and all RAP BO operations must be
- provided or self-implemented by developers in an ABAP behavior
- implementation
- - Unmanaged RAP BOs are, for example, relevant for brownfield
- scenarios, i. e. in scenarios in which transactional buffers and application logic is already
- available and should be embedded in the RAP world. Note that it is possible to have a managed RAP BO with unamanged parts, e.g. unamanged save or additional save. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_rap_bo.htm).
-- ABAP behavior implementation in an ABAP behavior pool (ABP)
- - An [ABAP behavior
- pool](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm "Glossary Entry")
- is a special [class
- pool](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_pool_glosry.htm "Glossary Entry")
- for an ABAP behavior implementation that implements the
- unmanaged RAP BO provider based on definitions in a BDEF. The
- class pool's name is specified in the BDEF.
- - The [global
- class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm "Glossary Entry")
- of a behavior pool does not implement the behavior itself. It is
- (initially) empty apart from the declaration and implementation part skeletons. The behavior implementation is coded in local
- [RAP handler
- classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm "Glossary Entry")
- and a [RAP saver
- class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class_glosry.htm "Glossary Entry")
- in the [CCIMP
- include](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenccimp_glosry.htm "Glossary Entry")
- of the behavior pool. These classes are called by the [RAP
- runtime
- engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_runtime_engine_glosry.htm "Glossary Entry")
- when the RAP BO is accessed. This is covered in more detail
- further down.
- - Usually, saver classes are not needed in managed RAP BOs (except
- for special variants of managed RAP BOs which are not covered
- here). Local handler classes are, as mentioned above, usually
- needed in managed RAP BOs if implementations are required that
- go beyond standard operations.
- - Note: In more complex scenarios, with RAP BOs that
- consist of many entities, you can define behavior pools for
- individual entities by adding the syntax to the [`define
- behavior
- for`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_define_beh.htm)
- notation. There is not a saver class for each entity but only
- one saver class for the BO as a whole. Any number of behavior
- pools can be assigned to a BDEF allowing applications a
- structuring into multiple units.
-
-
-Find more terms in the [RAP Glossary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_glossary.htm) of the ABAP Keyword Documentation.
-There are more artifacts and concepts related to RAP that go way beyond
-the scope of this cheat sheet. For example, a RAP BO can be exposed as a
-[business
-service](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbusiness_service_glosry.htm "Glossary Entry")
-to be accessed from outside [AS
-ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenas_abap_sys_environ_glosry.htm "Glossary Entry")
-and consumed. A [RAP BO
-consumer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_consumer_glosry.htm "Glossary Entry")
-is either the [RAP transactional
-engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_transac_engine_glosry.htm "Glossary Entry")
-that handles requests from outside the AS ABAP or, from inside AS ABAP,
-an ABAP program using ABAP EML (which this cheat sheet and the examples
-focus on).
-
-
-
-## Excursion: RAP Behavior Definition (BDEF)
-
-- As mentioned in the RAP terms and as the name implies, a RAP behavior definition describes a RAP business object (RAP BO) by defining its behavior for all of its RAP BO entities.
-- BDL source code is used in a BDEF.
-- Once you have created ...
- - the CDS root entity of a RAP BO, ADT helps you create the skeleton of a BDEF (e.g., right-click on the CDS root entity and choose *New Behavior Definition* from the pop-up).
- - the BDEF, ADT helps you create the skeleton of an ABAP behavior pool, as well as RAP handler and saver method declarations and the skeleton of implementations via ADT quick fixes.
-- More information (see also the subtopics there):
- - [Structure of a RAP behavior definition](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_bdef.htm)
- - [Infos about BDL syntax](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_syntax.htm)
- - [Infos about behavior definitions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl.htm)
-
-
-The following example shows a commented BDEF.
-Note that there is a wide variety of possible specifications and options. The example shows only a selection. For full details, refer to the ABAP Keyword Documentation.
-Some of the syntax examples are commented out, just for the sake of showing more syntax options.
-
-```js
-//Possible implementation types: managed, unmanaged, abstract, projection, interface
-//(which restrict/enable further specifications)
-//You can specifiy one or more implementation classes (behavior pools/ABPs -> bp...)
-//for the RAP BO (in some contexts, specifying no ABP is possible).
-//Specifying unique is mandatory (each operation can only be implemented once).
-managed implementation in class bp_some_demo unique;
-//For managed RAP BOs, you can enable user-defined saving options (optional additions
-//are available).
-//Purpose: Enhancing or replacing the default save sequence (Note: Only in this case,
-//the ABP has a local saver class/save_modified saver method)
-//managed with additional save with full data implementation in class bp_some_demo unique;
-//full data: Full instance data is passed for saving
-//managed with unmanaged save implementation in class bp_some_demo unique;
-
-//Enabling the strict mode (and version) to apply additional syntax checks; handled by
-//the RAP framework; it is recommended that you use the most recent version
-strict ( 2 );
-
-//Enabling RAP draft handling
-//with draft;
-
-//It is mandatory to specify an entity behavior definition for the RAP BO root entity.
-//Here, some_demo represents a CDS view entity.
-define behavior for some_demo
-//Specifying an alias name (e.g. to have a more telling name than the technical name of
-//the entity). When specifying an alias name, you should address the entity with the alias
-//name instead of the full name (e.g. in the signature of handler methods).
-//define behavior for some_demo alias root
-
-//Specifying the database table a RAP BO is based on (only available/mandatory in managed
-//BOs); note further requirements for diverse scenarios in the documentation
-persistent table some_dbtab
-
-//Mandatory specification of a draft table when a RAP BO is draft-enabled
-//draft table drafttab
-
-//Specifying the locking mechanism for entities, e.g. to prevent a simultaneous
-//modification. In unmanaged RAP BOs, this must be self-implemented in a dedicated handler
-//method
-lock master
-
-//Controlling authorization that is to be implemented in an ABP (also for managed)
-//You can specify variants: global (e.g. for restricting certain operations) and/or
-//instance (restrictions based on entity instances) or both of them (dedicated handler
-//methods must be implemented)
-//More variants are available that can be specified in the { ... } block below for
-//excluding and delegating authorization checks (e.g. authorization:update)
-authorization master ( instance )
-//authorization master ( global )
-//authorization master ( instance, global )
-
-//Defining late numbering for primary key fields (see the adjust_numbers handler method)
-//More numbering options are available such as early numbering, or, in the { ... } block below,
-//the 'numbering : managed' specification for particular fields.
-//late numbering
-
-//Defining a field as entity tag (ETag) field for optimistic concurrency control (i.e.
-//enabling transactional access to data by multiple users to avoid inconsistencies when
-//unintentionally changing already modified data). More options available, e.g. for
-//draft-enabled RAP BOs (total etag).
-//etag master some_field
-
-{
- //RAP BO operations
- //Standard operations (Note: Read is implicitly enabled, no specification available)
- create;
- update;
- //More additions are available dealing with authorization, feature control, precheck etc.
- //The example shows precheck. In doing so, you can implement a precheck (e.g. to prevent
- //unwanted changes) before instances are deleted in a dedicated handler method. A precheck
- //implementation is also available for other operations (e.g. actions).
- //As is true for various specifications, a comma-separated list of specifications is possible.
- delete( precheck );
-
- //Note: It is not possible to specify operations multiple times. The following specifications
- //just demonstrate syntax options. Anyway, the compiler helps you not to specify wrong notations.
- //Applying feature control
- //delete( features: global );
-
- //Applying authorization control
- //delete( authorization : update );
-
- //Operations for associations (many specification options are possible)
- //The following example means enabling create-by-association operations for associations
- //Assumption: _child is specified in the the underlying CDS data model.
- association _child { create; }
-
- //Non-standard operations (check the specification options in the documentation, e.g. feature
- //control and others are possible) such as actions (modify RAP BO instance) and functions (return
- //information). There are different flavors of actions such as non-factory and factory actions,
- //which themselves have different variations. Other flavors of actions are save actions (only to
- //be executed during save sequence), determine actions (allow RAP BO consumers to execute
- //determinations and validations on request), and draft actions.
-
- //Non-factory actions (modify existing instances)
- //Instance action, relates to instances, modify instances
- action act1;
-
- //Static action, not bound to instances, relates to the entrie entity
- static action act2;
-
- //Internal action, accessible only from within the ABP (internal can also be specified in other
- //contexts, e.g. operations)
- internal action act3;
-
- //You can optionally specify input or output parameters or both (not always possible for all
- //action types). The following example shows an output parameter, defined with the result
- //addition. It stores the result of an action in an internal table. Variants are possible for
- //the return type. Here, it is $self (result type is the same type as entity) It can, for
- //example, also be an abstract BDEF or a different entity.
- action act4 result [1] $self;
-
- //Input parameter specified following 'parameter' (in this case, a CDS abstract entity)
- action act5 parameter some_cds_abstract;
-
- //Factory action (to create instances, can be instance-bound or static)
- //Specifying the cardinality is mandatory
- factory action act6 [1];
-
- //Draft actions
- //Available for draft-enabled RAP BOs, allow data modification on the draft table; are
- //implicitly available; it is recommended for the draft actions to be specified explicitly;
- //for some of the methods, the 'with additional implementation' addition is available
-
- //Copies active instances to the draft table
- //draft action Edit;
-
- //Sets a lock for entity instances on the persistent database table
- //draft action Resume;
-
- //Copies draft table content to the persitent database table; recommendation: use the
- //optimized addition
- //draft action Activate optimized;
-
- //Clears entries from the draft database table
- //draft action Discard;
-
- //Corresponds to the determine actions for active instances;
- //used to validate draft data before transitioning to active data
- //draft determine action Prepare
- // {
- //You can assign validations and determinations defined with 'on save'
- // validation val;
- // }
-
- //Functions (similar to actions, there are optional additions, such as static)
- //Since they return information, specifying an output parameter is required.
- //Instance function
- function func1 result [0..*] $self;
-
- //Static function
- static function func2 result [1] some_cds_abstract;
-
- //Instance function with optional input parameter
- function func3 parameter some_cds_abstract result [1] $self;
-
- //Field characteristics
- //Field values cannot be created/updated
- field ( readonly ) field1;
-
- //Read-only during update (especially key fields created during create operations)
- field ( readonly : update ) key_field;
-
- //The mandatory specification denotes that values must be provided for the fields before persisting
- //them to the database.
- //Comma-separated list possible for the field characteristics in general;
- //mutliple characteristics can also be specified in a comma-separated list in the parentheses
- field ( mandatory ) field2, field3;
-
- //Defining access restrictions for fields
- field ( features : instance ) field4;
-
- //Validations
- //Checking the consitency of instances; validations are triggered based on conditions
- //Conditions (one or more are possible) can be specified for create, update, delete operations
- //and modified fields; note: not available for unmanaged, non-draft RAP BOs.
- validation val on save { create; field field1; }
-
- //Determinations
- //Modifying instances based on trigger conditions;
- //As above, conditions (one or more are possible) can be specified for create, update, delete
- //operations and modified fields. The triggering is possible for 'on modify' and 'on save'.
- determination det1 on modify { update; delete; field field5, field6; }
- determination det2 on save { create; field field7, field8; }
-
- //RAP business event (derived events with the specification 'managed evt ...' are also possible)
- event evt;
-
- //RAP side effects, to trigger a reload of affected properties on the UI
- //Trigger properties: Field changes, action executions
- //Multiple side effects can be specified within a { ... } block, separated by a colon
- //There are multiple options to specify the target following 'affect'; the example uses fields
- //to be reloaded
- side effects { field field1 affects field field4;
- field field2 affects field field4;
- field field3 affects field field4;
- action act1 affects field field4; }
-
-}
-
-
-//It is optional to specify an entity behavior definition for child entities
-define behavior for some_child_entity alias child
-
-//Applying locks dependent on the specified association (locks are delegated to
-//the specified association). In this case, it's the parent entity. Assumption:
-//_parent is specified in the the underlying CDS data model.
-lock dependent by _parent
-
-//Applying authorization checks dependent on the specified association
-//As above, the assumption is that _parent is specified in the underlying CDS
-//data model.
-authorization dependent by _parent
-
-{
- update;
- delete;
- field ( readonly ) key_field;
- field ( readonly : update ) key_field_child;
- association _parent;
-}
-```
-
-
-
-## ABAP Behavior Pools (ABP)
-
-As mentioned above, you can access RAP BO data from inside AS ABAP using
-EML. Among other things, EML allows you to read or modify RAP BOs by
-accessing the RAP BO data (the RAP BO instances) in the transactional
-buffer and trigger the persistent storage or reset changes. More
-precisely, when EML statements are executed, the calling of [RAP handler
-methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_method_glosry.htm "Glossary Entry")
-is triggered to access the transactional buffer of a RAP BO. As
-mentioned, for unmanaged RAP BOs or unmanaged parts of managed RAP BOs,
-the handler methods that are called are part of an ABAP behavior pool.
-
-The global class of an ABP has the addition [`FOR BEHAVIOR OF bdef`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_for_behavior_of.htm)
-to the definition while `bdef` stands for the name of the BDEF.
-This class is (initially) empty apart from the declaration and implementation part skeleton.
-
-```abap
-CLASS zbp_demo_abap_rap_draft_m DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zdemo_abap_rap_draft_m.
-ENDCLASS.
-
-CLASS zbp_demo_abap_rap_draft_m IMPLEMENTATION.
-ENDCLASS.
-```
-
-The actual implementation is done in local classes in the CCIMP include (*Local Types* tab in ADT) of the behavior pool. There,
-two kinds of local classes are to be defined and implemented that are
-related to the RAP BO's runtime: one or more [handler
-classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm "Glossary Entry")
-to implement the RAP BO behavior (in RAP handler methods) during the
-[RAP interaction
-phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm "Glossary Entry")
-(the data reading and modification phase) and a [saver
-class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class_glosry.htm "Glossary Entry")
-to implement the [RAP save
-sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry")
-(in [saver
-methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_method_glosry.htm "Glossary Entry")
-to save data from the transactional buffer to the database).
-
-
-
-### RAP Handler Classes and Methods
-
-- One or more handler classes implement the RAP interaction phase. For
- modularization purposes, one behavior pool can define multiple
- handler classes. For example, each entity can have its own handler
- class, or individual handler classes can be defined to distinguish
- between reading and changing RAP BO entities.
-- A handler class inherits from class
- `CL_ABAP_BEHAVIOR_HANDLER`.
-- These classes are implicitly `ABSTRACT` and `FINAL`
- since instantiating and calling only happens through the RAP runtime
- engine.
-- [ADT](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenadt_glosry.htm "Glossary Entry")
- helps you create the classes and methods (and basically the ABP as
- such) when creating the BDEF. A quick fix is available that creates
- the method definitions and a skeleton of the implementations
- automatically.
-
-Example: Handler class definition
-``` abap
-CLASS lhc_root DEFINITION INHERITING FROM cl_abap_behavior_handler.
-...
-ENDCLASS.
-```
-- Handler method definitions include the additions `... FOR ... FOR
- ...` followed by the kinds of operations. There are various
- options depending on the RAP BO operation.
-- Depending on the definition in the BDEF, there might be more additions
- with dedicated method parameters. For example, an action might
- be defined with a result parameter, hence, the method must be
- defined with the addition `RESULT` and a parameter.
-- The `FOR MODIFY` handler method can handle multiple entities
- and operations, i. e. not only create but also update or delete
- might be integrated in the method definition. However, it might be
- useful to split the handler method into separate methods for better
- readability.
-- See more details on the handler method definitions in the topic
- [`METHODS, FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_for_rap_behv.htm).
-
-Example: Handler method definitions
-``` abap
-"Create
-METHODS create FOR MODIFY
- IMPORTING entities FOR CREATE bdef.
-
-"Read: Specifying a read result is mandatory.
-METHODS read FOR READ
- IMPORTING keys FOR READ bdef RESULT result.
-
-"Action: action name is preceded by the BDEF name and a tilde after FOR ACTION
-METHODS some_action FOR MODIFY
- IMPORTING keys FOR ACTION bdef~some_action.
-```
-
-**Parameters of Handler Methods**
-
-- The handler method definitions contain RAP-specific additions like
- `FOR MODIFY`, `FOR CREATE` or `FOR READ` as
- well as mandatory or optional additions like `RESULT` that
- are followed by parameters.
-- Nearly all parameters are typed with [BDEF derived
- types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry")
- that have special RAP-related components as covered further down.
-- The parameters' names can be chosen freely. This is also true for
- the method names except for some predefined names.
-- Each handler method must have at least one importing parameter. The
- addition `IMPORTING` is optional since it is used
- implicitly. In most cases, entire instances or just key values
- of instances are imported.
-- All handler methods have changing parameters that are usually not
- explicitly specified in the definition but implicitly used. The
- explicit specification of the `CHANGING` addition is not needed. In most cases, these are
- [RAP response
- parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_response_param_glosry.htm "Glossary Entry").
- The following image shows the F2 information in ADT for the create
- handler method.
- 
-- The response parameters `mapped`, `failed` and
- `reported` (the names are predefined) can be considered as
- containers for information - information a RAP BO consumer is
- provided with by a RAP BO provider, for example, an SAP Fiori app
- displays an error message if something went wrong. The availability
- of the parameters depends on the handler method used (e. g.
- `mapped` is only available for operations creating
- instances).
- - `mapped`: Used to provide mapping information on RAP BO
- instances, for example, which key values were created for given
- content IDs (
- [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)).
- - `failed`: Information for identifying the data set for
- which an error occurred in a RAP operation
- - `reported`: Used, for example, to exchange error messages for each
- entity defined in the BDEF and [not related to a specific
- entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_other.htm).
- - Example: Technically, the `reported` parameter is a
- [deep
- structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm "Glossary Entry")
- containing, for example, the messages of the root entity and
- child entities. For example, if a create operation fails for a
- RAP BO instance of the root entity, a message, information about
- the instance key and other things can be included in this
- parameter which is passed to a RAP BO consumer. You could
- imagine that such an error message is displayed on an SAP Fiori
- UI if something goes wrong to inform the user.
-
-
-
-
-### RAP Saver Class and Saver Methods
-
-- A RAP saver class implements the [RAP save
- sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry").
- A saver class is usually only available in unmanaged RAP BOs (except
- for special variants of managed RAP BOs that are not outlined here).
-- The saver class is implicitly `ABSTRACT` and `FINAL`
- since the instantiating and calling only happens through the RAP
- runtime engine.
-- A saver class can be defined in the CCIMP include of an ABAP
- behavior pool. It includes the definitions and implementations of
- RAP saver methods.
-- The saver methods consist of a set of predefined methods having
- predefined names. Some of them are mandatory to implement, some are
- optional. The
- [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)
- method is only available in [late
- numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry")
- scenarios.
-- A saver class inherits from class
- `CL_ABAP_BEHAVIOR_SAVER`. The saver methods are
- declared by redefining predefined methods of the superclass. They
- implicitly have response parameters.
-- In contrast to RAP handler methods, saver methods do not have data
- of RAP BO instances as import parameter. Therefore, instance data
- must be handled via the transactional buffer when self-implementing
- the saver methods.
-- Saver methods are called when the RAP save sequence has been triggered by a [`COMMIT
- ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm)
- statement. Note that in natively supported RAP scenarios, for example, an SAP Fiori app using OData, the `COMMIT ENTITIES` call is performed implicitly and automatically by the [RAP runtime engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_runtime_engine_glosry.htm).
-- Find more information on RAP saver methods
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class.htm).
-
-Example: Definition of a RAP saver class and saver methods
-``` abap
-CLASS lsc_bdef DEFINITION INHERITING FROM cl_abap_behavior_saver.
- PROTECTED SECTION.
-
- "For final calculations and data modifications involving all
- "BOs in the current RAP transaction
- METHODS finalize REDEFINITION.
-
- "Checks the consistency of the transactional buffer before
- "the save method saves data to the database
- METHODS check_before_save REDEFINITION.
-
- "Preliminary IDs are mapped to final keys. Only for late numbering.
- METHODS adjust_numbers REDEFINITION.
-
- "Saves the current state of the transactional buffer to the database
- METHODS save REDEFINITION.
-
- "Clear the transactional buffer
- METHODS cleanup REDEFINITION.
- METHODS cleanup_finalize REDEFINITION.
-
-ENDCLASS.
-```
-
-
-
-## BDEF Derived Types
-
-The operands of EML statements and parameters of handler and saver
-methods are mainly special messenger tables for passing data and
-receiving results or messages, i. e. the communication between a RAP BO
-consumer and the RAP BO provider using EML consists (in most cases) of
-exchanging data stored in internal tables that have special ABAP types -
-[BDEF derived
-types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry").
-These types are tailor-made for RAP purposes.
-
-As the name implies, the types are derived by the [ABAP runtime
-framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm "Glossary Entry")
-from CDS entities and their behavior definition in the BDEF. With these
-special types, a type-safe access to RAP BOs is guaranteed.
-
-You can create internal tables (using [`TYPE TABLE
-FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_table_for.htm)),
-structures (using [`TYPE STRUCTURE
-FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_structure_for.htm))
-and data types with BDEF derived types. For all operations and behavior
-characteristics defined in the BDEF, types can be derived.
-
-The syntax uses - similar to the method definitions mentioned before -
-the addition `FOR` followed by the operation and the name of an
-entity (and, if need be, the concrete name, e. g. in case of an action
-defined in the BDEF).
-
-Each BDEF derived type can be categorized as
-[input](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_input_der_type_glosry.htm "Glossary Entry")
-or [output derived
-type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_output_der_type_glosry.htm "Glossary Entry")
-according to its use as importing or exporting parameters in methods of
-RAP BO providers. In most cases, structures of type `TYPE STRUCTURE
-FOR` can be considered as serving as [work
-area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry")
-and line type of the internal tables. However, there are also structured
-derived types that do serve as types for handler method parameters.
-
-The response parameters `mapped`, `failed` and
-`reported` have dedicated derived types: [`TYPE RESPONSE
-FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_response_for.htm).
-They are deep structures containing the information for the individual
-entities of the RAP BO. The components of these structures are internal
-tables of appropriate types with `TYPE TABLE FOR`.
-
-Examples for BDEF derived types:
-
-``` abap
-"Data objects with input derived types (entity = name of a root entity)
-
-"For an EML create operation
-DATA create_tab TYPE TABLE FOR CREATE entity.
-
-"For an update operation
-DATA update_tab TYPE TABLE FOR UPDATE entity.
-
-"Type for create-by-association operations specifying the name of the entity
-"and the association
-DATA cba_tab TYPE TABLE FOR CREATE entity\_child.
-
-"For an action execution; the name of the action is preceded by a tilde
-DATA action_imp TYPE TABLE FOR ACTION IMPORT entity~action1.
-
-"Data objects with output derived types
-
-"For a read operation
-DATA read_tab TYPE TABLE FOR READ RESULT entity.
-
-"For an action defined with a result
-DATA action_res TYPE TABLE FOR ACTION RESULT entity~action2.
-
-"Examples for structures and types
-DATA create_wa TYPE STRUCTURE FOR CREATE entity.
-
-"For permission retrieval
-DATA perm_req TYPE STRUCTURE FOR PERMISSIONS REQUEST entity.
-
-"For retrieving global features
-DATA feat_req TYPE STRUCTURE FOR GLOBAL FEATURES RESULT entity.
-
-"Type declaration using a BDEF derived type
-TYPES der_typ TYPE TABLE FOR DELETE entity.
-
-"Response parameters
-DATA map TYPE RESPONSE FOR MAPPED entity.
-DATA fail TYPE RESPONSE FOR FAILED entity.
-DATA rep TYPE RESPONSE FOR REPORTED entity.
-```
-> **💡 Note**
-> Some of the derived types can only be created and accessed in implementation classes.
-
-
-
-### Components of BDEF Derived Types
-
-Many of the BDEF derived types contain components of CDS entities like
-key and data fields that retain their original data type, for example, a
-messenger table typed with `TYPE TABLE FOR CREATE`. Certainly,
-if an instance is to be created, key and field values of a RAP BO
-instance are of relevance.
-
-Yet, all BDEF derived types contain special RAP components serving a
-dedicated purpose. The names of these RAP components begin with
-`%` to avoid naming conflicts with components of the CDS
-entities. The following image shows the F2 information of a BDEF derived
-type containing the `%` components and fields from the CDS
-entity.
-
-
-
-Some of the `%` components are [component
-groups](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_group_glosry.htm "Glossary Entry")
-summarizing groups of table columns under a single name. In doing so,
-they simplify the handling of derived types for developers. For example,
-the component group
-[`%data`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_data.htm)
-contains all primary key and data fields of a RAP BO entity (actually,
-by containing the keys, it also contains the component group
-[`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm)
-in the case above). The F2 information in ADT helps you find out about
-the available components in a variable. The image below shows the
-details of `%data` when clicking the *derived type*
-link in the first ADT F2 information screen.
-
-
-
-The availability of `%` components depends on definitions in the
-BDEF. Their availability also depends on more criteria, for example, the
-scenario. For example, the component
-[`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
-that represents a preliminary ID for a RAP BO instance is only available
-in [late
-numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry")
-scenarios. The draft indicator
-[`%is_draft`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_is_draft.htm)
-is only relevant in the context of
-[draft](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_with_draft.htm).
-
-Find more details on the available components in section [Components of
-BDEF Derived
-Types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_comp.htm).
-
-Bullet points on selected `%` components:
-
-- [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)
- - A string to define a content ID.
- - Content IDs are used as a unique and preliminary identifier for
- RAP BO operations in which instances are created and especially
- in cases where the key values of RAP BO instances are not yet
- determined
- - Assume that you create a RAP BO instance with an EML create
- request and the key value has not yet been determined. In the
- same request - a save has not yet been triggered - an update is
- requested for this RAP BO instance. Using the content ID, it is
- guaranteed that the update operation happens for the desired
- instance. For this purpose, derived types for operations like
- update or delete include the component
- [`%cid_ref`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid_ref.htm)
- to refer to the content ID `%cid` as the name implies.
- - Note: You should always fill `%cid` even if not
- needed. The specified content ID is only valid within one ABAP
- EML request. You can use the optional addition [`AUTO FILL CID`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm#!ABAP_ONE_ADD@1@) in EML modify operations to create `%cid` automatically. However, if you use this addition, you cannot refer to `%cid` in subsequent operations.
-- [`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm)/[`%tky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tky.htm)
- - Both are component groups summarizing all primary keys of a RAP
- BO instance.
- - Where possible, it is recommended that you use `%tky`
- instead of `%key`. `%tky` includes
- `%key` and also the draft indicator
- `%is_draft`. When using `%tky` in non-draft
- scenarios, you are prepared for a potential, later switch to a
- draft scenario. In doing so, you can avoid lots of adaptations
- in your code by manually adding the indicator.
-- [`%control`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_control.htm)
- - Component group that contains the names of all key
- and data fields of a RAP BO instance which indicate flags.
- - For example, it is used to get information on which fields are provided or set a
- flag for which fields are requested by RAP BO providers or RAP
- BO consumers respectively during the current EML request.
- - For this purpose, the value of each field in the
- `%control` structure is of type
- `ABP_BEHV_FLAG`. For the value setting,
- you can use the structured constant `mk` of interface
- `IF_ABAP_BEHV`. Note that the technical
- type is `x length 1`.
- - Example: If you want to read data from a RAP BO instance and
- particular non-key fields in `%control` are set to
- `if_abap_behv=>mk-off`, the values of these fields
- are not returned in the result.
-
-
-
-## EML Syntax
-
-The focus is here on selected EML statements. These statements can be
-fairly long and various additions are possible. Find more information on
-the EML statements
-[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeneml.htm).
-
-### EML Syntax for Modifying Operations
-
-The modifying operations covered include the standard operations (using
-the additions
-[`CREATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
-[`CREATE
-BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
-[`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
-and
-[`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm))
-and non-standard operations (actions) using the addition
-[`EXECUTE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm).
-All EML statements for the mentioned operations begin with
-[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities.htm).
-The following commented code snippets demonstrate the
-[short](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_short.htm)
-and [long
-form](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entities_long.htm)
-of EML `MODIFY` statements.
-
-> **💡 Note**
-> Unlike reading operations, modifying operations are not enabled by default. You must make the respective notations in the BDEF:
-> ```
-> ...
-> create;
-> update;
-> delete;
-> action some_act;
-> ...
-> ```
-
-Create operation for creating new instances of a RAP BO entity:
-
-``` abap
-"Declaration of data objects using BDEF derived types
-
-DATA: cr_tab TYPE TABLE FOR CREATE root_ent, "input derived type
- mapped_resp TYPE RESPONSE FOR MAPPED root_ent, "response parameters
- failed_resp TYPE RESPONSE FOR FAILED root_ent,
- reported_resp TYPE RESPONSE FOR REPORTED root_ent.
-
-"Input derived type for the EML statement is filled using the VALUE operator
-"Assumption: key_field is the key field having type i,
-"field1 and field2 are data fields with character-like data type.
-"Specify %cid even if not used or of interest; it must be unique within a request
-
-cr_tab = VALUE #(
- ( %cid = 'cid1' key_field = 1
- field1 = 'A' field2 = 'B' )
- ( %cid = 'cid2'
- "Just to demo %data/%key. You can specify fields with or without
- "the derived type components
- %data = VALUE #( %key-key_field = 2
- field1 = 'C'
- field2 = 'D' ) ) ).
-
-"EML statement, short form
-"root_ent must be the full name of the root entity, it is basically the name of the BDEF
-
-MODIFY ENTITY root_ent
- CREATE "determines the kind of operation
- FIELDS ( key_field field1 field2 ) WITH cr_tab "Fields to be respected for the
- "input derived type and the input
- "derived type itself
- MAPPED mapped_resp "mapping information
- FAILED failed_resp "information on failures with instances
- REPORTED reported_resp. "messages
-```
-
-> **💡 Note**
-> - Addition [`FIELDS ( ... ) WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm):
- This field selection option specifies which fields are to be
- respected for the operation. The derived type, i. e. an internal
- table containing the concrete RAP BO instance values, follows
- `WITH`. If a field is specified in the field list within the
- pair of parentheses after `FIELDS`, the `%control`
- flag for this field is automatically set to
- `if_abap_behv=>mk-on`. Likewise, if a field is not
- contained in the list, the flag in `%control` is set to
- `if_abap_behv=>mk-off`. Assume `field2` is not
- specified in the list. The value for `field2` will not be
- respected (even if a value is specified in the internal table). The
- initial value will be used for the field.
->- Retrieving the responses and specifying the parameters is optional.
- Assuming a data set with the value 2 for `key_field`
- already exists on the database for this BO, you should expect an
- entry for this particular instance in the `failed_resp`
- operand and potentially an error message in
- `reported_resp`, too. Nevertheless, especially in ABP
- implementations and depending on the context, you should implement
- and fill these parameters according to the [RAP BO
- contract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_contract_glosry.htm "Glossary Entry")
- to meet the variety of implementation rules.
->- `%cid` should be provided even if you are not interested in
- it and subsequent operations do not require the reference.
-
-Long form of an EML `MODIFY` statement:
-``` abap
-MODIFY ENTITIES OF root_ent "full name of root entity
- ENTITY root "root or child entity (alias name if available)
- CREATE FROM "FROM as further field selection variant
- VALUE #( ( %cid = 'cid' "Input derived type created inline
- key_field = 3
- field1 = 'E'
- field2 = 'F'
- %control = VALUE #( "Must be filled when using FROM
- key_field = if_abap_behv=>mk-on
- field1 = if_abap_behv=>mk-on
- field2 = if_abap_behv=>mk-on ) ) )
- MAPPED DATA(m) "Target variables declared inline
- FAILED DATA(f)
- REPORTED DATA(r).
-```
-
-> **💡 Note**
->- The entity specified after `ENTITY` can be either the root
- entity itself or a child entity. If an alias is defined, the alias
- should be used.
->- The addition `FIELDS ( ... ) WITH` from the previous
- snippet is basically a shortcut for the addition
- [`FROM`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm)
- that is used here. When using `FROM`, the values of the
- `%control` structure must be specified explicitly.
->- The BDEF derived types can also be created
- [inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm)
- as shown in the example using a [constructor
- expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_glosry.htm "Glossary Entry")
- for the input derived type and with `DATA` or
- [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm)
- for the responses.
->- The long form allows you to bundle several operations in one
- statement, either different operations on the same entity (for
- example, deleting some instances and updating some others) or
- operations on different entities of the same RAP BO (for example,
- creating a root entity instance and related instances of a child
- entity in one EML request). Long and short forms are also available
- for other EML statements.
->- The [`SET FIELDS WITH`](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapmodify_entity_entities_fields.htm#!ABAP_VARIANT_4@4@) addition is available as another field specification option. However, it has limitations that you should be aware of. It can cause syntax warnings. Check the documentation. It is recommended that you use `FIELDS ... WITH` and `FROM`.
-
-
-Excursion: Specifying `%control` component values in the short form of `VALUE` constructor expressions
-
-```abap
-"The following EML statement creates RAP BO instances. The BDEF derived
-"type is created inline. With the FROM addition, the %control values
-"must be specified explicitly. You can provide the corresponding values
-"for all table lines using the short form, i.e. outiside of the inner
-"parentheses, instead of individually specifying the values for each
-"instance within the parentheses. In this case, the corresponding %control
-"component value is assigned for all of the following table lines.
-MODIFY ENTITIES OF zdemo_abap_rap_ro_m
- ENTITY root
- CREATE FROM VALUE #(
- %control-key_field = if_abap_behv=>mk-on
- %control-field1 = if_abap_behv=>mk-on
- %control-field2 = if_abap_behv=>mk-on
- %control-field3 = if_abap_behv=>mk-on
- %control-field4 = if_abap_behv=>mk-off
- ( %cid = 'cid1'
- key_field = 1
- field1 = 'aaa'
- field2 = 'bbb'
- field3 = 10
- field4 = 100 )
- ( %cid = 'cid2'
- key_field = 2
- field1 = 'ccc'
- field2 = 'ddd'
- field3 = 20
- field4 = 200 ) )
- MAPPED DATA(m)
- FAILED DATA(f)
- REPORTED DATA(r).
-```
-
-
-The following EML statement combines multiple operations in one EML
-request. It demonstrates the use of `%cid` and
-`%cid_ref`. First, two instances are created by specifying
-`%cid`. An update operation in the same request only specifies a
-certain field within the parentheses of the `FIELDS ( ... )
-WITH` addition which denotes that only this particular field
-should be updated. The other field values remain unchanged. The
-reference to the instance is made via `%cid_ref`. Consider an
-EML request in which no instance to refer to using `%cid_ref`
-exists, e. g. for an update operation. You can also make the reference
-using the unique key. A delete operation is available in the same
-request, too. `DELETE` can only be followed by the addition
-`FROM`. In contrast to other derived types, the derived type
-that is expected here (`TYPE TABLE FOR DELETE`) only has
-`%cid_ref` and the key as components.
-``` abap
-MODIFY ENTITIES OF root_ent
- ENTITY root
- CREATE FIELDS ( key_field field1 field2 ) WITH
- VALUE #( ( %cid = 'cid4' key_field = 4
- field1 = 'G' field2 = 'H' )
- ( %cid = 'cid5' key_field = 5
- field1 = 'I' field2 = 'J' ) )
-
- UPDATE FIELDS ( field2 ) WITH
- VALUE #( ( %cid_ref = 'cid4' field2 = 'Z' ) )
-
- DELETE FROM
- VALUE #( ( %cid_ref = 'cid5' ) "Instance referenced via %cid_ref
- ( key_field = 9 ) ) "Instance referenced via the key
-...
-```
-
-EML statement including the execution of an action:
-``` abap
-MODIFY ENTITIES OF root_ent
- ENTITY root
- EXECUTE some_action
- FROM action_tab
- RESULT DATA(action_result) "Assumption: The action is defined with a result parameter.
- ...
-```
-
-The following code snippet shows a deep create. First, an instance is
-created for the root entity. Then, in the same request, instances are
-created for the child entity based on the root instance. In the example
-below, the assumption is that a composition is specified in the root
-view entity like `composition [1..*] of root_ent as _child` and `key_field` and
-`key_field_child` are the keys of the child view entity. The
-[`%target`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_target.htm)
-component group enters the picture here which contains the target's
-primary key and data fields.
-``` abap
-MODIFY ENTITIES OF root_ent
- ENTITY root_ent
- CREATE FIELDS ( key_field field1 field2 ) WITH
- VALUE #( ( %cid = 'cid6' key_field = 6
- field1 = 'I' field2 = 'J' ) )
- CREATE BY \_child
- FIELDS ( key_field_child field1_child field2_child ) WITH
- VALUE #( ( %cid_ref = 'cid6'
- %target = VALUE #( ( %cid = 'cid_child_1'
- key_field_child = 1
- field1_child = 'aa'
- field2_child = 'bb' )
- ( %cid = 'cid_child_2'
- key_field_child = 2
- field1_child = 'cc'
- field2_child = 'dd' ) ) ) )
-...
-```
-
-
-
-### EML Syntax for Reading Operations
-
-- Read-only operations always return a result, i.e. the syntax of the
- EML statement requires the addition `RESULT` and an operand.
-- When RAP BO instances are read, the returned data include the
- current status of instances in the transactional buffer which
- includes unsaved modifications on instances. If an instance is not
- yet available in the transactional buffer, the currently persisted
- data set is automatically read into the transactional buffer.
-- Note that read operations are always implicitly enabled for each
- entity listed in a BDEF, i. e. there is no extra definition in the
- BDEF in contrast to, for example, create or update.
-
-The following code snippet shows the long form of the EML
-[`READ`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_op.htm)
-statement for reading instances from the root entity. In `READ`
-statements, the additions `FIELDS ( ... ) WITH` and
-`FROM` can also be used to specify the fields that you intend to
-read. Here, the addition [`ALL FIELDS
-WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_fields.htm)
-is available for reading all field values.
-
-``` abap
-READ ENTITIES OF root_ent
- ENTITY root_ent
- ALL FIELDS WITH
- VALUE #( ( key_field = 1 ) "Derived type TYPE TABLE FOR READ IMPORT only includes the keys
- ( key_field = 2 ) )
- RESULT DATA(result)
- FAILED DATA(f)
- REPORTED DATA(r).
-```
-
-Read-by-association operations include the optional addition
-[`LINK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_op&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ONE_ADD@1@&tree=X)
-with which you can retrieve the keys of the source and target (i. e. the
-associated entity). The by-association operations work reciprocally, i.
-e. you can, for example, read a child instance via the parent and a
-parent instance via the child, too.
-
-``` abap
-"Read-by association operation: parent to child
-READ ENTITIES OF root_ent
- ENTITY root_ent
- BY \_child
- ALL FIELDS WITH VALUE #( ( key_field = 1 ) )
- RESULT DATA(rba_res1)
- LINK DATA(links1).
- ...
-
-"Read-by association operation: child to parent
-READ ENTITIES OF root_ent
- ENTITY child_ent
- BY \_parent
- ALL FIELDS WITH VALUE #( ( key_field = 1 key_field_child = 1 ) )
- RESULT DATA(rba_res2)
- LINK DATA(links2).
- ...
-```
-
-
-#### Dynamic Forms of EML Statements
-
-In addition to the short and long forms described above, various ABAP EML statements also have dynamic forms.
-Taking EML read operations as an example, the following code snippet shows a dynamic EML [`READ ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entities_operations.htm) statement. The relevant syntax element is the `OPERATIONS` addition.
-The dynamic form allows the collection of read operations for multiple RAP BOs in one EML statement.
-For more information, see the ABAP keyword documentation and the comments in the snippet.
-
-```abap
-"The statement is taken from the executable example. The example has a
-"root entity and a child entity. For both entities, RAP BO instances
-"are to be read (read and read-by-association operation).
-
-DATA:
- "The following data object is the operand of the dynamic EML statement
- "It is an internal table and has a special, RAP-specific type.
- op_tab TYPE abp_behv_retrievals_tab,
-
- "More data object declarations (internal tables typed with BDEF
- "derived types) that are relevant for the EML statement.
- "For both entities (root and child), RAP BO instances are to be
- "read. The internal tables are used for components of the internal
- "table op_tab further down.
- read_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m,
- read_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m,
- rba_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\_child,
- rba_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m\_child,
- rba_dyn_link TYPE TABLE FOR READ LINK zdemo_abap_rap_ro_m\_child.
-
-"Filling the internal tables, i.e. which instances are to be read
-"Root entity
-"Example:
-"- The key is comprised of the field 'key_field'. It is of type i.
-"- The %control structure is filled, flagging those fields that
-" are to be read. Flagging the key field is not required.
-read_dyn = VALUE #(
- ( %key-key_field = 1
- %control = VALUE #(
- field1 = if_abap_behv=>mk-on
- field2 = if_abap_behv=>mk-on
- field3 = if_abap_behv=>mk-on
- field4 = if_abap_behv=>mk-on ) )
- ( %key-key_field = 2
- %control = VALUE #(
- field1 = if_abap_behv=>mk-on
- field2 = if_abap_behv=>mk-on
- field3 = if_abap_behv=>mk-on
- field4 = if_abap_behv=>mk-on ) ) ).
-
-"Child entity
-"Instances to be read for a read-by-association operation
-"The shared key is 'key_field'.
-rba_dyn = VALUE #(
- ( %key-key_field = 1
- %control = VALUE #(
- key_ch = if_abap_behv=>mk-on
- field_ch1 = if_abap_behv=>mk-on
- field_ch2 = if_abap_behv=>mk-on ) )
- ( %key-key_field = 2
- %control = VALUE #(
- key_ch = if_abap_behv=>mk-on
- field_ch1 = if_abap_behv=>mk-on
- field_ch2 = if_abap_behv=>mk-on ) ) ).
-
-"Filling the internal table that is the operand of the
-"dynamic EML statement
-"This table has optional and mandatory components.
-op_tab = VALUE #(
- ( "op: Specifies the operation to be executed; is mandatory;
- " can be set with the predefined constants, e.g. OP-R-READ
- " etc., of interface IF_ABAP_BEHV
- op = if_abap_behv=>op-r-read
- "entity_name: Specifies the name of the RAP BO entity for which
- " the operation is executed; is mandatory
- entity_name = 'ZDEMO_ABAP_RAP_RO_M'
- "instances: Specifies a reference to an internal table holding
- " the input keys; must be appropriately typed; is mandatory
- instances = REF #( read_dyn )
- "results: Specifies a reference to an internal table with the required
- " BDEF derived type for the read results; is mandatory
- results = REF #( read_dyn_result ) )
- ( op = if_abap_behv=>op-r-read_ba
- entity_name = 'ZDEMO_ABAP_RAP_RO_M'
- "sub_name: Only relevant for specifying association names in
- " read-by-association operations; in that context, it is mandatory
- sub_name = '_CHILD'
- "full: Optional flag; specifies if all target instances are to be retrieved
- full = abap_true
- instances = REF #( rba_dyn )
- results = REF #( rba_dyn_result )
- "links: Reference to internal table holding the key pairs of the source and
- " target
- links = REF #( rba_dyn_link ) ) ).
-
-READ ENTITIES OPERATIONS op_tab.
-```
-
-
-### Persisting to the Database
-
-- A [`COMMIT
- ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm)
- statement triggers the RAP save sequence. Without such a statement,
- the modified RAP BO instances that are available in the
- transactional buffer are not persisted to the database. As mentioned above, in case of a natively supported RAP
- scenario (for example, when using OData), the `COMMIT
- ENTITIES` request is executed automatically.
-- `COMMIT ENTITIES` implicitly includes [`COMMIT
- WORK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit.htm).
-- Note: `COMMIT ENTITIES` statements cannot be used
- in behavior implementations.
-- There are multiple variants available for the statement as described
- in the ABAP Keyword Documentation
- [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm). For example, RAP responses can be retrieved, key conversion in late numbering scenarios, checking a RAP transaction in a simulation mode.
-- `COMMIT ENTITIES` statements set the system field
- `sy-subrc`. When using `COMMIT ENTITIES`, it is not
- guaranteed that `COMMIT WORK` is carried out successfully.
- Hence, you should include a check for `sy-subrc` after
- `COMMIT ENTITIES` so that you can react to failures
- accordingly.
-
-The following snippet shows a create operation. This operation has only
-an impact on the database with the `COMMIT ENTITIES` statement.
-Triggering the save sequence means that the execution of the statement
-triggers the calling of the saver methods available in the saver class
-of a behavior implementation. In managed scenarios (except for some
-special variants), the saving is done automatically without implementing
-a dedicated saver method.
-``` abap
-MODIFY ENTITIES OF root_ent
- ENTITY root_ent
- CREATE FIELDS ( key_field field1 field2 ) WITH
- VALUE #( ( %cid = 'cid' key_field = 7
- field1 = 'K' field2 = 'L' ) ).
-
-COMMIT ENTITIES.
-
-IF sy-subrc <> 0.
- ...
-ENDIF.
-```
-
-
-
-### Raising RAP Business Events
-
-- [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm) can be raised in ABAP behavior pools with [`RAISE ENTITY EVENT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_entity_event.htm) statements.
-- The focus of the snippets is on the local consumption of RAP business events. Prerequisites:
- - `event` specifications are available in the BDEF (e.g. `... event some_evt; ...`). For more details, refer to the [BDL documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_event.htm)
- - A [RAP event handler class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_event_handler_class_glosry.htm) is available that is used to implement [RAP event handler methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_event_handler_meth_glosry.htm).
- - Note that these methods are called asynchronously.
- - Similar to RAP handler and saver methods, RAP event handler methods are implemented in the CCIMP include of the RAP event handler class.
- - To locally consume RAP business events, a local class that inherits from `CL_ABAP_BEHAVIOR_EVENT_HANDLER` can be implemented in the CCIMP include of a RAP event handler class.
-- More information:
- - [ABAP for RAP Business Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_events.htm) in the ABAP Keyword Documentation
- - [Business Events](https://help.sap.com/docs/abap-cloud/abap-rap/business-events) in the SAP Help Portal
-
-```abap
-"---- Syntax for the declaration part of a global RAP event handler class ----
-CLASS cl_event_handler DEFINITION PUBLIC FOR EVENTS OF some_bdef.
- ...
-ENDCLASS.
-
-"---- Syntax for the declaration part of a local event handler class ----
-"---- in the CCIMP include of a RAP event handler class ----
-CLASS lhe_event DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
- ...
-ENDCLASS.
-
-"---- RAP event handler method definition ----
-"Notes:
-"- Must be defined as instance methods in the private visibility section.
-"- The input parameter par is an internal table of type TYPE TABLE FOR EVENT.
-"- This type includes the keys of RAP BO instances (and %param, if the event
-" is specified with a parameter in the BDEF)
-"- The methods do not contain RAP response parameters.
-METHODS meth FOR ENTITY EVENT par FOR some_bdef~some_evt.
-
-"---- RAISE ENTITY EVENT statement in an ABP, e.g. the save_modified method ----
-"---- in managed scenarios with additional save ----
-...
-CLASS lsc IMPLEMENTATION.
- METHOD save_modified.
- "Assumption: An event is specified for create operations in the BDEF as follows
- "event created;
- IF create-some_bdef IS NOT INITIAL.
- RAISE ENTITY EVENT some_bdef~created
- FROM VALUE #( FOR IN create-root ( %key = VALUE #( some_key = -some_key ) ) ).
- ENDIF.
-
- "Assumption: An event is specified for delete operations in the BDEF as follows
- "event deleted parameter some_abstract_entity;
- "The abstract entity has two parameters, for example, with which additional
- "information can be passed.
- IF delete-some_bdef IS NOT INITIAL.
- RAISE ENTITY EVENT some_bdef~deleted
- FROM VALUE #( FOR IN delete-some_bdef (
- %key = VALUE #( some_key = -some_key )
- %param = VALUE #( par_a = '01'
- par_b = 'Item deleted' ) ) ).
- ENDIF.
- ENDMETHOD.
-ENDCLASS.
-```
-
-
-
-### Additions to EML Statements in ABAP Behavior Pools
-
-- There are a [special additions when using EML in behavior
- pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeneml_in_abp.htm).
- One of them is [`IN LOCAL MODE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapin_local_mode.htm).
-- This addition can be used to exclude feature controls and
- authorization checks.
-- Consider the following use case: There is a field to display the
- booking status of a trip on a UI. In the BDEF, this field is
- specified as read-only. Hence, it cannot be modified by a user on
- the UI. However, there is a button on the UI to book the trip. This
- button might trigger an action to book the trip so that the value of
- the field changes from open to booked. To enable this, the
- underlying handler method for the modify operation with the action
- to be executed has the addition `IN LOCAL MODE` that ignores
- the feature control.
-
-Syntax:
-
-``` abap
-MODIFY ENTITIES OF root_ent IN LOCAL MODE
- ENTITY root
- EXECUTE book
- FROM action_tab
- ...
-```
-
-
-
-## RAP Excursions
-
-### Using Keys and Identifying RAP BO Instances in a Nutshell
-
-
- Expand to view the details
-
-
-
-The following bullet points outline important aspects regarding
- keys and identifying [RAP BO
-instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_instance_glosry.htm "Glossary Entry") in ABAP EML statements.
-
-**Why is it important?**
-
-- The [primary
- key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_key_glosry.htm "Glossary Entry")
- of a [RAP BO entity instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_entity_inst_glosry.htm "Glossary Entry")
- is composed of one or more [key fields](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenkey_field_glosry.htm "Glossary Entry").
-- These key fields stand for the fields that are specified with
- `key` in the underlying [CDS view entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_v2_view_glosry.htm "Glossary Entry")
- of the RAP BO.
-- The primary key uniquely identifies each RAP BO entity instance.
-- After the creation of an instance including the primary key during a [RAP create operation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_create_operation_glosry.htm "Glossary Entry"),
- the primary key can no longer be changed.
- - Note that there are different numbering concepts, such as [early](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_early_numbering_glosry.htm) and [late numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlate_numbering_glosry.htm "Glossary Entry"). In the latter concept, newly created entity instances are given their final key only shortly before saving in the database. Until then, the business logic uses a temporary key that has to be replaced.
-- If a data set with a particular primary key already exists in the
- persistent database table, the saving of a RAP BO instance is rejected because of a duplicate primary key.
-
-**How can a RAP BO instance be uniquely identified?**
-
-- It can be done by using a [RAP instance identifier](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_inst_identifier_glosry.htm "Glossary Entry")
- or [RAP content identifier](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_cont_identifier_glosry.htm "Glossary Entry")
- or both of them.
-- RAP instance identifier:
- - It consists of the primary key fields and all relevant [BDEF derived type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry")
- components.
- - To ease the reference to all of these components, special
- [component groups](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_group_glosry.htm "Glossary Entry")
- are available to summarize the components and make them
- addressable via one single name.
- - [`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm):
- Contains the primary key fields of a RAP BO instance
- - [`%tky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tky.htm):
- Specifies the transactional key. Comprises `%key` (and,
- thus, the primary key fields of a RAP BO instance) and more
- components that are relevant to uniquely identify a RAP BO
- instance. Among them,
- [`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
- (relevant for late numbering scenarios) and the draft indicator
- [`%is_draft`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_is_draft.htm)
- (relevant for
- [draft](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_with_draft.htm)
- scenarios). In non-late numbering or non-draft scenarios, these
- extra components are just blank. However, it is recommended that
- you use `%tky` in all scenarios since it simplifies a
- possible later switch, for example, to a draft scenario. In
- doing so, lots of adaptations to the code regarding the keys and
- the inclusion of `%is_draft` can be avoided.
-- RAP content identifier:
- - Reflected in the component
- [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)
- which is a string of type
- `ABP_BEHV_CID` to define a content ID.
- - Used as a unique and preliminary identifier for RAP BO instances
- in RAP create operations, especially where no primary key exists
- for the particular instance.
- - For newly created instances, the ID can then be used for performing further modifications, referencing to those instances using [`%cid_ref`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid_ref.htm) (which has the same value as %cid), for example, in RAP operations using [`CREATE BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm), [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm)
- and
- [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
- as well as
- [actions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_action.htm)
- with
- [`EXECUTE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm)).
- - In contrast to the primary key and the preliminary ID
- `%pid` for late numbering scenarios, `%cid` (and
- `%cid_ref`) are only available on a short-term basis
- for the current ABAP EML request within the [RAP interaction phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm "Glossary Entry") in one RAP transaction.
- - **Note:** Specify `%cid` even if there are no further operations referring to it.
-- Special case: Late numbering
- - As mentioned above, in late numbering scenarios newly created
- entity instances are given their final key only shortly before
- saving in the database, i. e. you deal with preliminary keys in
- the RAP interaction phase and the early phase of the [RAP save sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry").
- - In this case, you can use `%key` to hold the preliminary
- keys or use a preliminary ID in the dedicated component
- [`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
- which is of type `ABP_BEHV_PID` and
- only available in late numbering scenarios.
- - Similar to above, to uniquely identify RAP BO instances in late
- numbering scenarios, you can use either `%key` or
- `%pid` or both of them. In any case, the use of
- `%tky` is handy because it includes both components. You
- must ensure that `%tky` in total uniquely identifies the
- instances.
- - **Note:** A further component group to refer to the keys is available: [`%pky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pky.htm). `%pky` contains `%pid` and `%key` in late numbering scenarios. In non-late numbering scenarios, it just contains `%key`. `%pky` itself is contained in `%tky`. There are contexts, for example, particular actions, where `%tky` is not available but `%pky` is. This way, there is still the option to summarize `%pid` and `%key` in one component group in the absence of `%tky`.
-
-**General rule**: A RAP BO instance must - where available - always be uniquely
-identifiable by its transactional key (`%tky`) for internal
-processing during the RAP interaction phase. `%tky` always
-contains all relevant components for the chosen scenario.
-
-> **💡 Note**
-> Assignment of Key Component Groups
->
-> As a general best practice, you should use a RAP BO instance key component group when referring to the entire key, rather than listing the individual key fields. It is recommended that you use `%tky` whenever possible.
-> In the following cases, type compatibility cannot be guaranteed in component group assignments:
-> - Mixing key component groups when they refer to the same RAP BO entity, e.g. `wa-%tky = wa-%key`. Such an assignment should also be avoided when both component groups have an identical scope in terms of components (e.g. `%tky` and `%key` in non-late-numbering and non-draft scenarios).
-> - Mixing the same key component groups when referring to two different RAP BO entities, for example, `wa_root-%tky = wa_child-%tky`. In this case, adding more components later may cause syntax errors for an assignment that worked previously.
-> - Defining structured types that have the same components as key component groups, and then assigning data objects of that type to those of the respective, original key component group.
-> In the above cases, the `CORRESPONDING` operator can be used to ensure type compatibility in assignments to key component groups:
-> ```abap
->... %tky = CORRESPONDING #( wa-%tky ) ...
->... %key = CORRESPONDING #( wa-%key ) ...
->... %pky = CORRESPONDING #( wa-%pky ) ...
->```
-> In cases where different data objects of key component groups of a BDEF derived type are to be assigned to the same key component group of the same entity, a direct assignment works without a syntax warning because the content is identical. A direct assignment is recommended (`...wa1_root-%tky = wa2_root-%tky ...`). The use of the `CORRESPONDING` operator is unnecessary and less performant. This is true, for example, for key component group assignments in the context of RAP response parameters failed and reported.
-
-
-
-### RAP Concepts
-
-
- Expand to view the details
-
-
-
-**RAP numbering**
-
-- A concept that deals with setting values for primary key fields.
-- There are multiple options to handle the numbering for primary key
- fields depending on when (early in the RAP interaction phase or late
- in the RAP save sequence) and by whom (RAP BO consumer, behavior
- pool, or framework) the primary key values are set.
-- When:
- - [Early numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_early_numbering_glosry.htm "Glossary Entry"):
- The final key values are assigned during a RAP create operation
- in the interaction phase.
- - [Late numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry"):
- The final key values are assigned during the RAP save sequence
- (and here only in the RAP saver method
- [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)).
-- By whom
- - [External numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_ext_numbering_glosry.htm "Glossary Entry"):
- Key values are provided by the RAP BO consumer. For example, in
- a create operation, the key values are specified by the RAP BO
- consumer like other non-key field values. Basically, this is the
- concept with which the snippets above are tailored.
- - [Internal numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_numbering_glosry.htm "Glossary Entry"):
- Key values are provided by the RAP BO provider. For example, in
- a create operation, the key values are not specified in an EML
- create request by the RAP BO consumer but rather by the RAP BO
- provider. In case of a managed RAP BO, the key is automatically
- created by the framework which only works if the key is of a
- certain type (16-character byte-like
- [UUID](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuuid_glosry.htm "Glossary Entry")).
- In case of an unmanaged RAP BO, the key values are provided in a
- dedicated handler method which must be self-implemented. Note
- that late numbering is internal by default since no further RAP
- BO consumer interaction is possible in the late phase of the RAP
- save sequence.
-
-**Draft**
-
-- The draft concept in RAP allows the content of the transactional
- buffer to be stored in intermediate storages ([draft tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendraft_table_glosry.htm "Glossary Entry"))
- in order to allow transactions to expand over different ABAP
- sessions.
-- Like the concepts mentioned above, a RAP BO can be draft-enabled in
- the BDEF. If enabled, the application allows data modifications and the temporary storage of modifications but does not yet persist them to the database. The users of the application can continue modifying this data later and they might even use a different device from the one where they modified the data previously.
-- The draft indicator `%is_draft` is available for RAP BO instance identification. It is used to indicate if a RAP BO
- instance is a [draft instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_draft_instance_glosry.htm "Glossary Entry")
- or an [active instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_active_instance_glosry.htm "Glossary Entry").
- Conveniently, the component group `%tky` contains
- `%is_draft`. `%is_draft` can then be addressed via
- `%tky`.
-
-> **💡 Note**
-> Late numbering and identification in the late phase of the RAP save sequence
->- Context: RAP saver method
-> [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)
-> in which the final key values are assigned; the preliminary keys can
-> be included in `%key` or `%pid` or both of them.
->- `%pid` and the preliminary key values in `%key` are
-> automatically assigned to the following component groups when
-> reaching the `adjust_numbers` method:
-> - [`%tmp`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tmp.htm):
-> A component group that is assigned the preliminary key values
-> contained in `%key`. In doing so, `%tmp` takes
-> over the role that `%key` has had in the RAP interaction
-> phase to hold the preliminary key values.
-> - `%pid` remains as is. The component group
-> [`%pre`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pre.htm)
-> contains `%pid` and `%tmp` and, thus, all
-> preliminary identifiers.
->- In the `adjust_numbers` method, the preliminary keys are
-> transformed into the final keys, i. e. the preliminary keys are
-> mapped to `%key` (which holds the final keys in this
-> context) in the `mapped` [response parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_response_param_glosry.htm "Glossary Entry").
->- Depending on your use case to use either `%pid` or (the
-> preliminary key values in) `%key` (which is `%tmp`
-> here in this method) during the interaction phase or both of them,
-> you must ensure that `%pre` in total (since it contains both
-> `%pid` and `%tmp`) is unique and mapped to the final
-> keys that are to be contained in `%key`.
-
-
-
-### Ensuring Data Consistency in a RAP Transaction
-
-
- Expand to view the details
-
-
-
-The [LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenluw_glosry.htm) concept, which deals with the transfer of data from one consistent state to another, applies to applications using RAP. RAP transactions are integrated with the [SAP LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensap_luw_glosry.htm), which is a prerequisite for transactional consistency. RAP provides a standardized approach and rules ([RAP BO contract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_contract_glosry.htm)) for the [RAP business object (BO)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_glosry.htm) runtime to ensure that the RAP transaction is correctly implemented, data inconsistencies are avoided, and the SAP LUW is successfully completed.
-
-**Phases of a RAP Transaction**
-
-A RAP transaction is divided into two phases during the runtime of a RAP BO, while the second phase can be divided into two subphases that serve different purposes.
-
-
-
-[RAP interaction phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm):
-- [RAP handler methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_method_glosry.htm) are called in a [RAP handler class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm) that inherits from `CL_ABAP_BEHAVIOR_HANDLER`.
-- New data, i.e. RAP BO instances, are created in the [RAP transactional buffer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentransactional_buffer_glosry.htm), or persisted data is retrieved and inserted into the transactional buffer for further processing.
-- The state of the data may become inconsistent in the transactional buffer during this phase. However, the data remains consistent in the database because changes are made only in the transactional buffer.
-
-[RAP save sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm):
-- The RAP save sequence is triggered by a `COMMIT ENTITIES` statement. In natively supported RAP scenarios, such as an SAP Fiori application using OData, the `COMMIT ENTITIES` call is implicitly and automatically performed by the RAP runtime engine.
-- RAP saver methods are called in the RAP saver class, which inherits from the base class `CL_ABAP_BEHAVIOR_SAVER`.
-- Is divided into the [RAP early save phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenearly_rap_save_phase_glosry.htm) (ensures that the RAP BO instances in the transactional buffer - all RAP BOs in the current RAP transaction are involved - are in a consistent state so that they can be saved to the database) and the [RAP late save phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlate_rap_save_phase_glosry.htm) (to finally save data from the transactional buffer to the database).
-
-(Optional:) Saver methods called in the RAP early save phase:
-1. [`finalize`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_finalize.htm): For final calculations and data changes before saving. In managed scenarios, determinations specified with `ON SAVE` are called when reaching this method.
-
-2. [`check_before_save`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_check_before_save.htm): For data consistency checks in the transactional buffer. In managed scenarios, validations specified with `ON SAVE` are called when this method is reached.
-
-3. [`cleanup_finalize`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsaver_class_cleanup_finalize.htm): If there are failures in at least one of the previous saver methods, further processing with the RAP late save phase is rejected and the transaction returns to the interaction phase. Before that, this saver method is called, allowing changes made in the finalize method to be rolled back.
-
-If there are errors in the early save phase, `sy-subrc` returns the value 4 after `COMMIT ENTITIES` statements. If the data in the transactional buffer is consistent after the early save phase, the late save phase is processed, which also means that a point of no return has been reached. Unlike the early save phase, you cannot return to the interaction phase when you reach the late save phase. Either the RAP transaction ends with a successful commit, or the changes are rolled back and a runtime error occurs.
-
-Saver methods called in the RAP late save phase:
-1. [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm): Provides RAP BO instances with their final numbers. This method is available only in late numbering scenarios.
-2. [`save`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_save.htm) (or [`save_modified`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaprap_saver_meth_save_modified.htm) in managed scenarios with an unmanaged or additional save): Used to save data from the transactional buffer to the database. If there are no issues, the final database commit is triggered and an implicit `COMMIT WORK` is executed.
-
-[`cleanup`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_cleanup.htm) method: After a successful save, the [`cleanup`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_cleanup.htm) method clears the transactional buffer. It completes the save sequence.
-
-**Commit and Rollback in a RAP Transaction**
-The default ABAP statements for RAP are `COMMIT ENTITIES` (triggers the RAP save sequence and the final database commit; as mentioned above, in natively supported RAP scenarios, the commit is performed implicitly and automatically by the RAP runtime engine) and `ROLLBACK ENTITIES` (rolls back all changes of the current RAP transaction, i.e. the transactional buffer is cleared by calling the `cleanup` method). Both are RAP-specific and end the RAP transaction.
-
-*Notes on `COMMIT ...` and `ROLLBACK ...` statements due to the integration of RAP transactions into the SAP LUW:*
-
-- `COMMIT ENTITIES` implicitly triggers `COMMIT WORK`.
-- Using `COMMIT WORK` in RAP (instead of `COMMIT ENTITIES`) also triggers the RAP save sequence. If there are no errors in the RAP save sequence, the final database commit is successful. Only in this best-case scenario does `COMMIT WORK` have the same effect as `COMMIT ENTITIES`. However, if there are errors in the save sequence, a runtime error occurs in any case, while a return to the interaction phase is still possible when using `COMMIT ENTITIES`.
-- `COMMIT ENTITIES` provides RAP-specific functionality with various additions that are not possible with `COMMIT WORK`, such as RAP responses can be retrieved, key conversion in late numbering scenarios, checking a RAP transaction in a simulation mode.
-- There are short, long, and dynamic forms of `COMMIT ENTITIES` statements.
-- `COMMIT ENTITIES` statements implicitly enforce local updates with `COMMIT WORK`, or `COMMIT WORK AND WAIT` if the local update fails. Therefore, the update is either a local update or a synchronous update, but never an asynchronous update. When `COMMIT WORK` is used, the RAP BO consumer can choose between synchronous and asynchronous update for RAP BO entities.
-- `ROLLBACK ENTITIES` implicitly triggers `ROLLBACK WORK`. Both have the same effect when used in RAP. Therefore, they are interchangeable.
-
-> **💡 Note**
-> Special Case: Failures in the Late Save Phase
-> - In exceptional cases, for example, when [BAPIs](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenbapi_glosry.htm) are called to save RAP BO instances in the late save phase, it may happen that the basic rule that failures must not occur in the RAP late save phase and be detected in the RAP early save phase is violated.
-> - In such cases, the base class `CL_ABAP_BEHAVIOR_SAVER_FAILED` can be used for the RAP saver class.
-> - RAP BO consumers can be informed by filling the RAP response parameters (some of which are not available when using `CL_ABAP_BEHAVIOR_SAVER` as the base class) in the saver method implementation so that they can react accordingly.
-> - After a `COMMIT ENTITIES` statement and a failure in the late save phase, `sy-subrc` is set to 8.
-> - A subsequent RAP operation may result in a runtime error. If the RAP BO consumer is to continue after an error in the late phase of the RAP save sequence, an explicit `ROLLBACK ENTITIES` is required.
-
-**Allowed/Forbidden Operations in a Behavior Implementation in a RAP Transaction**
-
-The following restrictions apply to operations and/or statements in the individual phases of a RAP transaction in ABAP behavior implementations. Note that, depending on setting the strict mode in the BDEF, runtime errors may occur due to the use of forbidden statements, or static code checks may be applied. Note that most operations/statements refer to the use in the unrestricted ABAP language scope.
-
-|Operations/Statements|Interaction phase|Early save phase|Late save phase|Notes|
-|---|---|---|---|---|
-|[Database commits](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_commit_glosry.htm) using [secondary connections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_db_connection_glosry.htm)
(unrestricted ABAP language scope)| X| X| X |Secondary connections are allowed for infrastructure purposes, for example. They can be used to store data that is not part of the main transaction, such as application logs, traces, or number ranges. |
-|Database commits using the [standard connection](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_db_connection_glosry.htm)
(unrestricted ABAP language scope)| X| X| -| Database commits can be made in phases other than the late phase, for example, by calling external services or using a `WAIT` statement.|
-|[sRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensrfc_glosry.htm) (`CALL FUNCTION ... DESTINATION`), [aRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenarfc_glosry.htm) (`CALL FUNCTION ... STARTING NEW TASK`)
(unrestricted ABAP language scope)| X |X |-| Allowed in phases other than the late save phase, e.g. for the purpose of parallelization within the application. It is up to the application to ensure consistency, e.g. to ensure read-only access, to handle a potential two-phase commit, or to provide a proper error handling. |
-|Database modifications |- |-| X| Only allowed in the late save phase because the data being processed is always potentially inconsistent. Database changes in other phases would result in multiple database transactions instead of one transaction, which would disrupt the SAP LUW. |
-|[Update function module](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenupdate_function_module_glosry.htm) (`CALL FUNCTION ... IN UPDATE TASK`)
(unrestricted ABAP language scope)|-| -| X |Can be used to ensure that there is only one database transaction. In addition, registering function modules for update tasks at stages other than the late save phase would interfere with RAP draft scenarios, for example, where data is stored in draft tables. There is no way to unregister function modules once they have been registered. |
-|[bgRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenbgrfc_glosry.htm) (`CALL FUNCTION ... IN BACKGROUND UNIT`)
(unrestricted ABAP language scope)| -| -| X| |
-|[tRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentrfc_2_glosry.htm), [qRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenqrfc_glosry.htm) (`CALL FUNCTION ... IN BACKGROUND TASK`)
(unrestricted ABAP language scope)| -| -| - |Obsolete technologies. |
-|`PERFORM ON COMMIT`, `PERFORM ON ROLLBACK`
(unrestricted ABAP language scope)|(X) |(X) |X |Basically possible in all phases, but should be reserved for the late save. Note: The use of these statements indicates improper integration with RAP. It is especially important to check draft scenarios when calling legacy code and using these statements. Instead, ABAP EML or procedure calls that do not include a `COMMIT WORK` should be used. |
-|Transaction control `COMMIT WORK`, `ROLLBACK WORK` |X/-| X/-| X/- |When a transactional phase has been explicitly set by methods of the `CL_ABAP_TX` class (find more information [here](https://help.sap.com/docs/abap-cloud/abap-concepts/controlled-sap-luw)), the transaction owner is allowed to execute a commit or rollback statement. In the contexts of RAP (that is, where RAP is the transaction owner, for example, in handler and saver methods), local consumption of [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm), [bgPF](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbgpf_glosry.htm), and [classified APIs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassified_api_glosry.htm), commit or rollback statements are not allowed. |
-|[Dynpro](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_glosry.htm) processing (e.g. `SET SCREEN`, `CALL SCREEN`, `LEAVE SCREEN`, `CALL DIALOG`, `SUPPRESS DIALOG`, `MESSAGE` without `INTO`, `WRITE`, `STOP`)
(unrestricted ABAP language scope)|- |- |- |Not allowed in ABAP behavior implementations. Results in a runtime error. |
-|Transaction processing (`CALL TRANSACTION`, `LEAVE TRANSACTION`)
(unrestricted ABAP language scope)| -| -| - |Not allowed to prevent (unwanted) integration of other LUWs. |
-|Raising an exception (`RAISE EXCEPTION`) |-| -| - |It is not allowed to leave a RAP transaction this way. |
-|Report processing (`SUBMIT ...`)
(unrestricted ABAP language scope)|- |- |- |Not allowed in transactional contexts. Results in a syntax or runtime error. `SUBMIT ... AND RETURN` does not currently return an error, but it leads to potentially unwanted screen processing, and because of the missing return channel, there is no proper error handling. |
-
-
-
-
-
-
-## More Information
-
-- Section [ABAP for RAP Business
- Objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_for_rap_bos.htm)
- in the ABAP Keyword Documentation including EML
-- [RAP Glossary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_glossary.htm)
-- [Development guide for the ABAP RESTful Application Programming
- Model](https://help.sap.com/docs/ABAP_PLATFORM_NEW/fc4c71aa50014fd1b43721701471913d/289477a81eec4d4e84c0302fb6835035.html)
-- [RAP
- Contract](https://help.sap.com/docs/ABAP_PLATFORM_NEW/fc4c71aa50014fd1b43721701471913d/3a402c5cf6a74bc1a1de080b2a7c6978.html):
- Rules for the RAP BO provider and consumer implementation to ensure
- consistency and reliability
-
-
-
-## Executable Examples
-
-This cheat sheet is supported by different executable examples demonstrating various scenarios:
-- Demo RAP scenario with a managed RAP BO, external numbering: [zcl_demo_abap_rap_ext_num_m](./src/zcl_demo_abap_rap_ext_num_m.clas.abap)
-- Demo RAP scenario with an unmanaged RAP BO, external numbering: [zcl_demo_abap_rap_ext_num_u](./src/zcl_demo_abap_rap_ext_num_u.clas.abap)
-- Demo RAP scenario ("RAP calculator") with a managed, draft-enabled RAP BO, late numbering [zcl_demo_abap_rap_draft_ln_m](./src/zcl_demo_abap_rap_draft_ln_m.clas.abap)
-- Demonstrating the local consumption of [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm) in the context of a RAP demo scenario (managed RAP BO with managed [internal numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_numbering_glosry.htm) and [additional save](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_add_save_glosry.htm)): [zcl_demo_abap_rap_m_as](./src/zcl_demo_abap_rap_m_as.clas.abap)
-
-> **💡 Note**
-> - To reduce the complexity, the executable examples only focus on the technical side. ABAP classes play the role of a RAP BO consumer here.
-> - The examples do not represent real life scenarios and are not suitable as role models for proper RAP scenarios. They rather focus on the technical side by giving an idea how the communication and data exchange between a RAP BO consumer and RAP BO provider can work. Additionally, the examples show how the methods for non-standard RAP BO operations might be self-implemented in an ABAP behavior pool.
-> - Due to the simplification, the examples do not entirely meet all requirements of the [RAP BO contract](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenrap_bo_contract_glosry.htm) and do not represent semantic or best practice examples.
-> - You can check out the "RAP calculator" example using the preview version of an SAP Fiori Elements UI. See the comments in the class for more information.
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
-> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
+
+
+# ABAP for RAP: Entity Manipulation Language (ABAP EML)
+
+- [ABAP for RAP: Entity Manipulation Language (ABAP EML)](#abap-for-rap-entity-manipulation-language-abap-eml)
+ - [RAP Terms](#rap-terms)
+ - [Excursion: RAP Behavior Definition (BDEF)](#excursion-rap-behavior-definition-bdef)
+ - [ABAP Behavior Pools (ABP)](#abap-behavior-pools-abp)
+ - [RAP Handler Classes and Methods](#rap-handler-classes-and-methods)
+ - [RAP Saver Class and Saver Methods](#rap-saver-class-and-saver-methods)
+ - [BDEF Derived Types](#bdef-derived-types)
+ - [Components of BDEF Derived Types](#components-of-bdef-derived-types)
+ - [EML Syntax](#eml-syntax)
+ - [EML Syntax for Modifying Operations](#eml-syntax-for-modifying-operations)
+ - [EML Syntax for Reading Operations](#eml-syntax-for-reading-operations)
+ - [Dynamic Forms of EML Statements](#dynamic-forms-of-eml-statements)
+ - [Persisting to the Database](#persisting-to-the-database)
+ - [Raising RAP Business Events](#raising-rap-business-events)
+ - [Additions to EML Statements in ABAP Behavior Pools](#additions-to-eml-statements-in-abap-behavior-pools)
+ - [RAP Excursions](#rap-excursions)
+ - [Using Keys and Identifying RAP BO Instances in a Nutshell](#using-keys-and-identifying-rap-bo-instances-in-a-nutshell)
+ - [RAP Concepts](#rap-concepts)
+ - [Ensuring Data Consistency in a RAP Transaction](#ensuring-data-consistency-in-a-rap-transaction)
+ - [More Information](#more-information)
+ - [Executable Examples](#executable-examples)
+
+## RAP Terms
+
+[ABAP Entity Manipulation Language](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenaeml_glosry.htm) (or EML for short) is a subset of ABAP that allows you to access the data of [RAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenarap_glosry.htm) business objects in an ABAP program.
+The following points cover RAP-related terms such as *RAP business objects* and others for setting the context:
+
+- RAP business objects (RAP BO)
+ - A RAP BO is based on a special, tree-like hierarchical structure
+ of [CDS
+ entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_glosry.htm "Glossary Entry")
+ of a data model
+ - Such a structure of entities consists of [parent
+ entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenparent_entity_glosry.htm "Glossary Entry")
+ and [child
+ entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenchild_entity_glosry.htm "Glossary Entry")
+ that are themselves defined using [CDS
+ compositions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_composition_glosry.htm "Glossary Entry")
+ and [to-parent
+ associations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abento_parent_association_glosry.htm "Glossary Entry").
+ - The top parent entity of a [CDS composition
+ tree](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_composition_tree_glosry.htm "Glossary Entry")
+ is the root entity that represents the business object. With a
+ large composition tree, RAP BOs can be fairly complex. Or they
+ can be very simple by just consisting of one root entity alone.
+ - Note: There is a special syntax for the [CDS root entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenroot_entity_glosry.htm) of a RAP BO: [`define root view entity`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_define_root_view_v2.htm)
+- [RAP behavior
+ definition](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_behavior_definition_glosry.htm "Glossary Entry")
+ (BDEF)
+ - RAP BOs are described by the definitions specified in a special
+ [DDIC](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_glosry.htm "Glossary Entry")
+ artifact: RAP behavior definition (BDEF)
+ - A BDEF defines the [RAP business object
+ behavior](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_behavior_glosry.htm "Glossary Entry")
+ (i. e. the transactional behavior of a RAP BO)
+ - Transactional behavior means a BDEF defines [behavior
+ characteristics](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_properties_glosry.htm "Glossary Entry")
+ and [RAP BO
+ operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_operation_glosry.htm "Glossary Entry") i.
+ e. [RAP BO standard
+ operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_standard_operation_glosry.htm "Glossary Entry")
+ ([CRUD
+ operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencrud_glosry.htm "Glossary Entry")),
+ [non-standard
+ operations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_nstandard_operation_glosry.htm "Glossary Entry")
+ like specific [RAP
+ actions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_action_glosry.htm "Glossary Entry")
+ and
+ [functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_function_glosry.htm "Glossary Entry"),
+ and more.
+ - There are many other things that can be included impacting the
+ RAP BO behavior like [RAP feature
+ control](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_feature_control_glosry.htm "Glossary Entry"),
+ for example, defining which data is mandatory and which is
+ read-only, or
+ [determinations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_determination_glosry.htm "Glossary Entry")
+ and
+ [validations](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_validation_glosry.htm "Glossary Entry").
+ - BDEFs use [Behavior Definition
+ Language](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_glosry.htm "Glossary Entry")
+ (BDL) for the definitions. Find more information on the topic
+ and various options to define the transactional behavior in
+ section [BDL for Behavior
+ Definitions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl.htm)
+ in the ABAP Keyword Documentation.
+- Transactional buffer and implementation types
+ - A BDEF defines the behavior of a RAP BO and, thus, how to handle
+ its data. This data is available in the [RAP transactional
+ buffer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentransactional_buffer_glosry.htm "Glossary Entry").
+ - It is a storage for a RAP BO's data that is used and worked on
+ during an [SAP LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensap_luw_glosry.htm).
+ - This data includes [RAP BO
+ instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_instance_glosry.htm "Glossary Entry")
+ (i. e. concrete data sets of an entity). This is where EML
+ enters the picture: EML is used, among others, to access this data in the transactional buffer.
+ - Currently, there are two kinds of RAP BOs:
+ [managed](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmanaged_rap_bo_glosry.htm "Glossary Entry")
+ and [unmanaged RAP
+ BOs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunmanaged_rap_bo_glosry.htm "Glossary Entry").
+ - Managed and unmanaged are implementation types that are also
+ specified in the BDEF.
+ - The implementation type determines the [RAP BO
+ provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_provider_glosry.htm "Glossary Entry"), i.
+ e. how the transactional buffer is provided and how the behavior
+ of a RAP BO is implemented.
+- Managed RAP BOs:
+ - The managed RAP BO provider fully or partly provides the
+ transactional buffer and RAP BO behavior (for standard
+ operations only). In this case, the developers need not cater
+ for the transactional buffer and implement the standard
+ operations. This implementation is mostly relevant for
+ greenfield scenarios when starting from scratch.
+ - Example: Regarding CRUD operations in managed RAP BOs,
+ developers need not cater for an implementation at all. The
+ standard operations work out of the box. For example, in case of
+ an update operation, RAP BO instance data that is to be updated
+ is automatically read into the transactional buffer, and then
+ updated accordingly there. Finally, when triggering the saving,
+ the updated instance in the transactional buffer is
+ automatically saved to the database without any custom
+ development needed.
+ - The transactional buffer is provided, too. You do not need to
+ create the buffer yourself.
+ - Note: Usually, the behavior of a RAP BO requires some
+ additional implementations also in the context of managed RAP
+ BOs. For example, non-standard operations or feature controls
+ must be self-implemented in [ABAP behavior
+ pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm "Glossary Entry")
+ (see the details further down).
+- Unmanaged RAP BOs:
+ - Everything must be provided by the [unmanaged RAP BO
+ provider](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenunmanaged_rap_bo_prov_glosry.htm "Glossary Entry"), i.
+ e. the transactional buffer and all RAP BO operations must be
+ provided or self-implemented by developers in an ABAP behavior
+ implementation
+ - Unmanaged RAP BOs are, for example, relevant for brownfield
+ scenarios, i. e. in scenarios in which transactional buffers and application logic is already
+ available and should be embedded in the RAP world. Note that it is possible to have a managed RAP BO with unamanged parts, e.g. unamanged save or additional save. Find more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_rap_bo.htm).
+- ABAP behavior implementation in an ABAP behavior pool (ABP)
+ - An [ABAP behavior
+ pool](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbehavior_pool_glosry.htm "Glossary Entry")
+ is a special [class
+ pool](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_pool_glosry.htm "Glossary Entry")
+ for an ABAP behavior implementation that implements the
+ unmanaged RAP BO provider based on definitions in a BDEF. The
+ class pool's name is specified in the BDEF.
+ - The [global
+ class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenglobal_class_glosry.htm "Glossary Entry")
+ of a behavior pool does not implement the behavior itself. It is
+ (initially) empty apart from the declaration and implementation part skeletons. The behavior implementation is coded in local
+ [RAP handler
+ classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm "Glossary Entry")
+ and a [RAP saver
+ class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class_glosry.htm "Glossary Entry")
+ in the [CCIMP
+ include](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenccimp_glosry.htm "Glossary Entry")
+ of the behavior pool. These classes are called by the [RAP
+ runtime
+ engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_runtime_engine_glosry.htm "Glossary Entry")
+ when the RAP BO is accessed. This is covered in more detail
+ further down.
+ - Usually, saver classes are not needed in managed RAP BOs (except
+ for special variants of managed RAP BOs which are not covered
+ here). Local handler classes are, as mentioned above, usually
+ needed in managed RAP BOs if implementations are required that
+ go beyond standard operations.
+ - Note: In more complex scenarios, with RAP BOs that
+ consist of many entities, you can define behavior pools for
+ individual entities by adding the syntax to the [`define
+ behavior
+ for`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_define_beh.htm)
+ notation. There is not a saver class for each entity but only
+ one saver class for the BO as a whole. Any number of behavior
+ pools can be assigned to a BDEF allowing applications a
+ structuring into multiple units.
+
+
+Find more terms in the [RAP Glossary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_glossary.htm) of the ABAP Keyword Documentation.
+There are more artifacts and concepts related to RAP that go way beyond
+the scope of this cheat sheet. For example, a RAP BO can be exposed as a
+[business
+service](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbusiness_service_glosry.htm "Glossary Entry")
+to be accessed from outside [AS
+ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenas_abap_sys_environ_glosry.htm "Glossary Entry")
+and consumed. A [RAP BO
+consumer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_consumer_glosry.htm "Glossary Entry")
+is either the [RAP transactional
+engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_transac_engine_glosry.htm "Glossary Entry")
+that handles requests from outside the AS ABAP or, from inside AS ABAP,
+an ABAP program using ABAP EML (which this cheat sheet and the examples
+focus on).
+
+
+
+## Excursion: RAP Behavior Definition (BDEF)
+
+- As mentioned in the RAP terms and as the name implies, a RAP behavior definition describes a RAP business object (RAP BO) by defining its behavior for all of its RAP BO entities.
+- BDL source code is used in a BDEF.
+- Once you have created ...
+ - the CDS root entity of a RAP BO, ADT helps you create the skeleton of a BDEF (e.g., right-click on the CDS root entity and choose *New Behavior Definition* from the pop-up).
+ - the BDEF, ADT helps you create the skeleton of an ABAP behavior pool, as well as RAP handler and saver method declarations and the skeleton of implementations via ADT quick fixes.
+- More information (see also the subtopics there):
+ - [Structure of a RAP behavior definition](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_bdef.htm)
+ - [Infos about BDL syntax](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_syntax.htm)
+ - [Infos about behavior definitions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl.htm)
+
+
+The following example shows a commented BDEF.
+Note that there is a wide variety of possible specifications and options. The example shows only a selection. For full details, refer to the ABAP Keyword Documentation.
+Some of the syntax examples are commented out, just for the sake of showing more syntax options.
+
+```js
+//Possible implementation types: managed, unmanaged, abstract, projection, interface
+//(which restrict/enable further specifications)
+//You can specifiy one or more implementation classes (behavior pools/ABPs -> bp...)
+//for the RAP BO (in some contexts, specifying no ABP is possible).
+//Specifying unique is mandatory (each operation can only be implemented once).
+managed implementation in class bp_some_demo unique;
+//For managed RAP BOs, you can enable user-defined saving options (optional additions
+//are available).
+//Purpose: Enhancing or replacing the default save sequence (Note: Only in this case,
+//the ABP has a local saver class/save_modified saver method)
+//managed with additional save with full data implementation in class bp_some_demo unique;
+//full data: Full instance data is passed for saving
+//managed with unmanaged save implementation in class bp_some_demo unique;
+
+//Enabling the strict mode (and version) to apply additional syntax checks; handled by
+//the RAP framework; it is recommended that you use the most recent version
+strict ( 2 );
+
+//Enabling RAP draft handling
+//with draft;
+
+//It is mandatory to specify an entity behavior definition for the RAP BO root entity.
+//Here, some_demo represents a CDS view entity.
+define behavior for some_demo
+//Specifying an alias name (e.g. to have a more telling name than the technical name of
+//the entity). When specifying an alias name, you should address the entity with the alias
+//name instead of the full name (e.g. in the signature of handler methods).
+//define behavior for some_demo alias root
+
+//Specifying the database table a RAP BO is based on (only available/mandatory in managed
+//BOs); note further requirements for diverse scenarios in the documentation
+persistent table some_dbtab
+
+//Mandatory specification of a draft table when a RAP BO is draft-enabled
+//draft table drafttab
+
+//Specifying the locking mechanism for entities, e.g. to prevent a simultaneous
+//modification. In unmanaged RAP BOs, this must be self-implemented in a dedicated handler
+//method
+lock master
+
+//Controlling authorization that is to be implemented in an ABP (also for managed)
+//You can specify variants: global (e.g. for restricting certain operations) and/or
+//instance (restrictions based on entity instances) or both of them (dedicated handler
+//methods must be implemented)
+//More variants are available that can be specified in the { ... } block below for
+//excluding and delegating authorization checks (e.g. authorization:update)
+authorization master ( instance )
+//authorization master ( global )
+//authorization master ( instance, global )
+
+//Defining late numbering for primary key fields (see the adjust_numbers handler method)
+//More numbering options are available such as early numbering, or, in the { ... } block below,
+//the 'numbering : managed' specification for particular fields.
+//late numbering
+
+//Defining a field as entity tag (ETag) field for optimistic concurrency control (i.e.
+//enabling transactional access to data by multiple users to avoid inconsistencies when
+//unintentionally changing already modified data). More options available, e.g. for
+//draft-enabled RAP BOs (total etag).
+//etag master some_field
+
+{
+ //RAP BO operations
+ //Standard operations (Note: Read is implicitly enabled, no specification available)
+ create;
+ update;
+ //More additions are available dealing with authorization, feature control, precheck etc.
+ //The example shows precheck. In doing so, you can implement a precheck (e.g. to prevent
+ //unwanted changes) before instances are deleted in a dedicated handler method. A precheck
+ //implementation is also available for other operations (e.g. actions).
+ //As is true for various specifications, a comma-separated list of specifications is possible.
+ delete( precheck );
+
+ //Note: It is not possible to specify operations multiple times. The following specifications
+ //just demonstrate syntax options. Anyway, the compiler helps you not to specify wrong notations.
+ //Applying feature control
+ //delete( features: global );
+
+ //Applying authorization control
+ //delete( authorization : update );
+
+ //Operations for associations (many specification options are possible)
+ //The following example means enabling create-by-association operations for associations
+ //Assumption: _child is specified in the the underlying CDS data model.
+ association _child { create; }
+
+ //Non-standard operations (check the specification options in the documentation, e.g. feature
+ //control and others are possible) such as actions (modify RAP BO instance) and functions (return
+ //information). There are different flavors of actions such as non-factory and factory actions,
+ //which themselves have different variations. Other flavors of actions are save actions (only to
+ //be executed during save sequence), determine actions (allow RAP BO consumers to execute
+ //determinations and validations on request), and draft actions.
+
+ //Non-factory actions (modify existing instances)
+ //Instance action, relates to instances, modify instances
+ action act1;
+
+ //Static action, not bound to instances, relates to the entrie entity
+ static action act2;
+
+ //Internal action, accessible only from within the ABP (internal can also be specified in other
+ //contexts, e.g. operations)
+ internal action act3;
+
+ //You can optionally specify input or output parameters or both (not always possible for all
+ //action types). The following example shows an output parameter, defined with the result
+ //addition. It stores the result of an action in an internal table. Variants are possible for
+ //the return type. Here, it is $self (result type is the same type as entity) It can, for
+ //example, also be an abstract BDEF or a different entity.
+ action act4 result [1] $self;
+
+ //Input parameter specified following 'parameter' (in this case, a CDS abstract entity)
+ action act5 parameter some_cds_abstract;
+
+ //Factory action (to create instances, can be instance-bound or static)
+ //Specifying the cardinality is mandatory
+ factory action act6 [1];
+
+ //Draft actions
+ //Available for draft-enabled RAP BOs, allow data modification on the draft table; are
+ //implicitly available; it is recommended for the draft actions to be specified explicitly;
+ //for some of the methods, the 'with additional implementation' addition is available
+
+ //Copies active instances to the draft table
+ //draft action Edit;
+
+ //Sets a lock for entity instances on the persistent database table
+ //draft action Resume;
+
+ //Copies draft table content to the persitent database table; recommendation: use the
+ //optimized addition
+ //draft action Activate optimized;
+
+ //Clears entries from the draft database table
+ //draft action Discard;
+
+ //Corresponds to the determine actions for active instances;
+ //used to validate draft data before transitioning to active data
+ //draft determine action Prepare
+ // {
+ //You can assign validations and determinations defined with 'on save'
+ // validation val;
+ // }
+
+ //Functions (similar to actions, there are optional additions, such as static)
+ //Since they return information, specifying an output parameter is required.
+ //Instance function
+ function func1 result [0..*] $self;
+
+ //Static function
+ static function func2 result [1] some_cds_abstract;
+
+ //Instance function with optional input parameter
+ function func3 parameter some_cds_abstract result [1] $self;
+
+ //Field characteristics
+ //Field values cannot be created/updated
+ field ( readonly ) field1;
+
+ //Read-only during update (especially key fields created during create operations)
+ field ( readonly : update ) key_field;
+
+ //The mandatory specification denotes that values must be provided for the fields before persisting
+ //them to the database.
+ //Comma-separated list possible for the field characteristics in general;
+ //mutliple characteristics can also be specified in a comma-separated list in the parentheses
+ field ( mandatory ) field2, field3;
+
+ //Defining access restrictions for fields
+ field ( features : instance ) field4;
+
+ //Validations
+ //Checking the consitency of instances; validations are triggered based on conditions
+ //Conditions (one or more are possible) can be specified for create, update, delete operations
+ //and modified fields; note: not available for unmanaged, non-draft RAP BOs.
+ validation val on save { create; field field1; }
+
+ //Determinations
+ //Modifying instances based on trigger conditions;
+ //As above, conditions (one or more are possible) can be specified for create, update, delete
+ //operations and modified fields. The triggering is possible for 'on modify' and 'on save'.
+ determination det1 on modify { update; delete; field field5, field6; }
+ determination det2 on save { create; field field7, field8; }
+
+ //RAP business event (derived events with the specification 'managed evt ...' are also possible)
+ event evt;
+
+ //RAP side effects, to trigger a reload of affected properties on the UI
+ //Trigger properties: Field changes, action executions
+ //Multiple side effects can be specified within a { ... } block, separated by a colon
+ //There are multiple options to specify the target following 'affect'; the example uses fields
+ //to be reloaded
+ side effects { field field1 affects field field4;
+ field field2 affects field field4;
+ field field3 affects field field4;
+ action act1 affects field field4; }
+
+}
+
+
+//It is optional to specify an entity behavior definition for child entities
+define behavior for some_child_entity alias child
+
+//Applying locks dependent on the specified association (locks are delegated to
+//the specified association). In this case, it's the parent entity. Assumption:
+//_parent is specified in the the underlying CDS data model.
+lock dependent by _parent
+
+//Applying authorization checks dependent on the specified association
+//As above, the assumption is that _parent is specified in the underlying CDS
+//data model.
+authorization dependent by _parent
+
+{
+ update;
+ delete;
+ field ( readonly ) key_field;
+ field ( readonly : update ) key_field_child;
+ association _parent;
+}
+```
+
+
+
+## ABAP Behavior Pools (ABP)
+
+As mentioned above, you can access RAP BO data from inside AS ABAP using
+EML. Among other things, EML allows you to read or modify RAP BOs by
+accessing the RAP BO data (the RAP BO instances) in the transactional
+buffer and trigger the persistent storage or reset changes. More
+precisely, when EML statements are executed, the calling of [RAP handler
+methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_method_glosry.htm "Glossary Entry")
+is triggered to access the transactional buffer of a RAP BO. As
+mentioned, for unmanaged RAP BOs or unmanaged parts of managed RAP BOs,
+the handler methods that are called are part of an ABAP behavior pool.
+
+The global class of an ABP has the addition [`FOR BEHAVIOR OF bdef`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapclass_for_behavior_of.htm)
+to the definition while `bdef` stands for the name of the BDEF.
+This class is (initially) empty apart from the declaration and implementation part skeleton.
+
+```abap
+CLASS zbp_demo_abap_rap_draft_m DEFINITION PUBLIC ABSTRACT FINAL FOR BEHAVIOR OF zdemo_abap_rap_draft_m.
+ENDCLASS.
+
+CLASS zbp_demo_abap_rap_draft_m IMPLEMENTATION.
+ENDCLASS.
+```
+
+The actual implementation is done in local classes in the CCIMP include (*Local Types* tab in ADT) of the behavior pool. There,
+two kinds of local classes are to be defined and implemented that are
+related to the RAP BO's runtime: one or more [handler
+classes](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm "Glossary Entry")
+to implement the RAP BO behavior (in RAP handler methods) during the
+[RAP interaction
+phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm "Glossary Entry")
+(the data reading and modification phase) and a [saver
+class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class_glosry.htm "Glossary Entry")
+to implement the [RAP save
+sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry")
+(in [saver
+methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_method_glosry.htm "Glossary Entry")
+to save data from the transactional buffer to the database).
+
+
+
+### RAP Handler Classes and Methods
+
+- One or more handler classes implement the RAP interaction phase. For
+ modularization purposes, one behavior pool can define multiple
+ handler classes. For example, each entity can have its own handler
+ class, or individual handler classes can be defined to distinguish
+ between reading and changing RAP BO entities.
+- A handler class inherits from class
+ `CL_ABAP_BEHAVIOR_HANDLER`.
+- These classes are implicitly `ABSTRACT` and `FINAL`
+ since instantiating and calling only happens through the RAP runtime
+ engine.
+- [ADT](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenadt_glosry.htm "Glossary Entry")
+ helps you create the classes and methods (and basically the ABP as
+ such) when creating the BDEF. A quick fix is available that creates
+ the method definitions and a skeleton of the implementations
+ automatically.
+
+Example: Handler class definition
+``` abap
+CLASS lhc_root DEFINITION INHERITING FROM cl_abap_behavior_handler.
+...
+ENDCLASS.
+```
+- Handler method definitions include the additions `... FOR ... FOR
+ ...` followed by the kinds of operations. There are various
+ options depending on the RAP BO operation.
+- Depending on the definition in the BDEF, there might be more additions
+ with dedicated method parameters. For example, an action might
+ be defined with a result parameter, hence, the method must be
+ defined with the addition `RESULT` and a parameter.
+- The `FOR MODIFY` handler method can handle multiple entities
+ and operations, i. e. not only create but also update or delete
+ might be integrated in the method definition. However, it might be
+ useful to split the handler method into separate methods for better
+ readability.
+- See more details on the handler method definitions in the topic
+ [`METHODS, FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_for_rap_behv.htm).
+
+Example: Handler method definitions
+``` abap
+"Create
+METHODS create FOR MODIFY
+ IMPORTING entities FOR CREATE bdef.
+
+"Read: Specifying a read result is mandatory.
+METHODS read FOR READ
+ IMPORTING keys FOR READ bdef RESULT result.
+
+"Action: action name is preceded by the BDEF name and a tilde after FOR ACTION
+METHODS some_action FOR MODIFY
+ IMPORTING keys FOR ACTION bdef~some_action.
+```
+
+**Parameters of Handler Methods**
+
+- The handler method definitions contain RAP-specific additions like
+ `FOR MODIFY`, `FOR CREATE` or `FOR READ` as
+ well as mandatory or optional additions like `RESULT` that
+ are followed by parameters.
+- Nearly all parameters are typed with [BDEF derived
+ types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry")
+ that have special RAP-related components as covered further down.
+- The parameters' names can be chosen freely. This is also true for
+ the method names except for some predefined names.
+- Each handler method must have at least one importing parameter. The
+ addition `IMPORTING` is optional since it is used
+ implicitly. In most cases, entire instances or just key values
+ of instances are imported.
+- All handler methods have changing parameters that are usually not
+ explicitly specified in the definition but implicitly used. The
+ explicit specification of the `CHANGING` addition is not needed. In most cases, these are
+ [RAP response
+ parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_response_param_glosry.htm "Glossary Entry").
+ The following image shows the F2 information in ADT for the create
+ handler method.
+ 
+- The response parameters `mapped`, `failed` and
+ `reported` (the names are predefined) can be considered as
+ containers for information - information a RAP BO consumer is
+ provided with by a RAP BO provider, for example, an SAP Fiori app
+ displays an error message if something went wrong. The availability
+ of the parameters depends on the handler method used (e. g.
+ `mapped` is only available for operations creating
+ instances).
+ - `mapped`: Used to provide mapping information on RAP BO
+ instances, for example, which key values were created for given
+ content IDs (
+ [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)).
+ - `failed`: Information for identifying the data set for
+ which an error occurred in a RAP operation
+ - `reported`: Used, for example, to exchange error messages for each
+ entity defined in the BDEF and [not related to a specific
+ entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_other.htm).
+ - Example: Technically, the `reported` parameter is a
+ [deep
+ structure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_structure_glosry.htm "Glossary Entry")
+ containing, for example, the messages of the root entity and
+ child entities. For example, if a create operation fails for a
+ RAP BO instance of the root entity, a message, information about
+ the instance key and other things can be included in this
+ parameter which is passed to a RAP BO consumer. You could
+ imagine that such an error message is displayed on an SAP Fiori
+ UI if something goes wrong to inform the user.
+
+
+
+
+### RAP Saver Class and Saver Methods
+
+- A RAP saver class implements the [RAP save
+ sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry").
+ A saver class is usually only available in unmanaged RAP BOs (except
+ for special variants of managed RAP BOs that are not outlined here).
+- The saver class is implicitly `ABSTRACT` and `FINAL`
+ since the instantiating and calling only happens through the RAP
+ runtime engine.
+- A saver class can be defined in the CCIMP include of an ABAP
+ behavior pool. It includes the definitions and implementations of
+ RAP saver methods.
+- The saver methods consist of a set of predefined methods having
+ predefined names. Some of them are mandatory to implement, some are
+ optional. The
+ [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)
+ method is only available in [late
+ numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry")
+ scenarios.
+- A saver class inherits from class
+ `CL_ABAP_BEHAVIOR_SAVER`. The saver methods are
+ declared by redefining predefined methods of the superclass. They
+ implicitly have response parameters.
+- In contrast to RAP handler methods, saver methods do not have data
+ of RAP BO instances as import parameter. Therefore, instance data
+ must be handled via the transactional buffer when self-implementing
+ the saver methods.
+- Saver methods are called when the RAP save sequence has been triggered by a [`COMMIT
+ ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm)
+ statement. Note that in natively supported RAP scenarios, for example, an SAP Fiori app using OData, the `COMMIT ENTITIES` call is performed implicitly and automatically by the [RAP runtime engine](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_runtime_engine_glosry.htm).
+- Find more information on RAP saver methods
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_saver_class.htm).
+
+Example: Definition of a RAP saver class and saver methods
+``` abap
+CLASS lsc_bdef DEFINITION INHERITING FROM cl_abap_behavior_saver.
+ PROTECTED SECTION.
+
+ "For final calculations and data modifications involving all
+ "BOs in the current RAP transaction
+ METHODS finalize REDEFINITION.
+
+ "Checks the consistency of the transactional buffer before
+ "the save method saves data to the database
+ METHODS check_before_save REDEFINITION.
+
+ "Preliminary IDs are mapped to final keys. Only for late numbering.
+ METHODS adjust_numbers REDEFINITION.
+
+ "Saves the current state of the transactional buffer to the database
+ METHODS save REDEFINITION.
+
+ "Clear the transactional buffer
+ METHODS cleanup REDEFINITION.
+ METHODS cleanup_finalize REDEFINITION.
+
+ENDCLASS.
+```
+
+
+
+## BDEF Derived Types
+
+The operands of EML statements and parameters of handler and saver
+methods are mainly special messenger tables for passing data and
+receiving results or messages, i. e. the communication between a RAP BO
+consumer and the RAP BO provider using EML consists (in most cases) of
+exchanging data stored in internal tables that have special ABAP types -
+[BDEF derived
+types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry").
+These types are tailor-made for RAP purposes.
+
+As the name implies, the types are derived by the [ABAP runtime
+framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm "Glossary Entry")
+from CDS entities and their behavior definition in the BDEF. With these
+special types, a type-safe access to RAP BOs is guaranteed.
+
+You can create internal tables (using [`TYPE TABLE
+FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_table_for.htm)),
+structures (using [`TYPE STRUCTURE
+FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_structure_for.htm))
+and data types with BDEF derived types. For all operations and behavior
+characteristics defined in the BDEF, types can be derived.
+
+The syntax uses - similar to the method definitions mentioned before -
+the addition `FOR` followed by the operation and the name of an
+entity (and, if need be, the concrete name, e. g. in case of an action
+defined in the BDEF).
+
+Each BDEF derived type can be categorized as
+[input](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_input_der_type_glosry.htm "Glossary Entry")
+or [output derived
+type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_output_der_type_glosry.htm "Glossary Entry")
+according to its use as importing or exporting parameters in methods of
+RAP BO providers. In most cases, structures of type `TYPE STRUCTURE
+FOR` can be considered as serving as [work
+area](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwork_area_glosry.htm "Glossary Entry")
+and line type of the internal tables. However, there are also structured
+derived types that do serve as types for handler method parameters.
+
+The response parameters `mapped`, `failed` and
+`reported` have dedicated derived types: [`TYPE RESPONSE
+FOR`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptype_response_for.htm).
+They are deep structures containing the information for the individual
+entities of the RAP BO. The components of these structures are internal
+tables of appropriate types with `TYPE TABLE FOR`.
+
+Examples for BDEF derived types:
+
+``` abap
+"Data objects with input derived types (entity = name of a root entity)
+
+"For an EML create operation
+DATA create_tab TYPE TABLE FOR CREATE entity.
+
+"For an update operation
+DATA update_tab TYPE TABLE FOR UPDATE entity.
+
+"Type for create-by-association operations specifying the name of the entity
+"and the association
+DATA cba_tab TYPE TABLE FOR CREATE entity\_child.
+
+"For an action execution; the name of the action is preceded by a tilde
+DATA action_imp TYPE TABLE FOR ACTION IMPORT entity~action1.
+
+"Data objects with output derived types
+
+"For a read operation
+DATA read_tab TYPE TABLE FOR READ RESULT entity.
+
+"For an action defined with a result
+DATA action_res TYPE TABLE FOR ACTION RESULT entity~action2.
+
+"Examples for structures and types
+DATA create_wa TYPE STRUCTURE FOR CREATE entity.
+
+"For permission retrieval
+DATA perm_req TYPE STRUCTURE FOR PERMISSIONS REQUEST entity.
+
+"For retrieving global features
+DATA feat_req TYPE STRUCTURE FOR GLOBAL FEATURES RESULT entity.
+
+"Type declaration using a BDEF derived type
+TYPES der_typ TYPE TABLE FOR DELETE entity.
+
+"Response parameters
+DATA map TYPE RESPONSE FOR MAPPED entity.
+DATA fail TYPE RESPONSE FOR FAILED entity.
+DATA rep TYPE RESPONSE FOR REPORTED entity.
+```
+> **💡 Note**
+> Some of the derived types can only be created and accessed in implementation classes.
+
+
+
+### Components of BDEF Derived Types
+
+Many of the BDEF derived types contain components of CDS entities like
+key and data fields that retain their original data type, for example, a
+messenger table typed with `TYPE TABLE FOR CREATE`. Certainly,
+if an instance is to be created, key and field values of a RAP BO
+instance are of relevance.
+
+Yet, all BDEF derived types contain special RAP components serving a
+dedicated purpose. The names of these RAP components begin with
+`%` to avoid naming conflicts with components of the CDS
+entities. The following image shows the F2 information of a BDEF derived
+type containing the `%` components and fields from the CDS
+entity.
+
+
+
+Some of the `%` components are [component
+groups](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_group_glosry.htm "Glossary Entry")
+summarizing groups of table columns under a single name. In doing so,
+they simplify the handling of derived types for developers. For example,
+the component group
+[`%data`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_data.htm)
+contains all primary key and data fields of a RAP BO entity (actually,
+by containing the keys, it also contains the component group
+[`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm)
+in the case above). The F2 information in ADT helps you find out about
+the available components in a variable. The image below shows the
+details of `%data` when clicking the *derived type*
+link in the first ADT F2 information screen.
+
+
+
+The availability of `%` components depends on definitions in the
+BDEF. Their availability also depends on more criteria, for example, the
+scenario. For example, the component
+[`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
+that represents a preliminary ID for a RAP BO instance is only available
+in [late
+numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry")
+scenarios. The draft indicator
+[`%is_draft`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_is_draft.htm)
+is only relevant in the context of
+[draft](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_with_draft.htm).
+
+Find more details on the available components in section [Components of
+BDEF Derived
+Types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_comp.htm).
+
+Bullet points on selected `%` components:
+
+- [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)
+ - A string to define a content ID.
+ - Content IDs are used as a unique and preliminary identifier for
+ RAP BO operations in which instances are created and especially
+ in cases where the key values of RAP BO instances are not yet
+ determined
+ - Assume that you create a RAP BO instance with an EML create
+ request and the key value has not yet been determined. In the
+ same request - a save has not yet been triggered - an update is
+ requested for this RAP BO instance. Using the content ID, it is
+ guaranteed that the update operation happens for the desired
+ instance. For this purpose, derived types for operations like
+ update or delete include the component
+ [`%cid_ref`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid_ref.htm)
+ to refer to the content ID `%cid` as the name implies.
+ - Note: You should always fill `%cid` even if not
+ needed. The specified content ID is only valid within one ABAP
+ EML request. You can use the optional addition [`AUTO FILL CID`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm#!ABAP_ONE_ADD@1@) in EML modify operations to create `%cid` automatically. However, if you use this addition, you cannot refer to `%cid` in subsequent operations.
+- [`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm)/[`%tky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tky.htm)
+ - Both are component groups summarizing all primary keys of a RAP
+ BO instance.
+ - Where possible, it is recommended that you use `%tky`
+ instead of `%key`. `%tky` includes
+ `%key` and also the draft indicator
+ `%is_draft`. When using `%tky` in non-draft
+ scenarios, you are prepared for a potential, later switch to a
+ draft scenario. In doing so, you can avoid lots of adaptations
+ in your code by manually adding the indicator.
+- [`%control`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_control.htm)
+ - Component group that contains the names of all key
+ and data fields of a RAP BO instance which indicate flags.
+ - For example, it is used to get information on which fields are provided or set a
+ flag for which fields are requested by RAP BO providers or RAP
+ BO consumers respectively during the current EML request.
+ - For this purpose, the value of each field in the
+ `%control` structure is of type
+ `ABP_BEHV_FLAG`. For the value setting,
+ you can use the structured constant `mk` of interface
+ `IF_ABAP_BEHV`. Note that the technical
+ type is `x length 1`.
+ - Example: If you want to read data from a RAP BO instance and
+ particular non-key fields in `%control` are set to
+ `if_abap_behv=>mk-off`, the values of these fields
+ are not returned in the result.
+
+
+
+## EML Syntax
+
+The focus is here on selected EML statements. These statements can be
+fairly long and various additions are possible. Find more information on
+the EML statements
+[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeneml.htm).
+
+### EML Syntax for Modifying Operations
+
+The modifying operations covered include the standard operations (using
+the additions
+[`CREATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
+[`CREATE
+BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
+[`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
+and
+[`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm))
+and non-standard operations (actions) using the addition
+[`EXECUTE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm).
+All EML statements for the mentioned operations begin with
+[`MODIFY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities.htm).
+The following commented code snippets demonstrate the
+[short](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_short.htm)
+and [long
+form](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entities_long.htm)
+of EML `MODIFY` statements.
+
+> **💡 Note**
+> Unlike reading operations, modifying operations are not enabled by default. You must make the respective notations in the BDEF:
+> ```
+> ...
+> create;
+> update;
+> delete;
+> action some_act;
+> ...
+> ```
+
+Create operation for creating new instances of a RAP BO entity:
+
+``` abap
+"Declaration of data objects using BDEF derived types
+
+DATA: cr_tab TYPE TABLE FOR CREATE root_ent, "input derived type
+ mapped_resp TYPE RESPONSE FOR MAPPED root_ent, "response parameters
+ failed_resp TYPE RESPONSE FOR FAILED root_ent,
+ reported_resp TYPE RESPONSE FOR REPORTED root_ent.
+
+"Input derived type for the EML statement is filled using the VALUE operator
+"Assumption: key_field is the key field having type i,
+"field1 and field2 are data fields with character-like data type.
+"Specify %cid even if not used or of interest; it must be unique within a request
+
+cr_tab = VALUE #(
+ ( %cid = 'cid1' key_field = 1
+ field1 = 'A' field2 = 'B' )
+ ( %cid = 'cid2'
+ "Just to demo %data/%key. You can specify fields with or without
+ "the derived type components
+ %data = VALUE #( %key-key_field = 2
+ field1 = 'C'
+ field2 = 'D' ) ) ).
+
+"EML statement, short form
+"root_ent must be the full name of the root entity, it is basically the name of the BDEF
+
+MODIFY ENTITY root_ent
+ CREATE "determines the kind of operation
+ FIELDS ( key_field field1 field2 ) WITH cr_tab "Fields to be respected for the
+ "input derived type and the input
+ "derived type itself
+ MAPPED mapped_resp "mapping information
+ FAILED failed_resp "information on failures with instances
+ REPORTED reported_resp. "messages
+```
+
+> **💡 Note**
+> - Addition [`FIELDS ( ... ) WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm):
+ This field selection option specifies which fields are to be
+ respected for the operation. The derived type, i. e. an internal
+ table containing the concrete RAP BO instance values, follows
+ `WITH`. If a field is specified in the field list within the
+ pair of parentheses after `FIELDS`, the `%control`
+ flag for this field is automatically set to
+ `if_abap_behv=>mk-on`. Likewise, if a field is not
+ contained in the list, the flag in `%control` is set to
+ `if_abap_behv=>mk-off`. Assume `field2` is not
+ specified in the list. The value for `field2` will not be
+ respected (even if a value is specified in the internal table). The
+ initial value will be used for the field.
+>- Retrieving the responses and specifying the parameters is optional.
+ Assuming a data set with the value 2 for `key_field`
+ already exists on the database for this BO, you should expect an
+ entry for this particular instance in the `failed_resp`
+ operand and potentially an error message in
+ `reported_resp`, too. Nevertheless, especially in ABP
+ implementations and depending on the context, you should implement
+ and fill these parameters according to the [RAP BO
+ contract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_contract_glosry.htm "Glossary Entry")
+ to meet the variety of implementation rules.
+>- `%cid` should be provided even if you are not interested in
+ it and subsequent operations do not require the reference.
+
+Long form of an EML `MODIFY` statement:
+``` abap
+MODIFY ENTITIES OF root_ent "full name of root entity
+ ENTITY root "root or child entity (alias name if available)
+ CREATE FROM "FROM as further field selection variant
+ VALUE #( ( %cid = 'cid' "Input derived type created inline
+ key_field = 3
+ field1 = 'E'
+ field2 = 'F'
+ %control = VALUE #( "Must be filled when using FROM
+ key_field = if_abap_behv=>mk-on
+ field1 = if_abap_behv=>mk-on
+ field2 = if_abap_behv=>mk-on ) ) )
+ MAPPED DATA(m) "Target variables declared inline
+ FAILED DATA(f)
+ REPORTED DATA(r).
+```
+
+> **💡 Note**
+>- The entity specified after `ENTITY` can be either the root
+ entity itself or a child entity. If an alias is defined, the alias
+ should be used.
+>- The addition `FIELDS ( ... ) WITH` from the previous
+ snippet is basically a shortcut for the addition
+ [`FROM`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_fields.htm)
+ that is used here. When using `FROM`, the values of the
+ `%control` structure must be specified explicitly.
+>- The BDEF derived types can also be created
+ [inline](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_inline.htm)
+ as shown in the example using a [constructor
+ expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expression_glosry.htm "Glossary Entry")
+ for the input derived type and with `DATA` or
+ [`FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfinal_inline.htm)
+ for the responses.
+>- The long form allows you to bundle several operations in one
+ statement, either different operations on the same entity (for
+ example, deleting some instances and updating some others) or
+ operations on different entities of the same RAP BO (for example,
+ creating a root entity instance and related instances of a child
+ entity in one EML request). Long and short forms are also available
+ for other EML statements.
+>- The [`SET FIELDS WITH`](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abapmodify_entity_entities_fields.htm#!ABAP_VARIANT_4@4@) addition is available as another field specification option. However, it has limitations that you should be aware of. It can cause syntax warnings. Check the documentation. It is recommended that you use `FIELDS ... WITH` and `FROM`.
+
+
+Excursion: Specifying `%control` component values in the short form of `VALUE` constructor expressions
+
+```abap
+"The following EML statement creates RAP BO instances. The BDEF derived
+"type is created inline. With the FROM addition, the %control values
+"must be specified explicitly. You can provide the corresponding values
+"for all table lines using the short form, i.e. outiside of the inner
+"parentheses, instead of individually specifying the values for each
+"instance within the parentheses. In this case, the corresponding %control
+"component value is assigned for all of the following table lines.
+MODIFY ENTITIES OF zdemo_abap_rap_ro_m
+ ENTITY root
+ CREATE FROM VALUE #(
+ %control-key_field = if_abap_behv=>mk-on
+ %control-field1 = if_abap_behv=>mk-on
+ %control-field2 = if_abap_behv=>mk-on
+ %control-field3 = if_abap_behv=>mk-on
+ %control-field4 = if_abap_behv=>mk-off
+ ( %cid = 'cid1'
+ key_field = 1
+ field1 = 'aaa'
+ field2 = 'bbb'
+ field3 = 10
+ field4 = 100 )
+ ( %cid = 'cid2'
+ key_field = 2
+ field1 = 'ccc'
+ field2 = 'ddd'
+ field3 = 20
+ field4 = 200 ) )
+ MAPPED DATA(m)
+ FAILED DATA(f)
+ REPORTED DATA(r).
+```
+
+
+The following EML statement combines multiple operations in one EML
+request. It demonstrates the use of `%cid` and
+`%cid_ref`. First, two instances are created by specifying
+`%cid`. An update operation in the same request only specifies a
+certain field within the parentheses of the `FIELDS ( ... )
+WITH` addition which denotes that only this particular field
+should be updated. The other field values remain unchanged. The
+reference to the instance is made via `%cid_ref`. Consider an
+EML request in which no instance to refer to using `%cid_ref`
+exists, e. g. for an update operation. You can also make the reference
+using the unique key. A delete operation is available in the same
+request, too. `DELETE` can only be followed by the addition
+`FROM`. In contrast to other derived types, the derived type
+that is expected here (`TYPE TABLE FOR DELETE`) only has
+`%cid_ref` and the key as components.
+``` abap
+MODIFY ENTITIES OF root_ent
+ ENTITY root
+ CREATE FIELDS ( key_field field1 field2 ) WITH
+ VALUE #( ( %cid = 'cid4' key_field = 4
+ field1 = 'G' field2 = 'H' )
+ ( %cid = 'cid5' key_field = 5
+ field1 = 'I' field2 = 'J' ) )
+
+ UPDATE FIELDS ( field2 ) WITH
+ VALUE #( ( %cid_ref = 'cid4' field2 = 'Z' ) )
+
+ DELETE FROM
+ VALUE #( ( %cid_ref = 'cid5' ) "Instance referenced via %cid_ref
+ ( key_field = 9 ) ) "Instance referenced via the key
+...
+```
+
+EML statement including the execution of an action:
+``` abap
+MODIFY ENTITIES OF root_ent
+ ENTITY root
+ EXECUTE some_action
+ FROM action_tab
+ RESULT DATA(action_result) "Assumption: The action is defined with a result parameter.
+ ...
+```
+
+The following code snippet shows a deep create. First, an instance is
+created for the root entity. Then, in the same request, instances are
+created for the child entity based on the root instance. In the example
+below, the assumption is that a composition is specified in the root
+view entity like `composition [1..*] of root_ent as _child` and `key_field` and
+`key_field_child` are the keys of the child view entity. The
+[`%target`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_target.htm)
+component group enters the picture here which contains the target's
+primary key and data fields.
+``` abap
+MODIFY ENTITIES OF root_ent
+ ENTITY root_ent
+ CREATE FIELDS ( key_field field1 field2 ) WITH
+ VALUE #( ( %cid = 'cid6' key_field = 6
+ field1 = 'I' field2 = 'J' ) )
+ CREATE BY \_child
+ FIELDS ( key_field_child field1_child field2_child ) WITH
+ VALUE #( ( %cid_ref = 'cid6'
+ %target = VALUE #( ( %cid = 'cid_child_1'
+ key_field_child = 1
+ field1_child = 'aa'
+ field2_child = 'bb' )
+ ( %cid = 'cid_child_2'
+ key_field_child = 2
+ field1_child = 'cc'
+ field2_child = 'dd' ) ) ) )
+...
+```
+
+
+
+### EML Syntax for Reading Operations
+
+- Read-only operations always return a result, i.e. the syntax of the
+ EML statement requires the addition `RESULT` and an operand.
+- When RAP BO instances are read, the returned data include the
+ current status of instances in the transactional buffer which
+ includes unsaved modifications on instances. If an instance is not
+ yet available in the transactional buffer, the currently persisted
+ data set is automatically read into the transactional buffer.
+- Note that read operations are always implicitly enabled for each
+ entity listed in a BDEF, i. e. there is no extra definition in the
+ BDEF in contrast to, for example, create or update.
+
+The following code snippet shows the long form of the EML
+[`READ`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_op.htm)
+statement for reading instances from the root entity. In `READ`
+statements, the additions `FIELDS ( ... ) WITH` and
+`FROM` can also be used to specify the fields that you intend to
+read. Here, the addition [`ALL FIELDS
+WITH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_fields.htm)
+is available for reading all field values.
+
+``` abap
+READ ENTITIES OF root_ent
+ ENTITY root_ent
+ ALL FIELDS WITH
+ VALUE #( ( key_field = 1 ) "Derived type TYPE TABLE FOR READ IMPORT only includes the keys
+ ( key_field = 2 ) )
+ RESULT DATA(result)
+ FAILED DATA(f)
+ REPORTED DATA(r).
+```
+
+Read-by-association operations include the optional addition
+[`LINK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entity_entities_op&sap-language=EN&sap-client=000&version=X&anchor=!ABAP_ONE_ADD@1@&tree=X)
+with which you can retrieve the keys of the source and target (i. e. the
+associated entity). The by-association operations work reciprocally, i.
+e. you can, for example, read a child instance via the parent and a
+parent instance via the child, too.
+
+``` abap
+"Read-by association operation: parent to child
+READ ENTITIES OF root_ent
+ ENTITY root_ent
+ BY \_child
+ ALL FIELDS WITH VALUE #( ( key_field = 1 ) )
+ RESULT DATA(rba_res1)
+ LINK DATA(links1).
+ ...
+
+"Read-by association operation: child to parent
+READ ENTITIES OF root_ent
+ ENTITY child_ent
+ BY \_parent
+ ALL FIELDS WITH VALUE #( ( key_field = 1 key_field_child = 1 ) )
+ RESULT DATA(rba_res2)
+ LINK DATA(links2).
+ ...
+```
+
+
+### Dynamic Forms of EML Statements
+
+In addition to the short and long forms described above, various ABAP EML statements also have dynamic forms.
+Taking EML read operations as an example, the following code snippet shows a dynamic EML [`READ ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapread_entities_operations.htm) statement. The relevant syntax element is the `OPERATIONS` addition.
+The dynamic form allows the collection of read operations for multiple RAP BOs in one EML statement.
+For more information, see the ABAP keyword documentation and the comments in the snippet.
+
+```abap
+"The statement is taken from the executable example. The example has a
+"root entity and a child entity. For both entities, RAP BO instances
+"are to be read (read and read-by-association operation).
+
+DATA:
+ "The following data object is the operand of the dynamic EML statement
+ "It is an internal table and has a special, RAP-specific type.
+ op_tab TYPE abp_behv_retrievals_tab,
+
+ "More data object declarations (internal tables typed with BDEF
+ "derived types) that are relevant for the EML statement.
+ "For both entities (root and child), RAP BO instances are to be
+ "read. The internal tables are used for components of the internal
+ "table op_tab further down.
+ read_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m,
+ read_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m,
+ rba_dyn TYPE TABLE FOR READ IMPORT zdemo_abap_rap_ro_m\_child,
+ rba_dyn_result TYPE TABLE FOR READ RESULT zdemo_abap_rap_ro_m\_child,
+ rba_dyn_link TYPE TABLE FOR READ LINK zdemo_abap_rap_ro_m\_child.
+
+"Filling the internal tables, i.e. which instances are to be read
+"Root entity
+"Example:
+"- The key is comprised of the field 'key_field'. It is of type i.
+"- The %control structure is filled, flagging those fields that
+" are to be read. Flagging the key field is not required.
+read_dyn = VALUE #(
+ ( %key-key_field = 1
+ %control = VALUE #(
+ field1 = if_abap_behv=>mk-on
+ field2 = if_abap_behv=>mk-on
+ field3 = if_abap_behv=>mk-on
+ field4 = if_abap_behv=>mk-on ) )
+ ( %key-key_field = 2
+ %control = VALUE #(
+ field1 = if_abap_behv=>mk-on
+ field2 = if_abap_behv=>mk-on
+ field3 = if_abap_behv=>mk-on
+ field4 = if_abap_behv=>mk-on ) ) ).
+
+"Child entity
+"Instances to be read for a read-by-association operation
+"The shared key is 'key_field'.
+rba_dyn = VALUE #(
+ ( %key-key_field = 1
+ %control = VALUE #(
+ key_ch = if_abap_behv=>mk-on
+ field_ch1 = if_abap_behv=>mk-on
+ field_ch2 = if_abap_behv=>mk-on ) )
+ ( %key-key_field = 2
+ %control = VALUE #(
+ key_ch = if_abap_behv=>mk-on
+ field_ch1 = if_abap_behv=>mk-on
+ field_ch2 = if_abap_behv=>mk-on ) ) ).
+
+"Filling the internal table that is the operand of the
+"dynamic EML statement
+"This table has optional and mandatory components.
+op_tab = VALUE #(
+ ( "op: Specifies the operation to be executed; is mandatory;
+ " can be set with the predefined constants, e.g. OP-R-READ
+ " etc., of interface IF_ABAP_BEHV
+ op = if_abap_behv=>op-r-read
+ "entity_name: Specifies the name of the RAP BO entity for which
+ " the operation is executed; is mandatory
+ entity_name = 'ZDEMO_ABAP_RAP_RO_M'
+ "instances: Specifies a reference to an internal table holding
+ " the input keys; must be appropriately typed; is mandatory
+ instances = REF #( read_dyn )
+ "results: Specifies a reference to an internal table with the required
+ " BDEF derived type for the read results; is mandatory
+ results = REF #( read_dyn_result ) )
+ ( op = if_abap_behv=>op-r-read_ba
+ entity_name = 'ZDEMO_ABAP_RAP_RO_M'
+ "sub_name: Only relevant for specifying association names in
+ " read-by-association operations; in that context, it is mandatory
+ sub_name = '_CHILD'
+ "full: Optional flag; specifies if all target instances are to be retrieved
+ full = abap_true
+ instances = REF #( rba_dyn )
+ results = REF #( rba_dyn_result )
+ "links: Reference to internal table holding the key pairs of the source and
+ " target
+ links = REF #( rba_dyn_link ) ) ).
+
+READ ENTITIES OPERATIONS op_tab.
+```
+
+
+### Persisting to the Database
+
+- A [`COMMIT
+ ENTITIES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm)
+ statement triggers the RAP save sequence. Without such a statement,
+ the modified RAP BO instances that are available in the
+ transactional buffer are not persisted to the database. As mentioned above, in case of a natively supported RAP
+ scenario (for example, when using OData), the `COMMIT
+ ENTITIES` request is executed automatically.
+- `COMMIT ENTITIES` implicitly includes [`COMMIT
+ WORK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit.htm).
+- Note: `COMMIT ENTITIES` statements cannot be used
+ in behavior implementations.
+- There are multiple variants available for the statement as described
+ in the ABAP Keyword Documentation
+ [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcommit_entities.htm). For example, RAP responses can be retrieved, key conversion in late numbering scenarios, checking a RAP transaction in a simulation mode.
+- `COMMIT ENTITIES` statements set the system field
+ `sy-subrc`. When using `COMMIT ENTITIES`, it is not
+ guaranteed that `COMMIT WORK` is carried out successfully.
+ Hence, you should include a check for `sy-subrc` after
+ `COMMIT ENTITIES` so that you can react to failures
+ accordingly.
+
+The following snippet shows a create operation. This operation has only
+an impact on the database with the `COMMIT ENTITIES` statement.
+Triggering the save sequence means that the execution of the statement
+triggers the calling of the saver methods available in the saver class
+of a behavior implementation. In managed scenarios (except for some
+special variants), the saving is done automatically without implementing
+a dedicated saver method.
+``` abap
+MODIFY ENTITIES OF root_ent
+ ENTITY root_ent
+ CREATE FIELDS ( key_field field1 field2 ) WITH
+ VALUE #( ( %cid = 'cid' key_field = 7
+ field1 = 'K' field2 = 'L' ) ).
+
+COMMIT ENTITIES.
+
+IF sy-subrc <> 0.
+ ...
+ENDIF.
+```
+
+
+
+### Raising RAP Business Events
+
+- [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm) can be raised in ABAP behavior pools with [`RAISE ENTITY EVENT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_entity_event.htm) statements.
+- The focus of the snippets is on the local consumption of RAP business events. Prerequisites:
+ - `event` specifications are available in the BDEF (e.g. `... event some_evt; ...`). For more details, refer to the [BDL documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_event.htm)
+ - A [RAP event handler class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_event_handler_class_glosry.htm) is available that is used to implement [RAP event handler methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_event_handler_meth_glosry.htm).
+ - Note that these methods are called asynchronously.
+ - Similar to RAP handler and saver methods, RAP event handler methods are implemented in the CCIMP include of the RAP event handler class.
+ - To locally consume RAP business events, a local class that inherits from `CL_ABAP_BEHAVIOR_EVENT_HANDLER` can be implemented in the CCIMP include of a RAP event handler class.
+- More information:
+ - [ABAP for RAP Business Events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_events.htm) in the ABAP Keyword Documentation
+ - [Business Events](https://help.sap.com/docs/abap-cloud/abap-rap/business-events) in the SAP Help Portal
+
+```abap
+"---- Syntax for the declaration part of a global RAP event handler class ----
+CLASS cl_event_handler DEFINITION PUBLIC FOR EVENTS OF some_bdef.
+ ...
+ENDCLASS.
+
+"---- Syntax for the declaration part of a local event handler class ----
+"---- in the CCIMP include of a RAP event handler class ----
+CLASS lhe_event DEFINITION INHERITING FROM cl_abap_behavior_event_handler.
+ ...
+ENDCLASS.
+
+"---- RAP event handler method definition ----
+"Notes:
+"- Must be defined as instance methods in the private visibility section.
+"- The input parameter par is an internal table of type TYPE TABLE FOR EVENT.
+"- This type includes the keys of RAP BO instances (and %param, if the event
+" is specified with a parameter in the BDEF)
+"- The methods do not contain RAP response parameters.
+METHODS meth FOR ENTITY EVENT par FOR some_bdef~some_evt.
+
+"---- RAISE ENTITY EVENT statement in an ABP, e.g. the save_modified method ----
+"---- in managed scenarios with additional save ----
+...
+CLASS lsc IMPLEMENTATION.
+ METHOD save_modified.
+ "Assumption: An event is specified for create operations in the BDEF as follows
+ "event created;
+ IF create-some_bdef IS NOT INITIAL.
+ RAISE ENTITY EVENT some_bdef~created
+ FROM VALUE #( FOR IN create-root ( %key = VALUE #( some_key = -some_key ) ) ).
+ ENDIF.
+
+ "Assumption: An event is specified for delete operations in the BDEF as follows
+ "event deleted parameter some_abstract_entity;
+ "The abstract entity has two parameters, for example, with which additional
+ "information can be passed.
+ IF delete-some_bdef IS NOT INITIAL.
+ RAISE ENTITY EVENT some_bdef~deleted
+ FROM VALUE #( FOR IN delete-some_bdef (
+ %key = VALUE #( some_key = -some_key )
+ %param = VALUE #( par_a = '01'
+ par_b = 'Item deleted' ) ) ).
+ ENDIF.
+ ENDMETHOD.
+ENDCLASS.
+```
+
+
+
+### Additions to EML Statements in ABAP Behavior Pools
+
+- There are a [special additions when using EML in behavior
+ pools](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeneml_in_abp.htm).
+ One of them is [`IN LOCAL MODE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapin_local_mode.htm).
+- This addition can be used to exclude feature controls and
+ authorization checks.
+- Consider the following use case: There is a field to display the
+ booking status of a trip on a UI. In the BDEF, this field is
+ specified as read-only. Hence, it cannot be modified by a user on
+ the UI. However, there is a button on the UI to book the trip. This
+ button might trigger an action to book the trip so that the value of
+ the field changes from open to booked. To enable this, the
+ underlying handler method for the modify operation with the action
+ to be executed has the addition `IN LOCAL MODE` that ignores
+ the feature control.
+
+Syntax:
+
+``` abap
+MODIFY ENTITIES OF root_ent IN LOCAL MODE
+ ENTITY root
+ EXECUTE book
+ FROM action_tab
+ ...
+```
+
+
+
+## RAP Excursions
+
+### Using Keys and Identifying RAP BO Instances in a Nutshell
+
+
+ Expand to view the details
+
+
+
+The following bullet points outline important aspects regarding
+ keys and identifying [RAP BO
+instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_instance_glosry.htm "Glossary Entry") in ABAP EML statements.
+
+**Why is it important?**
+
+- The [primary
+ key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_key_glosry.htm "Glossary Entry")
+ of a [RAP BO entity instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_entity_inst_glosry.htm "Glossary Entry")
+ is composed of one or more [key fields](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenkey_field_glosry.htm "Glossary Entry").
+- These key fields stand for the fields that are specified with
+ `key` in the underlying [CDS view entity](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_v2_view_glosry.htm "Glossary Entry")
+ of the RAP BO.
+- The primary key uniquely identifies each RAP BO entity instance.
+- After the creation of an instance including the primary key during a [RAP create operation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_create_operation_glosry.htm "Glossary Entry"),
+ the primary key can no longer be changed.
+ - Note that there are different numbering concepts, such as [early](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_early_numbering_glosry.htm) and [late numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlate_numbering_glosry.htm "Glossary Entry"). In the latter concept, newly created entity instances are given their final key only shortly before saving in the database. Until then, the business logic uses a temporary key that has to be replaced.
+- If a data set with a particular primary key already exists in the
+ persistent database table, the saving of a RAP BO instance is rejected because of a duplicate primary key.
+
+**How can a RAP BO instance be uniquely identified?**
+
+- It can be done by using a [RAP instance identifier](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_inst_identifier_glosry.htm "Glossary Entry")
+ or [RAP content identifier](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_cont_identifier_glosry.htm "Glossary Entry")
+ or both of them.
+- RAP instance identifier:
+ - It consists of the primary key fields and all relevant [BDEF derived type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm "Glossary Entry")
+ components.
+ - To ease the reference to all of these components, special
+ [component groups](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomponent_group_glosry.htm "Glossary Entry")
+ are available to summarize the components and make them
+ addressable via one single name.
+ - [`%key`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_key.htm):
+ Contains the primary key fields of a RAP BO instance
+ - [`%tky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tky.htm):
+ Specifies the transactional key. Comprises `%key` (and,
+ thus, the primary key fields of a RAP BO instance) and more
+ components that are relevant to uniquely identify a RAP BO
+ instance. Among them,
+ [`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
+ (relevant for late numbering scenarios) and the draft indicator
+ [`%is_draft`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_is_draft.htm)
+ (relevant for
+ [draft](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_with_draft.htm)
+ scenarios). In non-late numbering or non-draft scenarios, these
+ extra components are just blank. However, it is recommended that
+ you use `%tky` in all scenarios since it simplifies a
+ possible later switch, for example, to a draft scenario. In
+ doing so, lots of adaptations to the code regarding the keys and
+ the inclusion of `%is_draft` can be avoided.
+- RAP content identifier:
+ - Reflected in the component
+ [`%cid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid.htm)
+ which is a string of type
+ `ABP_BEHV_CID` to define a content ID.
+ - Used as a unique and preliminary identifier for RAP BO instances
+ in RAP create operations, especially where no primary key exists
+ for the particular instance.
+ - For newly created instances, the ID can then be used for performing further modifications, referencing to those instances using [`%cid_ref`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_cid_ref.htm) (which has the same value as %cid), for example, in RAP operations using [`CREATE BY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm), [`UPDATE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm)
+ and
+ [`DELETE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm),
+ as well as
+ [actions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbdl_action.htm)
+ with
+ [`EXECUTE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmodify_entity_entities_op.htm)).
+ - In contrast to the primary key and the preliminary ID
+ `%pid` for late numbering scenarios, `%cid` (and
+ `%cid_ref`) are only available on a short-term basis
+ for the current ABAP EML request within the [RAP interaction phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm "Glossary Entry") in one RAP transaction.
+ - **Note:** Specify `%cid` even if there are no further operations referring to it.
+- Special case: Late numbering
+ - As mentioned above, in late numbering scenarios newly created
+ entity instances are given their final key only shortly before
+ saving in the database, i. e. you deal with preliminary keys in
+ the RAP interaction phase and the early phase of the [RAP save sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm "Glossary Entry").
+ - In this case, you can use `%key` to hold the preliminary
+ keys or use a preliminary ID in the dedicated component
+ [`%pid`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pid.htm)
+ which is of type `ABP_BEHV_PID` and
+ only available in late numbering scenarios.
+ - Similar to above, to uniquely identify RAP BO instances in late
+ numbering scenarios, you can use either `%key` or
+ `%pid` or both of them. In any case, the use of
+ `%tky` is handy because it includes both components. You
+ must ensure that `%tky` in total uniquely identifies the
+ instances.
+ - **Note:** A further component group to refer to the keys is available: [`%pky`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pky.htm). `%pky` contains `%pid` and `%key` in late numbering scenarios. In non-late numbering scenarios, it just contains `%key`. `%pky` itself is contained in `%tky`. There are contexts, for example, particular actions, where `%tky` is not available but `%pky` is. This way, there is still the option to summarize `%pid` and `%key` in one component group in the absence of `%tky`.
+
+**General rule**: A RAP BO instance must - where available - always be uniquely
+identifiable by its transactional key (`%tky`) for internal
+processing during the RAP interaction phase. `%tky` always
+contains all relevant components for the chosen scenario.
+
+> **💡 Note**
+> Assignment of Key Component Groups
+>
+> As a general best practice, you should use a RAP BO instance key component group when referring to the entire key, rather than listing the individual key fields. It is recommended that you use `%tky` whenever possible.
+> In the following cases, type compatibility cannot be guaranteed in component group assignments:
+> - Mixing key component groups when they refer to the same RAP BO entity, e.g. `wa-%tky = wa-%key`. Such an assignment should also be avoided when both component groups have an identical scope in terms of components (e.g. `%tky` and `%key` in non-late-numbering and non-draft scenarios).
+> - Mixing the same key component groups when referring to two different RAP BO entities, for example, `wa_root-%tky = wa_child-%tky`. In this case, adding more components later may cause syntax errors for an assignment that worked previously.
+> - Defining structured types that have the same components as key component groups, and then assigning data objects of that type to those of the respective, original key component group.
+> In the above cases, the `CORRESPONDING` operator can be used to ensure type compatibility in assignments to key component groups:
+> ```abap
+>... %tky = CORRESPONDING #( wa-%tky ) ...
+>... %key = CORRESPONDING #( wa-%key ) ...
+>... %pky = CORRESPONDING #( wa-%pky ) ...
+>```
+> In cases where different data objects of key component groups of a BDEF derived type are to be assigned to the same key component group of the same entity, a direct assignment works without a syntax warning because the content is identical. A direct assignment is recommended (`...wa1_root-%tky = wa2_root-%tky ...`). The use of the `CORRESPONDING` operator is unnecessary and less performant. This is true, for example, for key component group assignments in the context of RAP response parameters failed and reported.
+
+
+
+### RAP Concepts
+
+
+ Expand to view the details
+
+
+
+**RAP numbering**
+
+- A concept that deals with setting values for primary key fields.
+- There are multiple options to handle the numbering for primary key
+ fields depending on when (early in the RAP interaction phase or late
+ in the RAP save sequence) and by whom (RAP BO consumer, behavior
+ pool, or framework) the primary key values are set.
+- When:
+ - [Early numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_early_numbering_glosry.htm "Glossary Entry"):
+ The final key values are assigned during a RAP create operation
+ in the interaction phase.
+ - [Late numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_late_numbering_glosry.htm "Glossary Entry"):
+ The final key values are assigned during the RAP save sequence
+ (and here only in the RAP saver method
+ [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)).
+- By whom
+ - [External numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_ext_numbering_glosry.htm "Glossary Entry"):
+ Key values are provided by the RAP BO consumer. For example, in
+ a create operation, the key values are specified by the RAP BO
+ consumer like other non-key field values. Basically, this is the
+ concept with which the snippets above are tailored.
+ - [Internal numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_numbering_glosry.htm "Glossary Entry"):
+ Key values are provided by the RAP BO provider. For example, in
+ a create operation, the key values are not specified in an EML
+ create request by the RAP BO consumer but rather by the RAP BO
+ provider. In case of a managed RAP BO, the key is automatically
+ created by the framework which only works if the key is of a
+ certain type (16-character byte-like
+ [UUID](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuuid_glosry.htm "Glossary Entry")).
+ In case of an unmanaged RAP BO, the key values are provided in a
+ dedicated handler method which must be self-implemented. Note
+ that late numbering is internal by default since no further RAP
+ BO consumer interaction is possible in the late phase of the RAP
+ save sequence.
+
+**Draft**
+
+- The draft concept in RAP allows the content of the transactional
+ buffer to be stored in intermediate storages ([draft tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendraft_table_glosry.htm "Glossary Entry"))
+ in order to allow transactions to expand over different ABAP
+ sessions.
+- Like the concepts mentioned above, a RAP BO can be draft-enabled in
+ the BDEF. If enabled, the application allows data modifications and the temporary storage of modifications but does not yet persist them to the database. The users of the application can continue modifying this data later and they might even use a different device from the one where they modified the data previously.
+- The draft indicator `%is_draft` is available for RAP BO instance identification. It is used to indicate if a RAP BO
+ instance is a [draft instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_draft_instance_glosry.htm "Glossary Entry")
+ or an [active instance](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_active_instance_glosry.htm "Glossary Entry").
+ Conveniently, the component group `%tky` contains
+ `%is_draft`. `%is_draft` can then be addressed via
+ `%tky`.
+
+> **💡 Note**
+> Late numbering and identification in the late phase of the RAP save sequence
+>- Context: RAP saver method
+> [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm)
+> in which the final key values are assigned; the preliminary keys can
+> be included in `%key` or `%pid` or both of them.
+>- `%pid` and the preliminary key values in `%key` are
+> automatically assigned to the following component groups when
+> reaching the `adjust_numbers` method:
+> - [`%tmp`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_tmp.htm):
+> A component group that is assigned the preliminary key values
+> contained in `%key`. In doing so, `%tmp` takes
+> over the role that `%key` has had in the RAP interaction
+> phase to hold the preliminary key values.
+> - `%pid` remains as is. The component group
+> [`%pre`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapderived_types_pre.htm)
+> contains `%pid` and `%tmp` and, thus, all
+> preliminary identifiers.
+>- In the `adjust_numbers` method, the preliminary keys are
+> transformed into the final keys, i. e. the preliminary keys are
+> mapped to `%key` (which holds the final keys in this
+> context) in the `mapped` [response parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_response_param_glosry.htm "Glossary Entry").
+>- Depending on your use case to use either `%pid` or (the
+> preliminary key values in) `%key` (which is `%tmp`
+> here in this method) during the interaction phase or both of them,
+> you must ensure that `%pre` in total (since it contains both
+> `%pid` and `%tmp`) is unique and mapped to the final
+> keys that are to be contained in `%key`.
+
+
+
+### Ensuring Data Consistency in a RAP Transaction
+
+
+ Expand to view the details
+
+
+
+The [LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenluw_glosry.htm) concept, which deals with the transfer of data from one consistent state to another, applies to applications using RAP. RAP transactions are integrated with the [SAP LUW](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensap_luw_glosry.htm), which is a prerequisite for transactional consistency. RAP provides a standardized approach and rules ([RAP BO contract](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_contract_glosry.htm)) for the [RAP business object (BO)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_bo_glosry.htm) runtime to ensure that the RAP transaction is correctly implemented, data inconsistencies are avoided, and the SAP LUW is successfully completed.
+
+**Phases of a RAP Transaction**
+
+A RAP transaction is divided into two phases during the runtime of a RAP BO, while the second phase can be divided into two subphases that serve different purposes.
+
+
+
+[RAP interaction phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_phase_glosry.htm):
+- [RAP handler methods](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_method_glosry.htm) are called in a [RAP handler class](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabp_handler_class_glosry.htm) that inherits from `CL_ABAP_BEHAVIOR_HANDLER`.
+- New data, i.e. RAP BO instances, are created in the [RAP transactional buffer](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentransactional_buffer_glosry.htm), or persisted data is retrieved and inserted into the transactional buffer for further processing.
+- The state of the data may become inconsistent in the transactional buffer during this phase. However, the data remains consistent in the database because changes are made only in the transactional buffer.
+
+[RAP save sequence](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_save_seq_glosry.htm):
+- The RAP save sequence is triggered by a `COMMIT ENTITIES` statement. In natively supported RAP scenarios, such as an SAP Fiori application using OData, the `COMMIT ENTITIES` call is implicitly and automatically performed by the RAP runtime engine.
+- RAP saver methods are called in the RAP saver class, which inherits from the base class `CL_ABAP_BEHAVIOR_SAVER`.
+- Is divided into the [RAP early save phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenearly_rap_save_phase_glosry.htm) (ensures that the RAP BO instances in the transactional buffer - all RAP BOs in the current RAP transaction are involved - are in a consistent state so that they can be saved to the database) and the [RAP late save phase](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlate_rap_save_phase_glosry.htm) (to finally save data from the transactional buffer to the database).
+
+(Optional:) Saver methods called in the RAP early save phase:
+1. [`finalize`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_finalize.htm): For final calculations and data changes before saving. In managed scenarios, determinations specified with `ON SAVE` are called when reaching this method.
+
+2. [`check_before_save`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_check_before_save.htm): For data consistency checks in the transactional buffer. In managed scenarios, validations specified with `ON SAVE` are called when this method is reached.
+
+3. [`cleanup_finalize`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapsaver_class_cleanup_finalize.htm): If there are failures in at least one of the previous saver methods, further processing with the RAP late save phase is rejected and the transaction returns to the interaction phase. Before that, this saver method is called, allowing changes made in the finalize method to be rolled back.
+
+If there are errors in the early save phase, `sy-subrc` returns the value 4 after `COMMIT ENTITIES` statements. If the data in the transactional buffer is consistent after the early save phase, the late save phase is processed, which also means that a point of no return has been reached. Unlike the early save phase, you cannot return to the interaction phase when you reach the late save phase. Either the RAP transaction ends with a successful commit, or the changes are rolled back and a runtime error occurs.
+
+Saver methods called in the RAP late save phase:
+1. [`adjust_numbers`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_adjust_numbers.htm): Provides RAP BO instances with their final numbers. This method is available only in late numbering scenarios.
+2. [`save`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_save.htm) (or [`save_modified`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaprap_saver_meth_save_modified.htm) in managed scenarios with an unmanaged or additional save): Used to save data from the transactional buffer to the database. If there are no issues, the final database commit is triggered and an implicit `COMMIT WORK` is executed.
+
+[`cleanup`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_cleanup.htm) method: After a successful save, the [`cleanup`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensaver_method_cleanup.htm) method clears the transactional buffer. It completes the save sequence.
+
+**Commit and Rollback in a RAP Transaction**
+The default ABAP statements for RAP are `COMMIT ENTITIES` (triggers the RAP save sequence and the final database commit; as mentioned above, in natively supported RAP scenarios, the commit is performed implicitly and automatically by the RAP runtime engine) and `ROLLBACK ENTITIES` (rolls back all changes of the current RAP transaction, i.e. the transactional buffer is cleared by calling the `cleanup` method). Both are RAP-specific and end the RAP transaction.
+
+*Notes on `COMMIT ...` and `ROLLBACK ...` statements due to the integration of RAP transactions into the SAP LUW:*
+
+- `COMMIT ENTITIES` implicitly triggers `COMMIT WORK`.
+- Using `COMMIT WORK` in RAP (instead of `COMMIT ENTITIES`) also triggers the RAP save sequence. If there are no errors in the RAP save sequence, the final database commit is successful. Only in this best-case scenario does `COMMIT WORK` have the same effect as `COMMIT ENTITIES`. However, if there are errors in the save sequence, a runtime error occurs in any case, while a return to the interaction phase is still possible when using `COMMIT ENTITIES`.
+- `COMMIT ENTITIES` provides RAP-specific functionality with various additions that are not possible with `COMMIT WORK`, such as RAP responses can be retrieved, key conversion in late numbering scenarios, checking a RAP transaction in a simulation mode.
+- There are short, long, and dynamic forms of `COMMIT ENTITIES` statements.
+- `COMMIT ENTITIES` statements implicitly enforce local updates with `COMMIT WORK`, or `COMMIT WORK AND WAIT` if the local update fails. Therefore, the update is either a local update or a synchronous update, but never an asynchronous update. When `COMMIT WORK` is used, the RAP BO consumer can choose between synchronous and asynchronous update for RAP BO entities.
+- `ROLLBACK ENTITIES` implicitly triggers `ROLLBACK WORK`. Both have the same effect when used in RAP. Therefore, they are interchangeable.
+
+> **💡 Note**
+> Special Case: Failures in the Late Save Phase
+> - In exceptional cases, for example, when [BAPIs](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenbapi_glosry.htm) are called to save RAP BO instances in the late save phase, it may happen that the basic rule that failures must not occur in the RAP late save phase and be detected in the RAP early save phase is violated.
+> - In such cases, the base class `CL_ABAP_BEHAVIOR_SAVER_FAILED` can be used for the RAP saver class.
+> - RAP BO consumers can be informed by filling the RAP response parameters (some of which are not available when using `CL_ABAP_BEHAVIOR_SAVER` as the base class) in the saver method implementation so that they can react accordingly.
+> - After a `COMMIT ENTITIES` statement and a failure in the late save phase, `sy-subrc` is set to 8.
+> - A subsequent RAP operation may result in a runtime error. If the RAP BO consumer is to continue after an error in the late phase of the RAP save sequence, an explicit `ROLLBACK ENTITIES` is required.
+
+**Allowed/Forbidden Operations in a Behavior Implementation in a RAP Transaction**
+
+The following restrictions apply to operations and/or statements in the individual phases of a RAP transaction in ABAP behavior implementations. Note that, depending on setting the strict mode in the BDEF, runtime errors may occur due to the use of forbidden statements, or static code checks may be applied. Note that most operations/statements refer to the use in the unrestricted ABAP language scope.
+
+|Operations/Statements|Interaction phase|Early save phase|Late save phase|Notes|
+|---|---|---|---|---|
+|[Database commits](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_commit_glosry.htm) using [secondary connections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_db_connection_glosry.htm)
(unrestricted ABAP language scope)| X| X| X |Secondary connections are allowed for infrastructure purposes, for example. They can be used to store data that is not part of the main transaction, such as application logs, traces, or number ranges. |
+|Database commits using the [standard connection](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_db_connection_glosry.htm)
(unrestricted ABAP language scope)| X| X| -| Database commits can be made in phases other than the late phase, for example, by calling external services or using a `WAIT` statement.|
+|[sRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensrfc_glosry.htm) (`CALL FUNCTION ... DESTINATION`), [aRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenarfc_glosry.htm) (`CALL FUNCTION ... STARTING NEW TASK`)
(unrestricted ABAP language scope)| X |X |-| Allowed in phases other than the late save phase, e.g. for the purpose of parallelization within the application. It is up to the application to ensure consistency, e.g. to ensure read-only access, to handle a potential two-phase commit, or to provide a proper error handling. |
+|Database modifications |- |-| X| Only allowed in the late save phase because the data being processed is always potentially inconsistent. Database changes in other phases would result in multiple database transactions instead of one transaction, which would disrupt the SAP LUW. |
+|[Update function module](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenupdate_function_module_glosry.htm) (`CALL FUNCTION ... IN UPDATE TASK`)
(unrestricted ABAP language scope)|-| -| X |Can be used to ensure that there is only one database transaction. In addition, registering function modules for update tasks at stages other than the late save phase would interfere with RAP draft scenarios, for example, where data is stored in draft tables. There is no way to unregister function modules once they have been registered. |
+|[bgRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenbgrfc_glosry.htm) (`CALL FUNCTION ... IN BACKGROUND UNIT`)
(unrestricted ABAP language scope)| -| -| X| |
+|[tRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentrfc_2_glosry.htm), [qRFC](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenqrfc_glosry.htm) (`CALL FUNCTION ... IN BACKGROUND TASK`)
(unrestricted ABAP language scope)| -| -| - |Obsolete technologies. |
+|`PERFORM ON COMMIT`, `PERFORM ON ROLLBACK`
(unrestricted ABAP language scope)|(X) |(X) |X |Basically possible in all phases, but should be reserved for the late save. Note: The use of these statements indicates improper integration with RAP. It is especially important to check draft scenarios when calling legacy code and using these statements. Instead, ABAP EML or procedure calls that do not include a `COMMIT WORK` should be used. |
+|Transaction control `COMMIT WORK`, `ROLLBACK WORK` |X/-| X/-| X/- |When a transactional phase has been explicitly set by methods of the `CL_ABAP_TX` class (find more information [here](https://help.sap.com/docs/abap-cloud/abap-concepts/controlled-sap-luw)), the transaction owner is allowed to execute a commit or rollback statement. In the contexts of RAP (that is, where RAP is the transaction owner, for example, in handler and saver methods), local consumption of [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm), [bgPF](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbgpf_glosry.htm), and [classified APIs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassified_api_glosry.htm), commit or rollback statements are not allowed. |
+|[Dynpro](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_glosry.htm) processing (e.g. `SET SCREEN`, `CALL SCREEN`, `LEAVE SCREEN`, `CALL DIALOG`, `SUPPRESS DIALOG`, `MESSAGE` without `INTO`, `WRITE`, `STOP`)
(unrestricted ABAP language scope)|- |- |- |Not allowed in ABAP behavior implementations. Results in a runtime error. |
+|Transaction processing (`CALL TRANSACTION`, `LEAVE TRANSACTION`)
(unrestricted ABAP language scope)| -| -| - |Not allowed to prevent (unwanted) integration of other LUWs. |
+|Raising an exception (`RAISE EXCEPTION`) |-| -| - |It is not allowed to leave a RAP transaction this way. |
+|Report processing (`SUBMIT ...`)
(unrestricted ABAP language scope)|- |- |- |Not allowed in transactional contexts. Results in a syntax or runtime error. `SUBMIT ... AND RETURN` does not currently return an error, but it leads to potentially unwanted screen processing, and because of the missing return channel, there is no proper error handling. |
+
+
+
+
+
+
+## More Information
+
+- Section [ABAP for RAP Business
+ Objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_for_rap_bos.htm)
+ in the ABAP Keyword Documentation including EML
+- [RAP Glossary](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_glossary.htm)
+- [Development guide for the ABAP RESTful Application Programming
+ Model](https://help.sap.com/docs/ABAP_PLATFORM_NEW/fc4c71aa50014fd1b43721701471913d/289477a81eec4d4e84c0302fb6835035.html)
+- [RAP
+ Contract](https://help.sap.com/docs/ABAP_PLATFORM_NEW/fc4c71aa50014fd1b43721701471913d/3a402c5cf6a74bc1a1de080b2a7c6978.html):
+ Rules for the RAP BO provider and consumer implementation to ensure
+ consistency and reliability
+
+
+
+## Executable Examples
+
+This cheat sheet is supported by different executable examples demonstrating various scenarios:
+- Demo RAP scenario with a managed RAP BO, external numbering: [zcl_demo_abap_rap_ext_num_m](./src/zcl_demo_abap_rap_ext_num_m.clas.abap)
+- Demo RAP scenario with an unmanaged RAP BO, external numbering: [zcl_demo_abap_rap_ext_num_u](./src/zcl_demo_abap_rap_ext_num_u.clas.abap)
+- Demo RAP scenario ("RAP calculator") with a managed, draft-enabled RAP BO, late numbering [zcl_demo_abap_rap_draft_ln_m](./src/zcl_demo_abap_rap_draft_ln_m.clas.abap)
+- Demonstrating the local consumption of [RAP business events](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_entity_event_glosry.htm) in the context of a RAP demo scenario (managed RAP BO with managed [internal numbering](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_int_numbering_glosry.htm) and [additional save](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_add_save_glosry.htm)): [zcl_demo_abap_rap_m_as](./src/zcl_demo_abap_rap_m_as.clas.abap)
+
+> **💡 Note**
+> - To reduce the complexity, the executable examples only focus on the technical side. ABAP classes play the role of a RAP BO consumer here.
+> - The examples do not represent real life scenarios and are not suitable as role models for proper RAP scenarios. They rather focus on the technical side by giving an idea how the communication and data exchange between a RAP BO consumer and RAP BO provider can work. Additionally, the examples show how the methods for non-standard RAP BO operations might be self-implemented in an ABAP behavior pool.
+> - Due to the simplification, the examples do not entirely meet all requirements of the [RAP BO contract](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenrap_bo_contract_glosry.htm) and do not represent semantic or best practice examples.
+> - You can check out the "RAP calculator" example using the preview version of an SAP Fiori Elements UI. See the comments in the class for more information.
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
diff --git a/13_Program_Flow_Logic.md b/13_Program_Flow_Logic.md
index b297a93..a58a79f 100644
--- a/13_Program_Flow_Logic.md
+++ b/13_Program_Flow_Logic.md
@@ -1,672 +1,725 @@
-
-
-# Program Flow Logic
-
-- [Program Flow Logic](#program-flow-logic)
- - [Introduction](#introduction)
- - [Expressions and Functions for Conditions](#expressions-and-functions-for-conditions)
- - [Control Structures](#control-structures)
- - [`IF` Statements](#if-statements)
- - [Excursion: `COND` Operator](#excursion-cond-operator)
- - [`CASE`: Case Distinctions](#case-case-distinctions)
- - [Excursion: `SWITCH` Operator](#excursion-switch-operator)
- - [Loops](#loops)
- - [`DO`: Unconditional Loops](#do-unconditional-loops)
- - [Interrupting and Exiting Loops](#interrupting-and-exiting-loops)
- - [`WHILE`: Conditional Loops](#while-conditional-loops)
- - [Loops Across Tables](#loops-across-tables)
- - [Calling Procedures](#calling-procedures)
- - [Handling Exceptions](#handling-exceptions)
- - [Notes on Exception Classes](#notes-on-exception-classes)
- - [Raising Exceptions](#raising-exceptions)
- - [Excursion: Runtime Errors and Terminating Programs](#excursion-runtime-errors-and-terminating-programs)
- - [Executable Example](#executable-example)
-
-
-This cheat sheet gathers information on program flow logic. Find more details
-[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_flow_logic.htm)
-in the ABAP Keyword Documentation.
-
-## Introduction
-
-In ABAP, the flow of a program is controlled by [control structures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencontrol_structure_glosry.htm), [procedure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm) calls and the raising or handling of [exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexception_glosry.htm).
-
-Using control structures as an example, you can determine the conditions for further processing of code, for example, if at all or how often a statement block should be executed. Control structures - as, for example, realized by an `IF ... ELSEIF ... ELSE ... ENDIF.` statement - can include multiple [statement blocks](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatement_block_glosry.htm) that are executed depending on conditions.
-
-In a very simple form, such an [`IF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapif.htm) statement might look as follows:
-
-```abap
-DATA(num) = 1 + 1.
-
-"A simple condition: Checking if the value of num is 2
-IF num = 2.
- ... "Statement block
- "Here goes some code that should be executed if the condition is true.
-ELSE.
- ... "Statement block
- "Here goes some code that should be executed if the condition is false.
- "For example, if num is 1, 8, 235, 0 etc., then do something else.
-ENDIF.
-```
-
-
-
-## Expressions and Functions for Conditions
-- So, such control structures are executed depending on conditions as specified above: `... num = 2 ...` - a [logical expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm).
-- Control structures are generally controlled by logical expressions that define conditions for [operands](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_glosry.htm).
-- The result of such an expression is either true or false.
-- Logical expressions are either single [relational expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrelational_expression_glosry.htm) or expressions combined from one or more logical expressions with Boolean operators like `NOT`, `AND` and `OR`.
-
-```abap
-"Single relational expression
-IF num = 1.
- ...
-ENDIF.
-
-"Multiple expressions
-IF num = 1 AND flag = 'X'.
- ...
-ENDIF.
-
-IF num = 1 OR flag = 'X'.
- ...
-ENDIF.
-
-"Multiple expressions can be parenthesized explicitly
-IF ( num = 1 AND flag = 'X' ) OR ( num = 2 AND flag = 'X' ).
- ...
-ENDIF.
-```
-
-- The components of such relational expressions can be [comparisons](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_glosry.htm) or [predicates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_glosry.htm). Note that for [comparison expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm),
-the comparisons are carried out according to [comparison rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules.htm).
-
-The following code snippet shows a selection of possible expressions and operands of such expressions using a big `IF` statement. Certainly, such a huge statement is far from ideal. Here, the intention is to just cover many syntax options in one go for demonstration purposes.
-
-```abap
-"Some declarations to be used in the IF statement below
-DATA(num) = 2. "integer
-DATA(empty_string) = ``. "empty string
-DATA(flag) = 'x'.
-DATA(dref) = NEW string( `ref` ). "data reference variable
-
-"Object reference variable
-DATA oref TYPE REF TO object.
-"Creating an object and assigning it to the reference variable
-oref = NEW zcl_demo_abap_prog_flow_logic( ).
-
-"Declaration of and assignment to a field symbol
-FIELD-SYMBOLS TYPE string.
-ASSIGN `hallo` TO .
-
-"Creating an internal table of type string inline
-DATA(str_table) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ).
-
-"The following IF statement includes multiple expressions combined by AND to demonstrate different options
-
-"Comparisons
-IF 2 = num "equal, alternative EQ
-AND 1 <> num "not equal, alternative NE
-AND 1 < num "less than, alternative LT
-AND 3 > num "greater than, alternative GT
-AND 2 >= num "greater equal, alternative GE
-AND 2 <= num "less equal, alternative LE
-
-"Checks whether the content of an operand is within a closed interval
-AND num BETWEEN 1 AND 3
-AND NOT num BETWEEN 5 AND 7 "NOT negates a logical expression
-AND ( num >= 1 AND num <= 3 ) "Equivalent to 'num BETWEEN 1 AND 3';
- "here, demonstrating the use of parentheses
-
-"Comparison operators CO, CN ,CA, NA, CS, NS, CP, NP for character-like data types;
-"see the cheat sheet on string processing
-
-"Predicate Expressions
-AND empty_string IS INITIAL "Checks whether the operand is initial. The expression
- "is true, if the operand contains its type-dependent initial value
-AND num IS NOT INITIAL "NOT negates
-
-AND dref IS BOUND "Checks whether a data reference variable contains a valid reference and
- "can be dereferenced;
- "Negation (IS NOT BOUND) is possible which is also valid for the following examples
-AND oref IS BOUND "Checks whether an object reference variable contains a valid reference
-
-"IS INSTANCE OF checks whether for a
-"a) non-initial object reference variable the dynamic type
-"b) for an initial object reference variable the static type
-"is more specific or equal to a comparison type.
-AND oref IS INSTANCE OF zcl_demo_abap_prog_flow_logic
-AND oref IS INSTANCE OF if_oo_adt_classrun
-
-AND IS ASSIGNED "Checks whether a memory area is assigned to a field symbol
-
-"See the predicate expression IS SUPPLIED in the executable example.
-"It is available in method implementations and checks whether a formal parameter
-"of a procedure is filled or requested.
-
-"Predicate function: Some examples
-AND contains( val = pcre = `\D` ) "Checks whether a certain value is contained;
- "the example uses the pcre parameter for regular expressions;
- "it checks whether there is any non-digit character contained
-AND matches( val = pcre = `ha.+` ) "Compares a search range of the argument for the val parameter;
- "the example uses the pcre parameter for regular expressions;
- "it checks whether the value matches the pattern 'ha'
- "and a sequence of any characters
-
-"Predicate functions for table-like arguments
-"Checks whether a line of an internal table specified in the table expression
-"exists and returns the corresponding truth value.
-AND line_exists( str_table[ 2 ] )
-
-"Predicative method call
-"The result of the relational expression is true if the result of the functional method call
-"is not initial and false if it is initial. The data type of the result of the functional method call,
-"i. e. the return value of the called function method, is arbitrary.
-"A check is made for the type-dependent initial value.
-AND check_is_supplied( )
-"It is basically the short form of such a predicate expression:
-AND check_is_supplied( ) IS NOT INITIAL
-
-"Boolean Functions
-"Determine the truth value of a logical expression specified as an argument;
-"the return value has a data type dependent on the function and expresses
-"the truth value of the logical expression with a value of this type.
-
-"Function boolc: Returns a single-character character string of the type string.
-"If the logical expression is true, X is returned. False: A blank is returned.
-"Not to be compared with the constants abap_true and abap_false in relational expressions,
-"since the latter convert from c to string and ignore any blanks. Note: If the logical
-"expression is false, the result of boolc does not meet the condition IS INITIAL since
-"a blank and no empty string is returned. If this is desired, the function xsdbool
-"can be used instead of boolc.
-AND boolc( check_is_supplied( ) ) = abap_true
-
-"Result has the same ABAP type as abap_bool.
-AND xsdbool( check_is_supplied( ) ) = abap_true
-
-"Examples for possible operands
-
-"Data objects as shown in the examples above
-AND 2 = 2
-AND num = 2
-
-"Built-in functions
-AND to_upper( flag ) = 'X'
-AND NOT to_lower( flag ) = 'X'
-
-"Numeric functions
-AND ipow( base = num exp = 2 ) = 4
-
-"Functional methods
-"Method with exactly one return value
-AND addition( num1 = 1 num2 = 1 ) = 2
-
-"Calculation expressions
-AND 4 - 3 + 1 = num
-
-"String expressions
-AND `ha` && `llo` =
-
-"Constructor expression
-AND CONV i( '2.03' ) = num
-AND VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ) = str_table
-
-"Table expression
-AND str_table[ 2 ] = `b`.
-
- "All of the logical expressions are true.
-
-ELSE.
-
- "At least one of the logical expressions is false.
-
-ENDIF.
-```
-
-> **💡 Note**
-> Logical expressions and functions can also be used in other ABAP statements.
-
-
-
-## Control Structures
-
-### `IF` Statements
-
-- As already shown above, `IF` statements define statement blocks that can be included in [branches](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbranch_glosry.htm).
-- The statement blocks are executed depending on conditions.
-- A maximum of one statement block is executed.
-- The check is carried out from top to bottom. The statement block after the first logical expression that is true is executed.
-- If none of the logical expressions are true, the statement block after the `ELSE` statement is executed.
-- `ELSE` and `ELSEIF` statements are optional. However, it is recommended that you specify an `ELSE` so that at least one statement block is executed.
-- If the end of the executed statement block is reached or if no statement block has been executed, the processing is continued after `ENDIF.`.
-
-
-```abap
-"IF statement with multiple included ELSEIF statements
-IF log_exp1.
-
- ... "statement_block1
-
-ELSEIF log_exp2.
-
- ... "statement_block2
-
-ELSEIF log_exp3.
-
- ... "statement_block3
-
-... "further ELSEIF statements
-
-ELSE.
-
- ... "statement_blockn
-
-ENDIF.
-```
-
-
-Control structures can be nested.
-```abap
-DATA(num) = 1.
-DATA(flag) = 'X'.
-
-IF num = 1.
-
- IF flag = 'X'.
- ...
- ELSE.
- ...
- ENDIF.
-
-ELSE.
-
- ... "statement block, e. g.
- "ASSERT 1 = 0.
- "Not to be executed in this example.
-
-ENDIF.
-```
-
-> **💡 Note**
-> - Control structures can be nested. It is recommended that you do not include more than 5 nested control structures since the code will
-> get really hard to understand. Better go for outsourcing functionality into methods to reduce nested control control structures.
-> - Keep the number of consecutive control structures low.
-> - If you are convinced that a specified logical expression must always be true, you might include a statement like `ASSERT 1 = 0.` to go
-> sure - as implied in the example's `ELSE` statement above. However, an `ELSE` statement that is never executed might be a hint that
-> logical expressions might partly be redundant.
-
-
-
-#### Excursion: `COND` Operator
-
-- The conditional operator [`COND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_cond.htm) can also be used to implement branches in operand positions that are based on logical expressions.
-- Such conditional expressions have a result that is dependent on the logical expressions.
-- The result's data type is specified after `COND` right before the first parenthesis. It can also be the `#` character as a symbol for the operand type if the type can be derived from the context. See the ABAP Keyword Documentation and the cheat sheet on constructor expressions for more information.
-- All operands specified after `THEN` must be convertible to the result's data type.
-
-```abap
-... COND type( WHEN log_exp1 THEN result1
- WHEN log_exp2 THEN result2
- ...
- ELSE resultn ) ...
-```
-
-
-
-### `CASE`: Case Distinctions
-
-- [`CASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase.htm) statements are used for case distinctions.
-- Such statements can also contain multiple statement blocks of which a maximum of one is executed depending on the value of the operand specified after `CASE`.
-- The check is carried out from top to bottom. If the content of an operand specified after `WHEN` matches the content specified after `CASE`, the statement block is executed. Constant values should be specified as operands.
-- The `WHEN` statement can include more than one operand using the syntax `WHEN op1 OR op2 OR op3 ...`.
-- If no matches are found, the statement block is executed after the statement `WHEN OTHERS.` which is optional.
-- If the end of the executed statement block is reached or no statement block is executed, the processing continues after `ENDCASE.`.
-
-
-```abap
-CASE operand.
- WHEN op1.
- ... "statement_block
- WHEN op2.
- ... "statement_block
- WHEN op3 OR op4.
- ... "statement_block
- WHEN OTHERS.
- ... "statement_block
-ENDCASE.
-```
-
-Special control structure introduced by [`CASE TYPE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase_type.htm): Checks the type of object reference variables.
-
-```abap
-"oref must be an object reference variable with the static type of a class or an interface.
-CASE TYPE OF oref.
- WHEN TYPE some_class.
- ... "statement_block
- WHEN TYPE some_intf.
- ... "statement_block
- WHEN OTHERS.
- ... "statement_block
-ENDCASE.
-```
-
-
-
-#### Excursion: `SWITCH` Operator
-
-The conditional operator [`SWITCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_switch.htm) can also be used to make case distinctions in operand positions. As mentioned above for `COND`, a result is constructed. The same criteria apply for `SWITCH` as for `COND` regarding the type. See the ABAP Keyword Documentation and the cheat sheet on constructor expressions for more information.
-
-
-```abap
-... SWITCH type( operand
- WHEN const1 THEN result1
- WHEN const2 THEN result2
- ...
- ELSE resultn ) ...
-```
-
-
-
-### Loops
-
-#### `DO`: Unconditional Loops
-
-- A statement block specified between `DO` and `ENDDO` is carried out multiple times.
-- The loop is exited when a statement to terminate the loop is reached (`EXIT`, see further down). Otherwise, it is executed endlessly.
-
- ```abap
- DO.
- ... "statement_block
- "To be terminated with an EXIT statement.
- ENDDO.
- ```
-- To restrict the loop passes, you can use the `TIMES` addition and specify the maximum number of loop passes.
-
- ```abap
- DO 5 TIMES.
- ... "statement_block
- ENDDO.
- ```
-- The value of the system field `sy-index` within the statement block contains the number of previous loop passes including the current pass.
-
-
-
-#### Interrupting and Exiting Loops
-
-The following ABAP keywords are available for interrupting and exiting loops:
-
-| Keyword | Syntax | Details |
-|---|---|---|
-| [`CONTINUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcontinue.htm) | `CONTINUE.` | The current loop pass is terminated immediately and the program flow is continued with the next loop pass. |
-| [`CHECK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcheck_loop.htm) | `CHECK log_exp.` | Conditional termination. If the logical expression `log_exp` is false, the current loop pass is terminated immediately and the program flow is continued with the next loop pass. |
-| [`EXIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapexit_loop.htm) | `EXIT.` | The loop is terminated completely. The program flow resumes after the closing statement of the loop. |
-
-> **💡 Note**
-> - [`RETURN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreturn.htm) statements immediately terminate the current processing block. However, according to the [guidelines (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexit_procedure_guidl.htm), `RETURN` should only be used to exit procedures like methods.
-> - `EXIT` and `CHECK` might also be used for exiting procedures. However, their use inside loops is recommended.
-
-
-
-#### `WHILE`: Conditional Loops
-
-- Conditional loops introduced by `WHILE` and ended by `ENDWHILE` are repeated as long as a logical expression is true.
-- These loops can also be exited using the statements mentioned above.
-- Like in `DO` loops, the system field `sy-index` contains the number of previous loop passes including the current pass.
-
-```abap
-WHILE log_exp.
- ... "statement_block
-ENDWHILE.
-```
-
-
-
-#### Loops Across Tables
-Further keywords for defining loops are as follows. They are not dealt with here since they are covered in other ABAP cheat sheets.
-
-- [`LOOP ... ENDLOOP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab.htm) statements are meant for loops across internal tables. See also the cheat sheet on internal tables.
- - In contrast to the loops above, the system field `sy-index` is not set. Instead, the system field `sy-tabix` is set and which contains the table index of the current table line in the loop pass.
- - You can also realize loops using iteration expressions with `VALUE` and `REDUCE`. For more information, refer to the [Constructor Expressions](05_Constructor_Expressions.md) cheat sheet.
-- [`SELECT ... ENDSELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm) statements loop across the result set of a database access. See also the cheat sheet on ABAP SQL.
-
-
-
-## Calling Procedures
-
-Calling [procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm) would actually fit here in the context of dealing with program flow logic since they can be called explicitly in an [ABAP program](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm).
-However, ...
-1. in modern ABAP programs, only methods should be implemented (instead of [function modules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunction_module_glosry.htm) and [subroutines](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubroutine_glosry.htm) in most cases) and
-2. methods are described in the context of the ABAP cheat sheet on ABAP object orientation. Hence, see more details there.
-
-Regarding the exiting of procedures, note the hint mentioned above. The use of `RETURN` is recommended.
-
-
-
-## Handling Exceptions
-- [Exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexception_glosry.htm) ...
- - are events during the execution of an ABAP program that interrupt the program flow because it is not possible for the program to continue in a meaningful way. For such situations, you can implement an exception handling in which you can react on the situations appropriately. Consider, for example, the implementation of a simple calculation. If there is a division by zero, the program will be terminated with a [runtime error](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenruntime_error_glosry.htm) unless you handle the exception appropriately.
- - can be raised either by the program or by the [ABAP runtime framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm). Exceptions raised by the latter are generally caused by error situations that cannot be detected by the static program check. The division by zero is such an example.
- - should, in modern ABAP, only be designed as [class-based exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_based_exception_glosry.htm), i. e. exceptions are represented by [objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_glosry.htm) of classes. Global exception classes usually use the naming convention `CX_...`.
- - are either [catchable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencatchable_exception_glosry.htm) (they are based on predefined or self-defined exception classes) or [uncatchable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuncatchable_exception_glosry.htm) (they directly produce runtime errors, i. e. error situations cannot be handled appropriately).
-
-`TRY` control structures are meant for handling catchable exceptions locally:
-- To be prepared for potential exceptions that are raised when executing statements, the statements can be included and executed within a *protected area*, a [`TRY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptry.htm) control structure.
-- In doing so, it is possible for the ABAP runtime framework to catch exceptions and react on error situations.
-
- ```abap
- TRY.
- "statement block
- ENDTRY.
- ```
-
-- The `TRY` control structure in the snippet above produces a syntax warning. A [`CATCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcatch_try.htm) block is expected, too.
-- One or more class-based exceptions can be handled in one or more subsequent `CATCH` blocks. The `CATCH` statement must include an "appropriate" class-based exception. "Appropriate" means that, certainly, an exception class should be specified that is suitable for the error handling. In the following example, the predefined exception class `CX_SY_ZERODIVIDE` is specified that is, as the name implies, specific for the (potential) exception in case of a division by zero.
-
- ```abap
- TRY.
- "TRY block
- DATA(div1) = 1 / 0.
-
- "Predefined exception class cx_sy_zerodivide as suitable exception class to be used here.
- "If the exception is not handled, the program is terminated and the runtime error
- "COMPUTE_INT_ZERODIVIDE occurs.
- CATCH cx_sy_zerodivide.
- ... "CATCH block
- ENDTRY.
-
- "Example for catching an exception in the context of a table expression
- TRY.
- "Copying a line of an internal table
- DATA(line) = some_itab[ 12345 ].
-
- "Predefined exception class cx_sy_itab_line_not_found as suitable exception class to be used here.
- "If the exception is not handled, the program is terminated and the runtime error
- "ITAB_LINE_NOT_FOUND occurs.
- CATCH cx_sy_itab_line_not_found.
- ... "CATCH block
- ENDTRY.
-
- "Note on inheritance relationships in exception classes
- TRY.
- "TRY block
- DATA(div2) = 1 / 0.
-
- "A CATCH block is in this example not only valid for cx_sy_zerodivide as specified above
- "but also for all derived exceptions classes.
- "In the following CATCH block, the predefined exception class cx_sy_arithmetic_error
- "is specified. cx_sy_zerodivide is derived from cx_sy_arithmetic_error.
- "Hence, cx_sy_arithmetic_error can be specified and handle the exception, too.
- "Basically, using the exception root class cx_root would be also possible. However,
- "choosing an appropriate exception class is recommended. See further down.
-
- CATCH cx_sy_arithmetic_error.
- ... "CATCH block
- ENDTRY.
-
-
- "Multiple classes in a list and CATCH blocks can be specified
- "Note: If there are multiple CATCH blocks for exceptions that are in an inheritance
- "relationship, you must pay attention that the more special exceptions are specified
- "before the more general ones.
- TRY.
- ... "TRY block
- CATCH cx_abc cx_bla cx_blabla.
- ... "CATCH block
- CATCH cx_la cx_lala.
- ... "CATCH block
- CATCH cx_lalala.
- ... "CATCH block
- ENDTRY.
- ```
-
-- If the addition `INTO` is specified in the `CATCH` statement, a reference to the exception object is stored.
-- This is relevant to determine the exact exception, for example. In the code snippet above, the exception class `CX_SY_ZERODIVIDE` is mentioned. Consider a calculator. It should not only be able to deal with error situations like zero division but also, for example, overflows in arithmetic operations. The predefined exception class `CX_SY_ARITHMETIC_OVERFLOW` is available. It is also derived from `CX_SY_ARITHMETIC_ERROR`. If you then specify the exception class `CX_SY_ARITHMETIC_ERROR` which is higher up in the inheritance hierarchy and can handle both error situations (`CX_SY_ARITHMETIC_OVERFLOW` and `CX_SY_ZERODIVIDE`), the concrete exception that was raised is unclear. Using the `INTO` clause and the stored exception object, it is possible to carry out certain tasks, for example, retrieving and displaying the exception text.
-
- ```abap
- DATA: exception TYPE REF TO cx_root. "Note the root class
- "Note: For a self-defined exception class, the object reference must be typed appropriately.
-
- TRY.
- ... "TRY block
-
- "Storing a reference to the exception object.
- "Note: The type is cx_root since attributes and methods of the root class that are defined there can be accessed.
- CATCH INTO exception.
- ... "CATCH block
- ENDTRY.
-
- "Inline creation of exception object reference and getting exception texts
- TRY.
- ... "TRY block
-
- "The object reference variable can be created inline, for example, using DATA(...).
- CATCH cx_sy_arithmetic_error INTO DATA(error_oref).
- ... "catch block
- "To get exception texts, you can call, for example, the method get_text
- DATA(error_text) = error_oref->get_text( ).
-
- ENDTRY.
- ```
-
-- Regarding the program flow:
- - The statement block following `TRY.` is always processed. If an exception is raised within this `TRY` block, the system searches for an exception handler, i. e. a `CATCH` block that is able to handle the exception.
- - If there is no `CATCH` statement that is able to handle the catchable exception or if erroneous code is not within a `TRY` control structure at all, the exception is propagated to the caller.
- - Exceptions can be handled either in the context locally (using such a `TRY` control structure) or be propagated to the caller so that the caller is responsible for reacting appropriately (for example, in another `TRY` control structure) to the error situation. In doing so, you can better structure your code by reacting on error situations centrally instead of locally checking, for example, each procedure call individually.
- - If, at the end, the exception can nowhere be caught and handled, the program is terminated with a runtime error.
- - If the exception can be handled or no exception is raised in the `TRY` block and it reaches its end, the processing continues after `ENDTRY`.
-
-
-> **💡 Note**
-> - Non-class-based exceptions are considered obsolete and should not be defined any more in new developments according to the [guidelines (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclass_exception_guidl.htm) and are not dealt with here.
->- For all exceptions that are raised by the ABAP runtime environment and that are not handled, there is a corresponding runtime error. For example, in the case of exception class `CX_SY_ZERODIVIDE`, it is the runtime error `COMPUTE_INT_ZERODIVIDE`. For self-defined exception classes, an exception that is not handled generally triggers the runtime error `UNCAUGHT_EXCEPTION`.
-> - For `TRY` control structures, there are further additions available dealing with more advanced error handling, e. g. [resumable exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapresume.htm).
-
-
-
-#### Notes on Exception Classes
-- To distinguish exception classes from *regular* classes, use the naming convention `CX` as prefix and not `CL`.
-- All exception classes (also the self-defined ones) are directly or indirectly derived from three abstract subclasses: `CX_STATIC_CHECK`, `CX_DYNAMIC_CHECK` and `CX_NO_CHECK`. These three "exception class categories" have different properties.
-- The class `CX_ROOT` is the root class. Directly deriving from `CX_ROOT` is not possible.
-- Apart from global classes, exception classes can also be defined as local classes within an ABAP program.
-- As mentioned, there are predefined exception classes like `CX_SY_ZERODIVIDE` for divisions by zero. However, you can create your own exception classes so that you can react on issues that are specific to your ABAP program. The exception class must, as stated above, be derived from one of the three abstract classes:
- - `CX_STATIC_CHECK`: For forcing users to handle exceptions.
- Generally speaking, exceptions that can occur in procedures should be handled locally there in the implementation or be declared explicitly in the [procedure interface](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenparameter_interface_glosry.htm) so that a caller knows which error situations can be expected. Exception classes of type `CX_STATIC_CHECK` enforce this. A check is carried out statically at compile time. Users of a procedure are then forced to either handle the exception locally in a `TRY` control structure or the users declare the exception themselves in their procedure interface to propagate the exception to their users. If this is not the case, a warning is produced.
- - As an example, a method signature might look as follows. The addition `RAISING` in method signatures is used to declare one or more class-based exceptions that can be propagated from the method to the caller.
- - When users of this method implement the method, they are made aware of the fact that an error situation can occur and a particular exception can be raised. The assumption is that `CX_SOME_ERROR` is derived from `CX_STATIC_CHECK`. Users of the method should then prepare the code accordingly.
- ```abap
- "Method definition using the RAISING parameter
- CLASS-METHODS: some_meth IMPORTING str TYPE string
- RETURNING VALUE(ret_value) TYPE string
- RAISING cx_some_error.
-
- ...
-
- "Method call: Somewhere in the code of a user that calls the method
- "Exception handled locally in a TRY control structure.
- TRY.
- DATA(val) = some_meth( str = `hallo` ).
-
- CATCH cx_some_error.
- ...
- ENDTRY.
-
- "If it was just like this without the TRY control structure, a warning would be produced.
- DATA(val2) = some_meth( str = `hi` ).
- ```
-
- - `CX_DYNAMIC_CHECK`: For exceptions that can be checked and avoided by preconditions. As a consequence and in contrast to an exception class derived from `CX_STATIC_CHECK`, exception classes of type `CX_DYNAMIC_CHECK` do not enforce the local handling and the declaration in procedure interfaces. However, an appropriate exception handling should be implemented in cases in which you cannot rule out the raising of the exceptions in your program logic. The checking if a local handling or an explicit declaration in procedure interfaces is available is carried out at runtime only ("dynamic check") and only in case the exception is indeed raised.
- - If it is determined at runtime that such an exception is neither locally handled nor an interface is declared appropriately - and the exception is raised - a new exception of type `CX_SY_NO_HANDLER` is raised. In this case, the attribute `PREVIOUS` contains a reference to the original exception.
- - Example: The predefined class `CX_SY_ZERODIVIDE` is derived from `CX_DYNAMIC_CHECK`. The operands of a calculation can be checked appropriately (e. g. in case of a division, the implementation should guarantee that the second operand is not 0) before carrying out the arithmetic operation. In doing so, the exception can be avoided.
-
- - `CX_NO_CHECK`: For error situations that can basically occur any time, cannot be locally handled in a meaningful way or cannot be avoided even following a check. An example for such an error situation might be a lack of memory. If the handling of such exceptions was checked statically or dynamically, it would basically mean to specify it in each procedure interface - not ideal for a clear program structuring.
- - Note that exceptions derived from `CX_NO_CHECK` are always declared implicitly in all procedure interfaces.
-
-**Basic rule**: [Use a suitable exception category (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_category_guidl.htm).
-
-> **💡 Note**
-> - Each exception has a an [exception text](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_text_glosry.htm) that describes the error situation and that you can retrieve as outlined above. It helps you analyze the error. Plus, imagine using exceptions in the context of user interfaces. If a user faces an error situation, such exception texts may be displayed on the UI.
-> - Find more information on exception texts [here](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_texts.htm) in the ABAP Keyword Documentation.
-
-
-
-### Raising Exceptions
-
-- Either the ABAP runtime framework raises predefined exceptions or you raise exceptions programmatically using dedicated statements. You can raise both predefined and self-defined exceptions.
-- As the name implies, [`RAISE EXCEPTION`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_exception_class.htm) statements raise class-based exceptions and thus interrupt the execution of the current statement block.
-- The `COND` operator includes the optional addition `THROW` to raise class-based exceptions.
-
-```abap
-...
-"RAISE EXCEPTION statement
-"The TYPE addition specifies the type of the exception, i. e. the exception class.
-"The statement is also possible without TYPE. In that case, you can use an existing exception object.
-"Note that there are plenty of additions. Check the ABAP Keyword Documentation.
-RAISE EXCEPTION TYPE cx_sy_zerodivide.
-...
-
-"THROW addition for the COND operator
-... = COND #( WHEN ... THEN ...
- WHEN ... THEN ...
- ELSE THROW cx_some_error( ) ).
-```
-
-
-
-## Excursion: Runtime Errors and Terminating Programs
-- Runtime errors are caused by uncatchable exceptions when a program is executed, when a catchable exception is not caught, or they can be forced by, for example, using [`ASSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapassert.htm) statements.
-- Every runtime error terminates the program, which in turn raises a [database rollback](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_rollback_glosry.htm) and is documented by default in a [short dump](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshort_dump_glosry.htm).
-
-- Regarding `ASSERT` statements: `ASSERT` is followed by a logical expression. If the expression is false, the program is terminated and an uncatchable exception is raised resulting in the runtime error `ASSERTION_FAILED`. Note that each runtime error is identified by a name and assigned to a specific error situation.
-
-```abap
-"The ASSERT keyword is followed by a logical expression.
-"If the expression is false, the program is terminated and an uncatchable exception is raised
-"resulting in the runtime error ASSERTION_FAILED.
-
-DATA(flag) = abap_false.
-
-ASSERT flag = abap_true.
-```
-
-> **💡 Note**
-> - Each runtime error is identified by a name and assigned to a specific error situation.
-> - In ADT, you will see a message popping up and informing you about the runtime error. You can check the details by choosing the "Show" button in the pop-up. Furthermore, you can check the content of the "Feed Reader" tab in ADT. There, just expand your project and find the runtime errors caused by you.
-
-
-
-## Executable Example
-
-[zcl_demo_abap_prog_flow_logic](./src/zcl_demo_abap_prog_flow_logic.clas.abap)
-
-> **💡 Note**
-> - The executable example ...
-> - covers the following topics, among others:
-> - Control structures with `IF`, `CASE`, and `TRY`
-> - Excursions: `COND` and `SWITCH` operators
-> - Expressions and functions for conditions
-> - Predicate expression with `IS SUPPLIED`
-> - Loops with `DO`, `WHILE`, and `LOOP`
-> - Terminating loop passes
-> - Handling exceptions
-> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
+
+
+# Program Flow Logic
+
+- [Program Flow Logic](#program-flow-logic)
+ - [Introduction](#introduction)
+ - [Expressions and Functions for Conditions](#expressions-and-functions-for-conditions)
+ - [Control Structures](#control-structures)
+ - [`IF` Statements](#if-statements)
+ - [Excursion: `COND` Operator](#excursion-cond-operator)
+ - [`CASE`: Case Distinctions](#case-case-distinctions)
+ - [Excursion: `SWITCH` Operator](#excursion-switch-operator)
+ - [Loops](#loops)
+ - [`DO`: Unconditional Loops](#do-unconditional-loops)
+ - [Interrupting and Exiting Loops](#interrupting-and-exiting-loops)
+ - [`WHILE`: Conditional Loops](#while-conditional-loops)
+ - [Loops Across Tables](#loops-across-tables)
+ - [Calling Procedures](#calling-procedures)
+ - [Excursion: RETURN](#excursion-return)
+ - [Handling Exceptions](#handling-exceptions)
+ - [Notes on Exception Classes](#notes-on-exception-classes)
+ - [Raising Exceptions](#raising-exceptions)
+ - [Excursion: Runtime Errors and Terminating Programs](#excursion-runtime-errors-and-terminating-programs)
+ - [Executable Example](#executable-example)
+
+
+This cheat sheet gathers information on program flow logic. Find more details
+[here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_flow_logic.htm)
+in the ABAP Keyword Documentation.
+
+## Introduction
+
+In ABAP, the flow of a program is controlled by [control structures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencontrol_structure_glosry.htm), [procedure](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm) calls and the raising or handling of [exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexception_glosry.htm).
+
+Using control structures as an example, you can determine the conditions for further processing of code, for example, if at all or how often a statement block should be executed. Control structures - as, for example, realized by an `IF ... ELSEIF ... ELSE ... ENDIF.` statement - can include multiple [statement blocks](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstatement_block_glosry.htm) that are executed depending on conditions.
+
+In a very simple form, such an [`IF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapif.htm) statement might look as follows:
+
+```abap
+DATA(num) = 1 + 1.
+
+"A simple condition: Checking if the value of num is 2
+IF num = 2.
+ ... "Statement block
+ "Here goes some code that should be executed if the condition is true.
+ELSE.
+ ... "Statement block
+ "Here goes some code that should be executed if the condition is false.
+ "For example, if num is 1, 8, 235, 0 etc., then do something else.
+ENDIF.
+```
+
+
+
+## Expressions and Functions for Conditions
+- So, such control structures are executed depending on conditions as specified above: `... num = 2 ...` - a [logical expression](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogical_expression_glosry.htm).
+- Control structures are generally controlled by logical expressions that define conditions for [operands](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_glosry.htm).
+- The result of such an expression is either true or false.
+- Logical expressions are either single [relational expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrelational_expression_glosry.htm) or expressions combined from one or more logical expressions with Boolean operators like `NOT`, `AND` and `OR`.
+
+```abap
+"Single relational expression
+IF num = 1.
+ ...
+ENDIF.
+
+"Multiple expressions
+IF num = 1 AND flag = 'X'.
+ ...
+ENDIF.
+
+IF num = 1 OR flag = 'X'.
+ ...
+ENDIF.
+
+"Multiple expressions can be parenthesized explicitly
+IF ( num = 1 AND flag = 'X' ) OR ( num = 2 AND flag = 'X' ).
+ ...
+ENDIF.
+```
+
+- The components of such relational expressions can be [comparisons](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_glosry.htm) or [predicates](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpredicate_glosry.htm). Note that for [comparison expressions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomparison_expression_glosry.htm),
+the comparisons are carried out according to [comparison rules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlogexp_rules.htm).
+
+The following code snippet shows a selection of possible expressions and operands of such expressions using a big `IF` statement. Certainly, such a huge statement is far from ideal. Here, the intention is to just cover many syntax options in one go for demonstration purposes.
+
+```abap
+"Some declarations to be used in the IF statement below
+DATA(num) = 2. "integer
+DATA(empty_string) = ``. "empty string
+DATA(flag) = 'x'.
+DATA(dref) = NEW string( `ref` ). "data reference variable
+
+"Object reference variable
+DATA oref TYPE REF TO object.
+"Creating an object and assigning it to the reference variable
+oref = NEW zcl_demo_abap_prog_flow_logic( ).
+
+"Declaration of and assignment to a field symbol
+FIELD-SYMBOLS TYPE string.
+ASSIGN `hallo` TO .
+
+"Creating an internal table of type string inline
+DATA(str_table) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ).
+
+"The following IF statement includes multiple expressions combined by AND to demonstrate different options
+
+"Comparisons
+IF 2 = num "equal, alternative EQ
+AND 1 <> num "not equal, alternative NE
+AND 1 < num "less than, alternative LT
+AND 3 > num "greater than, alternative GT
+AND 2 >= num "greater equal, alternative GE
+AND 2 <= num "less equal, alternative LE
+
+"Checks whether the content of an operand is within a closed interval
+AND num BETWEEN 1 AND 3
+AND NOT num BETWEEN 5 AND 7 "NOT negates a logical expression
+AND ( num >= 1 AND num <= 3 ) "Equivalent to 'num BETWEEN 1 AND 3';
+ "here, demonstrating the use of parentheses
+
+"Comparison operators CO, CN ,CA, NA, CS, NS, CP, NP for character-like data types;
+"see the cheat sheet on string processing
+
+"Predicate Expressions
+AND empty_string IS INITIAL "Checks whether the operand is initial. The expression
+ "is true, if the operand contains its type-dependent initial value
+AND num IS NOT INITIAL "NOT negates
+
+AND dref IS BOUND "Checks whether a data reference variable contains a valid reference and
+ "can be dereferenced;
+ "Negation (IS NOT BOUND) is possible which is also valid for the following examples
+AND oref IS BOUND "Checks whether an object reference variable contains a valid reference
+
+"IS INSTANCE OF checks whether for a
+"a) non-initial object reference variable the dynamic type
+"b) for an initial object reference variable the static type
+"is more specific or equal to a comparison type.
+AND oref IS INSTANCE OF zcl_demo_abap_prog_flow_logic
+AND oref IS INSTANCE OF if_oo_adt_classrun
+
+AND IS ASSIGNED "Checks whether a memory area is assigned to a field symbol
+
+"See the predicate expression IS SUPPLIED in the executable example.
+"It is available in method implementations and checks whether a formal parameter
+"of a procedure is filled or requested.
+
+"Predicate function: Some examples
+AND contains( val = pcre = `\D` ) "Checks whether a certain value is contained;
+ "the example uses the pcre parameter for regular expressions;
+ "it checks whether there is any non-digit character contained
+AND matches( val = pcre = `ha.+` ) "Compares a search range of the argument for the val parameter;
+ "the example uses the pcre parameter for regular expressions;
+ "it checks whether the value matches the pattern 'ha'
+ "and a sequence of any characters
+
+"Predicate functions for table-like arguments
+"Checks whether a line of an internal table specified in the table expression
+"exists and returns the corresponding truth value.
+AND line_exists( str_table[ 2 ] )
+
+"Predicative method call
+"The result of the relational expression is true if the result of the functional method call
+"is not initial and false if it is initial. The data type of the result of the functional method call,
+"i. e. the return value of the called function method, is arbitrary.
+"A check is made for the type-dependent initial value.
+AND check_is_supplied( )
+"It is basically the short form of such a predicate expression:
+AND check_is_supplied( ) IS NOT INITIAL
+
+"Boolean Functions
+"Determine the truth value of a logical expression specified as an argument;
+"the return value has a data type dependent on the function and expresses
+"the truth value of the logical expression with a value of this type.
+
+"Function boolc: Returns a single-character character string of the type string.
+"If the logical expression is true, X is returned. False: A blank is returned.
+"Not to be compared with the constants abap_true and abap_false in relational expressions,
+"since the latter convert from c to string and ignore any blanks. Note: If the logical
+"expression is false, the result of boolc does not meet the condition IS INITIAL since
+"a blank and no empty string is returned. If this is desired, the function xsdbool
+"can be used instead of boolc.
+AND boolc( check_is_supplied( ) ) = abap_true
+
+"Result has the same ABAP type as abap_bool.
+AND xsdbool( check_is_supplied( ) ) = abap_true
+
+"Examples for possible operands
+
+"Data objects as shown in the examples above
+AND 2 = 2
+AND num = 2
+
+"Built-in functions
+AND to_upper( flag ) = 'X'
+AND NOT to_lower( flag ) = 'X'
+
+"Numeric functions
+AND ipow( base = num exp = 2 ) = 4
+
+"Functional methods
+"Method with exactly one return value
+AND addition( num1 = 1 num2 = 1 ) = 2
+
+"Calculation expressions
+AND 4 - 3 + 1 = num
+
+"String expressions
+AND `ha` && `llo` =
+
+"Constructor expression
+AND CONV i( '2.03' ) = num
+AND VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ) = str_table
+
+"Table expression
+AND str_table[ 2 ] = `b`.
+
+ "All of the logical expressions are true.
+
+ELSE.
+
+ "At least one of the logical expressions is false.
+
+ENDIF.
+```
+
+> **💡 Note**
+> Logical expressions and functions can also be used in other ABAP statements.
+
+
+
+## Control Structures
+
+### `IF` Statements
+
+- As already shown above, `IF` statements define statement blocks that can be included in [branches](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbranch_glosry.htm).
+- The statement blocks are executed depending on conditions.
+- A maximum of one statement block is executed.
+- The check is carried out from top to bottom. The statement block after the first logical expression that is true is executed.
+- If none of the logical expressions are true, the statement block after the `ELSE` statement is executed.
+- `ELSE` and `ELSEIF` statements are optional. However, it is recommended that you specify an `ELSE` so that at least one statement block is executed.
+- If the end of the executed statement block is reached or if no statement block has been executed, the processing is continued after `ENDIF.`.
+
+
+```abap
+"IF statement with multiple included ELSEIF statements
+IF log_exp1.
+
+ ... "statement_block1
+
+ELSEIF log_exp2.
+
+ ... "statement_block2
+
+ELSEIF log_exp3.
+
+ ... "statement_block3
+
+... "further ELSEIF statements
+
+ELSE.
+
+ ... "statement_blockn
+
+ENDIF.
+```
+
+
+Control structures can be nested.
+```abap
+DATA(num) = 1.
+DATA(flag) = 'X'.
+
+IF num = 1.
+
+ IF flag = 'X'.
+ ...
+ ELSE.
+ ...
+ ENDIF.
+
+ELSE.
+
+ ... "statement block, e. g.
+ "ASSERT 1 = 0.
+ "Not to be executed in this example.
+
+ENDIF.
+```
+
+> **💡 Note**
+> - Control structures can be nested. It is recommended that you do not include more than 5 nested control structures since the code will
+> get really hard to understand. Better go for outsourcing functionality into methods to reduce nested control control structures.
+> - Keep the number of consecutive control structures low.
+> - If you are convinced that a specified logical expression must always be true, you might include a statement like `ASSERT 1 = 0.` to go
+> sure - as implied in the example's `ELSE` statement above. However, an `ELSE` statement that is never executed might be a hint that
+> logical expressions might partly be redundant.
+
+
+
+#### Excursion: `COND` Operator
+
+- The conditional operator [`COND`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_cond.htm) can also be used to implement branches in operand positions that are based on logical expressions.
+- Such conditional expressions have a result that is dependent on the logical expressions.
+- The result's data type is specified after `COND` right before the first parenthesis. It can also be the `#` character as a symbol for the operand type if the type can be derived from the context. See the ABAP Keyword Documentation and the cheat sheet on constructor expressions for more information.
+- All operands specified after `THEN` must be convertible to the result's data type.
+
+```abap
+... COND type( WHEN log_exp1 THEN result1
+ WHEN log_exp2 THEN result2
+ ...
+ ELSE resultn ) ...
+```
+
+
+
+### `CASE`: Case Distinctions
+
+- [`CASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase.htm) statements are used for case distinctions.
+- Such statements can also contain multiple statement blocks of which a maximum of one is executed depending on the value of the operand specified after `CASE`.
+- The check is carried out from top to bottom. If the content of an operand specified after `WHEN` matches the content specified after `CASE`, the statement block is executed. Constant values should be specified as operands.
+- The `WHEN` statement can include more than one operand using the syntax `WHEN op1 OR op2 OR op3 ...`.
+- If no matches are found, the statement block is executed after the statement `WHEN OTHERS.` which is optional.
+- If the end of the executed statement block is reached or no statement block is executed, the processing continues after `ENDCASE.`.
+
+
+```abap
+CASE operand.
+ WHEN op1.
+ ... "statement_block
+ WHEN op2.
+ ... "statement_block
+ WHEN op3 OR op4.
+ ... "statement_block
+ WHEN OTHERS.
+ ... "statement_block
+ENDCASE.
+```
+
+Special control structure introduced by [`CASE TYPE OF`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcase_type.htm): Checks the type of object reference variables.
+
+```abap
+"oref must be an object reference variable with the static type of a class or an interface.
+CASE TYPE OF oref.
+ WHEN TYPE some_class.
+ ... "statement_block
+ WHEN TYPE some_intf.
+ ... "statement_block
+ WHEN OTHERS.
+ ... "statement_block
+ENDCASE.
+```
+
+
+
+#### Excursion: `SWITCH` Operator
+
+The conditional operator [`SWITCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_switch.htm) can also be used to make case distinctions in operand positions. As mentioned above for `COND`, a result is constructed. The same criteria apply for `SWITCH` as for `COND` regarding the type. See the ABAP Keyword Documentation and the cheat sheet on constructor expressions for more information.
+
+
+```abap
+... SWITCH type( operand
+ WHEN const1 THEN result1
+ WHEN const2 THEN result2
+ ...
+ ELSE resultn ) ...
+```
+
+
+
+### Loops
+
+#### `DO`: Unconditional Loops
+
+- A statement block specified between `DO` and `ENDDO` is carried out multiple times.
+- The loop is exited when a statement to terminate the loop is reached (`EXIT`, see further down). Otherwise, it is executed endlessly.
+
+ ```abap
+ DO.
+ ... "statement_block
+ "To be terminated with an EXIT statement.
+ ENDDO.
+ ```
+- To restrict the loop passes, you can use the `TIMES` addition and specify the maximum number of loop passes.
+
+ ```abap
+ DO 5 TIMES.
+ ... "statement_block
+ ENDDO.
+ ```
+- The value of the system field `sy-index` within the statement block contains the number of previous loop passes including the current pass.
+
+
+
+#### Interrupting and Exiting Loops
+
+The following ABAP keywords are available for interrupting and exiting loops:
+
+| Keyword | Syntax | Details |
+|---|---|---|
+| [`CONTINUE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcontinue.htm) | `CONTINUE.` | The current loop pass is terminated immediately and the program flow is continued with the next loop pass. |
+| [`CHECK`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcheck_loop.htm) | `CHECK log_exp.` | Conditional termination. If the logical expression `log_exp` is false, the current loop pass is terminated immediately and the program flow is continued with the next loop pass. |
+| [`EXIT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapexit_loop.htm) | `EXIT.` | The loop is terminated completely. The program flow resumes after the closing statement of the loop. |
+
+> **💡 Note**
+> - [`RETURN`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapreturn.htm) statements immediately terminate the current processing block. However, according to the [guidelines (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexit_procedure_guidl.htm), `RETURN` should only be used to exit procedures like methods.
+> - `EXIT` and `CHECK` might also be used for exiting procedures. However, their use inside loops is recommended.
+
+
+
+#### `WHILE`: Conditional Loops
+
+- Conditional loops introduced by `WHILE` and ended by `ENDWHILE` are repeated as long as a logical expression is true.
+- These loops can also be exited using the statements mentioned above.
+- Like in `DO` loops, the system field `sy-index` contains the number of previous loop passes including the current pass.
+
+```abap
+WHILE log_exp.
+ ... "statement_block
+ENDWHILE.
+```
+
+
+
+#### Loops Across Tables
+Further keywords for defining loops are as follows. They are not dealt with here since they are covered in other ABAP cheat sheets.
+
+- [`LOOP ... ENDLOOP`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaploop_at_itab.htm) statements are meant for loops across internal tables. See also the cheat sheet on internal tables.
+ - In contrast to the loops above, the system field `sy-index` is not set. Instead, the system field `sy-tabix` is set and which contains the table index of the current table line in the loop pass.
+ - You can also realize loops using iteration expressions with `VALUE` and `REDUCE`. For more information, refer to the [Constructor Expressions](05_Constructor_Expressions.md) cheat sheet.
+- [`SELECT ... ENDSELECT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapselect.htm) statements loop across the result set of a database access. See also the cheat sheet on ABAP SQL.
+
+
+
+## Calling Procedures
+
+Calling [procedures](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprocedure_glosry.htm) would actually fit here in the context of dealing with program flow logic since they can be called explicitly in an [ABAP program](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm).
+However, ...
+1. in modern ABAP programs, only methods should be implemented (instead of [function modules](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfunction_module_glosry.htm) and [subroutines](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubroutine_glosry.htm) in most cases) and
+2. methods are described in the context of the ABAP cheat sheet on ABAP object orientation. Hence, see more details there.
+
+Regarding the exiting of procedures, note the hint mentioned above. The use of `RETURN` is recommended.
+
+
+
+### Excursion: RETURN
+
+As mentioned, `RETURN` terminates the current processing block. Usually, the statement is intended for leaving processing blocks early.
+In case of functional method, i.e. methods that have one returning parameter, the `RETURN` statement can also be specified with an expression. In doing so, the
+following statement
+```abap
+res = some_expr.
+RETURN.
+```
+can also be specified as follows:
+```abap
+RETURN some_expr.
+```
+Here, the expression result is passed to the returning parameter without naming it explicitly. As an expression, you can specify a constructor expression (and using type inference with `#` means using the type of the returning parameter).
+
+Example:
+```abap
+CLASS zcl_some_class DEFINITION
+ PUBLIC
+ FINAL
+ CREATE PUBLIC.
+ PUBLIC SECTION.
+ INTERFACES: if_oo_adt_classrun.
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+ CLASS-METHODS multiply
+ IMPORTING num1 TYPE i
+ num2 TYPE i
+ RETURNING VALUE(result) TYPE i.
+ENDCLASS.
+CLASS zcl_some_class IMPLEMENTATION.
+ METHOD if_oo_adt_classrun~main.
+ DATA(res1) = multiply( num1 = 2 num2 = 3 ).
+ DATA(res2) = multiply( num1 = 10 num2 = 10 ).
+ DATA(res3) = multiply( num1 = 99999999 num2 = 99999999 ).
+ out->write( res1 ). "6
+ out->write( res2 ). "100
+ out->write( res3 ). "0
+ ENDMETHOD.
+ METHOD multiply.
+ TRY.
+ "result = num1 * num2.
+ RETURN num1 * num2.
+ CATCH cx_sy_arithmetic_error.
+ RETURN VALUE #( ).
+ ENDTRY.
+ ENDMETHOD.
+ENDCLASS.
+```
+
+
+
+## Handling Exceptions
+- [Exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenexception_glosry.htm) ...
+ - are events during the execution of an ABAP program that interrupt the program flow because it is not possible for the program to continue in a meaningful way. For such situations, you can implement an exception handling in which you can react on the situations appropriately. Consider, for example, the implementation of a simple calculation. If there is a division by zero, the program will be terminated with a [runtime error](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenruntime_error_glosry.htm) unless you handle the exception appropriately.
+ - can be raised either by the program or by the [ABAP runtime framework](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_runtime_frmwk_glosry.htm). Exceptions raised by the latter are generally caused by error situations that cannot be detected by the static program check. The division by zero is such an example.
+ - should, in modern ABAP, only be designed as [class-based exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclass_based_exception_glosry.htm), i. e. exceptions are represented by [objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_glosry.htm) of classes. Global exception classes usually use the naming convention `CX_...`.
+ - are either [catchable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencatchable_exception_glosry.htm) (they are based on predefined or self-defined exception classes) or [uncatchable](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenuncatchable_exception_glosry.htm) (they directly produce runtime errors, i. e. error situations cannot be handled appropriately).
+
+`TRY` control structures are meant for handling catchable exceptions locally:
+- To be prepared for potential exceptions that are raised when executing statements, the statements can be included and executed within a *protected area*, a [`TRY`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptry.htm) control structure.
+- In doing so, it is possible for the ABAP runtime framework to catch exceptions and react on error situations.
+
+ ```abap
+ TRY.
+ "statement block
+ ENDTRY.
+ ```
+
+- The `TRY` control structure in the snippet above produces a syntax warning. A [`CATCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapcatch_try.htm) block is expected, too.
+- One or more class-based exceptions can be handled in one or more subsequent `CATCH` blocks. The `CATCH` statement must include an "appropriate" class-based exception. "Appropriate" means that, certainly, an exception class should be specified that is suitable for the error handling. In the following example, the predefined exception class `CX_SY_ZERODIVIDE` is specified that is, as the name implies, specific for the (potential) exception in case of a division by zero.
+
+ ```abap
+ TRY.
+ "TRY block
+ DATA(div1) = 1 / 0.
+
+ "Predefined exception class cx_sy_zerodivide as suitable exception class to be used here.
+ "If the exception is not handled, the program is terminated and the runtime error
+ "COMPUTE_INT_ZERODIVIDE occurs.
+ CATCH cx_sy_zerodivide.
+ ... "CATCH block
+ ENDTRY.
+
+ "Example for catching an exception in the context of a table expression
+ TRY.
+ "Copying a line of an internal table
+ DATA(line) = some_itab[ 12345 ].
+
+ "Predefined exception class cx_sy_itab_line_not_found as suitable exception class to be used here.
+ "If the exception is not handled, the program is terminated and the runtime error
+ "ITAB_LINE_NOT_FOUND occurs.
+ CATCH cx_sy_itab_line_not_found.
+ ... "CATCH block
+ ENDTRY.
+
+ "Note on inheritance relationships in exception classes
+ TRY.
+ "TRY block
+ DATA(div2) = 1 / 0.
+
+ "A CATCH block is in this example not only valid for cx_sy_zerodivide as specified above
+ "but also for all derived exceptions classes.
+ "In the following CATCH block, the predefined exception class cx_sy_arithmetic_error
+ "is specified. cx_sy_zerodivide is derived from cx_sy_arithmetic_error.
+ "Hence, cx_sy_arithmetic_error can be specified and handle the exception, too.
+ "Basically, using the exception root class cx_root would be also possible. However,
+ "choosing an appropriate exception class is recommended. See further down.
+
+ CATCH cx_sy_arithmetic_error.
+ ... "CATCH block
+ ENDTRY.
+
+
+ "Multiple classes in a list and CATCH blocks can be specified
+ "Note: If there are multiple CATCH blocks for exceptions that are in an inheritance
+ "relationship, you must pay attention that the more special exceptions are specified
+ "before the more general ones.
+ TRY.
+ ... "TRY block
+ CATCH cx_abc cx_bla cx_blabla.
+ ... "CATCH block
+ CATCH cx_la cx_lala.
+ ... "CATCH block
+ CATCH cx_lalala.
+ ... "CATCH block
+ ENDTRY.
+ ```
+
+- If the addition `INTO` is specified in the `CATCH` statement, a reference to the exception object is stored.
+- This is relevant to determine the exact exception, for example. In the code snippet above, the exception class `CX_SY_ZERODIVIDE` is mentioned. Consider a calculator. It should not only be able to deal with error situations like zero division but also, for example, overflows in arithmetic operations. The predefined exception class `CX_SY_ARITHMETIC_OVERFLOW` is available. It is also derived from `CX_SY_ARITHMETIC_ERROR`. If you then specify the exception class `CX_SY_ARITHMETIC_ERROR` which is higher up in the inheritance hierarchy and can handle both error situations (`CX_SY_ARITHMETIC_OVERFLOW` and `CX_SY_ZERODIVIDE`), the concrete exception that was raised is unclear. Using the `INTO` clause and the stored exception object, it is possible to carry out certain tasks, for example, retrieving and displaying the exception text.
+
+ ```abap
+ DATA: exception TYPE REF TO cx_root. "Note the root class
+ "Note: For a self-defined exception class, the object reference must be typed appropriately.
+
+ TRY.
+ ... "TRY block
+
+ "Storing a reference to the exception object.
+ "Note: The type is cx_root since attributes and methods of the root class that are defined there can be accessed.
+ CATCH INTO exception.
+ ... "CATCH block
+ ENDTRY.
+
+ "Inline creation of exception object reference and getting exception texts
+ TRY.
+ ... "TRY block
+
+ "The object reference variable can be created inline, for example, using DATA(...).
+ CATCH cx_sy_arithmetic_error INTO DATA(error_oref).
+ ... "catch block
+ "To get exception texts, you can call, for example, the method get_text
+ DATA(error_text) = error_oref->get_text( ).
+
+ ENDTRY.
+ ```
+
+- Regarding the program flow:
+ - The statement block following `TRY.` is always processed. If an exception is raised within this `TRY` block, the system searches for an exception handler, i. e. a `CATCH` block that is able to handle the exception.
+ - If there is no `CATCH` statement that is able to handle the catchable exception or if erroneous code is not within a `TRY` control structure at all, the exception is propagated to the caller.
+ - Exceptions can be handled either in the context locally (using such a `TRY` control structure) or be propagated to the caller so that the caller is responsible for reacting appropriately (for example, in another `TRY` control structure) to the error situation. In doing so, you can better structure your code by reacting on error situations centrally instead of locally checking, for example, each procedure call individually.
+ - If, at the end, the exception can nowhere be caught and handled, the program is terminated with a runtime error.
+ - If the exception can be handled or no exception is raised in the `TRY` block and it reaches its end, the processing continues after `ENDTRY`.
+
+
+> **💡 Note**
+> - Non-class-based exceptions are considered obsolete and should not be defined any more in new developments according to the [guidelines (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclass_exception_guidl.htm) and are not dealt with here.
+>- For all exceptions that are raised by the ABAP runtime environment and that are not handled, there is a corresponding runtime error. For example, in the case of exception class `CX_SY_ZERODIVIDE`, it is the runtime error `COMPUTE_INT_ZERODIVIDE`. For self-defined exception classes, an exception that is not handled generally triggers the runtime error `UNCAUGHT_EXCEPTION`.
+> - For `TRY` control structures, there are further additions available dealing with more advanced error handling, e. g. [resumable exceptions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapresume.htm).
+
+
+
+#### Notes on Exception Classes
+- To distinguish exception classes from *regular* classes, use the naming convention `CX` as prefix and not `CL`.
+- All exception classes (also the self-defined ones) are directly or indirectly derived from three abstract subclasses: `CX_STATIC_CHECK`, `CX_DYNAMIC_CHECK` and `CX_NO_CHECK`. These three "exception class categories" have different properties.
+- The class `CX_ROOT` is the root class. Directly deriving from `CX_ROOT` is not possible.
+- Apart from global classes, exception classes can also be defined as local classes within an ABAP program.
+- As mentioned, there are predefined exception classes like `CX_SY_ZERODIVIDE` for divisions by zero. However, you can create your own exception classes so that you can react on issues that are specific to your ABAP program. The exception class must, as stated above, be derived from one of the three abstract classes:
+ - `CX_STATIC_CHECK`: For forcing users to handle exceptions.
+ Generally speaking, exceptions that can occur in procedures should be handled locally there in the implementation or be declared explicitly in the [procedure interface](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenparameter_interface_glosry.htm) so that a caller knows which error situations can be expected. Exception classes of type `CX_STATIC_CHECK` enforce this. A check is carried out statically at compile time. Users of a procedure are then forced to either handle the exception locally in a `TRY` control structure or the users declare the exception themselves in their procedure interface to propagate the exception to their users. If this is not the case, a warning is produced.
+ - As an example, a method signature might look as follows. The addition `RAISING` in method signatures is used to declare one or more class-based exceptions that can be propagated from the method to the caller.
+ - When users of this method implement the method, they are made aware of the fact that an error situation can occur and a particular exception can be raised. The assumption is that `CX_SOME_ERROR` is derived from `CX_STATIC_CHECK`. Users of the method should then prepare the code accordingly.
+ ```abap
+ "Method definition using the RAISING parameter
+ CLASS-METHODS: some_meth IMPORTING str TYPE string
+ RETURNING VALUE(ret_value) TYPE string
+ RAISING cx_some_error.
+
+ ...
+
+ "Method call: Somewhere in the code of a user that calls the method
+ "Exception handled locally in a TRY control structure.
+ TRY.
+ DATA(val) = some_meth( str = `hallo` ).
+
+ CATCH cx_some_error.
+ ...
+ ENDTRY.
+
+ "If it was just like this without the TRY control structure, a warning would be produced.
+ DATA(val2) = some_meth( str = `hi` ).
+ ```
+
+ - `CX_DYNAMIC_CHECK`: For exceptions that can be checked and avoided by preconditions. As a consequence and in contrast to an exception class derived from `CX_STATIC_CHECK`, exception classes of type `CX_DYNAMIC_CHECK` do not enforce the local handling and the declaration in procedure interfaces. However, an appropriate exception handling should be implemented in cases in which you cannot rule out the raising of the exceptions in your program logic. The checking if a local handling or an explicit declaration in procedure interfaces is available is carried out at runtime only ("dynamic check") and only in case the exception is indeed raised.
+ - If it is determined at runtime that such an exception is neither locally handled nor an interface is declared appropriately - and the exception is raised - a new exception of type `CX_SY_NO_HANDLER` is raised. In this case, the attribute `PREVIOUS` contains a reference to the original exception.
+ - Example: The predefined class `CX_SY_ZERODIVIDE` is derived from `CX_DYNAMIC_CHECK`. The operands of a calculation can be checked appropriately (e. g. in case of a division, the implementation should guarantee that the second operand is not 0) before carrying out the arithmetic operation. In doing so, the exception can be avoided.
+
+ - `CX_NO_CHECK`: For error situations that can basically occur any time, cannot be locally handled in a meaningful way or cannot be avoided even following a check. An example for such an error situation might be a lack of memory. If the handling of such exceptions was checked statically or dynamically, it would basically mean to specify it in each procedure interface - not ideal for a clear program structuring.
+ - Note that exceptions derived from `CX_NO_CHECK` are always declared implicitly in all procedure interfaces.
+
+**Basic rule**: [Use a suitable exception category (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_category_guidl.htm).
+
+> **💡 Note**
+> - Each exception has a an [exception text](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_text_glosry.htm) that describes the error situation and that you can retrieve as outlined above. It helps you analyze the error. Plus, imagine using exceptions in the context of user interfaces. If a user faces an error situation, such exception texts may be displayed on the UI.
+> - Find more information on exception texts [here](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexception_texts.htm) in the ABAP Keyword Documentation.
+
+
+
+### Raising Exceptions
+
+- Either the ABAP runtime framework raises predefined exceptions or you raise exceptions programmatically using dedicated statements. You can raise both predefined and self-defined exceptions.
+- As the name implies, [`RAISE EXCEPTION`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapraise_exception_class.htm) statements raise class-based exceptions and thus interrupt the execution of the current statement block.
+- The `COND` operator includes the optional addition `THROW` to raise class-based exceptions.
+
+```abap
+...
+"RAISE EXCEPTION statement
+"The TYPE addition specifies the type of the exception, i. e. the exception class.
+"The statement is also possible without TYPE. In that case, you can use an existing exception object.
+"Note that there are plenty of additions. Check the ABAP Keyword Documentation.
+RAISE EXCEPTION TYPE cx_sy_zerodivide.
+...
+
+"THROW addition for the COND operator
+... = COND #( WHEN ... THEN ...
+ WHEN ... THEN ...
+ ELSE THROW cx_some_error( ) ).
+```
+
+
+
+## Excursion: Runtime Errors and Terminating Programs
+- Runtime errors are caused by uncatchable exceptions when a program is executed, when a catchable exception is not caught, or they can be forced by, for example, using [`ASSERT`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapassert.htm) statements.
+- Every runtime error terminates the program, which in turn raises a [database rollback](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_rollback_glosry.htm) and is documented by default in a [short dump](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenshort_dump_glosry.htm).
+
+- Regarding `ASSERT` statements: `ASSERT` is followed by a logical expression. If the expression is false, the program is terminated and an uncatchable exception is raised resulting in the runtime error `ASSERTION_FAILED`. Note that each runtime error is identified by a name and assigned to a specific error situation.
+
+```abap
+"The ASSERT keyword is followed by a logical expression.
+"If the expression is false, the program is terminated and an uncatchable exception is raised
+"resulting in the runtime error ASSERTION_FAILED.
+
+DATA(flag) = abap_false.
+
+ASSERT flag = abap_true.
+```
+
+> **💡 Note**
+> - Each runtime error is identified by a name and assigned to a specific error situation.
+> - In ADT, you will see a message popping up and informing you about the runtime error. You can check the details by choosing the "Show" button in the pop-up. Furthermore, you can check the content of the "Feed Reader" tab in ADT. There, just expand your project and find the runtime errors caused by you.
+
+
+
+## Executable Example
+
+[zcl_demo_abap_prog_flow_logic](./src/zcl_demo_abap_prog_flow_logic.clas.abap)
+
+> **💡 Note**
+> - The executable example ...
+> - covers the following topics, among others:
+> - Control structures with `IF`, `CASE`, and `TRY`
+> - Excursions: `COND` and `SWITCH` operators
+> - Expressions and functions for conditions
+> - Predicate expression with `IS SUPPLIED`
+> - Loops with `DO`, `WHILE`, and `LOOP`
+> - Terminating loop passes
+> - Handling exceptions
+> - The steps to import and run the code are outlined [here](README.md#-getting-started-with-the-examples).
> - [Disclaimer](README.md#%EF%B8%8F-disclaimer)
\ No newline at end of file
diff --git a/16_Data_Types_and_Objects.md b/16_Data_Types_and_Objects.md
index 73a953e..ad56792 100644
--- a/16_Data_Types_and_Objects.md
+++ b/16_Data_Types_and_Objects.md
@@ -1,1498 +1,1484 @@
-
-
-# Data Types and Data Objects
-
-- [Data Types and Data Objects](#data-types-and-data-objects)
- - [Introduction](#introduction)
- - [Data Types and Objects: Definition](#data-types-and-objects-definition)
- - [ABAP Data Types](#abap-data-types)
- - [Elementary Data Types](#elementary-data-types)
- - [Complex Data Types](#complex-data-types)
- - [Reference Types](#reference-types)
- - [Declaring Data Types](#declaring-data-types)
- - [Generic Types](#generic-types)
- - [Data Objects](#data-objects)
- - [Declaring Data Objects](#declaring-data-objects)
- - [Assigning Values to Data Objects](#assigning-values-to-data-objects)
- - [Creating Data Objects Using Inline Declaration](#creating-data-objects-using-inline-declaration)
- - [Assigning References to Data Reference Variables](#assigning-references-to-data-reference-variables)
- - [Creating Anonymous Data Objects](#creating-anonymous-data-objects)
- - [Constants and Immutable Variables](#constants-and-immutable-variables)
- - [Type Conversion](#type-conversion)
- - [Terms Related to Data Types and Objects in a Nutshell](#terms-related-to-data-types-and-objects-in-a-nutshell)
- - [Notes on the Declaration Context](#notes-on-the-declaration-context)
- - [Excursions](#excursions)
- - [Enumerated Types and Objects](#enumerated-types-and-objects)
- - [Getting Type Information and Creating Types at Runtime](#getting-type-information-and-creating-types-at-runtime)
- - [Ranges Tables](#ranges-tables)
- - [Executable Example](#executable-example)
-
-## Introduction
-[ABAP statements](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_statement_glosry.htm) usually work with [data objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_object_glosry.htm), that is, with transient data that occupies memory space while the [data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_type_glosry.htm) defines the technical properties of the data objects.
-Since data types and data objects are closely related, this cheat sheet covers both topics.
-Note that the topics covered here are also partly covered in other ABAP cheat sheets. The purpose of this cheat sheet is to summarize the basics.
-
-## Data Types and Objects: Definition
-
-Data types
-- Define technical properties of all data objects that have these data types, such as the maximum length of a [text field](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentext_field_glosry.htm).
-- Are descriptions only, with no data memory attached except for administrative information.
-- Can occur in [ABAP programs](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_program_glosry.htm) as [bound data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbound_data_type_glosry.htm), that is, the type is a property of a data object, or as a [standalone data type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstand-alone_data_type_glosry.htm), that is, the data type is defined independently.
-- Can be defined locally in an ABAP program or globally in classes, interfaces and in the [ABAP Dictionary (DDIC)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_dictionary_glosry.htm).
-> **💡 Note**
-> - Note: Data types in the ABAP Dictionary are either created directly as [repository objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrepository_object_glosry.htm) ([DDIC data elements](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_element_glosry.htm)) or in a type pool (only in [Standard ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstandard_abap_glosry.htm)). [Database tables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendatabase_table_glosry.htm), [CDS entities](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_entity_glosry.htm) and their components can also be used as data types in ABAP programs.
-> - Their existence and visibility depends on the declaration context.
-
-Data objects:
-- Are objects (or [instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninstance_glosry.htm)) of a data type (similar to objects/instances of classes in [ABAP Objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_objects_glosry.htm)).
-- Occupy memory space and exist in different forms, for example, numeric or textual data can be contained in data objects.
-- The type of data that a data object can receive is determined by its data type.
-- Like data types, their existence and visibility depend on the declaration context.
-- Are usually used in [ABAP statements](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_statement_glosry.htm) by specifying them in the [operand position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenoperand_position_glosry.htm).
-
-
-> **💡 Note**
-> There are several differentations that further distinguish and characterize data types and objects. See [here](#terms-related-to-data-types-and-objects-in-a-nutshell).
-
-
-
-## ABAP Data Types
-
-ABAP is rich in built-in data types and offers a wide range of options for defining data types and data objects in different contexts.
-Data types can be divided into three groups:
-- [Elementary data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenelementary_data_type_glosry.htm)
-- [Complex data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplex_data_type_glosry.htm)
-- [Reference type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_type_glosry.htm)
-
-For an overview, see the [ABAP Type Hierarchy](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_hierarchy.htm) in the ABAP Keyword Documentation.
-
-### Elementary Data Types
-- Elementary (or scalar) data types are based directly on a set of [built-in ABAP types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuiltin_abap_type_glosry.htm).
-- Are not composed of other data types.
-- Are types for holding numeric values, text information, binary data and special types for date and time.
-- Are further divided into elementary types of fixed and variable length.
- - Note: The length and the memory requirements of data objects of fixed length data types are fixed, that is, they cannot change at runtime. The length and memory requirements of data objects of variable length data types can actually change at runtime, depending on their contents.
-- The following built-in elementary data types of fixed length are available:
- - Numeric types: Integers (`b`, `s`, `i`, `int8`), [decimal floating point numbers](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendecfloat_glosry.htm) (`decfloat16`, `decfloat34`), [binary floating point numbers](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbinfloat_glosry.htm) (`f`), and [packed numbers](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenpacked_number_glosry.htm) (`p`)
- - Character-like types: text fields (`c`) and [numeric text fields](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abennumeric_text_field_glosry.htm) (`n`)
- - Byte-like type: [byte fields](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_field_glosry.htm) (`x`)
- - Character-like date and time types: date fields (`d`) and time fields (`t`)
- - Time stamp type for time stamp fields (`utclong`).
-- Variable length:
- - Character-like type for [text strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentext_string_glosry.htm) (`string`)
- - Byte-like type for [byte strings](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbyte_string_glosry.htm) (`xstring`)
-
-> **💡 Note**
-> - The data types `c`, `n`, `x`, and `p` are incomplete, i.e., [generic data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengeneric_data_type_glosry.htm), with respect to their length. The type definition syntax has a special addition for this (`LENGTH`). In addition, `p` is also generic with respect to the number of decimal places (`DECIMALS` addition). See more about generic types in the following sections.
-> - The other types can be considered as [complete data types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencomplete_data_type_glosry.htm). They don't need any additional syntax elements for the definition.
-> - The numeric data types `b` and `s` cannot be specified directly in ABAP programs for short integers. Alternative [built-in DDIC types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuiltin_ddic_type_glosry.htm) are available.
-> - `decfloat16` and `decfloat34` for decimal floating point numbers can be regarded as more modern versions of `p` and `f`, combining their advantages.
-> - Although they are character-like, `t` and `d` can be used for calculations.
-> - See the ABAP Keyword Documentation [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuilt_in_types.htm) for more information about the initial values of the data types, the standard length, and so on.
-
-
-
-### Complex Data Types
-
-- Are composed of other types.
-- The following complex data types are available:
- - [Structured types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenstructured_type_glosry.htm): Represent a sequence of arbitrary data type (i.e., they can be elementary, reference, or complex data types). The typical syntax element for the local definition of a structure is `... BEGIN OF ... END OF ...`.
- - [Table types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_type_glosry.htm): Consist of a sequence of any number of lines of the same data type. It can be any elementary type, reference type, or complex data type. The type definition includes other properties such as the [table category](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_category_glosry.htm) (defines how tables can be accessed) and [table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentable_key_glosry.htm) (to identify the table lines). The typical syntax element is `... TABLE OF ...`.
- - [Enumerated types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenenum_type_glosry.htm): Specify a set of values in addition to the actual type properties. The typical syntax element is `... BEGIN OF ENUM ... END OF ENUM ...`. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenenumerated_types_usage.htm) and further down.
- - [Mesh types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenmesh_type_glosry.htm): Special structured type that contains only table types with structured line types as components that can be linked using mesh associations. The typical syntax element is `... BEGIN OF MESH ... END OF MESH ...`. See more information [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes_mesh.htm).
- - [BDEF derived types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrap_derived_type_glosry.htm): RAP-specific structured and table types. The typical syntax elements are `... TYPE STRUCTURE FOR ...` and `... TYPE TABLE FOR ...`. More information can be found [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrpm_derived_types.htm) and in the ABAP cheat sheet on ABAP EML.
-- A data object of a complex type can be accessed as a whole or by component.
-
-> **💡 Note**
-> Structured and table types are used in this cheat sheet as examples for complex types. For more information, see the ABAP Keyword Documentation and the ABAP cheat sheets for structures and internal tables.
-
-
-
-### Reference Types
-- Describe data objects that contain [references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm) to other objects (data objects and instances of classes), which are known as [reference variables](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_variable_glosry.htm).
-- There are two kinds of references: [Data references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_reference_glosry.htm) (references to data objects) and [object references](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenobject_reference_glosry.htm) (references to objects as instances of classes).
-- A reference type must be defined either in the ABAP program or in the ABAP Dictionary. There are no built-in reference types in ABAP.
-- The typical syntax element is `... REF TO ...`.
-
-> **💡 Note**
-> There are [generic ABAP types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abengeneric_abap_type_glosry.htm). Generic data types are types that do not define all of the properties of a data object. They can only be used for the typing of [formal parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenformal_parameter_glosry.htm) and [field symbols](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm). See an example further down.
-The only generic types that can be used after `TYPE REF TO` are `data` for the generic typing of data references, and `object`, for the generic typing of object references.
-
-
-
-### Declaring Data Types
-
-Data types are defined in an ABAP program using the [`TYPES`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abaptypes.htm) statement. Depending on the declaration context, the types can be accessed either locally or globally. As mentioned, data types can also be declared in the ABAP Dictionary. The focus here is on data type declarations in ABAP programs using `TYPES` statements.
-You can use built-in and user-defined data types to create data types (and data objects).
-
-The following code snippet shows various syntax options for declaring data types:
-
-Elementary types:
-
-```abap
-"Type declaration follows these patterns (LENGTH and DECIMALS only possible for particular types):
-"TYPES data_type TYPE some_type [LENGTH len] [DECIMALS dec].
-
-"Data type declarations based on built-in ABAP types
-
-"Numeric types
-TYPES te_i TYPE i.
-TYPES te_int8 TYPE int8.
-TYPES te_decfl16 TYPE decfloat16.
-TYPES te_decfl34 TYPE decfloat34.
-TYPES te_f TYPE f.
-TYPES te_p_l4_d2 TYPE p LENGTH 4 DECIMALS 2.
-"Note: LENGTH/DECIMALS must be specified when using the types c, p, n, x. in ABAP Objects contexts.
-
-"Character-like types
-"To combine TYPES statements, you can use chained statements, i.e. TYPES followed by a colon and
-"then listing the type declarations separated by a comma.
-TYPES: te_c5 TYPE c LENGTH 5,
- te_n4 TYPE n LENGTH 4,
- te_str TYPE string.
-
-"Byte-like types
-TYPES te_x_l2 TYPE x LENGTH 2.
-TYPES te_xstr TYPE xstring.
-
-"Types for date and time
-TYPES te_d TYPE d.
-TYPES te_t TYPE t.
-TYPES te_utc TYPE utclong.
-
-"You might also stumble on a length specification in parentheses following the data type name.
-"It is recommended that you use addition LENGTH instead of the parentheses.
-TYPES te_cfour(4) TYPE c.
-
-"**** Data type declarations based on existing types or data objects ****
-
-"Type declaration based on an existing type visible at this location;
-"all properties of the specified data type are inherited.
-TYPES te_another_i TYPE te_i.
-
-"Anticipating the data object declaration needed to demonstrate the LIKE addition
-DATA do_num TYPE i.
-
-"LIKE addition:
-"Type declaration based on an existing data object visible at this location;
-"all properties of the type of the specified data object are inherited.
-TYPES te_from_int LIKE do_num.
-
-"**** Data type declarations based on globally available types or data objects ****
-
-"DDIC Types
-"Note that the built-in types b and s cannot be specified for type declarations.
-"However, the value range for these types can be obtained by referencing the built-in DDIC
-"types INT1 and INT2. These are data elements.
-TYPES te_int1 TYPE int1.
-TYPES te_int2 TYPE int2.
-
-"Referring to types in global classes
-"In the example, the type exists in a global interface.
-TYPES te_elem_from_itf TYPE zdemo_abap_get_data_itf=>occ_rate.
-
-"Referring to a data object that exists in a global interface
-TYPES te_dobj_from_itf LIKE zdemo_abap_objects_interface=>stat_str.
-
-"Referring to a data object that exists in the public visibility section of a global class
-TYPES te_dobj_from_cl LIKE zcl_demo_abap_objects=>public_string.
-
-"Referring to a component of a DDIC table (also possible for views;
-"the components have elementary types)
-TYPES te_comp_ddic_tab TYPE zdemo_abap_carr-carrid.
-
-"Type pools (ABAP program, administrated by the ABAP Dictionary; may only be created in
-"standard ABAP; but is considered obsolete)
-"However, the following example is accessible in ABAP for Cloud Development, too.
-"The type pool contains the definitions of globally visible data types and constants.
-TYPES te_tp TYPE abap_bool.
-TYPES te_const_in_tp LIKE abap_true.
-```
-
-Structure and internal table types as examples for complex types:
-
-```abap
-"Structure type, can contain any type
-TYPES: BEGIN OF ts_misc_comps,
- comp1 TYPE i,
- comp2 TYPE string,
- comp3 TYPE te_i, "Existing type
- comp4 LIKE do_num, "Referring to existing data object
- comp5 TYPE string_table, "Internal table type (available in DDIC)
- comp6 TYPE TABLE OF zdemo_abap_carr WITH EMPTY KEY, "Internal table type (based on database table)
- comp7 TYPE REF TO i, "Reference type
- END OF ts_misc_comps.
-
-"Internal table types
-"Note: The examples only use the implicit STANDARD for standard tables.
-"Internal table type declaration based on a local structure type
-TYPES tt_local_ts TYPE TABLE OF ts_misc_comps WITH EMPTY KEY.
-
-"Internal table type declaration based on an elementary data type
-TYPES tt_int TYPE TABLE OF i.
-
-"Referring to existing types and data objects
-
-"Anticipating the creation of structured data objects for the LIKE addition
-DATA struc_local_ts TYPE ts_misc_comps.
-
-"Structure type creation based on an existing structured data object
-TYPES ts_w_like LIKE struc_local_ts.
-
-"Anticipating the creation of an internal table for the LIKE addition
-DATA itab_local_ts TYPE TABLE OF ts_misc_comps WITH EMPTY KEY.
-
-"Internal table type declaration based on an existing internal table
-TYPES tt_w_like LIKE itab_local_ts.
-
-"Internal table type declaration based on the existing internal table type
-TYPES tt_another_type TYPE tt_w_like.
-
-"Structured types based on an internal table's line type
-TYPES ts_type_line TYPE LINE OF tt_w_like.
-TYPES ts_like_line LIKE LINE OF itab_local_ts.
-
-"Internal table typed with internal table as line type
-TYPES tt_like_table LIKE TABLE OF itab_local_ts.
-
-"Referring to global types
-
-"Structure type based on DDIC type
-"In this case, a database table is specified whose line type is used as data type
-"in this type declaration. You may also use a CDS view (or classic DDIC view in
-"standard ABAP) or a dedicated structured type defined in the DDIC.
-TYPES ts_ddic_tab TYPE zdemo_abap_carr.
-
-"Internal table type based on internal type that exists in a gloabl interface
-TYPES tt_tab_type_from_itf TYPE zdemo_abap_get_data_itf=>carr_tab.
-
-"Internal table types with an elementary line type based on globally available types
-"Elementary table type
-TYPES tt_strtab TYPE string_table.
-"Elementary line type; the type is available in a global interface
-TYPES tt_elem_type_from_itf TYPE TABLE OF zdemo_abap_get_data_itf=>occ_rate.
-```
-
-Reference types:
-```abap
-"Declaring reference types with static types
-TYPES tr_i TYPE REF TO i.
-TYPES tr_str TYPE REF TO string.
-TYPES tr_ddic_tab TYPE REF TO zdemo_abap_carr.
-"Using the generic type data as static type
-TYPES tr_data TYPE REF TO data.
-
-"Referring to an existing reference type
-TYPES tr_ref_i TYPE tr_i.
-
-"Anticipating the creation of a data reference variable for showing the LIKE addition
-DATA dref_i TYPE REF TO i.
-
-"Creating a reference type based on a data reference variable
-TYPES tr_like_ref_i LIKE dref_i.
-
-"Creating a data object for the LIKE REF TO addition
-DATA str TYPE string.
-
-"Creating a reference type whose static type is inherited from the data type of the specified data object
-TYPES tr_like_ref2str LIKE REF TO str.
-
-"Reference table types
-TYPES tr_tab_ref_i TYPE TABLE OF REF TO i.
-DATA itab_str TYPE TABLE OF string.
-TYPES tr_like_table_ref LIKE TABLE OF REF TO itab_str.
-```
-
-
-
-### Generic Types
-
-- Generic types are available with which [formal parameters](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenformal_parameter_glosry.htm) of methods or [field symbols](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenfield_symbol_glosry.htm) can be specified.
-- At runtime, the actual data type is copied from the assigned [actual parameter](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenactual_parameter_glosry.htm) or
- memory area, i.e. they receive the complete data type only when an actual parameter
- is passed or a memory area is assigned.
-- More information:
- - [Generic ABAP Types](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuilt_in_types_generic.htm)
- - [ABAP cheat sheet about dynamic programming](06_Dynamic_Programming.md) regarding field symbols and `ASSIGN` statements
-
-The following code snippet demonstrates generic types with field symbols.
-
-```abap
-FIELD-SYMBOLS:
- "Any data type
- TYPE data,
- TYPE any,
- "Any data type can be assigned. Restrictions for formal parameters and 'data': no
- "numeric functions, no description functions, and no arithmetic expressions can be
- "passed to these parameters. However, you can bypass the restriction by applying the
- "CONV operator for the actual parameter.
-
- "Character-like types
- TYPE c, "Text field with a generic length
- TYPE clike, "Character-like (c, n, string, d, t and character-like flat structures)
- TYPE csequence, "Text-like (c, string)
- TYPE n, "Numeric text with generic length
- TYPE x, "Byte field with generic length
- TYPE xsequence, "Byte-like (x, xstring)
-
- "Numeric types
- TYPE decfloat, "decfloat16, decfloat34
- TYPE numeric, "Numeric ((b, s), i, int8, p, decfloat16, decfloat34, f)
-
TYPE p, "Packed number (generic length and number of decimal places)
-
- "Internal table types
- TYPE ANY TABLE, "Internal table with any table type
- TYPE HASHED TABLE,
- TYPE INDEX TABLE,
- TYPE SORTED TABLE,
- TYPE STANDARD TABLE,
-
TYPE table, "Standard table
-
- "Other types
- TYPE simple, "Elementary data type including enumerated types and
- "structured types with exclusively character-like flat components
-