From d2aebd178e64fd029f6938cbb351f1976f6df4ba Mon Sep 17 00:00:00 2001 From: danrega <16720986+danrega@users.noreply.github.com> Date: Fri, 10 Nov 2023 14:14:41 +0100 Subject: [PATCH] Update --- 01_Internal_Tables.md | 19 +++-- 06_Dynamic_Programming.md | 67 +++++++++++++---- 18_Dynpro.md | 6 +- 19_ABAP_for_Cloud_Development.md | 4 +- 20_Selection_Screens_Lists.md | 10 +-- README.md | 2 +- src/zcl_demo_abap_cloud_excursion.clas.abap | 4 +- src/zcl_demo_abap_dynamic_prog.clas.abap | 81 +++++++++++++++++++-- src/zdemo_abap_cds_ve_agg_exp.ddls.asddls | 2 +- src/zdemo_abap_cds_ve_assoc.ddls.asddls | 2 +- src/zdemo_abap_cds_ve_assoc_e.ddls.asddls | 2 +- src/zdemo_abap_cds_ve_joins.ddls.asddls | 2 +- src/zdemo_abap_cds_ve_sel.ddls.asddls | 2 +- 13 files changed, 158 insertions(+), 45 deletions(-) diff --git a/01_Internal_Tables.md b/01_Internal_Tables.md index 6680749..a691e39 100644 --- a/01_Internal_Tables.md +++ b/01_Internal_Tables.md @@ -68,7 +68,7 @@ Internal Tables ... - There are two types of table keys: a [primary table key](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenprimary_table_key_glosry.htm) and [secondary table keys](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abensecondary_table_key_glosry.htm). - Table keys ... - are intended to provide an optimized access to the content of internal tables. - - are either unique or non-unique, i.e. more than one line with the same key (duplicates) can exist in the internal table. Regarding the primary table key, the definition depends on the table category. For the secondary table key, the definition depends on the key type. For standard tables, the primary table key can also be defined as empty, i.e. it does not contain any key columns. Note that for standard tables, an optimized access is only possible with secondary table keys. + - are either unique or non-unique, i.e. more than one line with the same key (duplicates) can exist in the internal table or not. Regarding the primary table key, the definition depends on the table category. For the secondary table key, the definition depends on the key type. For standard tables, the primary table key can also be defined as empty, i.e. it does not contain any key columns. Note that for standard tables, an optimized access is only possible with secondary table keys. - Type of keys: - Sorted keys: - Are either the primary table keys of sorted tables or the secondary table keys of any table. @@ -380,6 +380,9 @@ DATA itab_a7 LIKE TABLE OF itab_a6. DATA(it_inline1) = itab_a1. DATA(it_inline2) = it_inline1. +"Using FINAL for creating immutable variables +FINAL(it_final) = it_inline1. + "Using the VALUE operator and an internal table type DATA(it_inline3) = VALUE tt_loc_str( ( ... ) ). @@ -531,7 +534,7 @@ DATA(it_in) = VALUE it_type( ( comp1 = a comp2 = b ... ) ( comp1 = c comp2 = d ... ) ). ``` -When you use the above assignments (`itab = ...`), the internal table is initialized and the existing content are deleted. To add new lines **without deleting existing content**, use the [`BASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvalue_constructor_params_itab.htm) addition. +When you use the above assignments (`itab = ...`), the internal table is initialized and the existing content is deleted. To add new lines **without deleting existing content**, use the [`BASE`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenvalue_constructor_params_itab.htm) addition. ``` abap itab = VALUE #( BASE itab ( comp1 = a comp2 = b ... ) @@ -540,7 +543,7 @@ itab = VALUE #( BASE itab ( comp1 = a comp2 = b ... ) **Adding lines of other tables** using the `LINES OF` addition to the `VALUE` operator. > **💡 Note**
-> Without the `BASE` addition, the existing content are deleted. It is assumed that the line type of the source table is compatible with that of the target table. +> Without the `BASE` addition, the existing content is deleted. It is assumed that the line type of the source table is compatible with that of the target table. ``` abap itab = VALUE #( ( comp1 = a comp2 = b ...)                 ( comp1 = a comp2 = b ...) @@ -559,17 +562,19 @@ itab = itab2. **Copying the content of another internal table** using the [`CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenconstructor_expr_corresponding.htm) operator. -- Note that the existing content are deleted. +- Note that the existing content is deleted. - As an alternative to the `CORRESPONDING` operator, you can use [`MOVE-CORRESPONDING`](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abapmove-corresponding.htm) statements. - The example assumes that the line types of the source and target table are not compatible. However, if the line types are compatible, the syntax will also work. - +- Several additions are possible. They can also be combined. Check the ABAP Keyword Documentation. + ``` abap itab = CORRESPONDING #( itab3 ). MOVE-CORRESPONDING itab3 TO itab. ``` -**Copying content and retaining existing content** using the `CORRESPONDING` operator. The `KEEPING TARGET LINES` addition of the `MOVE-CORRESPONDING` statement preserves the table content. +**Copying content and retaining existing content** using the `CORRESPONDING` operator. +The `KEEPING TARGET LINES` addition of the `MOVE-CORRESPONDING` statement preserves the table content. ``` abap itab = CORRESPONDING #( BASE ( itab ) itab3 ). @@ -1482,7 +1487,7 @@ and statements allow you to delete the entire table content. The difference between the two is in the handling of the memory space originally allocated to the table. When a table is cleared with `CLEAR`, -the content are removed, but the memory space initially requested remains +the content is removed, but the memory space initially requested remains allocated. If the table is filled again later, the memory space is still available, which is a performance advantage over clearing an internal table with `FREE`. Such a statement also diff --git a/06_Dynamic_Programming.md b/06_Dynamic_Programming.md index 4782b93..6b604bd 100644 --- a/06_Dynamic_Programming.md +++ b/06_Dynamic_Programming.md @@ -8,6 +8,7 @@ - [Field Symbols](#field-symbols) - [Data References](#data-references) - [Dynamic ABAP Statements](#dynamic-abap-statements) + - [CL\_ABAP\_DYN\_PRG: Validating Input for Dynamic Specifications](#cl_abap_dyn_prg-validating-input-for-dynamic-specifications) - [Runtime Type Services (RTTS)](#runtime-type-services-rtts) - [Getting Type Information at Runtime](#getting-type-information-at-runtime) - [Dynamically Creating Data Types at Runtime](#dynamically-creating-data-types-at-runtime) @@ -855,20 +856,58 @@ Note that dynamically specifying syntax elements has downsides, too. Consider so "The addition EXCEPTION-TABLE for exceptions is not dealt with here. ``` -Excursion: Checking the validity of dynamic specifications +### CL_ABAP_DYN_PRG: Validating Input for Dynamic Specifications -The following example uses the `CL_ABAP_DYN_PRG` class, which supports dynamic programming by checking the validity of dynamic specifications. -See the class documentation for more information. There are several methods that can be used for different use cases. In the example below, a method is used to check the database table name. To do this, the database table name is provided (`val` parameter), as well as the package in which it should be included (`packages` parameter). You can pass the `packages` formal parameter a table containing the names of packages in which the specified table should be included. Assuming you provide incorrect input for the table name, or the table is not contained in the specified packages, you can expect an exception to be raied. +You can use the `CL_ABAP_DYN_PRG` class to validate input for dynamic specifications. +There are several methods for different use cases. See the class documentation (click F2 on the class name in ADT) for more information. +The following examples show some of those methods. If the validation is successful, the methods in the examples return the input value. +Otherwise, an exception is raised. ```abap -DATA dbtab TYPE string. +"The following method checks database table names. The name is provided +"with the val parameter. The packages formal parameter expects a table +"containing the names of packages in which the specified table should be +"included. Assuming you provide incorrect input for the table name, or +"the table is not contained in the specified packages, you can expect an +"exception to be raied. + TRY. - dbtab = cl_abap_dyn_prg=>check_table_name_tab( + DATA(dbtab) = cl_abap_dyn_prg=>check_table_name_tab( val = `ZDEMO_ABAP_FLI` - packages = VALUE #( ( `TEST_ABAP_CHEAT_SHEETS` ) ) ). + packages = VALUE #( ( `TEST_ABAP_CHEAT_SHEETS` ) + ( `TEST_SOME_PACK` ) ) ). SELECT SINGLE * FROM (dbtab) INTO NEW @DATA(ref_wa). - CATCH cx_abap_not_a_table cx_abap_not_in_package INTO DATA(err). + CATCH cx_abap_not_a_table cx_abap_not_in_package. + ... +ENDTRY. + +"In the following examples, a method is used to check whether +"the input is allowed or not. For this, you specify an allowlist. +"Here, the relvant parameter expects a comma-separated list of +"allowed values. +TRY. + DATA(value1) = cl_abap_dyn_prg=>check_allowlist( + val = `A` + allowlist_str = `A,B,C,D` ). + + ... "Here might go an ABAP SQL statement with a dynamic specification. + CATCH cx_abap_not_in_allowlist.. + ... +ENDTRY. + +"Another parameter of the method expects an internal table that +"contains the allowed values. +TRY. + DATA(value2) = cl_abap_dyn_prg=>check_allowlist( + val = `XYZ` + allowlist_htab = VALUE #( ( `A` ) + ( `B` ) + ( `C` ) + ( `D` ) ) ). + + ... "Here might go an ABAP SQL statement with a dynamic specification. + CATCH cx_abap_not_in_allowlist. ... ENDTRY. ``` @@ -967,7 +1006,7 @@ type_descr_obj_elem = CAST #( cl_abap_typedescr=>describe_by_name( 'ELEM_TYPE' ) "Using the older cast operator ?= type_descr_obj_elem ?= cl_abap_typedescr=>describe_by_name( 'ELEM_TYPE' ). -"Inline declaration is handy to avoid helper variables. +"Inline declarations are handy to avoid helper variables. DATA(type_descr_obj_inl_1) = CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_name( 'ELEM_TYPE' ) ). @@ -980,7 +1019,7 @@ DATA(type_kind) = type_descr_obj_inl_1->type_kind. "C DATA(output_length) = type_descr_obj_inl_1->output_length. "5 "In the following example, the type properties are retrieved -"without casting. The data object has the type ref to +"without cast. The data object has the type ref to "cl_abap_typedescr. See the hierarchy tree above. "The reference in the type description object references an "object from one of the classes CL_ABAP_ELEMDESCR, CL_ABAP_ENUMDESCR, @@ -988,7 +1027,7 @@ DATA(output_length) = type_descr_obj_inl_1->output_length. "5 "CL_ABAP_CLASSDESCR, or CL_ABAP_INTFDESCR. "In the following case, it is CL_ABAP_ELEMDESCR. "Note that in most of the following examples, the explicit -"casting is included when retrieving a reference to the type +"cast is included when retrieving a reference to the type "description object. TYPES another_elem_type TYPE n LENGTH 3. DATA(type_descr_obj_inl_2) = cl_abap_typedescr=>describe_by_name( 'ANOTHER_ELEM_TYPE' ). @@ -1057,22 +1096,22 @@ DATA(ref_type_type_kind) = "to a data object here. The relevant method is describe_by_data. "Elementary data object -DATA dobj_elem type i. +DATA dobj_elem TYPE i. DATA(ty_des_obj_el) = CAST cl_abap_elemdescr( cl_abap_typedescr=>describe_by_data( dobj_elem ) ). "Structure -DATA dobj_struc type zdemo_abap_carr. +DATA dobj_struc TYPE zdemo_abap_carr. DATA(ty_des_obj_struc) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( dobj_struc ) ). "Internal table -DATA dobj_itab type table of zdemo_abap_carr with empty key. +DATA dobj_itab TYPE TABLE OF zdemo_abap_carr WITH EMPTY KEY. DATA(ty_des_obj_itab) = CAST cl_abap_tabledescr( cl_abap_typedescr=>describe_by_data( dobj_itab ) ). "Reference variable -DATA dref_var type ref to string. +DATA dref_var TYPE REF TO string. DATA(ty_des_obj_dref) = CAST cl_abap_refdescr( cl_abap_typedescr=>describe_by_data( dref_var ) ). ``` diff --git a/18_Dynpro.md b/18_Dynpro.md index be9946e..58a8362 100644 --- a/18_Dynpro.md +++ b/18_Dynpro.md @@ -43,7 +43,7 @@ This cheat sheet provides a high-level overview of classic dynpro topics with a > - 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 touch on 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. +> - 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. Although it looks like ABAP, it is not ABAP. > - 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). @@ -672,7 +672,7 @@ Example: dynnr = '9400'. "Assign the activetab component tabstr-activetab = 'SOME_TAB'. -"Providing teh prgram name +"Providing the prgram name prog = sy-repid. ... @@ -739,7 +739,7 @@ After the import of the repository, proceed as follows: Expand to see explanations of the executable example
-Th example demonstrates dynpro-related statements. In the dynpros, you can select various options for checking out the effect of the syntax. +The example demonstrates dynpro-related statements. In the dynpros, you can select various options for checking out the effect of the syntax. It covers the following aspects: - Dynpro flow logic and related statements (`MODULE`, `FIELD`, `CHAIN`/`ENDCHAIN`, `LOOP`/`ENDLOOP`, `CALL SUBSCREEN`) diff --git a/19_ABAP_for_Cloud_Development.md b/19_ABAP_for_Cloud_Development.md index c89fcb2..734e5ea 100644 --- a/19_ABAP_for_Cloud_Development.md +++ b/19_ABAP_for_Cloud_Development.md @@ -9,7 +9,7 @@ - [Executable Example](#executable-example) -This ABAP cheat sheet briefly touches on the terms ABAP Cloud and classic ABAP to set the context for [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). +This ABAP cheat sheet briefly touches on the terms ABAP Cloud and classic ABAP to get an idea about [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). It provides references to more detailed information on the topic. # Terms @@ -132,7 +132,7 @@ It provides references to more detailed information on the topic. b) Create an example class - Create a global class and insert the code from above. Depending on the name of the class you created, replace the class name in the snippet. - - If you have not imported the ABAP cheat sheet GitHub repository, remove the lines of code using artifacts from that repository, i.e. change the `SELECT` and `READ REPORT` statemnets. You should not see any syntax errors. Activate the class. + - If you have not imported the ABAP cheat sheet GitHub repository, remove the lines of code using artifacts from that repository, i.e. change the `SELECT` and `READ REPORT` statements. You should not see any syntax errors. Activate the class. - Run the class with *F9*. The code should have been processed up to the `BREAK-POINT` statement and the debugger should have started. You may want to check the content of the variables in the debugger. Choose *Terminate* to exit the debugger. - So, unlike in the case of ABAP Cloud above, the code should not cause any problems (other than the fact that it does not make a lot of sense). - For the example class created, check the information in the *Properties* tab. Choose *General*. The *ABAP Language Version* is maintained as *Standard ABAP*: diff --git a/20_Selection_Screens_Lists.md b/20_Selection_Screens_Lists.md index bdce2c5..65adfff 100644 --- a/20_Selection_Screens_Lists.md +++ b/20_Selection_Screens_Lists.md @@ -139,7 +139,7 @@ PARAMETERS pd LIKE (some_dobj). PARAMETERS pe TYPE c LENGTH 1. PARAMETERS pf TYPE n LENGTH 5. -"You may also see specifications in which the length is specified in parentheses. +"Specifications in which the length is specified in parentheses. "For better readability, specifying LENGTH explicitly is recommended. PARAMETERS pg(2) TYPE c. "No length specified means LENGTH 1 by default @@ -193,7 +193,7 @@ PARAMETERS ps TYPE c AS CHECKBOX. "Explicit type specification (but no explicit "- Regarding the data type, the same applies as for AS CHECKBOX "- Only one parameter can be defined with the DEFAULT addition "- If DEFAULT is not specified, the first parameter of the group is set to the value X -"- Here, a chained statements is used. +"- Here, a chained statement is used. PARAMETERS: prb1 RADIOBUTTON GROUP rbgr, prb2 type c RADIOBUTTON GROUP rbgr, "Explicit type specification prb3 RADIOBUTTON GROUP rbgr DEFAULT 'X'. "Select this radiobutton by default @@ -607,9 +607,9 @@ WRITE /5(30) 'this is displayed completely'. "Position/length only specified as numeric literals as above, then the "addition AT can be omitted WRITE AT /3(12) 'lorem ipsum'. -"You may also see length specifications with * or **. In that case, the -"output length depends on the data type of the data object. There are -"special rules. See the ABAP Keyword Documentation for the details. +"Length specifications with * or **. In that case, the output length +"depends on the data type of the data object. There are special rules. +"See the ABAP Keyword Documentation for the details. DATA dc34 TYPE decfloat34 VALUE ' 1.2345 '. WRITE /(*) dc34. WRITE /1(**) dc34. diff --git a/README.md b/README.md index 8408bba..7bc6a0e 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ ABAP cheat sheets[^1] ... |[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)| |[CDS View Entities](15_CDS_View_Entities.md)|Note that cheat sheet content is available in [this blog](https://blogs.sap.com/2022/10/24/feature-matrix-data-modeling-with-abap-core-data-services/). The focus here is on the example CDS artifacts and the [executable example class](./src/zcl_demo_abap_cds_ve.clas.abap), which include comments.|[zcl_demo_abap_cds_ve](./src/zcl_demo_abap_cds_ve.clas.abap)| -|[SAP LUW](17_SAP_LUW.md)|Provides a high-level overview on the [SAP LUW](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensap_luw_glosry.htm) concept that deals with data consistency with a focus on SAP LUW-related statements
💡 Several statements covered in the cheat sheet and the executable example are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).|Program `ZDEMO_ABAP_SAP_LUW`| +|[SAP LUW](17_SAP_LUW.md)|Provides a high-level overview of the [SAP LUW](https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm?file=abensap_luw_glosry.htm) concept that deals with data consistency with a focus on SAP LUW-related statements
💡 Several statements covered in the cheat sheet and the executable example are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).|Program `ZDEMO_ABAP_SAP_LUW`| |[Dynpro](18_Dynpro.md)|Provides a high-level overview of dynpro topics with a focus on dynpro-related statements
💡 The content of this cheat sheet and the executable example are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).|Program `ZDEMO_ABAP_DYNPRO`| |[Selection Screens and Classic Lists](20_Selection_Screens_Lists.md)|Provides a high-level overview of selection screens and classic lists with a focus on related statements
💡 The content of this cheat sheet and the executable examples are only relevant to [classic ABAP](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenclassic_abap_glosry.htm).|Program `ZDEMO_ABAP_SELSCR_LISTS_INTRO` (the "intro" program, from which the other related example programs can be started)| diff --git a/src/zcl_demo_abap_cloud_excursion.clas.abap b/src/zcl_demo_abap_cloud_excursion.clas.abap index c2c91ea..04b7eb8 100644 --- a/src/zcl_demo_abap_cloud_excursion.clas.abap +++ b/src/zcl_demo_abap_cloud_excursion.clas.abap @@ -160,7 +160,7 @@ CLASS zcl_demo_abap_cloud_excursion IMPLEMENTATION. DATA(up_to_year) = 2050. "The statement retrieves the leap years between the current year and - "the specfied years. A released CDS view is used as data source. + "the specified year. A released CDS view is used as data source. SELECT calendaryear FROM i_calendaryear WHERE calendaryear BETWEEN @current_year AND @up_to_year @@ -221,7 +221,7 @@ CLASS zcl_demo_abap_cloud_excursion IMPLEMENTATION. AND ReleasedObjectName LIKE 'CL_ABAP_RANDOM_P%' INTO TABLE @DATA(rel_cl_abap_random). - out->write( |\nRead result::| ). + out->write( |\nRead result:| ). out->write( data = rel_cl_abap_random name = `rel_cl_abap_random` ). "Getting the number of all released classes in the system diff --git a/src/zcl_demo_abap_dynamic_prog.clas.abap b/src/zcl_demo_abap_dynamic_prog.clas.abap index a21b418..e872a86 100644 --- a/src/zcl_demo_abap_dynamic_prog.clas.abap +++ b/src/zcl_demo_abap_dynamic_prog.clas.abap @@ -1662,10 +1662,11 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION. ********************************************************************** out->write( zcl_demo_abap_aux=>heading( `37b) Excursion: Checking the validity of dynamic specifications` ) ). - "The following example uses the CL_ABAP_DYN_PRG class, which supports - "dynamic programming by checking the validity of dynamic specifications. + "The following examples use methods of the CL_ABAP_DYN_PRG class, which supports + "dynamic programming by checking the validity for dynamic specifications. "Check out the class documentation for more information. - "In the example, several table names are provided in a string table that + + "In the following example, several table names are provided in a string table that "is looped over. Some wrong table names are intentionally included. "You can provide the "packages" formal parameter with a table that contains "the names of packages in which the tables should be included. The @@ -1673,6 +1674,9 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION. "specified. If you imported it into a package with a different name, "change the value accordingly. Otherwise, none of the tables is found. + out->write( `****** Checking if the input is a database table name, inlcuded in given packages ******` ). + out->write( |\n| ). + DATA(table_names) = VALUE string_table( ( `ZDEMO_ABAP_CARR` ) ( `ZDEMO_ABAP_FLI` ) ( `NO_DBTAB` ) @@ -1692,18 +1696,83 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION. SELECT SINGLE * FROM (dbtab) INTO NEW @DATA(ref_wa). out->write( |Result for { wa_tab }:| ). - out->write( |\n| ). - out->write( |\n| ). out->write( ref_wa->* ). out->write( |\n| ). CATCH cx_abap_not_a_table cx_abap_not_in_package INTO DATA(err). out->write( |Result for { wa_tab }:| ). - out->write( |\n| ). out->write( err->get_text( ) ). out->write( |\n| ). ENDTRY. ENDLOOP. + "In the following example, the check_allowlist method is used to check + "whether the input is allowed or not. Similar to above, an internal + "is filled with demo input. Here, a parameter is used that expects + "a comma-separated list of allowed values. + + out->write( `****** Checking if input is allowed or not ******` ). + out->write( |\n| ). + + DATA(to_be_checked) = VALUE string_table( ( `A` ) + ( `B` ) + ( `C` ) + ( `D` ) + ( `HALLO` ) + ( `ABAP` ) ). + + LOOP AT to_be_checked INTO DATA(chk). + TRY. + DATA(value) = cl_abap_dyn_prg=>check_allowlist( val = chk + allowlist_str = `A,B,C,ABAP` ). + out->write( |{ value } is allowed.| ). + CATCH cx_abap_not_in_allowlist INTO err. + out->write( err->get_text( ) ). + ENDTRY. + ENDLOOP. + + out->write( |\n| ). + + "The following example is similar to the one above. However, in this case, + "a parameter is used that expects an internal table containing the allowed + "values. + + LOOP AT to_be_checked INTO chk. + TRY. + value = cl_abap_dyn_prg=>check_allowlist( val = chk + allowlist_htab = VALUE #( ( `X` ) + ( `B` ) + ( `HALLO` ) + ( `Y` ) + ( `ABAP` ) ) ). + out->write( |{ value } is allowed.| ). + CATCH cx_abap_not_in_allowlist INTO err. + out->write( err->get_text( ) ). + ENDTRY. + ENDLOOP. + + out->write( |\n| ). + out->write( `****** Checking if input can be a column name and does not contain invalid characters ******` ). + out->write( |\n| ). + + "The following example uses a method with which the validity of column names + "of database tables can be checked. + + to_be_checked = VALUE #( ( `CARRID` ) + ( `CONNID` ) + ( `SOME_COLUMN` ) + ( `??NOPE??` ) + ( `...!` ) ). + + LOOP AT to_be_checked INTO chk. + TRY. + DATA(col_name) = cl_abap_dyn_prg=>check_column_name( val = chk + strict = abap_true ). + out->write( |{ col_name } is allowed.| ). + CATCH cx_abap_invalid_name INTO err. + out->write( err->get_text( ) ). + ENDTRY. + ENDLOOP. + ********************************************************************** out->write( zcl_demo_abap_aux=>heading( `38) Dynamic Invoke` ) ). diff --git a/src/zdemo_abap_cds_ve_agg_exp.ddls.asddls b/src/zdemo_abap_cds_ve_agg_exp.ddls.asddls index 7d4d08a..a58eac3 100644 --- a/src/zdemo_abap_cds_ve_agg_exp.ddls.asddls +++ b/src/zdemo_abap_cds_ve_agg_exp.ddls.asddls @@ -4,7 +4,7 @@ //////////////////////////------ NOTES ------////////////////////////////////// // - CDS view entity selects from a demo database table // - Demonstrates various aggregate expressions in the element list -// - As a prerequisite, run the class zcl_abap_demo_cds_ve to populate the +// - As a prerequisite, run the class zcl_demo_abap_cds_ve to populate the // database tables of the example. Otherwise, no data is displayed. // //////////////////////------ DATA PREVIEW ------/////////////////////////////// diff --git a/src/zdemo_abap_cds_ve_assoc.ddls.asddls b/src/zdemo_abap_cds_ve_assoc.ddls.asddls index b09ce4d..7274f2d 100644 --- a/src/zdemo_abap_cds_ve_assoc.ddls.asddls +++ b/src/zdemo_abap_cds_ve_assoc.ddls.asddls @@ -4,7 +4,7 @@ // - CDS view entity that selects from a demo CDS view entity and demonstrates // associations. A selection of use cases of associations is covered. For // more information and examples, see the ABAP Keyword Documentation. -// - As a prerequisite, run the class zcl_abap_demo_cds_ve to populate the +// - As a prerequisite, run the class zcl_demo_abap_cds_ve to populate the // database tables of the example. Otherwise, no data is displayed. // - For further notes on associations, see the commented out information further // down. diff --git a/src/zdemo_abap_cds_ve_assoc_e.ddls.asddls b/src/zdemo_abap_cds_ve_assoc_e.ddls.asddls index 74596a5..1d5ca27 100644 --- a/src/zdemo_abap_cds_ve_assoc_e.ddls.asddls +++ b/src/zdemo_abap_cds_ve_assoc_e.ddls.asddls @@ -4,7 +4,7 @@ // - CDS view entity that selects from a demo database table. // - The purpose of this CDS view entity is to demonstrate associations. The view // is used as a data source in another CDS view entity. -// - As a prerequisite, run the class zcl_abap_demo_cds_ve to populate the +// - As a prerequisite, run the class zcl_demo_abap_cds_ve to populate the // database tables of the example. Otherwise, no data is displayed. // //////////////////////------ DATA PREVIEW ------/////////////////////////////// diff --git a/src/zdemo_abap_cds_ve_joins.ddls.asddls b/src/zdemo_abap_cds_ve_joins.ddls.asddls index 486afd1..19a0b1b 100644 --- a/src/zdemo_abap_cds_ve_joins.ddls.asddls +++ b/src/zdemo_abap_cds_ve_joins.ddls.asddls @@ -3,7 +3,7 @@ //////////////////////////------ NOTES ------////////////////////////////////// // - CDS view entity selects from a demo database table // - Demonstrates various joins -// - As a prerequisite, run the class zcl_abap_demo_cds_ve to populate the +// - As a prerequisite, run the class zcl_demo_abap_cds_ve to populate the // database tables of the example. Otherwise, no data is displayed. // It is particularly needed in this case because it contains entries to // visualize the effect of outer joins. diff --git a/src/zdemo_abap_cds_ve_sel.ddls.asddls b/src/zdemo_abap_cds_ve_sel.ddls.asddls index ce762d0..e982878 100644 --- a/src/zdemo_abap_cds_ve_sel.ddls.asddls +++ b/src/zdemo_abap_cds_ve_sel.ddls.asddls @@ -4,7 +4,7 @@ //////////////////////////------ NOTES ------////////////////////////////////// // - CDS view entity selects from a demo database table // - Demonstrates various syntax options regarding operands and expressions -// - As a prerequisite, run the class zcl_abap_demo_cds_ve to populate the +// - As a prerequisite, run the class zcl_demo_abap_cds_ve to populate the // database tables of the example. Otherwise, no data is displayed. // //////////////////////------ DATA PREVIEW ------///////////////////////////////