From 78e8e9ca892f3892d44b05b09ca3804d4f6a78de Mon Sep 17 00:00:00 2001
From: danrega <16720986+danrega@users.noreply.github.com>
Date: Wed, 18 Dec 2024 16:43:40 +0100
Subject: [PATCH] Update
---
01_Internal_Tables.md | 85 +++---
02_Structures.md | 8 +-
03_ABAP_SQL.md | 33 ++-
04_ABAP_Object_Orientation.md | 107 ++++++--
05_Constructor_Expressions.md | 486 ++++++++++++++++++++++++++++------
06_Dynamic_Programming.md | 51 ++++
07_String_Processing.md | 2 +-
08_EML_ABAP_for_RAP.md | 30 ++-
13_Program_Flow_Logic.md | 2 +-
21_XML_JSON.md | 230 ++++++++++++++++
27_Exceptions.md | 2 +-
11 files changed, 881 insertions(+), 155 deletions(-)
diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md
index e2b8172..e457411 100644
--- a/01_Internal_Tables.md
+++ b/01_Internal_Tables.md
@@ -9,9 +9,8 @@
- [Creating Internal Tables and Types](#creating-internal-tables-and-types)
- [Specifying Keys in Internal Table Declarations](#specifying-keys-in-internal-table-declarations)
- [Internal Tables Based on Locally Created Line/Table Types](#internal-tables-based-on-locally-created-linetable-types)
- - [Line/Table Type Options of Internal Tables](#linetable-type-options-of-internal-tables)
+ - [Overview of Line and Table Type Options with Internal Tables](#overview-of-line-and-table-type-options-with-internal-tables)
- [Creating Internal Tables By Inline Declaration](#creating-internal-tables-by-inline-declaration)
- - [Creating Internal Tables Dynamically](#creating-internal-tables-dynamically)
- [Populating Internal Tables](#populating-internal-tables)
- [Copying Internal Tables](#copying-internal-tables)
- [Using INSERT and APPEND Statements to Populate Internal Tables](#using-insert-and-append-statements-to-populate-internal-tables)
@@ -53,6 +52,8 @@
- [Excursion: Joining/Merging Internal Tables into Internal Tables](#excursion-joiningmerging-internal-tables-into-internal-tables)
- [Sorting Internal Tables](#sorting-internal-tables)
- [Modifying Internal Table Content](#modifying-internal-table-content)
+ - [Modifying Read Table Lines](#modifying-read-table-lines)
+ - [Modifying Table Lines Using ABAP MODIFY Statements](#modifying-table-lines-using-abap-modify-statements)
- [Deleting Internal Table Content](#deleting-internal-table-content)
- [Deleting Adjacent Duplicate Lines](#deleting-adjacent-duplicate-lines)
- [Deleting the Entire Internal Table Content](#deleting-the-entire-internal-table-content)
@@ -66,6 +67,7 @@
- [Ranges Tables](#ranges-tables)
- [Comparing Content of Compatible Internal Tables](#comparing-content-of-compatible-internal-tables)
- [BDEF Derived Types (ABAP EML)](#bdef-derived-types-abap-eml)
+ - [Creating Internal Tables Dynamically](#creating-internal-tables-dynamically)
- [More Information](#more-information)
- [Executable Example](#executable-example)
@@ -243,7 +245,7 @@ DATA itab4 LIKE itab1 ... "Based on an existing in
> **💡 Note**
> - If the table category is not specified (`... TYPE TABLE OF ...`), it is automatically `... TYPE STANDARD TABLE OF ...`.
-> - Using [Runtime Type Creation (RTTC)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrun_time_type_creation_glosry.htm "Glossary Entry"), you can define and create new internal tables and table types as [type description objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_object_glosry.htm) at runtime. For more information, see the [Dynamic Programming](06_Dynamic_Programming.md) ABAP cheat sheet.
+> - Using [Runtime Type Creation (RTTC)](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenrun_time_type_creation_glosry.htm "Glossary Entry"), you can define and create new internal tables and table types as [type description objects](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abentype_object_glosry.htm) at runtime. For more information, see the [Dynamic Programming](06_Dynamic_Programming.md) ABAP cheat sheet. Also find a snippet on creating internal tables dynamically by specifying the type dynamically [below](#creating-internal-tables-dynamically).
The following code snippets contain 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, many of 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.
@@ -455,7 +457,7 @@ DATA it27 LIKE TABLE OF it25.
| Subject | Notes/Code Snippet | +
| Populating an existing structure or a structure created inline | + ++ +``` abap +"Declaring structured data type and structured data object +"(also used in the following snippets) TYPES: BEGIN OF struc_type, a TYPE i, b TYPE c LENGTH 3, @@ -129,28 +140,41 @@ TYPES: BEGIN OF struc_type, DATA struc TYPE struc_type. -"Using VALUE constructor expression "Note: The data type can be retrieved from the context. Then, # can "be specified. struc = VALUE #( a = 1 b = 'aaa' ). +"The following syntax is also possible (explicit data type +"specification although the type can be determined). +struc = VALUE struc_type( a = 2 b = 'bbb' ). + +"Using such a VALUE constructor expression instead of, for example, +"assigning the component values individually using the component +"selector (-). +struc-a = 3. +struc-b = 'ccc'. + "Using an inline declaration "In the following example, the type cannot be retrieved from the "context. Therefore, an explicit specification of the type is "required. -DATA(struc2) = VALUE struc_type( a = 2 b = 'bbb' ). +DATA(struc2) = VALUE struc_type( a = 4 b = 'ddd' ). +``` -"The following syntax is also possible (explicit data type -"specification although the type can be determined). -struc = VALUE struc_type( a = 3 b = 'ccc' ). + | +
| -"Internal table +Populating an existing internal table or an internal table created inline + + | + ++ + +``` abap "Note the extra pair of parentheses for an individual table line. DATA itab TYPE TABLE OF struc_type WITH EMPTY KEY. @@ -172,9 +196,21 @@ DATA(itab2) = VALUE itab_type( ( a = 7 b = 'ggg' ) "Unstructured line types work without component names. DATA(itab3) = VALUE string_table( ( `Hello` ) ( `world` ) ). +``` -"-------------- Creating initial values -------------- + | +
| + +Creating initial values for all types + + | + ++ +``` abap "Type-specific initial value for data objects by leaving the "VALUE constructor expression empty "Structure (the entire structure is initial) @@ -203,9 +239,21 @@ DATA(int) = VALUE i( ). DATA int2 TYPE i. int2 = VALUE #( ). DATA(xstr) = VALUE xstring( ). +``` -"-------------- VALUE constructor used for nested/deep data objects -------------- + | +
| + +`VALUE` constructor used for nested/deep data objects + + | + ++ +``` abap "Creating a nested structure DATA: BEGIN OF nested_struc, a TYPE i, @@ -228,13 +276,21 @@ TYPES deep_itab_type LIKE TABLE OF nested_struc WITH EMPTY KEY. DATA(deep_itab) = VALUE deep_itab_type( ( nested_struc ) "Adding an existing structure ( a = 3 struct = VALUE #( b = 3 c = 'ccc' ) ) ( a = 4 struct = VALUE #( b = 4 c = 'ddd' ) ) ). +``` -"-------------- Additions to VALUE constructor expressions -------------- -"Note: LET and FOR expressions can be added to VALUE constructor expressions. -"Find more information further down. + | +
| +`BASE` addition + + | + ++ +``` abap "A constructor expression without the BASE addition initializes the target variable. "Therefore, you can use the addition if you do not want to construct a structure or "internal table from scratch but keep existing content. @@ -254,9 +310,21 @@ itab = VALUE #( ( a = 1 b = 'aaa' ) itab = VALUE #( BASE itab ( a = 3 b = 'ccc' ) ( a = 4 b = 'ddd' ) ). +``` -"-------------- LINES OF addition ------------- + | +
| + +`LINES OF` addition + + | + ++ +``` abap "All or some lines of another table can be included in the target internal table "(provided that they have appropriate line types). "With the LINES OF addition, more additions can be specified. @@ -270,9 +338,22 @@ itab = VALUE #( ( a = 1 b = 'aaa' ) itab = VALUE #( ( LINES OF itab5 STEP 2 ) "Adding every second line ( LINES OF itab6 USING KEY primary_key ) ). "Specifying a table key +``` + + | +
| + +Short form for internal tables with structured line types + + | + +-"-------------- Short form for internal tables with structured line types -------------- +``` abap "- Assignments of values to individual structure components are possible outside of inner " parentheses "- In that case, all of the following components in the inner parentheses are assigned that @@ -348,7 +429,110 @@ MODIFY ENTITIES OF zdemo_abap_rap_ro_m MAPPED DATA(m) FAILED DATA(f) REPORTED DATA(r). -``` +``` + + | +
| + +Assigning incompatible structures + + | + +
+
+- The example makes use of the `BASE` addition, and includes a `CORRESPONDING` expression.
+- The `s1` structure is assigned the identically named components of the `s2` structure.
+- Other components are assigned by explicitly specifying them.
+
+ + +``` abap +DATA: + BEGIN OF s1, + comp1 TYPE i, + comp2 TYPE i, + comp3 TYPE i, + comp4 TYPE i, + comp5 TYPE i, + END OF s1, + BEGIN OF s2, + comp1 TYPE i VALUE 1, + comp2 TYPE i VALUE 2, + comp3 TYPE i VALUE 3, + END OF s2. + +s1 = VALUE #( BASE CORRESPONDING #( s2 ) comp4 = 4 comp5 = 5 ). +``` + + |
+
| + +Table iterations with `FOR` + + | + +
+
+- Have the semantics of `LOOP AT` statements
+- Find more examples [below](#iteration-expressions-using-for)
+
+ + +``` abap +TYPES: BEGIN OF s, + col1 TYPE c LENGTH 5, + col2 TYPE i, + col3 TYPE i, + END OF s. +TYPES itab_type TYPE TABLE OF s WITH EMPTY KEY. +DATA(itab) = VALUE itab_type( ( col1 = 'a' col2 = 1 col3 = 30 ) + ( col1 = 'bb' col2 = 2 col3 = 10 ) + ( col1 = 'ccc' col2 = 3 col3 = 20 ) ). + +DATA(it1) = VALUE itab_type( FOR wa IN itab ( col1 = wa-col1 && 'z' + col2 = wa-col2 + 1 ) ). +``` + + |
+
| + +`LET` expressions + + | + +
+
+- They define one or more variables (field symbols are also possible) as local (i.e. local to the expression) helper fields and assigns values to them.
+- Find more examples [below](#let-expressions)
+
+ + +``` abap +DATA(strtab) = VALUE string_table( LET mark = '!' IN + ( |abc{ mark }| ) + ( |def{ mark }| ) + ( |ghi{ mark }| ) ). +``` + + |
+
| + +Using data objects declared inline in various ABAP statements + + | + +
Using the inline construction of structures and internal tables, you can
avoid the declaration of extra variables in many contexts, for example,
@@ -361,7 +545,8 @@ statements like
(which is not to be confused with the ABAP statement having the same
name) for modifying database tables.
-Examples:
+ + ``` abap "ABAP statements "Modifiying individual internal table entries based on a structure created inline @@ -389,11 +574,36 @@ MODIFY zdemo_abap_carr FROM TABLE @( VALUE #( url = 'another_url' ) ) ). ``` -> **💡 Note** -> Some of the additions and concepts mentioned here are -also valid for other constructor expressions further down but not -necessarily mentioned explicitly. See the details on the syntax -options of the constructor operators in the ABAP Keyword Documentation. + |
+
| + +Grouping lines in internal tables + + | + +
+
+- Regarding grouping lines in internal tables, find more information in the [Internal Tables: Grouping](11_Internal_Tables_Grouping.md) cheat sheet.
+- More code snippets on grouping lines, covering syntax such as `FOR GROUPS` with the `VALUE` and `REDUCE` operators, are available [below](#grouping-lines-in-internal-tables-with-valuereduce).
+
+ + +``` abap +... +DATA(it_val_1) = VALUE string_table( FOR GROUPS gr OF wa IN itab4grp + GROUP BY wa-col1 ASCENDING + WITHOUT MEMBERS + ( |{ gr }| ) ). +``` + + |
+
| Subject | Notes/Code Snippet | +
| + +Explicit conversion + + | + +
+
``` abap
"Result: 0.2
DATA(conv_res) = CONV decfloat34( 1 / 5 ).
@@ -1047,14 +1273,26 @@ itab = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
"Using CONV to convert the internal table to the required table type.
DATA(conv_itab) = CONV inttab_type( itab ).
ASSIGN conv_itab TO |
+
| + +Constructing data objects + + | + +
As outlined above, you can construct structures and internal
tables using the `VALUE` operator. Using `VALUE` for
constructing [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") and providing values is not possible. You can only use it to create a data object with an initial value, for example `DATA(str) = VALUE string( ).`. The `CONV` operator closes this gap.
+ + ``` abap DATA(a) = CONV decfloat34( '0.4' ). @@ -1079,7 +1317,13 @@ DATA e TYPE string. DATA(f) = `hallo`. "Produces a syntax warning "DATA(g) = CONV string( `hallo` ). -``` +``` + + |
+
| Subject | Notes/Code Snippet | +
| + +Lossless assignments + + | + ++ +``` abap "Note: An assignment is made in accordance with conversion rules. Check "the ABAP Keyword Documentation for these rules. An assignment is only "made if no values are lost. Otherwise, an error occurs. Either it is @@ -1120,9 +1377,22 @@ TRY. DATA(as4) = EXACT clen3( 'abcd' ). CATCH cx_sy_conversion_data_loss. ENDTRY. +``` -"-------------- Lossless calculations ------------- + | +
| + +Lossless calculations + + | + ++ + +``` abap "The first statement works, whereas the second statement raises an exception. "A rounding to two decimal places is required. TYPES packednum TYPE p LENGTH 8 DECIMALS 2. @@ -1134,7 +1404,12 @@ TRY. DATA(calc3) = EXACT packednum( 1 / 3 ). CATCH cx_sy_conversion_rounding. ENDTRY. -``` +``` + + | +
| Subject | Notes/Code Snippet | +
| + +Creating a result depending on logical expressions + + | + ++ ``` abap DATA(day_or_night) = COND #( WHEN cl_abap_context_info=>get_system_time( ) BETWEEN '050000' AND '220000' THEN `day` @@ -1299,15 +1590,41 @@ IF cl_abap_context_info=>get_system_time( ) BETWEEN '050000' AND '220000'. ELSE. day_or_night = `night`. ENDIF. +``` -"Multiple logical expressions initiated by WHEN -"Also LET expressions are possible. See more details further down. + | +
| + +Multiple logical expressions initiated by `WHEN`, using `LET` + + | + ++ +``` abap DATA(time_of_day) = COND #( LET time = cl_abap_context_info=>get_system_time( ) IN WHEN time BETWEEN '050001' AND '120000' THEN |Good morning, it's { time TIME = ISO }.| WHEN time BETWEEN '120001' AND '180000' THEN |Good afternoon, it's { time TIME = ISO }.| WHEN time BETWEEN '180001' AND '220000' THEN |Good evening, it's { time TIME = ISO }.| ELSE |Good night, it's { time TIME = ISO }.| ). +``` + | +
| + +`THROW` addition to raise an exception + + | + ++ + +``` abap "THROW addition to raise an exception (working like RAISE EXCEPTION TYPE statements) "by specifying an exception class "Note: It is possible to ... @@ -1327,14 +1644,35 @@ ENDTRY. "Excursion for the example above: The following statement does not result in an "error in ABAP (zero division 'allowed' if the first operand has also the value 0). div = 0 / 0. +``` + | +
| + +`THROW SHORTDUMP` addition to raise a runtime error + + | + ++ +``` abap "THROW SHORTDUMP addition to raise a runtime error (working like RAISE SHORTDUMP "TYPE statements) by specifying an exception class; a message can be also passed, "and input parameters can be filled -div = COND decfloat34( WHEN num1 <> 0 AND num2 <> 0 THEN num1 / num2 - WHEN num1 = 0 AND num2 <> 0 THEN num1 / num2 - ELSE THROW SHORTDUMP cx_sy_zerodivide( ) ). -``` +DATA(int1) = 0. +DATA(int2) = 0. + +DATA(division) = COND decfloat34( WHEN int1 <> 0 AND int2 <> 0 THEN int1 / int2 + WHEN int1 = 0 AND int2 <> 0 THEN int1 / int2 + ELSE THROW SHORTDUMP cx_sy_zerodivide( ) ). +``` + + | +