diff --git a/02_Structures.md b/02_Structures.md index 22b5e37..f19a991 100644 --- a/02_Structures.md +++ b/02_Structures.md @@ -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

⬆️ back to top

+### 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` ). +``` + +

⬆️ back to top

+ ### 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) diff --git a/05_Constructor_Expressions.md b/05_Constructor_Expressions.md index 4646046..665e4de 100644 --- a/05_Constructor_Expressions.md +++ b/05_Constructor_Expressions.md @@ -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**
>- 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**
@@ -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 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 . "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 ---------- diff --git a/06_Dynamic_Programming.md b/06_Dynamic_Programming.md index b9b7ee3..160b6e7 100644 --- a/06_Dynamic_Programming.md +++ b/06_Dynamic_Programming.md @@ -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 #( ). diff --git a/11_ABAP_SQL_Grouping_Internal_Tables.md b/11_Internal_Tables_Grouping.md similarity index 97% rename from 11_ABAP_SQL_Grouping_Internal_Tables.md rename to 11_Internal_Tables_Grouping.md index 019f05c..72a2883 100644 --- a/11_ABAP_SQL_Grouping_Internal_Tables.md +++ b/11_Internal_Tables_Grouping.md @@ -1,8 +1,8 @@ -# 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) diff --git a/13_Program_Flow_Logic.md b/13_Program_Flow_Logic.md index ae80ce4..b297a93 100644 --- a/13_Program_Flow_Logic.md +++ b/13_Program_Flow_Logic.md @@ -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.

⬆️ back to top

diff --git a/16_Data_Types_and_Objects.md b/16_Data_Types_and_Objects.md index 19195de..fb9d060 100644 --- a/16_Data_Types_and_Objects.md +++ b/16_Data_Types_and_Objects.md @@ -52,7 +52,7 @@ Data objects: > **💡 Note**
-> 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).

⬆️ back to top

@@ -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 ) ). diff --git a/21_XML_JSON.md b/21_XML_JSON.md index 2033b3d..1f99e63 100644 --- a/21_XML_JSON.md +++ b/21_XML_JSON.md @@ -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: diff --git a/22_Misc_ABAP_Classes.md b/22_Misc_ABAP_Classes.md index 37c07f3..fac17ad 100644 --- a/22_Misc_ABAP_Classes.md +++ b/22_Misc_ABAP_Classes.md @@ -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. ``` diff --git a/README.md b/README.md index e1eedec..39423c6 100644 --- a/README.md +++ b/README.md @@ -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) | | |[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)|