Update content

This commit is contained in:
danrega
2023-05-08 16:52:32 +02:00
parent 5f64588465
commit b7eb7350c4
2 changed files with 450 additions and 82 deletions

View File

@@ -130,12 +130,6 @@ ASSIGN num TO <fs_gen>. "Could be any of the data objects
"is automatically derived. "is automatically derived.
ASSIGN num TO FIELD-SYMBOL(<fs_inl>). ASSIGN num TO FIELD-SYMBOL(<fs_inl>).
"You can also assign a particular component of a structure.
"Second component of the structure
ASSIGN COMPONENT 2 OF STRUCTURE struc TO <fs_gen>.
ASSIGN COMPONENT 'CARRID' OF STRUCTURE struc TO <fs_gen>.
"CASTING addition for matching types of data object and field symbol "CASTING addition for matching types of data object and field symbol
"when assigning memory areas "when assigning memory areas
TYPES c_len_3 TYPE c LENGTH 3. TYPES c_len_3 TYPE c LENGTH 3.
@@ -409,7 +403,7 @@ DATA(struc) = ref_carr->*.
DATA(carrid) = ref_carr->carrid. DATA(carrid) = ref_carr->carrid.
ref_carr->carrid = 'UA'. ref_carr->carrid = 'UA'.
"This syntax also works but it is less "comfortable". "This longer syntax with the dereferencing operator also works.
ref_carr->*-carrname = 'United Airlines'. ref_carr->*-carrname = 'United Airlines'.
"Checking if a data reference variable can be dereferenced. "Checking if a data reference variable can be dereferenced.
@@ -421,6 +415,37 @@ ENDIF.
"However, the garbage collector takes care of removing the references "However, the garbage collector takes care of removing the references
"automatically once the data is not used any more by a reference. "automatically once the data is not used any more by a reference.
CLEAR ref_carr. CLEAR ref_carr.
******************************************************
"Excursion: Generic data references in older ABAP releases
"Non-generic type
DATA ref_int TYPE REF TO i.
ref_int = NEW #( ).
ref_int->* = 123.
"Generic type
DATA ref_generic TYPE REF TO data.
ref_generic = NEW i( ).
"In older ABAP releases, CREATE DATA statements were needed.
CREATE DATA ref_generic TYPE i.
"The only option to access the variable in older releases was via field symbols.
ASSIGN ref_generic->* TO FIELD-SYMBOL(<fs_generic>).
<fs_generic> = 123.
"An access as the following, as it is possible in modern ABAP, was not possible.
ref_generic->* = 123.
"As shown in the example below, using dereferenced generic references is possible
"in various places in modern ABAP.
DATA ref_sel TYPE REF TO data.
CREATE DATA ref_sel TYPE TABLE OF zdemo_abap_carr.
SELECT *
FROM zdemo_abap_carr
INTO TABLE @ref_sel->*.
``` ```
**Data references in use** **Data references in use**
@@ -518,44 +543,105 @@ In this context, you can usually use elementary, character-like data objects - t
Note that dynamically specifying syntax elements has downsides, too. Consider some erroneous character-like content of such data objects. There is no syntax warning. At runtime, it can lead to runtime errors. Note that dynamically specifying syntax elements has downsides, too. Consider some erroneous character-like content of such data objects. There is no syntax warning. At runtime, it can lead to runtime errors.
- Dynamically specifying components - Dynamic specifications in ...
- statements for processing internal tables
``` abap ``` abap
"SORT statements: Sorting an internal table by dynamically specifying the component "SORT: Dynamically specifying component name to be sorted for
"Populating an internal table "Populating an internal table
SELECT * SELECT *
FROM zdemo_abap_carr FROM zdemo_abap_carr
INTO TABLE @DATA(itab). INTO TABLE @DATA(itab).
"Dynamically specifying component name to be sorted for "Named data object
"Named data object DATA(field_name) = 'CARRNAME'.
DATA(field_name) = 'CARRNAME'. SORT itab BY (field_name).
SORT itab BY (field_name).
"Unnamed data object "Unnamed data object
SORT itab BY ('CURRCODE'). SORT itab BY ('CURRCODE').
"ASSIGN statements "READ TABLE: Dynamically specifying keys
READ TABLE itab INTO DATA(wa) WITH KEY (field_name) = ...
"Declaring a field symbol "MODIFY: Dynamically specifying WHERE conditions
FIELD-SYMBOLS <fs> type any. DATA(condition) = ( `CARRID = 'LH'` ).
"Dynamically specifying components of structures MODIFY itab FROM ... TRANSPORTING ... WHERE (condition).
ASSIGN itab[ 1 ]-('CURRCODE') to <fs>.
DATA(struc) = itab[ 2 ]. "DELETE: Dynamically specifying WHERE conditions
ASSIGN struc-(field_name) to <fs>. DELETE itab USING KEY ... WHERE (condition).
"Dynamically specifying components of structures that are referenced by "LOOP: Dynamically specifying keys
"a data reference variable DATA(k) = `SOME_KEY`.
DATA(dref) = REF #( struc ).
ASSIGN dref->('URL') to <fs>.
"Dynamically specifying component of a class/interface LOOP AT itab INTO DATA(wa_lo) USING KEY (k).
"In the example, the field symbol is declared inline. ...
ASSIGN zdemo_abap_objects_interface=>('CONST_INTF') TO FIELD-SYMBOL(<fs_inl>). ENDLOOP.
``` ```
- ASSIGN statements
``` abap
"Accessing components of structures dynamically
"Populating a structure
SELECT SINGLE *
FROM zdemo_abap_carr
INTO @DATA(wa).
"Declaring a field symbol
FIELD-SYMBOLS <fs> type any.
DATA(comp_name) = 'CARRNAME'.
ASSIGN wa-(comp_name) TO <fs>. "named data object
ASSIGN wa-('CARRID') TO <fs>. "unnamed data object
"The statements set sy-subrc value. No exception occurs in case of an unsuccessful assignment.
ASSIGN wa-('XYZ') TO <fs>.
IF sy-subrc <> 0.
...
ENDIF.
"Numeric expressions are possible. Its value is interpreted as the position
"of the component in the structure.
ASSIGN wa-(4) TO <fs>.
"If the value is 0, the memory area of the entire structure is assigned to the field symbol.
ASSIGN wa-(0) TO <fs>.
"The statements above replace the following, older statements.
ASSIGN COMPONENT 'CARRID' OF STRUCTURE wa TO <fs>.
ASSIGN COMPONENT 5 OF STRUCTURE wa TO <fs>.
"Populating a structure that is referenced by a data reference variable
SELECT SINGLE *
FROM zdemo_abap_carr
INTO NEW @DATA(ref_struc).
"Note the object component selector. The field symbol is created inline here.
ASSIGN ref_struc->('CARRNAME') TO FIELD-SYMBOL(<fs_inl>).
*************************************************************
"Dynamically specifying attributes of classes/interfaces
DATA(cl_name) = 'CL_SOME_CLASS'.
DATA(dobj) = 'SOME_DOBJ'.
ASSIGN cl_some_class=>(dobj) TO <fs>.
ASSIGN (cl_name)=>some_dobj TO <fs>.
ASSIGN (cl_name)=>(dobj) TO <fs>.
"Class reference variable pointing to an object that contains attributes
"and that are specified dynamically.
DATA cl_ref TYPE REF TO cl_some_class.
cl_ref = NEW #( ).
ASSIGN cl_ref->('some_attribute') TO FIELD-SYMBOL(<another_fs>).
"If ELSE UNASSIGN is specified, no memory area is assigned to the field symbol.
"It has the state unassigned after the ASSIGN statement.
ASSIGN cl_ref->('attr_xyz') TO FIELD-SYMBOL(<attr>) ELSE UNASSIGN.
```
- Dynamically specifying data types - Dynamically specifying data types
@@ -601,6 +687,12 @@ Note that dynamically specifying syntax elements has downsides, too. Consider so
FROM (db_table) FROM (db_table)
INTO TABLE @itab->*. INTO TABLE @itab->*.
"Similar to the NEW operator, you can use the addition NEW here to create an anonymous data object
"in place. The advantage is that the data type is constructed in a suitable way.
SELECT *
FROM (db_table)
INTO TABLE NEW @DATA(a_dobj).
"Dynamic WHERE clause "Dynamic WHERE clause
"This is an example for using an internal table with a character-like row type "This is an example for using an internal table with a character-like row type
DATA(where_clause) = VALUE string_table( ( `CARRID = 'LH'` ) DATA(where_clause) = VALUE string_table( ( `CARRID = 'LH'` )

View File

@@ -3,42 +3,47 @@
* ABAP cheat sheet: Dynamic programming * ABAP cheat sheet: Dynamic programming
* *
* -------------------------- PURPOSE ---------------------------------- * -------------------------- PURPOSE ----------------------------------
* - Example to demonstrate various syntactical options and concepts related * - Example to demonstrate various syntax options and concepts related
* to dynamic programming. * to dynamic programming.
* - Topics covered: Field symbols and data references (both as supporting * - Topics covered: Field symbols and data references (both as supporting
* elements for dynamic programming), dynamic ABAP syntax components, * elements for dynamic programming), dynamic ABAP syntax components,
* runtime type services (RTTS), i. e. runtime type identification (RTTI) * runtime type services (RTTS), i. e. runtime type identification (RTTI)
* and runtime type creation (RTTC) * and runtime type creation (RTTC)
* - To provide a "real" dynamic determination at runtime, the example * - To provide a "real" dynamic determination at runtime for several code
* includes local classes in the CCIMP include (local types tab in ADT) * examples in this class, the example class includes local classes
* whose methods return character-like content to be used in the * in the CCIMP include (local types tab in ADT) whose methods return
* ABAP statements. The content is predefined in these classes but * character-like content to be used in the ABAP statements. The content
* the content that is actually used in the end is random. * is predefined in these classes but the content that is actually used
* in the end is random.
* *
* ----------------------- GETTING STARTED ----------------------------- * ----------------------- GETTING STARTED -----------------------------
* - Open the class with the ABAP Development Tools (ADT). * - Open the class with the ABAP Development Tools (ADT).
* - Choose F9 to run the class. * - Choose F9 to run the class.
* - Check the console output. * - Check the console output.
* - To understand the context and the ABAP syntax used, refer to the * - To understand the context and the ABAP syntax used, refer to the
* notes included in the class as comments or refer to the respective * notes included in the class as comments or refer to the respective
* topic in the ABAP Keyword Documentation. * topic in the ABAP Keyword Documentation.
* - Due to the amount of console output, the examples contain numbers * - Due to the amount of console output, the examples contain numbers
* (e.g. 1) ..., 2) ..., 3) ...) for the individual example sections. * (e.g. 1) ..., 2) ..., 3) ...) for the individual example sections.
* Also, the variable name is displayed in most cases. So to find * Also, the variable name is displayed in most cases. So to find
* the relevant output in the console easier and faster, just search * the relevant output in the console easier and faster, just search
* for the number/variable name in the console (CTRL+F in the console) * for the number/variable name in the console (CTRL+F in the console)
* or use the debugger. * or use the debugger.
* *
* ----------------------------- NOTE ----------------------------------- * ----------------------------- NOTE -----------------------------------
* Some code sections are commented out. The syntax is only available in
* newer ABAP releases. Comment them in if you are running a newer
* ABAP release, for example, in the SAP BTP environment.
*
* The code presented in this class is intended only to support the ABAP * The code presented in this class is intended only to support the ABAP
* cheat sheets. It is not intended for direct use in a production system * cheat sheets. It is not intended for direct use in a production system
* environment. The code examples in the ABAP cheat sheets are primarily * environment. The code examples in the ABAP cheat sheets are primarily
* intended to provide a better explanation and visualization of the * intended to provide a better explanation and visualization of the
* syntax and semantics of ABAP statements, not to solve concrete * syntax and semantics of ABAP statements, not to solve concrete
* programming tasks. For production application programs, you should * programming tasks. For production application programs, you should
* always work out your own solution for each individual case. There is * always work out your own solution for each individual case. There is
* no guarantee for the correctness or completeness of the code. * no guarantee for the correctness or completeness of the code.
* Furthermore, there is no legal responsibility or liability for any * Furthermore, there is no legal responsibility or liability for any
* errors or their consequences that may occur when using the the example * errors or their consequences that may occur when using the the example
* code. * code.
* *
@@ -155,12 +160,6 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
"Inline declaration is possible, too. The type is automatically derived. "Inline declaration is possible, too. The type is automatically derived.
ASSIGN num_a TO FIELD-SYMBOL(<fs_inl>). ASSIGN num_a TO FIELD-SYMBOL(<fs_inl>).
"Assigning structure components to field symbols
"Component position
ASSIGN COMPONENT 2 OF STRUCTURE struc_a TO <fs_data_a>.
"Component name
ASSIGN COMPONENT 'CONNID' OF STRUCTURE struc_a TO <fs_data_a>.
output->display( `No output for this section. See the code.` ). output->display( `No output for this section. See the code.` ).
********************************************************************** **********************************************************************
@@ -435,8 +434,13 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
DO. DO.
"sy-index represents the position of a structure component "sy-index represents the position of a structure component
"NOTE: The following statement is replaced by the newer syntax that is
"commented out below. Therefore, it is recommended that you use this
"syntax in newer ABAP releases.
ASSIGN COMPONENT sy-index OF STRUCTURE <struct> TO <comp>. ASSIGN COMPONENT sy-index OF STRUCTURE <struct> TO <comp>.
"ASSIGN <struct>-(sy-index) to <comp>.
IF sy-subrc <> 0. IF sy-subrc <> 0.
"If all components are processed, the loop is exited. "If all components are processed, the loop is exited.
EXIT. EXIT.
@@ -846,23 +850,133 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `Dynamic ABAP Statements` ). output->next_section( `Dynamic ABAP Statements` ).
output->display( `20) Assignment of Dynamically ` && output->display( `20a) Dynamic Specifications in ASSIGN Statements (1) - Attributes of Classes/Interfaces` ).
`Determined Data Objects to Field Symbols` ).
"A dynamically determined data object is assigned to a field symbol. "The following examples demonstrate a selection of various dynamic specifications
"In this case, data objects that are declared in the public section of "that are possible with ASSIGN statements.
"the local demo class are assigned to a field symbol.
"Dynamic specification of attributes of classes/interfaces that are assigned to a field symbol.
DATA(dobj_name) = lcl_det_at_runtime=>get_dyn_dobj( ). DATA(dobj_name) = lcl_det_at_runtime=>get_dyn_dobj( ).
ASSIGN lcl_det_at_runtime=>(dobj_name) TO FIELD-SYMBOL(<fs_m>). ASSIGN lcl_det_at_runtime=>(dobj_name) TO FIELD-SYMBOL(<fs_m1>).
output->display( |Data object name determined at runtime: { dobj_name } | ). output->display( |Data object name determined at runtime: { dobj_name } | ).
output->display( |The content of the data object is: { <fs_m> } | ). output->display( |The content of the data object is: { <fs_m1> } | ).
dobj_name = lcl_det_at_runtime=>get_dyn_dobj( ).
"Completely dynamic assign
ASSIGN ('lcl_det_at_runtime')=>(dobj_name) TO FIELD-SYMBOL(<fs_m2>).
output->display( input = <fs_m2> name = `<fs_m2>` ).
ASSIGN ('zdemo_abap_objects_interface')=>('const_intf') TO FIELD-SYMBOL(<fs_m3>).
output->display( input = <fs_m3> name = `<fs_m3>` ).
"Class/interface reference variables pointing to an object that contains attributes
"and that are specified dynamically.
DATA iref TYPE REF TO zdemo_abap_objects_interface.
DATA(cl_ref) = NEW zcl_demo_abap_objects( ).
iref = cl_ref.
ASSIGN iref->('const_intf') TO FIELD-SYMBOL(<fs_m4>).
output->display( input = <fs_m4> name = `<fs_m4>` ).
ASSIGN cl_ref->('another_string') TO FIELD-SYMBOL(<fs_m5>).
output->display( input = <fs_m5> name = `<fs_m5>` ).
**********************************************************************
"Note: Comment in the following example in newer ABAP releases and in the SAP BTP environment.
* output->next_section( `20b) Dynamic Specifications in ASSIGN Statements (2) - Setting sy-subrc/ELSE UNASSIGN` ).
*
* "In dynamic assignments, the statement ASSIGN sets the return code sy-subrc.
* "If ELSE UNASSIGN is specified, no memory area is assigned to the field symbol. It has the state unassigned after the ASSIGN statement.
*
* DATA(attr) = VALUE string_table( ( `another_string` ) ( `public_string` ) ( `this_will_fail` ) ).
*
* LOOP AT attr INTO DATA(attribute).
*
* ASSIGN cl_ref->(attribute) TO FIELD-SYMBOL(<attr>) ELSE UNASSIGN.
* IF sy-subrc = 0.
* output->display( |Successful assignment for attribute "{ attribute }". sy-subrc = { sy-subrc }. | ).
* output->display( input = <attr> name = `<attr>` ).
* ELSE.
* output->display( |Assignment not successful for attribute "{ attribute }". sy-subrc = { sy-subrc }. | ).
* ENDIF.
*
* IF <attr> IS ASSIGNED.
* output->display( `The field symbol is assigned.` ).
* output->display( `--------------------` ).
* ELSE.
* output->display( `The field symbol is not assigned.` ).
* ENDIF.
*
* ENDLOOP.
**********************************************************************
"Note: The following code contains syntax that is only available in
"newer ABAP releases and in the SAP BTP environment. In these contexts,
"you can comment in the code.
output->next_section( `20c) Dynamic Specifications in ASSIGN Statements (3) - Structure Components` ).
"Dynamic specification of structure components that are assigned to a field symbol.
SELECT SINGLE * FROM zdemo_abap_carr INTO @DATA(wa).
"Reading into data reference variable
SELECT SINGLE * FROM zdemo_abap_carr INTO NEW @DATA(ref_m).
DATA(comp_name) = lcl_det_at_runtime=>get_dyn_field( ).
* ASSIGN wa-(comp_name) TO FIELD-SYMBOL(<fs_m6>).
*
* ASSIGN wa-('CARRNAME') TO FIELD-SYMBOL(<fs_m7>).
*
* IF sy-subrc = 0.
* DATA(subrc1) = sy-subrc.
* ENDIF.
*
* "No exception occurs in case of an unsuccessful assignment.
* ASSIGN wa-('CRRNM') TO FIELD-SYMBOL(<fs_m8>).
*
* IF sy-subrc <> 0.
* DATA(subrc2) = sy-subrc.
* ENDIF.
*
* "Numeric expressions are possible. Its value is interpreted as the position
* "of the component in the structure.
* ASSIGN wa-(4) TO FIELD-SYMBOL(<fs_m9>).
*
* "If the value is 0, the memory area of the entire structure is assigned to the field symbol.
* ASSIGN wa-(0) TO FIELD-SYMBOL(<fs_m10>).
"The above statements replace the following syntax syntax
ASSIGN COMPONENT 'CARRID' OF STRUCTURE wa TO FIELD-SYMBOL(<fs_m11>).
ASSIGN COMPONENT 5 OF STRUCTURE wa TO FIELD-SYMBOL(<fs_m12>).
"Dynamically specifying components of structures that are referenced by
"a data reference variable
ASSIGN ref_m->('CARRNAME') TO FIELD-SYMBOL(<fs_m13>).
* output->display( input = <fs_m6> name = `<fs_m6>` ).
* output->display( input = <fs_m7> name = `<fs_m7>` ).
* output->display( input = subrc1 name = `subrc1` ).
* output->display( input = subrc2 name = `subrc2` ).
* output->display( input = <fs_m9> name = `<fs_m9>` ).
* output->display( input = <fs_m10> name = `<fs_m10>` ).
output->display( input = <fs_m11> name = `<fs_m11>` ).
output->display( input = <fs_m12> name = `<fs_m12>` ).
output->display( input = <fs_m13> name = `<fs_m13>` ).
********************************************************************** **********************************************************************
output->next_section( `21) Dynamically Specifying Components` ). output->next_section( `Dynamically Specifying Components/Clauses in Statements for Processing Internal Tables with ...` ).
output->display( `21) SORT` ).
"A field is determined at runtime on whose basis a sorting is done on an "A field is determined at runtime on whose basis a sorting is done on an
"internal table. "internal table.
@@ -881,10 +995,172 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
|by which the sorting was done: { field_name } | ). |by which the sorting was done: { field_name } | ).
output->display( input = carr_itab name = `carr_itab` ). output->display( input = carr_itab name = `carr_itab` ).
**********************************************************************
output->next_section( `22) READ TABLE` ).
"Dynamic key specification in READ TABLE statements
TYPES: BEGIN OF s,
comp TYPE string,
value TYPE string,
END OF s.
TYPES comps_type TYPE TABLE OF s WITH EMPTY KEY.
"Providing components and values for READ TABLE statement
DATA(comps) = VALUE comps_type( ( comp = `CARRID` value = `LH` )
( comp = `CONNID` value = `0555` )
( comp = `SEATSOCC` value = `115` )
( comp = `CARRID` value = `XY` ) ). "not found
SELECT *
FROM zdemo_abap_fli
INTO TABLE @DATA(itab_read_tab_dyn).
LOOP AT comps INTO DATA(wa_comps).
READ TABLE itab_read_tab_dyn
INTO DATA(read_line)
WITH KEY (wa_comps-comp) = wa_comps-value.
IF sy-subrc = 0.
output->display( input = wa_comps-comp name = `wa_comps-comp` ).
output->display( input = wa_comps-value name = `wa_comps-value` ).
output->display( input = read_line name = `read_line` ).
CLEAR read_line.
ELSE.
output->display( input = wa_comps-comp name = `wa_comps-comp` ).
output->display( input = wa_comps-value name = `wa_comps-value` ).
output->display( `Line not found.` ).
ENDIF.
ENDLOOP.
**********************************************************************
output->next_section( `23) MODIFY` ).
"Dynamic WHERE condition in MODIFY statements
"Note:
"- The addition WHERE can only be specified together with the addition TRANSPORTING.
"- Invalid logical expressions raise an exception from the class CX_SY_ITAB_DYN_LOOP.
TYPES:
BEGIN OF line,
col1 TYPE c LENGTH 1,
col2 TYPE i,
END OF line.
DATA itab_mod_tab_dyn TYPE SORTED TABLE OF line
WITH UNIQUE KEY col1.
itab_mod_tab_dyn = VALUE #( ( col1 = 'A' col2 = 1 )
( col1 = 'B' col2 = 10 )
( col1 = 'C' col2 = 100 ) ).
output->display( `Internal table content before modifications:` ).
output->display( input = itab_mod_tab_dyn name = `itab_mod_tab_dyn` ).
"Providing conditions for MODIFY statement
DATA(conditions) = VALUE string_table( ( `col2 < 5` )
( `col2 = 10` )
( `colxyz > 50` ) ). "to fail
LOOP AT itab_mod_tab_dyn INTO DATA(wa_mod_dyn).
TRY.
DATA(condition) = conditions[ sy-tabix ].
MODIFY itab_mod_tab_dyn
FROM VALUE line( col2 = wa_mod_dyn-col2 * 2 )
TRANSPORTING col2
WHERE (condition).
CATCH cx_sy_itab_dyn_loop.
output->display( |Invalid WHERE condition "{ condition }".| ).
ENDTRY.
ENDLOOP.
output->display( `Internal table content after modifications:` ).
output->display( input = itab_mod_tab_dyn name = `itab_mod_tab_dyn` ).
**********************************************************************
output->next_section( `24) DELETE` ).
"Dynamic WHERE condition in DELETE statements
DATA itab_del_tab_dyn TYPE TABLE OF i WITH EMPTY KEY
WITH NON-UNIQUE SORTED KEY skey COMPONENTS table_line.
itab_del_tab_dyn = VALUE #( ( 100 )
( 200 )
( 300 )
( 400 )
( 500 )
( 600 ) ).
output->display( `Internal table content before modifications:` ).
output->display( input = itab_del_tab_dyn name = `itab_del_tab_dyn` ).
DO 3 TIMES.
TRY.
CASE sy-index.
WHEN 1.
condition = `table_line <= 200`.
WHEN 2.
condition = `table_line >= 500`.
WHEN 3.
condition = `col1 = 600`.
ENDCASE.
DELETE itab_del_tab_dyn
USING KEY skey
WHERE (condition).
output->display( |Condition: { condition }| ).
output->display( input = itab_del_tab_dyn name = `itab_del_tab_dyn` ).
CATCH cx_sy_itab_dyn_loop.
output->display( |Invalid WHERE condition "{ condition }".| ).
ENDTRY.
ENDDO.
**********************************************************************
output->next_section( `25) LOOP` ).
"Dynamic specification of the key in LOOP statements
"In the example, the loop can be executed with the entries 'skey' and 'primary_key'.
"This is not case sensitive. Any other entries produce a runtime error.
DATA(keys) = VALUE string_table( ( `primary_key` ) ( `SKEY` ) ).
DATA itab_loop TYPE TABLE OF i
WITH NON-UNIQUE KEY primary_key COMPONENTS table_line
WITH NON-UNIQUE SORTED KEY skey COMPONENTS table_line.
itab_loop = VALUE #( ( 3 ) ( 2 ) ( 1 ) ).
DATA itab_dyn_key LIKE itab_loop.
LOOP AT keys INTO DATA(k).
LOOP AT itab_loop INTO DATA(wa_lo) USING KEY (k).
APPEND wa_lo TO itab_dyn_key.
ENDLOOP.
output->display( |Loop over internal table using key "{ k }".| ).
output->display( input = itab_dyn_key name = `itab_dyn_key` ).
CLEAR itab_dyn_key.
ENDLOOP.
********************************************************************** **********************************************************************
output->next_section( `Dynamically Specifying Clauses in ABAP SQL SELECT Statements` ). output->next_section( `Dynamically Specifying Clauses in ABAP SQL SELECT Statements` ).
output->display( `22) SELECT List` ). output->display( `26) SELECT List` ).
"In the example, the SELECT list that is used in a SELECT statement is "In the example, the SELECT list that is used in a SELECT statement is
"determined at runtime. "determined at runtime.
@@ -904,7 +1180,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `23) FROM Clause` ). output->next_section( `27) FROM Clause` ).
"In the example, the FROM clause that is used in a SELECT statement is "In the example, the FROM clause that is used in a SELECT statement is
"determined at runtime. Here, the number of entries of a database table "determined at runtime. Here, the number of entries of a database table
@@ -921,7 +1197,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `24) WHERE Clause` ). output->next_section( `28) WHERE Clause` ).
"In the example, the WHERE clause that is used in a SELECT statement is "In the example, the WHERE clause that is used in a SELECT statement is
"determined at runtime. Here, the WHERE clause is based on a string "determined at runtime. Here, the WHERE clause is based on a string
@@ -942,7 +1218,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `25) Excursion: Multiple Dynamically Specified ` && output->next_section( `29) Excursion: Multiple Dynamically Specified ` &&
`Clauses in an ABAP SQL SELECT Statement` ). `Clauses in an ABAP SQL SELECT Statement` ).
"In this example, multiple clauses in a SELECT statement are "In this example, multiple clauses in a SELECT statement are
@@ -979,7 +1255,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `26) Dynamic Invoke` ). output->next_section( `30) Dynamic Invoke` ).
"In the example, both class and method are determined at runtime for "In the example, both class and method are determined at runtime for
"the method call. The suitable parameter table is filled in the "the method call. The suitable parameter table is filled in the
@@ -1020,7 +1296,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `27) RTTI: Determining Data and Object Types at Runtime` ). output->next_section( `31) RTTI: Determining Data and Object Types at Runtime` ).
"The example demonstrates RTTI as follows: "The example demonstrates RTTI as follows:
"- The method call takes care of providing the name of a type. It is implemented "- The method call takes care of providing the name of a type. It is implemented
@@ -1159,7 +1435,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `28) RTTC: Dynamically Creating Elementary Data Objects` ). output->next_section( `32) RTTC: Dynamically Creating Elementary Data Objects` ).
"The example demonstrates RTTC as follows: "The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a built-in data type and more "- The method call takes care of providing the name of a built-in data type and more
@@ -1198,7 +1474,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `29) RTTC: Dynamically Creating Structured Data Object (1)` ). output->next_section( `33) RTTC: Dynamically Creating Structured Data Object (1)` ).
"The example demonstrates RTTC as follows: "The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a database table name. "- The method call takes care of providing the name of a database table name.
@@ -1236,7 +1512,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `30) RTTC: Dynamically Creating Structured Data Object (2)` ). output->next_section( `34) RTTC: Dynamically Creating Structured Data Object (2)` ).
"This example includes the dynamic definition of a structure with three components "This example includes the dynamic definition of a structure with three components
"using the GET method of the CL_ABAP_STRUCTDESCR class. "using the GET method of the CL_ABAP_STRUCTDESCR class.
@@ -1292,7 +1568,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `31) RTTC: Dynamically Creating Internal Table (1)` ). output->next_section( `35) RTTC: Dynamically Creating Internal Table (1)` ).
"The example demonstrates RTTC as follows: "The example demonstrates RTTC as follows:
"- The method call takes care of providing the name of a database table name. "- The method call takes care of providing the name of a database table name.
@@ -1319,7 +1595,7 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
********************************************************************** **********************************************************************
output->next_section( `32) RTTC: Dynamically Creating Internal Table (2)` ). output->next_section( `36) RTTC: Dynamically Creating Internal Table (2)` ).
"In the example an internal table type is created based on a DDIC type. "In the example an internal table type is created based on a DDIC type.
"See the comments in the code. "See the comments in the code.
@@ -1376,4 +1652,4 @@ CLASS zcl_demo_abap_dynamic_prog IMPLEMENTATION.
output->display( input = ref_tab->* name = `ref_tab->*` ). output->display( input = ref_tab->* name = `ref_tab->*` ).
ENDMETHOD. ENDMETHOD.
ENDCLASS. ENDCLASS.