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)