From 85e0479fa39bcb5542cc75642b43874f926dab1f Mon Sep 17 00:00:00 2001
From: danrega <16720986+danrega@users.noreply.github.com>
Date: Mon, 30 Dec 2024 13:15:44 +0100
Subject: [PATCH] Update
---
01_Internal_Tables.md | 19 ++---
23_Date_and_Time.md | 173 ++++++++++++++++++++++++++++++++++++++++
24_Builtin_Functions.md | 4 +-
3 files changed, 185 insertions(+), 11 deletions(-)
diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md
index e457411..2e35532 100644
--- a/01_Internal_Tables.md
+++ b/01_Internal_Tables.md
@@ -944,7 +944,7 @@ DATA str_tab_c TYPE string_table.
-| Adding new lines without deleting existing content |
+ BASE addition: Adding new lines without deleting existing content |
When you use the above assignments to an existing internal table (`itab = ...`), the internal table is initialized and the existing content is deleted. To add new lines without deleting existing content, use the [`BASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvalue_constructor_params_itab.htm) addition.
@@ -959,7 +959,7 @@ itab = VALUE #( BASE itab ( comp1 = a comp2 = b ... )
|
-| Adding lines of other tables |
+ LINES OF addition: Adding lines of other tables |
... using the `LINES OF` addition to the `VALUE` operator.
@@ -1017,7 +1017,7 @@ MOVE-CORRESPONDING itab3 TO itab.
|
-| Copying content and retaining existing content |
+ BASE/KEEPING TARGET LINES additions: Copying content and retaining existing content |
... using the `CORRESPONDING` operator.
@@ -1033,7 +1033,7 @@ MOVE-CORRESPONDING itab3 TO itab KEEPING TARGET LINES.
|
-| Assigning components using mapping relationships |
+ MAPPING addition: 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.
@@ -1048,7 +1048,7 @@ itab = CORRESPONDING #( itab3 MAPPING a = c b = d ).
|
-| Excluding components from the assignment |
+ EXCEPT addition: Excluding components from the assignment |
... using the `EXCEPT` addition to the `CORRESPONDING` operator.
@@ -1067,7 +1067,7 @@ itab = CORRESPONDING #( itab3 EXCEPT * ).
|
-| Preventing runtime errors when duplicate lines are assigned |
+ DISCARDING DUPLICATES addition: 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.
@@ -1083,12 +1083,12 @@ itab = CORRESPONDING #( itab2 DISCARDING DUPLICATES ).
|
-| Copying data from deep internal tables |
+ DEEP/EXPANDING NESTED TABLES additions: Copying data from deep internal tables |
- A deep internal table is a table with [deep](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendeep_glosry.htm) line type, which means the table can itself contain internal tables as components, among others.
- The `BASE` addition does not delete the existing content.
-- See also the alternative `MOVE-CORRESPONDING` statements.
+- See also the alternative `MOVE-CORRESPONDING` statements that use the `EXPANDING NESTED TABLES` addition.
@@ -4404,7 +4404,8 @@ ENDCLASS.
### Restrictions Regarding Selecting from Internal Tables
- This excursion is intended to underscore the restrictions mentioned above and in the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensql_engine_restr.htm) in more detail when selecting from internal tables.
-- Components having deep types, such as strings, cannot be included, for example, in the `SELECT` list or `WHERE` clause.
+- Components having deep types cannot be included, for example, in the `SELECT` list or `WHERE` clause.
+- Among the non-allowed types of internal table components are strings (as they are deep types) and `utclong`.
- Note that only those fields are checked (and sent to the database) that are actually used (as shown in the example below).
- However, the type string is allowed if it is declared using the built-in dictionary type `sstring` (for example, a component typed with a [data element](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendata_element_glosry.htm) or a [CDS simple type](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abencds_simple_type_glosry.htm) that uses `sstring`).
diff --git a/23_Date_and_Time.md b/23_Date_and_Time.md
index c4090fc..29dfd6e 100644
--- a/23_Date_and_Time.md
+++ b/23_Date_and_Time.md
@@ -185,6 +185,7 @@ DATA(day_from_date) = xco_date->day.
⬆️ back to top
### Validity of Date Fields
+
- Before accessing date (or time) fields, ensure that the content of these fields is valid to avoid unexpected results, such as incorrect calculations.
- The ABAP runtime framework checks the validity of these fields in various contexts, including lossless assignments and assignments to numeric fields (see [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenchar_date_time_fields_validity.htm)):
- Lossless assignments: If an invalid value is encountered in a source field, an exception will be raised instead of producing the initial value.
@@ -234,13 +235,73 @@ DATA(day_sub) = substring( val = some_date off = 6 len = 2 ). "02
DATA(year_repl) = replace( val = some_date off = 0 len = 4 with = `2025` ). "20250102
"Offset and length specifications
+"Read access
+DATA(off_len_spec_year) = some_date(4). "2024
+DATA(off_len_spec_year_2) = some_date+0(4). "2024
+DATA(off_len_spec_month) = some_date+4(2). "01
DATA(off_len_spec_day) = some_date+6(2). "02
+"Write access
some_date+4(2) = '10'. "20241002
+
+"Excursion: Comparison rules for character-like date types
+"The following example specifies an internal table that has a component
+"of type d. Using a ranges table and SELECT statements different table
+"entries are retrieved.
+"Note the comparison rule for type d (and type t): Content is compared
+"from left to right, and the first different character determines which
+"operand is greater.
+
+TYPES: BEGIN OF str_w_date,
+ num TYPE i,
+ date TYPE d,
+ END OF str_w_date,
+ tab_type_w_date TYPE TABLE OF str_w_date WITH EMPTY KEY.
+
+DATA(date_tab) = VALUE tab_type_w_date(
+ ( num = 1 date = '20241017' )
+ ( num = 2 date = '20241030' )
+ ( num = 3 date = '20241101' )
+ ( num = 4 date = '20241105' )
+ ( num = 5 date = '20241112' )
+ ( num = 6 date = '20241201' )
+ ( num = 7 date = '20241215' )
+ ( num = 8 date = '20241227' )
+ ( num = 9 date = '20241231' )
+ ( num = 10 date = '20250101' )
+ ( num = 11 date = '20250110' )
+ ( num = 12 date = '20250203' ) ).
+
+"Declaring a ranges table
+DATA rangestab TYPE RANGE OF d.
+
+"Populating a ranges table using VALUE
+"Include sign, including all December dates in the result set and all dates
+"earlier than November
+rangestab = VALUE #( sign = 'I'
+ option = 'BT' ( low = '20241201' high = '20241231' )
+ option = 'LT' ( low = '20241101' ) ).
+
+"Using a SELECT statement and the IN addition to retrieve internal table
+"content based on the ranges table specifications
+SELECT num FROM @date_tab AS dtab
+ WHERE date IN @rangestab
+ INTO TABLE @DATA(date_result1).
+"The result includes: 1, 2, 6, 7, 8, 9
+
+"Exclude sign, excluding all December dates in the result set
+rangestab = VALUE #( sign = 'E'
+ option = 'BT' ( low = '20241201' high = '20241231' ) ).
+
+SELECT num FROM @date_tab AS dtab
+ WHERE date IN @rangestab
+ INTO TABLE @DATA(date_result2).
+"The result includes: 1, 2, 3, 4, 5, 10, 11, 12
```
⬆️ back to top
### Numeric Access/Calculations
+
- When converting date fields to numeric values, the type `d` produces an integer representing the number of days since 01.01.0001.
- This is especially important when using date fields in calculations and converting the values to numeric types.
- The XCO library offers methods for performing calculations. In the code snippet, examples use the `value` attribute. The return value of the method calls is of type `string`. For more information, refer to the class documentation.
@@ -443,6 +504,15 @@ DATA(hour_extr) = substring( val = some_time off = 0 len = 2 ). "12
DATA(minute_extr) = substring( val = some_time off = 2 len = 2 ). "34
DATA(second_extr) = substring( val = some_time off = 4 len = 2 ). "56
+"Offset and length specifications
+"Read access
+DATA(off_len_spec_hour) = some_time(2). "12
+DATA(off_len_spec_hour_2) = some_time+0(2). "12
+DATA(off_len_spec_minutes) = some_time+2(2). "34
+DATA(off_len_spec_seconds) = some_time+4(2). "56
+"Write access
+some_time+4(2) = '10'. "123410
+
"Retrieving the current seconds, minutes, hours using XCO
"e.g. 59
DATA(sec_w_xco) = xco_cp=>sy->time( xco_cp_time=>time_zone->user )->second.
@@ -497,6 +567,109 @@ DATA(time_xco_subtr) = xco_cp=>sy->time( xco_cp_time=>time_zone->user
)->as( xco_cp_time=>format->iso_8601_extended
)->value.
+"------------ Calculating the time delta between two time values ------------
+
+DATA: time1 TYPE t VALUE '210000',
+ time2 TYPE t VALUE '040000'.
+
+"Calculating the time difference by subtracting
+"Note that the resulting data object is of type i.
+"The time values are automatically converted to type i.
+"Following the conversion rule of type t to i, the resulting value
+"is calculated as follows: format hhmmss of type t -> integer values
+"as a result of the calculation hh * 3600 + mm * 60 + ss.
+
+"-61200
+DATA(time_diff) = time2 - time1.
+
+"75600
+DATA(time1_conv2i) = CONV i( time1 ).
+ASSERT time1_conv2i = ( 21 * 3600 ) + ( 00 * 60 ) + 00.
+
+"14400
+DATA(time2_conv2i) = CONV i( time2 ).
+ASSERT time2_conv2i = ( 04 * 3600 ) + ( 00 * 60 ) + 00.
+ASSERT time2_conv2i - time1_conv2i = time_diff.
+
+"---- Calculating the total values of the time difference in seconds, minutes and hours ----
+"The MOD operator is used and works in a way that the positive remainder
+"of the division of the left operand by the right is returned. Therefore,
+"it is irrelevant whether the time difference value is either positive or
+"negative.
+"The value 86400 is used as right operand, representing the number of seconds
+"per day/24 hours.
+"25200
+DATA(time_diff_seconds_total) = ( time2 - time1 ) MOD 86400.
+
+"120.05
+DATA(time_diff_minutes_total) = CONV decfloat34( ( ( time2 - time1 ) MOD 86400 ) / 60 ).
+
+"2.000833333333333333333333333333333
+DATA(time_diff_hours_total) = CONV decfloat34( ( ( ( time2 - time1 ) MOD 86400 ) / 3600 ) ).
+
+"---- Representing the time difference in a data object of type t ----
+DATA diff_time TYPE t.
+
+DATA(diff) = ( time2 - time1 ) MOD 86400.
+
+"The following calculations use the DIV operator
+"This operator returns the integer part of the division of the left operand
+"by the right
+DATA(hours) = diff DIV 3600.
+diff = diff MOD 3600.
+DATA(minutes) = diff DIV 60.
+DATA(seconds) = diff MOD 60.
+
+"diff_time: '070000'
+diff_time(2) = hours.
+diff_time+2(2) = minutes.
+diff_time+4(2) = seconds.
+
+"More examples
+time1 = '225958'.
+time2 = '010001'.
+
+"diff_time: '020003'
+diff_time(2) = ( ( time2 - time1 ) MOD 86400 ) DIV 3600.
+diff_time+2(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) DIV 60.
+diff_time+4(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) MOD 60.
+
+time1 = '010001'.
+time2 = '225958'.
+
+"diff_time: '215957'
+diff_time(2) = ( ( time2 - time1 ) MOD 86400 ) DIV 3600.
+diff_time+2(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) DIV 60.
+diff_time+4(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) MOD 60.
+
+"diff_time: '154342'
+time1 = '132415'.
+time2 = '050757'.
+diff_time(2) = ( ( time2 - time1 ) MOD 86400 ) DIV 3600.
+diff_time+2(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) DIV 60.
+diff_time+4(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) MOD 60.
+
+time1 = '050757'.
+time2 = '132415'.
+
+"diff_time: '081618'
+diff_time(2) = ( ( time2 - time1 ) MOD 86400 ) DIV 3600.
+diff_time+2(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) DIV 60.
+diff_time+4(2) = ( ( ( time2 - time1 ) MOD 86400 ) MOD 3600 ) MOD 60.
+
+"---- Excursion: / and DIV operators (and why DIV is used above) ----
+time1 = '132415'.
+time2 = '050757'.
+
+"Compare the result of the following statements that use different operators
+"15
+DATA(hours_w_div) = ( ( time2 - time1 ) MOD 86400 ) DIV 3600.
+
+"16 (result of type i, result is rounded)
+DATA(hours_no_div) = ( ( time2 - time1 ) MOD 86400 ) / 3600.
+"15.72833333333333333333333333333333
+DATA(hours_no_div_dec) = CONV decfloat34( ( ( time2 - time1 ) MOD 86400 ) / 3600 ).
+
"------------ Conversions with the CL_ABAP_TIMEFM class ------------
"Using the CL_ABAP_TIMEFM class, you can perform conversions with external
diff --git a/24_Builtin_Functions.md b/24_Builtin_Functions.md
index 64c08ab..a0bf8ab 100644
--- a/24_Builtin_Functions.md
+++ b/24_Builtin_Functions.md
@@ -16,7 +16,7 @@
- [More (Special) Functions](#more-special-functions)
- [coalesce Function](#coalesce-function)
- [More Information](#more-information)
- - [Executable Examples](#executable-examples)
+ - [Executable Example](#executable-example)
This ABAP cheat sheet includes a variety of built-in functions in ABAP, along with code snippets to demonstrate their functionality. Many of the functions covered here are also included in other ABAP cheat sheets that focus on specific topics.
@@ -1751,7 +1751,7 @@ SELECT tab2~key_field,
- [Overview of functions](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuilt_in_functions_overview.htm)
- [Built-in functions that can be used by ABAP CDS and ABAP SQL](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenddic_builtin_functions.htm)
-## Executable Examples
+## Executable Example
[zcl_demo_abap_builtin_func](./src/zcl_demo_abap_builtin_func.clas.abap)
|