This commit is contained in:
danrega
2024-10-15 14:10:37 +02:00
parent 0cf1aa18ae
commit f5f9fbf35f
4 changed files with 270 additions and 13 deletions

View File

@@ -57,6 +57,7 @@
- [Excursions](#excursions)
- [Improving Read Performance with Secondary Table Keys](#improving-read-performance-with-secondary-table-keys)
- [Example: Exploring Read Access Performance with Internal Tables](#example-exploring-read-access-performance-with-internal-tables)
- [Generic Table Types with Formal Parameters of Methods and Field Symbols](#generic-table-types-with-formal-parameters-of-methods-and-field-symbols)
- [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)
- [Comparing Content of Compatible Internal Tables](#comparing-content-of-compatible-internal-tables)
@@ -2723,6 +2724,58 @@ DATA(itab) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ( `d` ) ( `e` ) ).
"5
DATA(number_of_lines) = lines( itab ).
"Excursion: Finding out the number of lines in a table by specifying concrete
"component values, e.g. you want to find out how many lines exist in the table
"that have the value 1 for comp2
TYPES: BEGIN OF struct,
comp1 TYPE c LENGTH 3,
comp2 TYPE i,
END OF struct,
tab_type TYPE TABLE OF struct WITH EMPTY KEY.
DATA(it) = VALUE tab_type( ( comp1 = 'a' comp2 = 1 )
( comp1 = 'b' comp2 = 1 )
( comp1 = 'c' comp2 = 1 )
( comp1 = 'd' comp2 = 2 )
( comp1 = 'e' comp2 = 3 )
( comp1 = 'f' comp2 = 4 )
( comp1 = 'g' comp2 = 5 ) ).
"7
DATA(line_num) = lines( it ).
"Finding out the number of lines in a table by component value, e.g.
"using constructor expressions and specifying a WHERE clause.
"The example creates an new internal table inline using VALUE and a FOR loop,
"specified with a WHERE clause. The lines function is applied to the
"table created inline.
"3
DATA(line_num_filtered1) = lines( VALUE tab_type( FOR wa IN it WHERE ( comp2 = 1 ) ( wa ) ) ).
"Using the REDUCE operator
"The example adds 1 to the resulting integer if the comp2 value of the iterated line is greater than 1.
"The lines function is not relevant in the example.
"4
DATA(line_num_filtered2) = REDUCE i( INIT var = 0
FOR <line> IN it
WHERE ( comp2 > 1 )
NEXT var += 1 ).
"Using the FILTER operator
"Note: The source table must have at least one sorted key or a hash key for accessing.
"If the table does not have such a primary table key, a secondary table key must be available.
TYPES: tab_type_sorted TYPE TABLE OF struct with NON-UNIQUE SORTED KEY sec_key COMPONENTS comp2.
DATA it_sorted type tab_type_sorted.
it_sorted = it.
"The example creates an new internal table inline using FILTER,
"specified with a WHERE clause. The lines function is applied to the
"table created inline.
"3
DATA(line_num_filtered3) = lines( FILTER #( it_sorted USING KEY sec_key WHERE comp2 = 1 ) ).
"4
DATA(line_num_filtered4) = lines( FILTER #( it_sorted USING KEY sec_key WHERE comp2 > 1 ) ).
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
@@ -3317,6 +3370,7 @@ SELECT SINGLE comp1, comp2, comp3 FROM @itab2 AS it WHERE comp3 = sstring`ABAP`
- Explicit specification is the recommended way because it is
easier to understand and can prevent unwanted sorting results,
especially with tables with standard key.
- You can also sort dynamically. For more information, refer to the [Dynamic Programming](06_Dynamic_Programming.md) cheat sheet.
<table>
@@ -4500,6 +4554,101 @@ ENDCLASS.
<p align="right"><a href="#top">⬆️ back to top</a></p>
### Generic Table Types with Formal Parameters of Methods and Field Symbols
- [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 with generic types.
- 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.
- Among them, there are generic table types. For more information, refer to the [Data Types and Objects](16_Data_Types_and_Objects.md) cheat sheet and the [documentation](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenbuilt_in_types_generic.htm).
- The following example mainly demonstrates formal parameters of methods that are typed with generic table types. The method calls and the tables passed are only possible if the generic types fits. For example, you cannot pass a hashed table to a method whose importing parameter is typed with the generic type `INDEX TABLE`. Invalid method calls and table passing are commented out.
```abap
CLASS zcl_some_class DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
CLASS-METHODS process_any_table IMPORTING itab TYPE ANY TABLE.
CLASS-METHODS process_standard_tables1 IMPORTING itab TYPE STANDARD TABLE.
CLASS-METHODS process_standard_tables2 IMPORTING itab TYPE TABLE.
CLASS-METHODS process_sorted_tables IMPORTING itab TYPE SORTED TABLE.
CLASS-METHODS process_hashed_tables IMPORTING itab TYPE HASHED TABLE.
CLASS-METHODS process_index_tables IMPORTING itab TYPE INDEX TABLE.
ENDCLASS.
CLASS zcl_some_class IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA standard_tab TYPE TABLE OF string WITH EMPTY KEY.
DATA sorted_tab TYPE SORTED TABLE OF string WITH NON-UNIQUE KEY table_line.
DATA hashed_tab TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line.
"ANY TABLE
process_any_table( standard_tab ).
process_any_table( sorted_tab ).
process_any_table( hashed_tab ).
"(STANDARD) TABLE
process_standard_tables1( standard_tab ).
"process_standard_tables1( sorted_tab ).
"process_standard_tables1( hashed_tab ).
process_standard_tables2( standard_tab ).
"process_standard_tables2( sorted_tab ).
"process_standard_tables2( hashed_tab ).
"SORTED TABLE
"process_sorted_tables( standard_tab ).
process_sorted_tables( sorted_tab ).
"process_sorted_tables( hashed_tab ).
"HASHED TABLE
"process_hashed_tables( standard_tab ).
"process_hashed_tables( sorted_tab ).
process_hashed_tables( hashed_tab ).
"INDEX TABLE
process_index_tables( standard_tab ).
process_index_tables( sorted_tab ).
"process_index_tables( hashed_tab ).
"Note: Field symbols can also be typed with generic types.
FIELD-SYMBOLS <fs_std_table> TYPE table.
ASSIGN standard_tab TO <fs_std_table>.
"ASSIGN sorted_tab TO <fs_std_table>.
"ASSIGN hashed_tab TO <fs_std_table>.
FIELD-SYMBOLS <fs_index_table> TYPE INDEX TABLE.
ASSIGN standard_tab TO <fs_index_table>.
ASSIGN sorted_tab TO <fs_index_table>.
"ASSIGN hashed_tab TO <fs_index_table>.
ENDMETHOD.
METHOD process_any_table.
ENDMETHOD.
METHOD process_hashed_tables.
ENDMETHOD.
METHOD process_index_tables.
ENDMETHOD.
METHOD process_sorted_tables.
ENDMETHOD.
METHOD process_standard_tables1.
ENDMETHOD.
METHOD process_standard_tables2.
ENDMETHOD.
ENDCLASS.
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
### Searching and Replacing Substrings in Internal Tables with Character-Like Data Types

View File

@@ -1580,14 +1580,23 @@ itab_ref = VALUE #( ( NEW demo_struct( col1 = 1 col2 = `aaa` col3 = `zzz` ) ) ).
"- Many of the following statements provide similar additions offering dynamic
" specifications, such as USING KEY and dynamic component name specifications.
"------- SORT ------
"----------------------------------------------------------
"------------------------ SORT (1) ------------------------
"----------------------------------------------------------
"Note: See more dynamic specifications with SORT statements
"further down.
"Named data object specified within parenteses
DATA(field_name) = 'COL1'.
SORT itab_ek BY (field_name) DESCENDING.
"Unnamed data object specified within parenteses
SORT itab_ek BY ('COL2') ASCENDING.
"------- READ TABLE ------
"-------------------------------------------------------------
"------------------------ READ TABLE ------------------------
"-------------------------------------------------------------
"Reading by specifying keys dynamically
"Implicitly specifying the table key values in a work area (USING KEY addition)
DATA(wa_read) = VALUE demo_struct( col2 = `aaa` ).
@@ -1626,7 +1635,10 @@ IF sy-subrc <> 0.
...
ENDIF.
"------- Table expressions ------
"-------------------------------------------------------------
"------------------------ Table expressions ------------------
"-------------------------------------------------------------
"Similar to READ TABLE statements, you can specify table lines with 3 alternatives:
"index read, read using free key, table key
"Also there, dynamic specifications are possible regarding the key specifications.
@@ -1652,7 +1664,10 @@ DATA(wa_te4) = itab[ KEY ('PRIMARY_KEY') COMPONENTS ('COL1') = 1 ].
itab[ 1 ]-('COL2') = `jkl`.
itab_ref[ 1 ]->('COL2') = `mno`.
"------- LOOP AT ------
"--------------------------------------------------------
"------------------------ LOOP AT -----------------------
"--------------------------------------------------------
"USING KEY addition: Overriding the standard order determined by the table category
LOOP AT itab REFERENCE INTO DATA(ref) USING KEY ('SK').
...
@@ -1676,7 +1691,10 @@ LOOP AT itab REFERENCE INTO ref WHERE (cond_loop).
...
ENDLOOP.
"------- INSERT ------
"--------------------------------------------------------
"------------------------ INSERT ------------------------
"--------------------------------------------------------
"The USING KEY addition (which accepts a dynamic specification) affects the order in which lines are inserted.
"Result of the following example when using the ...
@@ -1704,7 +1722,10 @@ LOOP AT itab INTO DATA(wa_pk) USING KEY ('PRIMARY_KEY').
APPEND wa_pk TO it_primekey_idx.
ENDLOOP.
"------- MODIFY ------
"--------------------------------------------------------
"------------------------ MODIFY ------------------------
"--------------------------------------------------------
"In the following example, a line is modified based on a work area and a table key.
"The component col1 is left out from the work area intentionally.
"If the primary table key was used, the value of sy-subrc would be 4, and no modification was done.
@@ -1723,7 +1744,10 @@ MODIFY itab INDEX 2 USING KEY ('SK') FROM VALUE #( col3 = `ttt` ) TRANSPORTING (
DATA(cond_mod) = `COL1 < 3`.
MODIFY itab FROM VALUE #( col3 = `sss` ) TRANSPORTING ('COL3') WHERE (cond_mod).
"------- DELETE ------
"--------------------------------------------------------
"------------------------ DELETE ------------------------
"--------------------------------------------------------
"A single line or multipled lines can be deleted.
"Note that DELETE ADJACENT DUPLICATES statements can also be specified using
"dynamic parts.
@@ -1746,6 +1770,87 @@ DATA(condition_tab) = VALUE string_table( ( `COL1 < 3` )
( `OR` )
( `COL3 = ``www``` ) ).
DELETE itab WHERE (condition_tab).
"--------------------------------------------------------
"------------------------ SORT (2) ------------------------
"--------------------------------------------------------
"Sorting by dynamically specified components in a sort table, i. e.an
"internal table of type abap_sortorder_tab.
"Notes:
"- Each line of this sort table specifies a component of the sort key.
"- If this table is initial, there is no sorting.
"- The sort priority is based on the order of the lines in the sort table.
TYPES: BEGIN OF struct,
comp1 TYPE i,
comp2 TYPE string,
comp3 TYPE c LENGTH 3,
END OF struct.
DATA it TYPE TABLE OF struct WITH EMPTY KEY.
it = VALUE #( ( comp1 = 1 comp2 = `B` comp3 = 'a' )
( comp1 = 1 comp2 = `A` comp3 = 'b' )
( comp1 = 2 comp2 = `D` comp3 = 'c' )
( comp1 = 2 comp2 = `C` comp3 = 'd' )
( comp1 = 3 comp2 = `F` comp3 = 'e' )
( comp1 = 3 comp2 = `E` comp3 = 'f' ) ).
DATA(it_original) = it.
"Note: The line type is abap_sortorder.
DATA(sort) = VALUE abap_sortorder_tab( ).
"No sorting because the sort table is initial.
SORT it BY (sort).
it = it_original.
"Note: Ascending is the default sort order. The following example flags
"the descending sort order explicitly.
sort = VALUE abap_sortorder_tab( ( name = `COMP1` descending = 'X' ) ).
SORT it BY (sort).
it = it_original.
sort = VALUE abap_sortorder_tab( ( name = `COMP1` descending = '' )
( name = `COMP2` descending = 'X' ) ).
SORT it BY (sort).
it = it_original.
"Sort priority based on the order of lines in the sort table
"In this example, the values of comp3 are set up so that a clear
"sort order is determined. Since the component is specified first in the
"sort table, this sorting has priority. Note the values of comp2 in the
"result table.
sort = VALUE abap_sortorder_tab( ( name = `COMP3` descending = 'X' )
( name = `COMP2` descending = 'X' ) ).
SORT it BY (sort).
"Specifying an invalid component name raises an exception
sort = VALUE abap_sortorder_tab( ( name = `XYZ` descending = 'X' ) ).
TRY.
SORT it BY (sort).
CATCH cx_sy_dyn_table_ill_comp_val INTO DATA(error).
ENDTRY.
ASSERT error IS NOT INITIAL.
it = it_original.
"Specifying an expression/functional method call whose result is a sort
"table of type abap_sortorder_tab
"In this case, BY is followed by the expression/functional method call,
"not enclosed in parentheses.
"The example shows expressions with sort tables created inline
SORT it BY VALUE abap_sortorder_tab( ( name = `COMP1` descending = 'X' ) ).
it = it_original.
DATA(comp_names) = VALUE string_table( ( `comp1` ) ( `comp2` ) ).
SORT it BY VALUE abap_sortorder_tab( FOR wa IN comp_names ( name = condense( to_upper( wa ) ) ) ).
```
<p align="right"><a href="#top">⬆️ back to top</a></p>

View File

@@ -488,12 +488,16 @@ fixed-length string does not include them.
Syntax examples:
``` abap
"strlen
DATA(len_c) = strlen( 'abc ' ). "3
DATA(len_str) = strlen( `abc ` ). "6
DATA(len_c_a) = strlen( 'abc ' ). "3
DATA(len_c_b) = strlen( ' abc ' ). "6
DATA(len_str_a) = strlen( `abc ` ). "6
DATA(len_str_b) = strlen( ` abc ` ). "9
"numofchar
len_c = numofchar( 'abc ' ). "3
len_str = numofchar( `abc ` ). "3
len_c_a = numofchar( 'abc ' ). "3
len_c_b = numofchar( ' abc ' ). "6
len_str_a = numofchar( `abc ` ). "3
len_str_a = numofchar( ` abc ` ). "6
DATA(xstr) = CONV xstring( `480065006C006C006F00200077006F0072006C0064002100` ).
DATA(len_xstr) = xstrlen( xstr ). "24

View File

@@ -1650,8 +1650,7 @@ instances](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?
`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.
- As a general rule, 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.