diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md index ed9baeb..1a799c7 100644 --- a/01_Internal_Tables.md +++ b/01_Internal_Tables.md @@ -5,7 +5,7 @@ - [Internal Tables](#internal-tables) - [Introduction](#introduction) - [Basic Properties of Internal Tables](#basic-properties-of-internal-tables) - - [Table Keys in Internal Tables (Primary, Secondary, Standard, Empty)](#table-keys-in-internal-tables-primary-secondary-standard-empty) + - [Table Keys (Primary, Secondary, Standard, Empty) and Table Indexes](#table-keys-primary-secondary-standard-empty-and-table-indexes) - [Creating Internal Tables and Types](#creating-internal-tables-and-types) - [Populating Internal Tables](#populating-internal-tables) - [Copying Internal Tables](#copying-internal-tables) @@ -128,7 +128,7 @@ Internal Tables ...

⬆️ back to top

-## Table Keys in Internal Tables (Primary, Secondary, Standard, Empty) +## Table Keys (Primary, Secondary, Standard, Empty) and Table Indexes
Expand to view the details @@ -144,7 +144,7 @@ Internal Tables ... - Note that the key fields in sorted and hashed tables are read-only. This is not valid for standard tables. - The specification of the primary key can be omitted only for standard tables. The primary table key is then automatically defined as a non-unique standard key. - The primary table key has the predefined name `primary_key`, by which it can also be addressed explicitly. However, its use is optional, and it is usually not necessary to specify it explicitly. You can also specify an alias name for the primary key. -- When accessing internal tables using the table key, the primary key is always used implicitly in processing statements if no secondary key is specified. Note that the primary table key must be specified in table expressions if the primary key is to be used explicitly. +- When accessing internal tables using the table key, the primary key is always used implicitly in processing statements if no secondary key is specified. Note that the primary table key must be specified in table expressions if the primary key is to be used explicitly. > **💡 Note**
> The key can consist of individual key fields or the entire line of the internal table. In this case, the pseudo component `table_line` can be used to denote the primary table key. For non-structured line types, this is the only way to define the key. @@ -175,13 +175,18 @@ Internal Tables ... if an unstructured line type is tabular. - Note: When using an [inline declaration](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abeninline_declaration_glosry.htm "Glossary Entry") such as `... INTO TABLE @DATA(itab) ...` in `SELECT` statements, the resulting table is a standard table and has an empty key. +> **💡 Primary table index**
+> - Index tables, such as sorted and standard tables, have a primary table index. +> - Each table line receives a unique line number from the primary table index. +> - The index updates each time a line is added or removed. + **Secondary table keys** - Secondary table keys ... - are optional for all table categories. - can be unique/non-unique sorted keys or unique hash keys. - have a self-defined name. An alias name can also be specified. -- A secondary table index is created internally for each sorted secondary key. This allows index access to hashed tables via the secondary table key. In this case, `sy-tabix` is set. +- A [secondary table index](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_index_glosry.htm) is created internally for each sorted secondary key. This allows index access to hashed tables via the secondary table key. In this case, `sy-tabix` is set. - When accessing internal tables using the secondary table key, the key name (or the alias if specified) must be specified. They are not selected automatically. If no secondary key is specified in a processing statement, the primary key or primary table index is always used. If you want to make use of this key in ABAP statements, for example, `READ`, `LOOP AT` or `MODIFY` statements, you must specify the key explicitly using the appropriate additions, for example, `WITH ... KEY ... COMPONENTS` or `USING KEY`. - Use cases: - To improve read performance. @@ -193,7 +198,7 @@ Internal Tables ... > **💡 Note**
> - See examples of internal table declarations using the table keys mentioned above in the following section. -> - See an example that uses secondary table keys [below](#improving-read-performance-with-secondary-table-keys). +> - See more information and examples that focus on table access using keys and index below.
@@ -3927,7 +3932,7 @@ REPLACE ALL OCCURRENCES OF `Z` ### Ranges Tables - Internal tables that have the predefined columns `SIGN`, `OPTION`, `LOW`, and `HIGH` - - `SIGN`: type c with length 1; indicates whether each line is included ('I') or excluded ('E') from the result set. + - `SIGN`: type c with length 1; indicates whether each line is included (`I`) or excluded (`E`) from the result set. - `OPTION`: type c with length 2; specifies the selection option for the condition. It uses comparison operators such as `EQ`, `NE`, `GE`, `GT`, `LE`, `LT`, `CP`, `NP`, `BT`, `NB`. Special rules apply for certain operators such as when using `CP` or `NP`, the `LOW` and `HIGH` columns must be character values. - `LOW`: The lower comparison value. - `HIGH`: The higher comparison value. diff --git a/04_ABAP_Object_Orientation.md b/04_ABAP_Object_Orientation.md index 834a25d..3282dd5 100644 --- a/04_ABAP_Object_Orientation.md +++ b/04_ABAP_Object_Orientation.md @@ -15,15 +15,17 @@ - [Methods](#methods) - [Parameter Interface](#parameter-interface) - [Constructors](#constructors) + - [Example for Method Definitions](#example-for-method-definitions) - [Working with Objects and Components](#working-with-objects-and-components) - [Declaring Object Reference Variables](#declaring-object-reference-variables) - [Creating Objects](#creating-objects) - [Working with Reference Variables](#working-with-reference-variables) - [Accessing Attributes](#accessing-attributes) - [Calling Methods](#calling-methods) + - [Excursion: Inline Declarations, Returning Parameters](#excursion-inline-declarations-returning-parameters) - [Method Chaining](#method-chaining) - [Self-Reference me](#self-reference-me) - - [Example Class](#example-class) + - [Excursion: Example Class](#excursion-example-class) - [Inheritance](#inheritance) - [Additions: ABSTRACT and FINAL](#additions-abstract-and-final) - [Redefining Methods](#redefining-methods) @@ -33,6 +35,7 @@ - [Defining Interfaces](#defining-interfaces) - [Implementing Interfaces](#implementing-interfaces) - [Interface Reference Variables and Accessing Objects](#interface-reference-variables-and-accessing-objects) + - [Excursion: Example Interface](#excursion-example-interface) - [Excursions](#excursions) - [Friendship](#friendship) - [Friendship between Global and Local Classes](#friendship-between-global-and-local-classes) @@ -343,10 +346,7 @@ ENDCLASS. ### Visibility of Components -In the class declaration part, you must specify (at least one of the) three -[visibility -sections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm "Glossary Entry") -and include class components to define their visibility. These visibility sections serve the purpose of encapsulation in ABAP Objects. For example, you do not want to make certain components publicly available for all users. The visibility sections are as follows: +In the class declaration part, you specify three [visibility sections](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvisibility_section_glosry.htm "Glossary Entry") and include class components to define their visibility. These visibility sections serve the purpose of encapsulation in ABAP Objects. For example, you do not want to make certain components publicly available for all users. The visibility sections are as follows: @@ -590,7 +590,9 @@ In the simplest form, methods can have no parameter at all. Apart from that, met instantiated and an instance is created. - Can have `IMPORTING` parameters and raise exceptions. -**Example for method definitions** +

⬆️ back to top

+ +#### Example for Method Definitions The following snippet shows multiple method definitions in the public section of a global class. Most of the formal @@ -898,6 +900,125 @@ class_name=>meth( EXPORTING i = j k = l RECEIVING m = DATA(n) ).

⬆️ back to top

+#### Excursion: Inline Declarations, Returning Parameters + +- The example code below highlights the convenience of inline declarations when defining target data objects for output parameters. +- This approach allows you to create data objects on the spot, eliminating the need for additional helper variables. +- It also mitigates the risk of type mismatches. +- However, when declaring a method with both exporting and returning parameters, it is not possible to specify target data objects for both inline at the same time in case of functional method calls. +- Additional code snippets illustrate various ways to use methods declared with returning parameters in expression positions. + +```abap +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + CLASS-METHODS meth1 IMPORTING i_str TYPE string + i_tab TYPE string_table OPTIONAL + EXPORTING e_dec TYPE decfloat34 + e_tab TYPE string_table + RETURNING VALUE(r_int) TYPE i. + CLASS-METHODS meth2 RETURNING VALUE(r_tab) TYPE string_table. + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + + +CLASS zcl_some_class IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + "Note: Calling the method in the same class means specifying 'zcl_some_class=>' is optional here. + + "Standalone method call + "Specifying target data objects for all output parameters + "Inline declarations are handy because you can create an + "appropriately typed data object in place. No need to + "create an extra variable, check on the type etc. + zcl_some_class=>meth1( + EXPORTING + i_str = `ABAP` + IMPORTING + e_dec = DATA(a) + e_tab = DATA(b) + RECEIVING + r_int = DATA(c) + ). + + "Functional method call + "The target data object of the returning parameter is specified on the left side of an assignment. + "Note: In this case, you cannot specify inline declarations for the exporting parameters. + DATA e TYPE decfloat34. + DATA f TYPE string_table. + DATA(g) = zcl_some_class=>meth1( + EXPORTING + i_str = `ABAP` + IMPORTING + "e_dec = DATA(h) + "e_tab = DATA(i) + e_dec = e + e_tab = f + ). + + "Benefits of returning parameters: They can, for example, be used in expressions + "The following snippets show a selection (and ignore the available exporting + "parameters). + + CASE zcl_some_class=>meth1( i_str = `ABAP` ). + WHEN 0. ... + WHEN 1. ... + WHEN OTHERS. ... + ENDCASE. + + IF zcl_some_class=>meth1( i_str = `ABAP` ) > 5. + ... + ELSE. + ... + ENDIF. + + "IF used with a predicative method call + "The result of the relational expression is true if the result of the functional + "method call is not initial and false if it is initial. The data type of the result + "of the functional meth1od call, i. e. the return value of the called function method, + "is arbitrary. A check is made for the type-dependent initial value. + IF zcl_some_class=>meth1( i_str = `ABAP` ). + ... + ELSE. + ... + ENDIF. + + DO zcl_some_class=>meth1( i_str = `ABAP` ) TIMES. + ... + ENDDO. + + "Method call result as actual parameter + DATA(j) = zcl_some_class=>meth1( i_str = `ABAP` i_tab = zcl_some_class=>meth2( ) ). + + "Examples of returning parameters typed with a table type + LOOP AT zcl_some_class=>meth2( ) INTO DATA(wa1). + ... + ENDLOOP. + + READ TABLE zcl_some_class=>meth2( ) INTO DATA(wa2) INDEX 1. + + ENDMETHOD. + + METHOD meth1. + ... "Method implementation + ENDMETHOD. + + METHOD meth2. + ... "Method implementation + ENDMETHOD. + +ENDCLASS. +``` + +

⬆️ back to top

+ ### Method Chaining As shown in the previous example, method chaining is possible for functional method calls (i.e. methods that have exactly one return value declared with `RETURNING`) at appropriate read positions. In this case, the method's return value is used as an ABAP operand. @@ -985,7 +1106,7 @@ ENDMETHOD.

⬆️ back to top

-### Example Class +### Excursion: Example Class The commented example class below explores various aspects covered in the previous sections. You can create a demo class called `zcl_demo_test` and copy and paste the following code. Once activated, you can choose *F9* in ADT to run the class. The example is designed to display output in the console that shows the result of calling different methods. @@ -2017,9 +2138,9 @@ ENDINTERFACE. implement the methods of the interface. The implementation is then relevant for a subclass inheriting from a superclass that includes such an interface declaration. Note that the whole class must be abstract. - The additions [`FINAL METHODS`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) followed by method names or [`ALL METHODS FINAL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapinterfaces_class.htm) for the `INTERFACES` statement in the declaration part of classes flag the method(s) as final. -- In the interface, methods can mark their implementation as optional using the additions [`DEFAULT - IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) - or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm). +- In the interface, methods can mark their implementation as optional using the additions [`DEFAULT IGNORE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm) or [`DEFAULT FAIL`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmethods_default.htm). + - `DEFAULT IGNORE`: When a method with such a declaration is called without an implementation, it behaves as though no implementation exists. + - `DEFAULT FAIL`: If an unimplemented method is called, it triggers the `CX_SY_DYN_CALL_ILLEGAL_METHOD` exception. Syntax for using interfaces in classes: @@ -2044,7 +2165,7 @@ CLASS class IMPLEMENTATION. ... ENDCLASS. -"Abstract class +"----------------------- Abstract class ----------------------- CLASS cl_super DEFINITION ABSTRACT. PUBLIC SECTION. INTERFACES intf ALL METHODS ABSTRACT. @@ -2140,6 +2261,206 @@ i_ref = NEW class( ).

⬆️ back to top

+### Excursion: Example Interface + +Expand the following collapsible section to view the code of an example. To try it out, create a demo interface named `zif_some_interface`, a class named `zcl_some_class`, and paste the code into the artifacts. After activation, choose *F9* in ADT to execute the class. The example is set up to display output in the console. + +
+ Expand to view the details + +
+ +Example interface: +```abap +INTERFACE zif_some_interface + PUBLIC . + + TYPES c3 type c length 3. + DATA add_result TYPE i. + CLASS-DATA: subtr_result TYPE i. + METHODS addition IMPORTING num1 TYPE i + num2 TYPE i. + CLASS-METHODS subtraction IMPORTING num1 TYPE i + num2 TYPE i. + + METHODS meth_ignore DEFAULT IGNORE returning value(int) type i. + METHODS meth_fail DEFAULT FAIL returning value(int) type i. + +ENDINTERFACE. +``` + +When you have activated the interface, create the class. The following steps comment on various things. + +Example class implementations: + +1) +- When you create the class, you can add `INTERFACES zif_some_interface.` to the public visibility section. +- Using the quick fix in ADT, you can automatically add the method implementation skeletons of the interface methods. +- Note that the interface methods declared with `DEFAULT IGNORE` and `DEFAULT FAIL` are not automatically added. If implementations are desired, you can manually add the implementations for these methods. See the following step. +- The example class also implements the interface `if_oo_adt_classrun`. + +```abap +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + INTERFACES zif_some_interface. + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + + +CLASS zcl_some_class IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + ENDMETHOD. + + METHOD zif_some_interface~addition. + ENDMETHOD. + + METHOD zif_some_interface~subtraction. + ENDMETHOD. + +ENDCLASS. +``` + +2) +- Adding the implementations for the interface methods declared with `DEFAULT IGNORE` and `DEFAULT FAIL`. + +```abap +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + INTERFACES zif_some_interface. + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + + +CLASS zcl_some_class IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + ENDMETHOD. + + METHOD zif_some_interface~addition. + ENDMETHOD. + + METHOD zif_some_interface~subtraction. + ENDMETHOD. + + METHOD zif_some_interface~meth_fail. + ENDMETHOD. + + METHOD zif_some_interface~meth_ignore. + ENDMETHOD. + +ENDCLASS. +``` + +3) +- The following example class represents an exectuable example that displays output in the ADT console. +- Apart from simple demo implementations, it includes alias names specified for interface components. +- The interface methods declared with `DEFAULT IGNORE` and `DEFAULT FAIL` are intentionally not implemented, but the methods are nevertheless called. + - Interface method declared with `DEFAULT IGNORE`: No implementation available, and no value is assigned for the returning parameter. Therefore, the value is initial. + - Interface method declared with `DEFAULT FAIL`: If the exception is not caught, a runtime error occurs. +- The example demonstrates method calls using object and interface reference variables. + +```abap +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + INTERFACES zif_some_interface. + ALIASES res FOR zif_some_interface~add_result. + ALIASES add FOR zif_some_interface~addition. + ALIASES subtr FOR zif_some_interface~subtraction. + PROTECTED SECTION. + PRIVATE SECTION. +ENDCLASS. + + +CLASS zcl_some_class IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + + "Examples using an object reference variable + DATA(oref) = NEW zcl_some_class( ). + + oref->add( num1 = 1 num2 = 2 ). + DATA(res1) = oref->res. + out->write( res1 ). + + oref->subtr( num1 = 1 num2 = 2 ). + DATA(res2) = oref->zif_some_interface~subtr_result. + out->write( res2 ). + + "Referring to a type declared in the interface + DATA char_a TYPE zif_some_interface~c3. + DATA char_b TYPE zif_some_interface=>c3. + + "Calling non-implemented methods + DATA(int_ig_a) = oref->zif_some_interface~meth_ignore( ). + ASSERT int_ig_a = 0. + + TRY. + DATA(int_fl_a) = oref->zif_some_interface~meth_fail( ). + CATCH cx_sy_dyn_call_illegal_method INTO DATA(error). + out->write( error->get_text( ) ). + ENDTRY. + + "Similar examples using an interface reference variable + DATA iref TYPE REF TO zif_some_interface. + iref = NEW zcl_some_class( ). + + iref->addition( num1 = 3 num2 = 5 ). + DATA(res3) = iref->add_result. + out->write( res3 ). + + iref->subtraction( num1 = 3 num2 = 5 ). + DATA(res4) = iref->subtr_result. + out->write( res4 ). + + "Referring to a type declared in the interface + DATA char_c TYPE iref->c3. + + "Calling non-implemented methods + DATA(int_ig_b) = iref->meth_ignore( ). + ASSERT int_ig_b = 0. + + TRY. + DATA(int_fl_b) = iref->meth_fail( ). + CATCH cx_sy_dyn_call_illegal_method INTO error. + out->write( error->get_text( ) ). + ENDTRY. + ENDMETHOD. + + METHOD add. + res = num1 + num2. + ENDMETHOD. + + METHOD subtr. + zif_some_interface~subtr_result = num1 - num2. + ENDMETHOD. +ENDCLASS. +``` + + +
+ +

⬆️ back to top

+ ## Excursions ### Friendship diff --git a/07_String_Processing.md b/07_String_Processing.md index f844deb..3af5663 100644 --- a/07_String_Processing.md +++ b/07_String_Processing.md @@ -21,7 +21,7 @@ - [Reversing Strings](#reversing-strings) - [Inserting Substrings into Strings](#inserting-substrings-into-strings) - [Overlaying Content](#overlaying-content) - - [Processing Substrings](#processing-substrings) + - [Accessing and Processing Substrings](#accessing-and-processing-substrings) - [Searching and Replacing](#searching-and-replacing) - [Searching for Specific Characters](#searching-for-specific-characters) - [Replacing Specific Characters in Strings](#replacing-specific-characters-in-strings) @@ -480,6 +480,7 @@ s1 = |{ '00001234' ALPHA = RAW }|. "00001234 fixed-length string does not include them. - To exclude trailing blanks in all cases, regardless of the data type, you can use the built-in [`numofchar`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenlength_functions.htm) function. +- [`xstrlen`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abendescriptive_functions_binary.htm) returns the number of bytes of a byte-like argument. Syntax examples: ``` abap @@ -490,6 +491,9 @@ DATA(len_str) = strlen( `abc ` ). "6 "numofchar len_c = numofchar( 'abc ' ). "3 len_str = numofchar( `abc ` ). "3 + +DATA(xstr) = CONV xstring( `480065006C006C006F00200077006F0072006C0064002100` ). +DATA(len_xstr) = xstrlen( xstr ). "24 ```

⬆️ back to top

@@ -549,7 +553,7 @@ statements to split strings in multiple segments. split can be stored in separate data objects or internal tables that have a character-like line type. - Note that if the number of specified targets is -less than the number of segments returned by the split, the last target receives the remaining unsplit segements. If more targets are specified, the targets that do not receive a segment are +less than the number of segments returned by the split, the last target receives the remaining unsplit segments. If more targets are specified, the targets that do not receive a segment are initialized. - Therefore, specifying individual targets with `SPLIT` statements is useful if the number of expected segments is known. @@ -659,9 +663,17 @@ SHIFT s3 RIGHT DELETING TRAILING ` `. "' hallo' (length is kept) "Removing trailing blanks in strings without leading blanks; "you can use the following sequence of statements DATA(s4) = `hallo `. +DATA(s5) = s4. SHIFT s4 RIGHT DELETING TRAILING ` `. "' hallo' SHIFT s4 LEFT DELETING LEADING ` `. "'hallo' +"To remove trailing blanks, you can also use the following method of the +"cl_abap_string_utilities class. +cl_abap_string_utilities=>del_trailing_blanks( CHANGING str = s5 ). +ASSERT s4 = s5. +"Note the c2str_preserving_blanks method for preserving trailing blanks +"when assigning text fields to data objects of type string. + "String functions with parameters s1 = `hallo`. @@ -785,7 +797,7 @@ OVERLAY txt1 WITH txt2 ONLY 'ab'.

⬆️ back to top

-## Processing Substrings +## Accessing and Processing Substrings - The string function [`substring`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm) allows you to specify the position (parameter `off`) and the length @@ -798,15 +810,11 @@ from the beginning of the string. - If `len` is not specified, the rest of the remaining characters is respected. If the offset and length are greater than the actual length of the string, the exception `CX_SY_RANGE_OUT_OF_BOUNDS` is raised. -- You may also encounter the syntax for accessing substrings by specifying the offset -and length using the `+` character after a variable. - - The length is specified in parentheses. Specifying an asterisk (`*`) means -that the rest of the remaining string is respected. - - This syntax option -even allows write access to substrings for fixed-length strings. Read -access is possible for both fixed-length and variable-length strings. - - However, this syntax can be confused with the use of tokens in the -context of dynamic programming. +- You can also access substrings by specifying certain data objects in certain positions using the data object name (field symbols and dereferenced data reference variables are also possible) and the length in parentheses. + - Additionally, you can specify the offset using the `+` character after a variable. + - Specifying the length with an asterisk (`*`) means that the rest of the remaining string is respected. + - This syntax option even allows write access to substrings for fixed-length strings. Read access is possible for both fixed-length and variable-length strings. + - However, this syntax can be confused with the use of tokens in the context of dynamic programming. - There are other string functions available for dealing with substrings, such as [`substring_after`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm), [`substring_before`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensubstring_functions.htm), @@ -835,15 +843,42 @@ s2 = substring( val = s1 off = 6 len = 5 ). "ipsum DATA(txt) = 'Lorem ipsum dolor sit amet'. "Type c -"Offset and length specification using the + sign after a variable -DATA(ch6) = txt+0(5). "Lorem +"Offset and length specification for substring access +"Length specification only in parentheses, no offset +"specification means starting from 0 +DATA(ch6) = txt(5). "Lorem + +"Offset specification using the + sign after a variable +"The following example corresponds to the previous one +"(offset 0 explicitly specified) +DATA(ch7) = txt+0(5). "Lorem + +DATA(ch8) = txt+6(5). "ipsum "* means respecting the rest of the remaining string -DATA(ch7) = txt+12(*). "dolor sit amet +DATA(ch9) = txt+12(*). "dolor sit amet +"Using the syntax in various contexts, e.g. modifying the +"text field CLEAR txt+11(*). "Lorem ipsum -txt+0(5) = 'Hallo'. "Hallo ipsum dolor sit amet +txt = 'Lorem ipsum dolor sit amet'. +txt(5) = 'Hallo'. "Hallo ipsum dolor sit amet +txt+7(3) = '###'. "Hallo i###m dolor sit amet + +"Field symbol +TYPES abc TYPE c LENGTH 26. +FIELD-SYMBOLS TYPE abc. +DATA(alphabet) = 'abcdefghijklmnopqrstuvwxyz'. +ASSIGN alphabet TO . +DATA(part_of_abc_1) = (3). "abc ++12(*) = '###'. "abcdefghijkl### + +"Data reference variable +alphabet = 'abcdefghijklmnopqrstuvwxyz'. +DATA(dref_str) = NEW abc( alphabet ). +DATA(part_of_abc_2) = dref_str->*+20(*). "uvwxyz +dref_str->*+25(1) = '#'. "abcdefghijklmnopqrstuvwxy# "Further string functions s1 = `aa1bb2aa3bb4`. @@ -1005,8 +1040,13 @@ statements to perform replacements directly on the source field. Syntax examples: ``` abap DATA(s1) = `___abc_def_____ghi_`. -DATA(s2) = translate( val = s1 from = `hi_` to = `##` ). "abcdefg## -s2 = translate( val = s1 from = `_` to = `##` ). "###abc#def#####ghi# +DATA(s2) = translate( val = s1 from = `hi_` to = `?!+` ). "+++abc+def+++++g?!+ + +"'from' specifies three characters, while 'to' only specifies two +s2 = translate( val = s1 from = `hi_` to = `?!` ). "abcdefg?! + +"'to' specifies more characters than 'from' +s2 = translate( val = s1 from = `_` to = `#?!` ). "###abc#def#####ghi# "TRANSLATE statement. The value after USING is interpreted as a string composed of character pairs. "Starting with the first pair, a search is performed in text for the diff --git a/13_Program_Flow_Logic.md b/13_Program_Flow_Logic.md index cb85565..e4e9db7 100644 --- a/13_Program_Flow_Logic.md +++ b/13_Program_Flow_Logic.md @@ -187,7 +187,7 @@ AND check_is_supplied( ) IS NOT INITIAL "expression is false, the result of boolc does not meet the condition IS INITIAL since "a blank and no empty string is returned. If this is desired, the function xsdbool "can be used instead of boolc. -AND boolc( check_is_supplied( ) ) = `X` +AND boolc( check_is_supplied( ) ) = 'X' "Result has the same ABAP type as abap_bool. AND xsdbool( check_is_supplied( ) ) = abap_true @@ -206,7 +206,7 @@ AND NOT to_lower( flag ) = 'X' AND ipow( base = num exp = 2 ) = 4 "Functional methods -"Method with exactly one return value +"Assume such a method exists having one return value AND addition( num1 = 1 num2 = 1 ) = 2 "Calculation expressions @@ -222,11 +222,11 @@ AND VALUE string_table( ( `a` ) ( `b` ) ( `c` ) ) = str_table "Table expression AND str_table[ 2 ] = `b`. - "All of the logical expressions are true. + ... "All of the logical expressions are true. ELSE. - "At least one of the logical expressions is false. + ... "At least one of the logical expressions is false. ENDIF. ``` @@ -388,7 +388,7 @@ ENDCASE. #### Excursion: `SWITCH` Operator -The conditional operator [`SWITCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_switch.htm) can also be used to make case distinctions in operand positions. As mentioned above for `COND`, a result is constructed. The same criteria apply for `SWITCH` as for `COND` regarding the type. See the ABAP Keyword Documentation and the cheat sheet on constructor expressions for more information. See also the [Constructor Expressions](05_Constructor_Expressions.md) cheat sheet for more information and examples. +The conditional operator [`SWITCH`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconditional_expression_switch.htm) can also be used to make case distinctions in operand positions. As mentioned above for `COND`, a result is constructed. The same criteria apply for `SWITCH` as for `COND` regarding the type. See also the ABAP Keyword Documentation and the [Constructor Expressions](05_Constructor_Expressions.md) cheat sheet for more information and examples. ```abap @@ -915,7 +915,7 @@ WAIT UP TO 3 SECONDS. ... "Second retrieval of the current time stamp after the WAIT statements DATA(ts2) = utclong_current( ). -"Calcularing the difference of the two time stamps +"Calculating the difference of the two time stamps cl_abap_utclong=>diff( EXPORTING high = ts2 low = ts1 IMPORTING seconds = DATA(seconds) ). @@ -1134,6 +1134,7 @@ ASSERT number > -1. ASSERT 1 = 1. DATA(flag) = abap_false. +"Raises a runtime error ASSERT flag = abap_true. ``` diff --git a/17_SAP_LUW.md b/17_SAP_LUW.md index 5a6ea51..ccafcb7 100644 --- a/17_SAP_LUW.md +++ b/17_SAP_LUW.md @@ -372,7 +372,7 @@ After the import of the repository, proceed as follows: > **💡 Note**
> - The executable example ... -> - demonstrates the SAP LUW using classic dynpros to provide a self-contained and simple example that highlights the considerations regarding implicit database commits, without putting the spotlight on dynpros. Note that classic dynpros are outdated for application programs. New developments should use web-based UIs, such as SAPUI5 or Web Dynpro. +> - demonstrates the SAP LUW using classic dynpros to provide a self-contained and simple example that highlights the considerations regarding implicit database commits, without putting the spotlight on dynpros. Note that classic dynpros are outdated for application programs. New developments should use web-based UIs, such as SAPUI5. > - covers the following topics in simple contexts: > - Demonstrating synchronous update, asynchronous update, and local update triggered by `COMMIT WORK`, `COMMIT WORK AND WAIT`, and `SET UPDATE TASK LOCAL` using update function modules. > - Demonstrating the statements `PERFORM ... ON COMMIT` and `PERFORM ... ON ROLLBACK` using subroutines. diff --git a/18_Dynpro.md b/18_Dynpro.md index a625620..a79bff7 100644 --- a/18_Dynpro.md +++ b/18_Dynpro.md @@ -28,7 +28,8 @@ ## Introduction -⚠️ The content of this cheat sheet and the executable example are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_abap_glosry.htm). +> **💡 Note**
+> The content of this cheat sheet and the executable example are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_abap_glosry.htm). [User interfaces (UI)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenuser_interface_glosry.htm) are not limited to displaying some information, they must also allow the user to interact with the program. In modern UI technologies, this can be achieved through [events](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenevent_glosry.htm), i.e. [user actions](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenuser_action_glosry.htm) on a UI trigger events, and UI methods register these events and react accordingly. In this way, users control the program flow through their actions. @@ -38,13 +39,13 @@ This is where [dynpros](https://help.sap.com/doc/abapdocu_latest_index_htm/lates This cheat sheet provides a high-level overview of classic dynpro topics with a focus on dynpro-related statements, supported by an executable example to check the syntax in action. > **💡 Note**
-> - Classic dynpros are outdated for application programs. New developments should use web-based UIs, such as SAPUI5 or Web Dynpro. +> - Classic dynpros are outdated for application programs. New developments should use web-based UIs, such as SAPUI5. > - Dynpros cannot be created in ABAP Cloud. > - This cheat sheet ... > - is not intended to encourage you to start creating classic dynpros for programming new applications. > - does not cover all facets, techniques, and keywords in great detail. > - is intended to cover a selection of dynpro-related topics and syntax that you may encounter in older ABAP code. If you need more information, always consult the ABAP Keyword Documentation. -> - Some of the statements described here - the ones used in the dynpro flow logic - are programmed in a special programming language. +> - The statements covered in the dynpro flow logic are specific to dynpros. > - Links to the ABAP Keyword Documentation in this cheat sheet refer to the documentation for [Standard ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenstandard_abap_glosry.htm) (latest version). ## About Dynpros @@ -52,8 +53,8 @@ This cheat sheet provides a high-level overview of classic dynpro topics with a - Stands for dynamic program, i.e. the program execution is dynmically controlled by user interactions - Can only be defined in [function groups](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenfunction_group_glosry.htm), [module pools](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenmodul_pool_glosry.htm) (not [class pools](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclass_pool_glosry.htm)) and [executable program](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenexecutable_program_glosry.htm) (*reports*; the focus in the cheat sheet is on the latter) - Can be identified by a unique, four-digit [dynpro number](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_number_glosry.htm) in an [ABAP program](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_program_glosry.htm). Note that leading zeros need not be specified when calling the dynpro. Number 1000 is reserved, as are other dynpro number ranges (e.g. used by SAP). The current dynpro can be retrieved using `sy-dynnr`. - - Is displayed in a window of [SAP GUI](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensap_gui_glosry.htm) - - Consists of the following main aspects: + - Are displayed in a window of [SAP GUI](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensap_gui_glosry.htm) + - Consist of the following main aspects: - Specific characteristics when creating the dynpro. To name a few: - Dynpro type: Defines whether the dynpro is displayed in the full GUI window (if *Normal* is selected), in a pop-up window (*Modal Dialog Box*), or as a subscreen in a specific area within another dynpro in the same ABAP program. - [Next dynpro](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abennext_dynpro_glosry.htm): Statically specifies the next dynpro to be displayed in a [dynpro sequence](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_sequence_glosry.htm). Setting the next dynpro to 0 or leaving the attribute blank will make the current dynpro the last dynpro in the sequence. If the next dynpro number is the same as the current dynpro, the dynpro continues to be called. The static next dynpro can be overwritten temporarily and dynamically in the ABAP program. @@ -63,11 +64,11 @@ This cheat sheet provides a high-level overview of classic dynpro topics with a - To add screen elements, use the [layout editor](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenlayout_editor_glosry.htm) of the [screen painter](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenscreen_painter_glosry.htm) tool. It is available only in the [ABAP Workbench](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenabap_workbench_glosry.htm). - For each screen element, you can define various static properties (attributes) that control its appearance. Double-clicking a screen element in the layout editor opens the attribute maintenance dialog box. - Various static attributes of the screen elements can be overwritten dynamically from within the ABAP program using special statements. - - Has its own data objects, called [dynpro fields](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_field_glosry.htm) (see more below) - - Is called either by another dynpro (as the next dynpro), by a [transaction code](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentransaction_code_glosry.htm) ([dialog transaction](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendialog_transaction_glosry.htm)), or by ABAP statements (e.g. `CALL SCREEN`). Several dynpros in a single ABAP program can be called in sequence to form a dynpro sequence. + - Have their own data objects, called [dynpro fields](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendynpro_field_glosry.htm) (see more below) + - Are called either by another dynpro (as the next dynpro), by a [transaction code](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abentransaction_code_glosry.htm) ([dialog transaction](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendialog_transaction_glosry.htm)), or by ABAP statements (e.g. `CALL SCREEN`). Several dynpros in a single ABAP program can be called in sequence to form a dynpro sequence. > **💡 Note**
-> There are special dynpros ([selection screens](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenselection_screen_glosry.htm), [classic lists](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_list_glosry.htm)). They are created implicitly. +> There are special dynpros ([selection screens](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenselection_screen_glosry.htm), [classic lists](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_list_glosry.htm)). They are created implicitly. See the [Selection Screens and Classic Lists](20_Selection_Screens_Lists.md) cheat sheet.

⬆️ back to top

@@ -76,7 +77,7 @@ This cheat sheet provides a high-level overview of classic dynpro topics with a - Represents the procedural part of a dynpro - Controls the dynpro processing, fills and processes the dynpro fields - Is defined in the *Flow Logic* tab in the screen painter -- Has its own programming language, similar to ABAP, but runs in AS ABAP +- The statements in the dynpro flow logic are specific to dynpro. Nevertheless, they run in AS ABAP. - Contains [processing blocks](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenprocessing_block_glosry.htm) introduced by special keywords - The processing blocks are executed in response to the [PAI](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenpai_glosry.htm), [PBO](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenpbo_glosry.htm), [POH](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenpoh_glosry.htm), and [POV](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenpov_glosry.htm) events of the corresponding ABAP program, and call [dialog modules](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abendialog_module_glosry.htm): diff --git a/20_Selection_Screens_Lists.md b/20_Selection_Screens_Lists.md index 52fadff..6b019ab 100644 --- a/20_Selection_Screens_Lists.md +++ b/20_Selection_Screens_Lists.md @@ -28,7 +28,8 @@ ## Introduction -⚠️ The content of this cheat sheet and the executable examples are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_abap_glosry.htm). +> **💡 Note**
+> The content of this cheat sheet and the executable examples are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_abap_glosry.htm). [Selection screens](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenselection_screen_glosry.htm) and [classic lists](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abenclassic_list_glosry.htm) are among the classic ABAP user interfaces. They are integrated into the ABAP language itself, which means that special ABAP statements are available to create and handle them. diff --git a/21_XML_JSON.md b/21_XML_JSON.md index 9a817ec..3336b4e 100644 --- a/21_XML_JSON.md +++ b/21_XML_JSON.md @@ -10,6 +10,7 @@ - [sXML](#sxml) - [XML Transformations](#xml-transformations) - [CALL TRANSFORMATION Syntax](#call-transformation-syntax) + - [Exploring CALL TRANSFORMATION Syntax Using the Predefined Identity Transformation ID](#exploring-call-transformation-syntax-using-the-predefined-identity-transformation-id) - [Working with JSON](#working-with-json) - [Creating and Reading JSON Data Using sXML](#creating-and-reading-json-data-using-sxml) - [Transforming JSON Data Using Transformations](#transforming-json-data-using-transformations) @@ -402,7 +403,7 @@ To perform transformations in ABAP, you can use: - Repository objects written in XSLT - XSLT can process ABAP data because ABAP data is first implicitly transformed into the asXML format. The result of this implicit transformation (the asXML format) is then used as the actual source for the XSL transformation. - Identity transformations - - SAP-delivered and predefined XSL transformation with the name `ID` + - Predefined XSL transformation with the name `ID` - Used to read and write the asXML (and also asJSON) format. - When the transformation ID is called, the resulting intermediate formats (asXML, asJSON) are the direct output. - When used, for example, to transform ABAP data, such as a structure, to XML, the transformation does not change the structure itself. You can, however, change the structure by implementing your own XSLT. @@ -495,7 +496,7 @@ CALL TRANSFORMATION ... SOURCE (srctab) **Specifying the result of the transformation** -There are multiple options. Check the executable example to see them in action. +There are multiple options. Check the executable example to explore them in action. ```abap "--------------------- Transforming to XML data ---------------------- @@ -524,6 +525,192 @@ CALL TRANSFORMATION ... SOURCE ...

⬆️ back to top

+#### Exploring CALL TRANSFORMATION Syntax Using the Predefined Identity Transformation ID + +The following example explores various syntax options for `CALL TRANSFORMATION` statements, using the predefined identity transformation `ID`. + +To try the example out, create a demo class named `zcl_some_class` and paste the code into it. After activation, choose *F9* in ADT to execute the class. The example is set up to display output in the console. + +```abap +CLASS zcl_some_class DEFINITION + PUBLIC + FINAL + CREATE PUBLIC . + + PUBLIC SECTION. + INTERFACES if_oo_adt_classrun. + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + + +CLASS zcl_some_class IMPLEMENTATION. + + METHOD if_oo_adt_classrun~main. + + TYPES: BEGIN OF line, + char TYPE c LENGTH 3, + int TYPE i, + END OF line, + t_type TYPE TABLE OF line WITH EMPTY KEY. + DATA(tab) = VALUE t_type( ( char = 'aaa' int = 1 ) + ( char = 'bbb' int = 2 ) + ( char = 'ccc' int = 3 ) ). + + out->write( `ABAP <-> XML using XSLT (Using the Predefined Identity Transformation ID)` ). + +********************************************************************** + + out->write( `-------- Transforming ABAP data: ... SOURCE ... --------` ). + "This section covers syntax options after SOURCE without XML. + + "ABAP (specifying ABAP data object) -> asXML/xstring + "itab stands for the name of the XML element (check ... ... in the output) + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML DATA(xml_tab_a). + + DATA(xml_a) = cl_abap_conv_codepage=>create_in( )->convert( xml_tab_a ). + out->write( data = xml_a name = `xml_a` ). + + "ABAP (specifying ABAP data objects dynamically using an internal table + "of type abap_trans_srcbind_tab) -> asXML/xstring + + DATA(srctab) = VALUE abap_trans_srcbind_tab( ( name = 'ITAB' value = REF #( tab ) ) ). + CALL TRANSFORMATION id SOURCE (srctab) + RESULT XML DATA(xml_tab_b). + + DATA(xml_b) = cl_abap_conv_codepage=>create_in( )->convert( xml_tab_b ). + out->write( data = xml_b name = `xml_b` ). + +********************************************************************** + + out->write( `-------- Transforming XML data: ... SOURCE XML ... --------` ). + "This section covers syntax options after SOURCE XML. + "Apart from data objects of type string or xstring containing XML data + "in XML 1.0 format, standard tables with flat character-like or byte-like + "line type, you can also specify certain references to iXML and sXML libraries + + "sxml/ixml references as source + "The examples use XML data from above + DATA(sxml_reader) = cl_sxml_string_reader=>create( xml_tab_a ). + + CALL TRANSFORMATION id SOURCE XML sxml_reader + RESULT XML DATA(xml_tab_c). + + DATA(xml_c) = cl_abap_conv_codepage=>create_in( )->convert( xml_tab_c ). + out->write( data = xml_c name = `xml_c` ). + + DATA(ixmlr) = cl_ixml_core=>create( ). + DATA(ixml_doc1) = ixmlr->create_document( ). + DATA(ixml_cr_streamr) = ixmlr->create_stream_factory( ). + DATA(ixml_i_stream) = ixml_cr_streamr->create_istream_xstring( xml_tab_a ). + + CALL TRANSFORMATION id SOURCE XML ixml_i_stream + RESULT XML DATA(xml_tab_d). + + DATA(xml_d) = cl_abap_conv_codepage=>create_in( )->convert( xml_tab_d ). + out->write( data = xml_d name = `xml_d` ). + +********************************************************************** + + out->write( `-------- Transforming to XML data: ... RESULT XML ... --------` ). + "This section covers syntax options after RESULT XML. + "Note: The following examples always use ABAP data objects as source + "(... SOURCE ...). + + "ABAP -> asXML/xstring + "This syntax option has already been used above. + "When declared inline, the target data object has the type xstring. + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML DATA(xml_tab_e). + + "Specifying a data object of type xstring + DATA xml_tab_f TYPE xstring. + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML xml_tab_f. + + "ABAP -> asXML/string + DATA str TYPE string. + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML str. + + "ABAP -> asXML/table with a flat character-like line type + TYPES c50 TYPE c LENGTH 50. + TYPES c50_tab_type TYPE TABLE OF c50 WITH EMPTY KEY. + DATA chartab TYPE c50_tab_type. + + "The following statement inlcudes the OPTIONS addition. + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML chartab + OPTIONS xml_header = 'NO'. + + out->write( data = chartab name = `chartab` ). + + "ABAP -> asXML/table with a flat byte-like line type + TYPES x50 TYPE x LENGTH 50. + TYPES x50_tab_type TYPE TABLE OF x50 WITH EMPTY KEY. + DATA xtab TYPE x50_tab_type. + "The following statement inlcudes the OPTIONS addition + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML xtab + OPTIONS xml_header = 'NO'. + + out->write( data = xtab name = `xtab` ). + + "iXML/sXML references + "Using an iXML output stream + DATA xstrg TYPE xstring. + DATA(ixml) = cl_ixml_core=>create( ). + DATA(ixml_doc) = ixml->create_document( ). + DATA(ixml_cr_stream) = ixml->create_stream_factory( ). + DATA(ixml_o_stream) = ixml_cr_stream->create_ostream_xstring( string = xstrg ). + + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML ixml_o_stream. + + ixml->create_renderer( document = ixml_doc + ostream = ixml_o_stream )->render( ). + + DATA(xml_from_ixml) = cl_abap_conv_codepage=>create_in( )->convert( xstrg ). + out->write( data = xml_from_ixml name = `xml_from_ixml` ). + + "Using an sXML writer + DATA(sxml) = CAST if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_xml10 + encoding = 'UTF-8' ) ). + CALL TRANSFORMATION id SOURCE itab = tab + RESULT XML sxml. + + DATA(xml_from_sxml) = CAST cl_sxml_string_writer( sxml )->get_output( ). + DATA(conv_xml_from_sxml) = cl_abap_conv_codepage=>create_in( )->convert( xml_from_sxml ). + out->write( data = conv_xml_from_sxml name = `conv_xml_from_sxml` ). + +********************************************************************** + + out->write( `-------- Transforming to ABAP data: ... RESULT ... --------` ). + + "This section covers syntax options after RESULT without XML. + "XML from above is used as source. + DATA tab_b LIKE tab. + CALL TRANSFORMATION id SOURCE XML xml_tab_a + RESULT itab = tab_b. + out->write( data = tab_b name = `tab_b` ). + + "An internal table of type abap_trans_resbind_tab can be specified. + DATA tab_c LIKE tab. + DATA(restab) = VALUE abap_trans_resbind_tab( ( name = 'ITAB' value = REF #( tab_c ) ) ). + + CALL TRANSFORMATION id SOURCE XML xml_tab_a + RESULT (restab). + + out->write( data = tab_c name = `tab_c` ). + ENDMETHOD. + +ENDCLASS. +``` + +

⬆️ back to top

+ ## Working with JSON - You can .. - create/render and read/parse JSON data in ABAP using the readers and writers in the sXML library. See the processing of XML data in the sXML section above. Parsing and rendering JSON data works in a similar way. However, instead of using XML readers/writers, you use JSON readers/writers. @@ -1090,7 +1277,7 @@ ENDCLASS. ### Serializing and Deserializing Objects -- To serialize and deserialize objects (i.e. instances of classes), you can use `CALL TRANSFORMATION` statements. As a prerequisite, the classes must implement the `IF_SERIALIZABLE_OBJECT` interface. +- To serialize and deserialize objects (i.e. instances of classes), you can use `CALL TRANSFORMATION` statements. As a prerequisite, the classes must implement the `IF_SERIALIZABLE_OBJECT` interface. The example uses the predefined identity transformation `ID`. - Find more information and examples [here](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenasxml_class_instances.htm) in the ABAP Keyword Documentation. @@ -1354,10 +1541,8 @@ ENDTRY. DATA(len_xstr_decomp) = xstrlen( xstr_decomp ). "101 DATA(conv_str) = cl_abap_conv_codepage=>create_in( )->convert( xstr_decomp ). -DATA(is_equal) = COND #( WHEN len_xstr = len_xstr_decomp - AND str = conv_str - THEN 'X' - ELSE '' ). "Result: X +"abap_true +DATA(is_equal) = xsdbool( len_xstr = len_xstr_decomp AND str = conv_str ). ``` ## More Information diff --git a/22_Misc_ABAP_Classes.md b/22_Misc_ABAP_Classes.md index 08c3dd9..2c7acdd 100644 --- a/22_Misc_ABAP_Classes.md +++ b/22_Misc_ABAP_Classes.md @@ -558,10 +558,8 @@ ENDTRY. DATA(len_xstr_decomp) = xstrlen( xstr_decomp ). "101 DATA(conv_str) = cl_abap_conv_codepage=>create_in( )->convert( xstr_decomp ). -DATA(is_equal) = COND #( WHEN len_xstr = len_xstr_decomp - AND str = conv_str - THEN 'X' - ELSE '' ). "Result: X +"abap_true +DATA(is_equal) = xsdbool( len_xstr = len_xstr_decomp AND str = conv_str ). "------- (De)compressing character strings ------- DATA zipped TYPE xstring.