From 8c42134f334b5bd0890671266d7528e20e89d6ff Mon Sep 17 00:00:00 2001 From: danrega <16720986+danrega@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:13:50 +0100 Subject: [PATCH] Update --- 01_Internal_Tables.md | 86 +++++++++------- 04_ABAP_Object_Orientation.md | 30 +++--- 05_Constructor_Expressions.md | 13 +-- 06_Dynamic_Programming.md | 4 +- 07_String_Processing.md | 183 +++++++++++++++++++++++++++++++++- 16_Data_Types_and_Objects.md | 2 +- 21_XML_JSON.md | 2 +- 22_Released_ABAP_Classes.md | 95 ++++++++++++++++-- 23_Date_and_Time.md | 2 +- 9 files changed, 342 insertions(+), 75 deletions(-) diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md index ca83f24..e2b8172 100644 --- a/01_Internal_Tables.md +++ b/01_Internal_Tables.md @@ -199,11 +199,20 @@ Internal Tables ... - have a self-defined name. An alias name can also be specified. - 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`. +- The table access using secondary table keys is always optimized. - Use cases: - - To improve read performance. - - For very large internal tables (that are populated once and changed very often) + - To enable different key accesses for an internal table + - To enable an optimized key access to internal tables (i.e. to improve read performance), even for standard tables + - To enable index access for hashed tables - Standard tables, whose primary table keys cannot be unique, can be provided with a means of ensuring that unique table entries are read. - - Note that defining secondary table keys involves additional administration costs (additional memory consumption). Therefore, the use of secondary table keys should be reserved for cases where the benefits outweigh the extra costs. + - Typically used ... + - for large internal tables (that are populated once and infrequently changed) + - for smaller tables, especially standard tables, for ensuring uniqueness of entries (in standard tables, the primary key cannot be unique) + - if predominantly fast read accesses are required. Then non-unique sorted secondary table keys can be used, especially for existing internal tables because a later change of the table declaration does not affect exsisting statements. + - if predominantly uniqueness is required. Then unique hash secondary table keys can be used. This is also true for smaller internal tables. + - Note that defining secondary table keys involves additional administration costs such as additional memory consumption and regarding the key update + - Unique secondary table keys are immediately updated, whereas non-unique secondary table keys are not (only when the table is accessed using the key). + - The use of secondary table keys should be reserved for cases where the benefits outweigh the extra costs. So, it may not be advisable to use secondary table keys for very small tables or if you very often change the content of the table. - For more details, see the programming guidelines for secondary keys: [Secondary Key (F1 docu for standard ABAP)](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensecondary_key_guidl.htm "Guideline"). @@ -371,10 +380,11 @@ DATA it21 TYPE SORTED TABLE OF zdemo_abap_flsch "Excursion: Example of using table keys and alias names using a LOOP AT statement. "All of the statements below are possible. "Note that if the secondary table key is not specified (and if the USING KEY addition is not -"used in the example), the primary table key is respected by default. +"used in the example), the primary table key is respected by default. So, the first statement +"specifying the primary table key explicitly is the same as not specifying it. "Further ABAP statements, such as READ or MODIFY, are available in which the key can be "explicitly specified to process internal tables. -LOOP AT it21 INTO DATA(wa) USING KEY primary_key. +LOOP AT it21 INTO DATA(wa) USING KEY primary_key. "LOOP AT it21 INTO DATA(wa) USING KEY k1. "LOOP AT it21 INTO DATA(wa) USING KEY cities. "LOOP AT it21 INTO DATA(wa) USING KEY s1. @@ -1126,7 +1136,7 @@ MOVE-CORRESPONDING itab_nested1 TO itab_nested2 EXPANDING NESTED TABLES KEEPING CORRESPONDING with lookup table -- You can constructs an internal table by joining an internal table and a lookup table and comparing their components. +- You can construct an internal table by joining an internal table and a lookup table and comparing their components. - Syntax pattern of the variant: ```abap ... CORRESPONDING type|#( itab FROM lookup_tab @@ -3930,12 +3940,12 @@ DATA(itab) = itab_original. "all values of the 'num' component in the original table lines "(except the first line) are initial as the loop is exited. LOOP AT itab ASSIGNING FIELD-SYMBOL(). - DATA(tabix) = sy-tabix. - -num = tabix. - INSERT VALUE #( text = tabix ) INTO itab INDEX tabix + 1. - IF tabix = 50. - EXIT. - ENDIF. + DATA(tabix) = sy-tabix. + -num = tabix. + INSERT VALUE #( text = tabix ) INTO itab INDEX tabix + 1. + IF tabix = 50. + EXIT. + ENDIF. ENDLOOP. *Internal table content (parts of it): @@ -3964,9 +3974,9 @@ ENDLOOP. itab = itab_original. LOOP AT itab ASSIGNING . - tabix = sy-tabix. - -num = tabix. - DELETE itab INDEX tabix + 1. + tabix = sy-tabix. + -num = tabix. + DELETE itab INDEX tabix + 1. ENDLOOP. *Internal table content: @@ -4001,26 +4011,26 @@ DATA new_line_counter TYPE i. DATA tabix_copy TYPE i. LOOP AT itab ASSIGNING . - tabix = sy-tabix. - new_line_counter += 1. + tabix = sy-tabix. + new_line_counter += 1. - "Asserting that sy-tabix value has changed accordingly. - IF tabix <> 1. + "Asserting that sy-tabix value has changed accordingly. + IF tabix <> 1. ASSERT tabix = tabix_copy + 2. - ENDIF. + ENDIF. - DATA(new_line_text) = |---- New line { new_line_counter } ----|. - INSERT VALUE #( text = new_line_text ) INTO itab INDEX tabix ASSIGNING . + DATA(new_line_text) = |---- New line { new_line_counter } ----|. + INSERT VALUE #( text = new_line_text ) INTO itab INDEX tabix ASSIGNING . - DATA(idx_new) = line_index( itab[ text = new_line_text num = 0 ] ). - -num = idx_new. + DATA(idx_new) = line_index( itab[ text = new_line_text num = 0 ] ). + -num = idx_new. - DATA(idx_existing) = line_index( itab[ text = -text num = 0 ] ). - DATA(new_text) = |{ -text }(existing line, index before insertion: { tabix })|. - -text = new_text. - -num = idx_existing. + DATA(idx_existing) = line_index( itab[ text = -text num = 0 ] ). + DATA(new_text) = |{ -text }(existing line, index before insertion: { tabix })|. + -text = new_text. + -num = idx_existing. - tabix_copy = tabix. + tabix_copy = tabix. ENDLOOP. *Internal table content: @@ -4068,10 +4078,10 @@ LOOP AT itab ASSIGNING . INSERT INTO TABLE itab_copy. TRY. - IF CONV i( -text ) MOD 2 = 0. + IF CONV i( -text ) MOD 2 = 0. DELETE itab INDEX tabix - 1. - ENDIF. - CATCH cx_sy_conversion_no_number. + ENDIF. + CATCH cx_sy_conversion_no_number. ENDTRY. ENDLOOP. @@ -4110,10 +4120,10 @@ DATA(str_tab) = VALUE string_table( ( `a` ) ( `#` ) ( `c` ) ( `#` ) ( `e` ) ( `f` ) ( `g` ) ( `#` ) ( `i` ) ( `j` ) ). LOOP AT str_tab REFERENCE INTO DATA(dref). - tabix = sy-tabix. - IF dref->* CS `#`. + tabix = sy-tabix. + IF dref->* CS `#`. DELETE str_tab INDEX tabix. - ENDIF. + ENDIF. ENDLOOP. *Internal table content: @@ -4130,8 +4140,8 @@ ENDLOOP. "The entire internal table cannot be deleted within loops. "The following statements commented out are not possible. LOOP AT str_tab REFERENCE INTO dref. - "CLEAR str_tab. - "str_tab = VALUE #( ). + "CLEAR str_tab. + "str_tab = VALUE #( ). ENDLOOP. ``` @@ -5412,7 +5422,7 @@ Notes on ... ... secondary table key and secondary table index: - Secondary table keys, which can be sorted or hashed, are available for all table categories. - They enhance table access efficiency and performance. -- Declaring a secondary table key generates a corresponding secondary table index. However, the index for a non-unique key does not update immediately upon adding or deleting a line. The update happens when the internal table is accessed using the secondary table key. +- Declaring a secondary table key generates a corresponding secondary table index. However, the index for a non-unique key does not update immediately upon adding or deleting a line (for unique keys, it does). The update happens when the internal table is accessed using the secondary table key. - In ABAP statements, you must specify the secondary table key explicitly. Otherwise, the primary table key is used implicitly. - Data access using the secondary table key is always optimized, even for standard tables. Thus, even older standard tables can gain from optimized access by adding secondary table keys later, without impacting existing table-related statements. - However, weigh the administrative costs of secondary table keys. Use them only in scenarios where they offer substantial benefits, like large internal tables that are filled once and rarely altered. Frequent modifications can lead to regular index updates, potentially impacting performance. diff --git a/04_ABAP_Object_Orientation.md b/04_ABAP_Object_Orientation.md index b1c15db..a99d2a5 100644 --- a/04_ABAP_Object_Orientation.md +++ b/04_ABAP_Object_Orientation.md @@ -561,7 +561,7 @@ In the simplest form, methods can have no parameter at all. Apart from that, met - If passing by reference is used, a local data object is not created for the actual parameter. Instead, the procedure is given a [reference](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreference_glosry.htm "Glossary Entry") to the actual parameter during the call and works with the actual parameter itself. - Note that parameters that are input and passed by reference cannot be modified in the procedure. However, the use of a reference is beneficial regarding the performance compared to creating a local data object. -The following example shows a class with a simple method demonstrating the syntax for formal paremeter specifications. Complete types are used. +The following example shows a class with a simple method demonstrating the syntax for formal parameter specifications. Complete types are used. ```abap CLASS zcl_some_class DEFINITION @@ -589,6 +589,8 @@ CLASS zcl_some_class IMPLEMENTATION. METHOD if_oo_adt_classrun~main. + "The values 1, hello, and 2 are actual parameters supplied when + "the method is called. DATA(result) = meth( i_a = 1 i_b = `hello` i_c = 2 ). @@ -598,11 +600,11 @@ CLASS zcl_some_class IMPLEMENTATION. METHOD meth. ... "Method implementation - "No change for input parameters passed by reference + "Input parameters passed by reference cannot be changed in the method implementation. "i_a += 1. "i_b &&= ` world`. - "Input parameters passed by reference can be changed in the method. + "Input parameters passed by value can be changed in the method implementation. i_c += 1. ENDMETHOD. @@ -669,7 +671,9 @@ CLASS zcl_some_class DEFINITION "---- Local types ---- i_o TYPE c3 "elementary type i_p TYPE der_type "table type (BDEF derived type) - "---- Note: Examaples for not allowed types of formal parameters ---- + "---- Note: Examples such as the following are not allowed type specifications of formal parameters. ---- + "---- In the following cases, extra (local) type declarations with TYPES are required before the -------- + "---- method declaration to type the formal parameters. ------------------------------------------------- "i_no1 TYPE c LENGTH 3 "i_no2 TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY "---- Reference types ---- @@ -682,14 +686,14 @@ CLASS zcl_some_class DEFINITION i_v TYPE LINE OF zcl_demo_abap_amdp=>carr_fli_tab i_w TYPE LINE OF der_type "---- LIKE addition (types based on existing data objects) ---- - i_x LIKE int "Local type + i_x LIKE int "Local data object i_y LIKE zcl_demo_abap_dtype_dobj=>comma "Constant specified in a class i_z LIKE zdemo_abap_objects_interface=>stat_str "Data object specified in an interface "---- LIKE LINE OF addition (types based on existing internal tables) ---- - i_1 LIKE LINE OF itab "Local type + i_1 LIKE LINE OF itab "Local internal table "---- LIKE REF TO addition (reference types based on existing data object) ---- - i_2 LIKE REF TO int "Local type (elementary) - i_3 LIKE REF TO itab "Local type (table) + i_2 LIKE REF TO int "Local elementary data object + i_3 LIKE REF TO itab "Local internal table . PROTECTED SECTION. @@ -740,15 +744,15 @@ CLASS zcl_some_class DEFINITION "---- Character-like types ---- i_c TYPE c "Text field with a generic length - i_clike TYPE clike "Character-like (c n string d t and character-like flat structures) - i_csequence TYPE csequence "Text-like (c string) + i_clike TYPE clike "Character-like (c, n, string, d, t, and character-like flat structures) + i_csequence TYPE csequence "Text-like (c, string) i_n TYPE n "Numeric text with generic length i_x TYPE x "Byte field with generic length - i_xsequence TYPE xsequence "Byte-like (x xstring) + i_xsequence TYPE xsequence "Byte-like (x, xstring) "---- Numeric types ---- i_decfloat TYPE decfloat "decfloat16 decfloat34 - i_numeric TYPE numeric "Numeric ((b s) i int8 p decfloat16 decfloat34 f) + i_numeric TYPE numeric "Numeric (i, int8, p, decfloat16, decfloat34, f, (b, s)) i_p TYPE p "Packed number (generic length and number of decimal places) "---- Internal table types ---- @@ -904,7 +908,7 @@ CLASS zcl_some_class IMPLEMENTATION. "--- sorted table: Allowed --- i_sorted_table = s-tab_so - "--- index table: Not allowed --- + "--- sorted table: Not allowed --- "i_sorted_table = s-tab_std "i_sorted_table = s-tab_ha diff --git a/05_Constructor_Expressions.md b/05_Constructor_Expressions.md index 483798b..62ac963 100644 --- a/05_Constructor_Expressions.md +++ b/05_Constructor_Expressions.md @@ -6,8 +6,6 @@ - [Introduction](#introduction) - [VALUE](#value) - [CORRESPONDING](#corresponding) - - [DEFAULT Addition When Using MAPPING](#default-addition-when-using-mapping) - - [CORRESPONDING with Lookup Table](#corresponding-with-lookup-table) - [NEW](#new) - [CONV](#conv) - [EXACT](#exact) @@ -578,9 +576,8 @@ two statements are not the same: >MOVE-CORRESPONDING struc1 TO struc2. >``` -

⬆️ back to top

-### DEFAULT Addition When Using MAPPING +**`DEFAULT` addition when using `MAPPING`** - This addition allows the assignment of values for a target component based on an expression (which is evaluated before the `CORRESPONDING` expression). - `DEFAULT` can be preceded by the source component. In this case, the source component's value is assigned to the left-hand side only if the source component is not initial. If it is initial, the value of the expression following the `DEFAULT` addition is assigned. @@ -664,9 +661,8 @@ struc2 = CORRESPONDING #( *1 a hallo 2 d 30 ``` -

⬆️ back to top

-### CORRESPONDING with Lookup Table +**`CORRESPONDING` with lookup table** - Constructs an internal table by joining an internal table and a lookup table and comparing their components - Syntax pattern of the variant: @@ -689,7 +685,7 @@ struc2 = CORRESPONDING #( - The target internal table should match the type of `itab`. - The search must use a sorted table key or a hash key: - Omit the `KEY` addition only if the lookup table `lookup_tab` is sorted or hashed. - - When using KEY, specify either: + - When using `KEY`, specify either: - A secondary key. - The primary key's default name `primary_key` or an alias, but only for sorted or hashed lookup tables. - When used: @@ -736,7 +732,7 @@ DATA(it2) = CORRESPONDING it_type( it1_copy FROM lookup_tab USING character = ch ASSERT it2 = it1. -"Examples assignments to demonstrate the KEY and MAPPING additions +"Example assignments to demonstrate the KEY and MAPPING additions TYPES: BEGIN OF s2, a TYPE string, @@ -813,7 +809,6 @@ it3 = CORRESPONDING #( it3 FROM lookup_table USING KEY sk c = a d = b ). *2a 2b --- --- --- --- *3a 3b --- --- 7a --- - "Notes on the example assignment: "- See above. Here, the MAPPING addition is included. It is used to specify " mapping relationships for the assignments. The example specifies a mapping diff --git a/06_Dynamic_Programming.md b/06_Dynamic_Programming.md index 5b71255..41704c1 100644 --- a/06_Dynamic_Programming.md +++ b/06_Dynamic_Programming.md @@ -2013,14 +2013,14 @@ CLASS zcl_example_class IMPLEMENTATION. END OF comp_struc. DATA it_comps TYPE TABLE OF comp_struc WITH EMPTY KEY. - "Database table of type string containing names of database tables; + "Internal table of type string containing names of database tables; "table is looped over to output content of all database tables DATA(dbtabs) = VALUE string_table( ( `ZDEMO_ABAP_CARR` ) ( `ZDEMO_ABAP_FLI` ) ( `ZDEMO_ABAP_FLSCH` ) ). LOOP AT dbtabs INTO DATA(dbtab). - "Retrieving database content of a dynamically specified database table + "Retrieving database content of a dynamically specified database table (up to 5 rows) TRY. SELECT * FROM (dbtab) diff --git a/07_String_Processing.md b/07_String_Processing.md index 349e01f..6347573 100644 --- a/07_String_Processing.md +++ b/07_String_Processing.md @@ -42,7 +42,8 @@ - [Escaping Special Characters](#escaping-special-characters) - [Excursions](#excursions) - [Comparison Operators for Character-Like Data Types in a Nutshell](#comparison-operators-for-character-like-data-types-in-a-nutshell) - - [Miscellaneous Classes for String Processing](#miscellaneous-classes-for-string-processing) + - [Classes for String Processing](#classes-for-string-processing) + - [Character String and Byte String Processing with ABAP Statements](#character-string-and-byte-string-processing-with-abap-statements) - [Executable Example](#executable-example) @@ -537,8 +538,17 @@ CONCATENATE s1 s2 INTO s3 SEPARATED BY `#`. "ABAP#abap ABAP "strings. The ones of variable length strings are respected by default. CONCATENATE 'a ' 'b ' 'c ' INTO DATA(ch) RESPECTING BLANKS. "'a b c ' -"Concatenating lines of internal tables into a string -CONCATENATE LINES OF itab INTO t SEPARATED BY ` `. +"Concatenating lines of internal tables with character-like line type into a string +DATA(itab) = VALUE string_table( ( `abc` ) ( `def` ) ( `ghi` ) ). + +"abcdefghi +CONCATENATE LINES OF itab INTO DATA(conc_tab1). + +"abc def ghi +CONCATENATE LINES OF itab INTO DATA(conc_tab2) SEPARATED BY ` `. + +"abc,def,ghi +CONCATENATE LINES OF itab INTO DATA(conc_tab3) SEPARATED BY `,`. "Using concat_lines_of s1 = concat_lines_of( table = itab ). "Without separator @@ -2058,7 +2068,7 @@ IF s8 NP `*c#D*`. ... "false; sy-fdpos: 2

⬆️ back to top

-### Miscellaneous Classes for String Processing +### Classes for String Processing As also covered in the [Released ABAP Classes](22_Released_ABAP_Classes.md) cheat sheet, the following list shows a selected set of classes that support string processing. - `CL_ABAP_CHAR_UTILITIES`: As previously mentioned, this class provides utilities for string processing, such as attributes that represent new lines and horizontal tabs. @@ -2234,6 +2244,171 @@ As also covered in the [Released ABAP Classes](22_Released_ABAP_Classes.md) chea

⬆️ back to top

+### Character String and Byte String Processing with ABAP Statements + +- Several ABAP statements include the `IN CHARACTER MODE` and `IN BYTE MODE` additions. +- These additions determine whether operations process character strings or byte strings. +- If neither option is specified, the default is character string processing (i.e. `IN CHARACTER MODE`). +- Byte string processing with the `IN BYTE MODE` addition is supported by the following ABAP statements: `CONCATENATE`, `FIND`, `REPLACE`, `SHIFT`, `SPLIT`. +- In byte string processing, the data objects used must be byte-like. For character string processing, only character-like data objects are allowed. + + +The following code snippet explores various statements with the `IN CHARACTER MODE` and `IN BYTE MODE` additions. + +```abap +DATA off TYPE i. +DATA(abc_str) = `abc def ghi jkl mno pqr stu vwx yz`. +DATA(copy_str) = abc_str. + +"----------------------------------------------------------------------------- +"------------------------ FIND and REPLACE statements ------------------------ +"----------------------------------------------------------------------------- + +"------------------------ IN CHARACTER MODE addition ------------------------ + +"Searching for the first blank in the string +"3 +FIND ` ` IN abc_str IN CHARACTER MODE MATCH OFFSET off. + +"The following example is the same as the previous as the IN CHARACTER MODE +"addition is optional. The FIRST OCCURRENCE OF addition is also optional. +"Just using FIND without FIRST OCCURRENCE OF means searching for the first +"occurrence by default. +"3 +FIND FIRST OCCURRENCE OF ` ` IN abc_str MATCH OFFSET off. + +"Searching for all blanks in the string +FIND ALL OCCURRENCES OF ` ` IN abc_str IN CHARACTER MODE RESULTS DATA(res). +DATA(offsets_of_findings) = concat_lines_of( + table = VALUE string_table( FOR wa IN res ( condense( val = CONV string( wa-offset ) to = `` ) ) ) sep = `, ` ). +"3, 7, 11, 15, 19, 23, 27, 31 + +"Replacing the first blank in the string +"abc#def ghi jkl mno pqr stu vwx yz +REPLACE ` ` IN abc_str WITH `#` IN CHARACTER MODE. + +abc_str = copy_str. + +"Replacing all blanks in the string +"abc#def#ghi#jkl#mno#pqr#stu#vwx#yz +REPLACE ALL OCCURRENCES OF ` ` IN abc_str WITH `#` IN CHARACTER MODE. + +abc_str = copy_str. + +"------------------------ IN BYTE MODE addition ------------------------ + +"Converting to xstring +"6162632064656620676869206A6B6C206D6E6F20707172207374752076777820797A +DATA(abc_xstr) = cl_abap_conv_codepage=>create_out( )->convert( abc_str ). +"20 +DATA(blank_xstr) = cl_abap_conv_codepage=>create_out( )->convert( ` ` ). +"23 +DATA(repl_xstr) = cl_abap_conv_codepage=>create_out( )->convert( `#` ). +DATA(copy_xstr) = abc_xstr. + +"Searching for the first byte that represents a blank in the UTF-8 code page +"3 +FIND blank_xstr IN abc_xstr IN BYTE MODE MATCH OFFSET off. + +FIND ALL OCCURRENCES OF blank_xstr IN abc_xstr IN BYTE MODE RESULTS res. +"3, 7, 11, 15, 19, 23, 27, 31 +DATA(offsets_of_findings_xstr) = concat_lines_of( + table = VALUE string_table( FOR wa IN res ( condense( val = CONV string( wa-offset ) to = `` ) ) ) sep = `, ` ). + +"Replacing the first byte that represents a blank in the UTF-8 code page +"6162632364656620676869206A6B6C206D6E6F20707172207374752076777820797A +REPLACE blank_xstr IN abc_xstr WITH repl_xstr IN BYTE MODE. + +abc_xstr = copy_xstr. + +"Replacing all bytes that represent a blank in the UTF-8 code page +"6162632364656623676869236A6B6C236D6E6F23707172237374752376777823797A +REPLACE ALL OCCURRENCES OF blank_xstr IN abc_xstr WITH repl_xstr IN BYTE MODE. + +"----------------------------------------------------------------------------- +"--------------------------- CONCATENATE statements -------------------------- +"----------------------------------------------------------------------------- + +DATA(part_str1) = `abc`. +DATA(part_str2) = `def`. + +"abcdef +CONCATENATE part_str1 part_str2 INTO DATA(concat_str) IN CHARACTER MODE. +"abc/def +CONCATENATE part_str1 part_str2 INTO concat_str SEPARATED BY `/` IN CHARACTER MODE. + +"Same as above +CONCATENATE part_str1 part_str2 INTO concat_str. +CONCATENATE part_str1 part_str2 INTO concat_str SEPARATED BY `/`. + +DATA(part_xstr1) = cl_abap_conv_codepage=>create_out( )->convert( part_str1 ). +DATA(part_xstr2) = cl_abap_conv_codepage=>create_out( )->convert( part_str2 ). +DATA(sep_xstr) = cl_abap_conv_codepage=>create_out( )->convert( `/` ). + +"616263646566 +CONCATENATE part_xstr1 part_xstr2 INTO DATA(concat_xstr) IN BYTE MODE. +"abcdef +DATA(concat_xstr_converted) = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr ). +"6162632F646566 +CONCATENATE part_xstr1 part_xstr2 INTO concat_xstr SEPARATED BY sep_xstr IN BYTE MODE. +"abc/def +concat_xstr_converted = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr ). + +"Creating a table of type xstring +DATA(xstr_table) = VALUE xstring_table( ( part_xstr1 ) ( part_xstr2 ) ). +"616263646566 +CONCATENATE LINES OF xstr_table INTO DATA(concat_xstr_tab) IN BYTE MODE. +"abcdef +DATA(concat_xstr_tab_converted) = cl_abap_conv_codepage=>create_in( )->convert( concat_xstr_tab ). + +"----------------------------------------------------------------------------- +"------------------------------- SHIFT statements ---------------------------- +"----------------------------------------------------------------------------- + +DATA(str) = `abcdef`. +DATA(copy) = str. + +"bcdef +SHIFT str IN CHARACTER MODE. + +str = copy. + +"Same as +SHIFT str. + +str = copy. +"616263646566 +DATA(xstr) = cl_abap_conv_codepage=>create_out( )->convert( str ). + +"6263646566 +SHIFT xstr IN BYTE MODE. + +"----------------------------------------------------------------------------- +"------------------------------- SPLIT statements ---------------------------- +"----------------------------------------------------------------------------- + +str = `abc def`. + +"`abc` / `def` +SPLIT str AT space INTO DATA(str1) DATA(str2) IN CHARACTER MODE. +SPLIT str AT space INTO TABLE DATA(tab_str) IN CHARACTER MODE. + +"Same as above +SPLIT str AT space INTO str1 str2. +SPLIT str AT space INTO TABLE tab_str. + +"61626320646566 +xstr = cl_abap_conv_codepage=>create_out( )->convert( str ). +"20 +blank_xstr = cl_abap_conv_codepage=>create_out( )->convert( ` ` ). + +"`616263` / `646566` +SPLIT xstr AT blank_xstr INTO DATA(xstr1) DATA(xstr2) IN BYTE MODE. +SPLIT xstr AT blank_xstr INTO TABLE DATA(xstr_tab) IN BYTE MODE. +``` + +

⬆️ back to top

+ ## Executable Example [zcl_demo_abap_string_proc](./src/zcl_demo_abap_string_proc.clas.abap) diff --git a/16_Data_Types_and_Objects.md b/16_Data_Types_and_Objects.md index c37a32d..7976695 100644 --- a/16_Data_Types_and_Objects.md +++ b/16_Data_Types_and_Objects.md @@ -1933,7 +1933,7 @@ SELECT SINGLE ### Non-Admissible Values of Literals -Note recent syntax warnings when using literals that represent invalid values for target types. The following example demonstrates the assignement of literals using admissible and non-admissible values. You can copy and paste the code into a demo class in your SAP BTP ABAP Environment to explore the syntax warnings. +Note recent syntax warnings when using literals that represent invalid values for target types. The following example demonstrates the assignment of literals using admissible and non-admissible values. You can copy and paste the code into a demo class in your SAP BTP ABAP Environment to explore the syntax warnings. ```abap diff --git a/21_XML_JSON.md b/21_XML_JSON.md index 4934106..5758273 100644 --- a/21_XML_JSON.md +++ b/21_XML_JSON.md @@ -1103,7 +1103,7 @@ DATA(json_created_xco) = json_builder_xco->get_data( )->to_string( ). "Note: The JSON was intentionally created without the underscores in the "name to demonstrate the 'apply' method. The following example demonstrates "a transformation of camel case and underscore notation. As above, check out -"more options by clicking CTRL + Space after '...transformation->'. +"more options by using CTRL + Space after '...transformation->'. CLEAR json2struc_xco. xco_cp_json=>data->from_string( json_created_xco )->apply( VALUE #( ( xco_cp_json=>transformation->pascal_case_to_underscore ) ) )->write_to( REF #( json2struc_xco ) ). diff --git a/22_Released_ABAP_Classes.md b/22_Released_ABAP_Classes.md index 879d202..20138aa 100644 --- a/22_Released_ABAP_Classes.md +++ b/22_Released_ABAP_Classes.md @@ -18,7 +18,7 @@ - [Information about Non-Initial Structure Components](#information-about-non-initial-structure-components) - [Comparing Content of Compatible Internal Tables](#comparing-content-of-compatible-internal-tables) - [Dynamic Programming](#dynamic-programming) - - [Getting the User Name](#getting-the-user-name) + - [Getting the Current User Name](#getting-the-current-user-name) - [XML/JSON](#xmljson) - [ABAP Repository Object Information](#abap-repository-object-information) - [Generating ABAP Repository Objects](#generating-abap-repository-objects) @@ -1944,7 +1944,7 @@ ENDTRY.

⬆️ back to top

-## Getting the User Name +## Getting the Current User Name @@ -2352,6 +2352,65 @@ TRY. ENDTRY. ``` +The following snippet includes some file attachments: + +```abap +TRY. + "Creating a new mail instance + DATA(mail) = cl_bcs_mail_message=>create_instance( ). + "Settings + mail->set_sender( '...@...' ). + mail->add_recipient( '...@...' ). + mail->set_subject( 'Test Mail' ). + mail->set_main( cl_bcs_mail_textpart=>create_instance( + iv_content = `

Test Mail

Please find some files attached.
Cheers

` + iv_content_type = `text/html` ) ). + + "Adding attachments + "Adding a text file + mail->add_attachment( cl_bcs_mail_textpart=>create_text_plain( + iv_content = `This is some sample text.` + iv_filename = `txt_file.txt` ) ). + + "Adding an XML file + mail->add_attachment( cl_bcs_mail_textpart=>create_instance( + iv_content = `` && + `` && + ` ` && + ` A` && + ` 01-01-2024` && + ` ` && + ` ` && + ` abc` && + ` def` && + ` ghi` && + ` ` && + `` + iv_content_type = `text/xml` + iv_filename = `xml_file.xml` ) ). + + "Adding a zip file + DATA(zip) = NEW cl_abap_zip( ). + DATA(txt_content) = `This is some sample text for a file that is zipped.`. + TRY. + DATA(conv_xstring) = cl_abap_conv_codepage=>create_out( codepage = `UTF-8` )->convert( txt_content ). + CATCH cx_sy_conversion_codepage. + ENDTRY. + zip->add( EXPORTING name = |test_txt_file.txt| + content = conv_xstring ). + DATA(zipped_file) = zip->save( ). + + mail->add_attachment( cl_bcs_mail_binarypart=>create_instance( + iv_content = zipped_file + iv_content_type = 'application/x-zip-compressed' + iv_filename = 'zip_file.zip' ) ). + + mail->send( ). + CATCH cx_bcs_mail INTO DATA(error_mail). + DATA(error_mail_msg) = error_mail->get_text( ). +ENDTRY. +``` +
@@ -3719,25 +3778,49 @@ ENDCLASS. The following example creates a zip file and adds three txt files with sample content. Note that the example snippet for `CL_WEB_HTTP_CLIENT_MANAGER` and `CL_HTTP_DESTINATION_PROVIDER` (calling services) also includes the use of `CL_ABAP_ZIP`. ```abap -"Create zip file +"Creating a zip file DATA(zip) = NEW cl_abap_zip( ). -"Adding 3 files to a zip file +"Adding 3 files to the zip file DO 3 TIMES. - DATA(some_content) = |{ sy-index }. Some text content|. + DATA(some_content) = |Some text content for file number { sy-index }.|. TRY. DATA(conv_xstring) = cl_abap_conv_codepage=>create_out( codepage = `UTF-8` )->convert( some_content ). CATCH cx_sy_conversion_codepage. ENDTRY. - "Add xstring as file content to zip + "Adding xstring as file content to zip zip->add( EXPORTING name = |file{ sy-index }.txt| content = conv_xstring ). ENDDO. +"Saving the zip file DATA(zipped_file) = zip->save( ). + +"Unzipping a zip file +DATA unzipped_content_tab TYPE string_table. + +DATA(unzip) = NEW cl_abap_zip( ). +unzip->load( zipped_file ). + +LOOP AT unzip->files INTO DATA(file). + unzip->get( EXPORTING name = file-name + IMPORTING content = DATA(unzipped_content) + ). + "Converting xstring to string + TRY. + DATA(conv_string) = cl_abap_conv_codepage=>create_in( )->convert( unzipped_content ). + CATCH cx_sy_conversion_codepage. + ENDTRY. + APPEND conv_string TO unzipped_content_tab. +ENDLOOP. + +*Content of unzipped_content_tab: +*Some text content for file number 1. +*Some text content for file number 2. +*Some text content for file number 3. ``` diff --git a/23_Date_and_Time.md b/23_Date_and_Time.md index 4b401fe..c4090fc 100644 --- a/23_Date_and_Time.md +++ b/23_Date_and_Time.md @@ -65,7 +65,7 @@ The main data types for date, time, and time stamps in ABAP are as follows: > - Long form; the time stamp is represented precisely to 100 ns with seven decimal places > - Format: `yyyymmddhhmmss.sssssss` (in addition to the short form, the seven decimal places are fractions of a second) > - Many code snippets in the cheat sheet include examples that utilize the [XCO library](https://help.sap.com/docs/btp/sap-business-technology-platform/xco-library?version=Cloud), which offers various options for handling dates, times, and time stamps. The cheat sheet includes a selection. Note that, in most cases, the return value of the XCO calls in the snippets is of type `string`. For more detailed information, refer to the class documentation and the [SAP Help Portal](https://help.sap.com/docs/btp/sap-business-technology-platform/xco-library?version=Cloud). -> - In [ABAP for Cloud Development](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_for_cloud_dev_glosry.htm), do not use the date and time-related system fields such as `sy-datum`, `sy-uzeit`, `sy-timlo`, `sy-datlo`, and others. User-related time and date values can be retrieved using the XCO library as shown below. +> - In [ABAP for Cloud Development](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenabap_for_cloud_dev_glosry.htm), do not use the date and time-related system fields such as `sy-datum`, `sy-uzeit`, `sy-timlo`, `sy-datlo`, and others, as they relate to system-specific values that are not relevant in the cloud context, in cloud systems. User-related time and date values can be retrieved using the XCO library as shown below. Example: