This commit is contained in:
danrega
2024-01-22 10:08:37 +01:00
parent 72c3f5f33c
commit b3e216cb0b
9 changed files with 89 additions and 66 deletions

View File

@@ -9,6 +9,7 @@
- [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)
@@ -364,13 +365,13 @@ address-city   = `349875 Botanica`.
``` abap
"# used: type of the operand can be implicitly derived
address = VALUE #( name   = `Mr. Duncan Pea`
                  street = `Vegetable Lane 11`.
                  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`.
                   street = `Vegetable Lane 11`
                   city   = `349875 Botanica` ).
"Nesting value operators
@@ -406,6 +407,31 @@ DATA(str_ref) = NEW struc_nested( a = 1
<p align="right"><a href="#top">⬆️ back to top</a></p>
### 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` ).
```
<p align="right"><a href="#top">⬆️ back to top</a></p>
### 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)

View File

@@ -62,7 +62,7 @@
position](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenwrite_position_glosry.htm "Glossary Entry").
In doing so, such a variable declared inline can be given the
appropriate type and result of the constructor expression in one
go: `DATA(dec) = VALUE decfloat34( '1.23' )`.
go: `DATA(strtable) = VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ).` or `DATA(dec) = CONV decfloat34( '1.23' ).`.
> **✔️ Hint**<br>
>- The construction of a result, i. e. a target [data
@@ -301,7 +301,7 @@ DATA(itab7) = VALUE tabtype( b = 'aaa' ( a = 1 c = `xxx` )
"ranges table.
TYPES int_tab_type TYPE TABLE OF i WITH EMPTY KEY.
"Populating an integer table with values from 1 to 20 (see iteration
"expressions with FOR furhter down)
"expressions with FOR further down)
DATA(inttab) = VALUE int_tab_type( FOR x = 1 WHILE x <= 20 ( x ) ).
DATA rangetab TYPE RANGE OF i.
@@ -386,7 +386,7 @@ MODIFY zdemo_abap_carr FROM TABLE @( VALUE #(
( carrid = 'ZZ'
carrname = 'ZZ Airways'
currcode = 'EUR'
url =  'some_url' ) ) ).
url =  'another_url' ) ) ).
```
> **💡 Note**<br>
@@ -439,7 +439,7 @@ Examples:
"The following examples demonstrate simple assignments
"with the CORRESPONDING operator using these syntax patterns.
"Note:
"- The examples show only a selection of pssible additions.
"- The examples show only a selection of possible additions.
"- There are various combinations of additions possible.
"- The effect of the statements is shown in lines commented out.
@@ -457,13 +457,13 @@ DATA: BEGIN OF s1,
a TYPE i,
b TYPE c LENGTH 3,
c TYPE c LENGTH 5,
END OF s1.
END OF s1.
DATA: BEGIN OF s2,
a TYPE i,
b TYPE c LENGTH 3,
d TYPE string,
END OF s2.
END OF s2.
"Populating structures
s1 = VALUE #( a = 1 b = 'aaa' c = 'bbbbb' ).
@@ -770,10 +770,11 @@ DATA(res) = 1 / 5.
TYPES inttab_type TYPE TABLE OF i WITH EMPTY KEY.
DATA itab TYPE SORTED TABLE OF i WITH NON-UNIQUE DEFAULT KEY.
FIELD-SYMBOLS <fs> TYPE inttab_type.
itab = VALUE #( ( 1 ) ( 2 ) ( 3 ) ).
"The following assignment is not possible due to incompatible types,
"although the internal table has the same line type (but there is a
"different table type and key).
"The following assignment is not possible due to incompatible types.
"The internal table has the same line type, but it has a different
"table type and key.
"ASSIGN itab TO <fs>.
"Using CONV to convert the internal table to the required table type.
@@ -797,7 +798,8 @@ DATA e TYPE decfloat34.
e = '0.4'.
"Redundant conversion
"Derives the string type automatically
"The variable derives the type (string) automatically from the
"literal with the backquotes on the right-hand side.
DATA(f) = `hallo`.
"Produces a syntax warning
"DATA(g) = CONV string( `hallo` ).
@@ -843,7 +845,7 @@ TRY.
CATCH cx_sy_conversion_data_loss.
ENDTRY.
"-------------- Lossless Calculations -------------
"-------------- Lossless calculations -------------
"The first statement works, whereas the second statement raises an exception.
"A rounding to two decimal places is required.
@@ -1032,7 +1034,7 @@ ELSE.
ENDIF.
"Multiple logical expressions initiated by WHEN
"Also LET expressions (see details further down) are possible.
"Also LET expressions are possible. See more details further down.
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 }.|
@@ -1051,12 +1053,12 @@ TRY.
DATA(div) = COND decfloat34( WHEN num1 <> 0 AND num2 <> 0 THEN num1 / num2
WHEN num1 = 0 AND num2 <> 0 THEN num1 / num2
ELSE THROW cx_sy_zerodivide( ) ).
CATCH cx_sy_zerodivide.
CATCH cx_sy_zerodivide.
DATA(two_zeros) = `Zero division`.
ENDTRY.
"Excursion: The following statement does not result in an error in ABAP (zero
"division 'allowed' if the first operand has also the value 0).
"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 (working like RAISE SHORTDUMP
@@ -1089,24 +1091,24 @@ DATA(operator) = '*'.
DATA(num1) = 5.
DATA(num2) = 7.
DATA(calc_result) = SWITCH #( operator
WHEN '+' THEN |{ num1 + num2 STYLE = SIMPLE }|
WHEN '-' THEN |{ num1 - num2 STYLE = SIMPLE }|
WHEN '*' THEN |{ num1 * num2 STYLE = SIMPLE }|
WHEN '/' THEN |{ CONV decfloat34( num1 / num2 ) STYLE = SIMPLE }|
ELSE `Wrong operator.` ).
WHEN '+' THEN |{ num1 + num2 STYLE = SIMPLE }|
WHEN '-' THEN |{ num1 - num2 STYLE = SIMPLE }|
WHEN '*' THEN |{ num1 * num2 STYLE = SIMPLE }|
WHEN '/' THEN |{ CONV decfloat34( num1 / num2 ) STYLE = SIMPLE }|
ELSE `Wrong operator.` ).
"A constructor expression as above instead of, for example, a CASE statement as follows.
CASE operator.
WHEN '+'.
calc_result = |{ num1 + num2 STYLE = SIMPLE }|.
WHEN '-'.
calc_result = |{ num1 - num2 STYLE = SIMPLE }|.
WHEN '*'.
calc_result = |{ num1 * num2 STYLE = SIMPLE }|.
WHEN '/'.
calc_result = |{ CONV decfloat34( num1 / num2 ) STYLE = SIMPLE }|.
WHEN OTHERS.
calc_result = `Wrong operator.`.
WHEN '+'.
calc_result = |{ num1 + num2 STYLE = SIMPLE }|.
WHEN '-'.
calc_result = |{ num1 - num2 STYLE = SIMPLE }|.
WHEN '*'.
calc_result = |{ num1 * num2 STYLE = SIMPLE }|.
WHEN '/'.
calc_result = |{ CONV decfloat34( num1 / num2 ) STYLE = SIMPLE }|.
WHEN OTHERS.
calc_result = `Wrong operator.`.
ENDCASE.
```
@@ -1225,10 +1227,9 @@ DATA(time_of_day) = CONV string(
"Getting a particular column name of an existing internal table using RTTI
"An internal table (it contains information on the table's structured type; the
"component names, among others) is assigned to a data object that is declared
"inline. This is an example of how powerful constructor expressions (and inline
"declarations) are: You can make code more concise. Think of extra declarations
"for the data objects, or using the older ?= operator for the casts. Many more
"lines of code would be required.
"inline. This is an example of making code more concise with constructor expressions
"and inline declarations. Assume you use extra declarations for the data objects, or
"use the older ?= operator for the casts. Many more lines of code are required.
DATA(components) = CAST cl_abap_structdescr( CAST cl_abap_tabledescr(
cl_abap_typedescr=>describe_by_data( it ) )->get_table_line_type( ) )->components.
DATA(comp2_a) = components[ 2 ]-name. "COMP2
@@ -1339,8 +1340,8 @@ TYPES: BEGIN OF s,
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 ) ).
( col1 = 'bb' col2 = 2 col3 = 10 )
( col1 = 'ccc' col2 = 3 col3 = 20 ) ).
"-------------- Table iterations --------------
@@ -1552,8 +1553,8 @@ TYPES: BEGIN OF s,
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 ) ).
( col1 = 'bb' col2 = 2 col3 = 10 )
( col1 = 'ccc' col2 = 3 col3 = 20 ) ).
"---------- Table iterations ----------

View File

@@ -654,10 +654,11 @@ DATA(ref_bound) = COND #( WHEN ref_carr IS BOUND THEN ref_carr->carrid ELSE `is
"However, the garbage collector takes care of removing the references
"automatically once the data is not used any more by a reference.
CLEAR ref_carr.
```
******************************************************
"Excursion: Generic data references and field symbols
**Excursion: Generic data references and field symbols**
```abap
"Non-generic type
DATA ref_int TYPE REF TO i.
ref_int = NEW #( ).

View File

@@ -1,8 +1,8 @@
<a name="top"></a>
# ABAP SQL: Grouping Internal Tables
# Internal Tables: Grouping
- [ABAP SQL: Grouping Internal Tables](#abap-sql-grouping-internal-tables)
- [Internal Tables: Grouping](#internal-tables-grouping)
- [Introduction](#introduction)
- [Grouping by One Column](#grouping-by-one-column)
- [Grouping by More than One Column](#grouping-by-more-than-one-column)

View File

@@ -426,7 +426,7 @@ Further keywords for defining loops are as follows. They are not dealt with here
- [`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`. See the example class for the internal table cheat sheet.
- 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.
<p align="right"><a href="#top">⬆️ back to top</a></p>

View File

@@ -52,7 +52,7 @@ Data objects:
> **💡 Note**<br>
> There are several differentations that further distinguish and characterize data types and objects. See [here](#glossary-terms-in-a-nutshell).
> 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).
<p align="right"><a href="#top">⬆️ back to top</a></p>
@@ -1446,8 +1446,7 @@ Find more information in the [cheat sheet about dynamic programming](06_Dynamic_
- 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 (see iteration
"expressions with FOR furhter down)
"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 ) ).

View File

@@ -174,7 +174,7 @@ ENDIF.
- Allows you to parse and render XML data in a token-based (iterating across all nodes, i.e. tokens, in the tree structure of the XML data) and object-oriented way (wrapping methods of the token-based access; providing an object-oriented way to access XML nodes)
- Unlike iXML, ...
- more formats are possible (standard XML 1.0, but also XOP, binary XML, and JSON).
- no document is created in DOM format (if you do not need to a DOM representation and DTDs, sXML is a more performant alternative to iXML).
- no document is created in DOM format (if you do not need a DOM representation and DTDs, sXML is a more performant alternative to iXML).
Creating XML data using sXML:

View File

@@ -1456,21 +1456,17 @@ CLASS zcl_some_class DEFINITION
"Data types and objects for the data cluster
"that contains information to be output
TYPES: BEGIN OF bline,
id TYPE i,
clstr TYPE x LENGTH 100,
END OF bline.
CLASS-DATA buffer TYPE TABLE OF bline WITH EMPTY KEY.
DATA itab TYPE string_table.
CLASS-DATA buffer TYPE xstring.
DATA obj TYPE string.
DATA parallel_log TYPE string_table.
DATA jtab TYPE string_table.
DATA inst_name TYPE string.
"Structure to hold information for the output
DATA: BEGIN OF info,
name TYPE string,
tmstmp TYPE utclong,
END OF info.
"Preparing the data cluster
METHODS handle_cluster IMPORTING name TYPE string_table.
METHODS handle_cluster IMPORTING name TYPE string.
ENDCLASS.
CLASS zcl_some_class IMPLEMENTATION.
@@ -1489,16 +1485,16 @@ CLASS zcl_some_class IMPLEMENTATION.
"purposes. The handle_cluster method is used to manually
"provide the name of the object reference variable for
"output purposes.
handle_cluster( VALUE #( ( `inst1` ) ) ).
handle_cluster( `inst1` ).
DATA(inst1) = NEW zcl_some_class( ).
handle_cluster( VALUE #( ( `inst2` ) ) ).
handle_cluster( `inst2` ).
DATA(inst2) = NEW zcl_some_class( ).
handle_cluster( VALUE #( ( `inst3` ) ) ).
handle_cluster( `inst3` ).
DATA(inst3) = NEW zcl_some_class( ).
handle_cluster( VALUE #( ( `inst4` ) ) ).
handle_cluster( `inst4` ).
DATA(inst4) = NEW zcl_some_class( ).
WAIT UP TO 1 SECONDS.
@@ -1548,7 +1544,7 @@ CLASS zcl_some_class IMPLEMENTATION.
"A data cluster is used to have a self-contained example class
"that can be run with F9.
TRY.
IMPORT itab = jtab FROM INTERNAL TABLE buffer.
IMPORT str = inst_name FROM DATA BUFFER buffer.
CATCH cx_sy_import_format_error INTO DATA(error).
ENDTRY.
@@ -1558,7 +1554,7 @@ CLASS zcl_some_class IMPLEMENTATION.
"expected to be the only input in the table, as well as
"a time stamp to compare with other time stamps that are
"output.
info = VALUE #( name = VALUE #( jtab[ 1 ] OPTIONAL )
info = VALUE #( name = inst_name
tmstmp = utclong_current( ) ).
ENDIF.
ENDMETHOD.
@@ -1568,8 +1564,8 @@ CLASS zcl_some_class IMPLEMENTATION.
"pass the name of the object reference variable that
"was added manually via the input parameter 'name'.
CLEAR buffer.
itab = name.
EXPORT itab = itab TO INTERNAL TABLE buffer.
obj = name.
EXPORT str = obj TO DATA BUFFER buffer.
ENDMETHOD.
ENDCLASS.
```

View File

@@ -72,7 +72,7 @@ ABAP cheat sheets[^1] ...
|[ABAP for RAP: Entity Manipulation Language (ABAP EML)](08_EML_ABAP_for_RAP.md)| Setting EML in the context of RAP, standard (create, read, update, delete) and non-standard operations (actions) | <ul><li>[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)</li><br><li>[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)</li><br><li>[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) <br>Note that this example can also be checked out using the preview version of an SAP Fiori UI. Check the comments in the class for the steps.</li></ul> |
|[Excursion Down to Bits and Bytes](09_Bits_and_Bytes.md)|Covers the technical background of data types and data objects|-|
|[ABAP SQL: Working with Hierarchies](10_ABAP_SQL_Hierarchies.md)|Summarizes the functions ABAP SQL offers together with ABAP CDS for working with hierarchical data that is stored in database tables|-|
|[ABAP SQL: Grouping Internal Tables](11_ABAP_SQL_Grouping_Internal_Tables.md)|Covers the `GROUP BY` clause in ABAP SQL|[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap)|
|[Internal Tables: Grouping](11_Internal_Tables_Grouping.md)|Covers the `GROUP BY` clause in statements for internal tables.|[zcl_demo_abap_sql_group_by](./src/zcl_demo_abap_sql_group_by.clas.abap)|
|[ABAP Managed Database Procedures (AMDP)](12_AMDP.md)|Covers ABAP Managed Database Procedures (AMDP): AMDP Procedures and AMDP Functions (including CDS Table Functions)|[zcl_demo_abap_amdp](./src/zcl_demo_abap_amdp.clas.abap)|
|[Program Flow Logic](13_Program_Flow_Logic.md)|Deals with control structures (`IF`, `CASE`), loops (`DO`, `WHILE`) and exception handling|[zcl_demo_abap_prog_flow_logic](./src/zcl_demo_abap_prog_flow_logic.clas.abap)|
|[ABAP Unit Tests](14_ABAP_Unit_Tests.md)|Contains basic information about unit testing in ABAP|[zcl_demo_abap_unit_test](./src/zcl_demo_abap_unit_test.clas.abap)|