Update
This commit is contained in:
@@ -437,15 +437,16 @@ MODIFY ENTITIES OF zdemo_abap_rap_ro_m
|
||||
<tr>
|
||||
<td>
|
||||
|
||||
Assigning incompatible structures
|
||||
Assigning incompatible structures and internal tables
|
||||
|
||||
</td>
|
||||
|
||||
<td>
|
||||
|
||||
- The example makes use of the `BASE` addition, and includes a `CORRESPONDING` expression.
|
||||
- The `s1` structure is assigned the identically named components of the `s2` structure.
|
||||
- Other components are assigned by explicitly specifying them.
|
||||
- The `s1` structure is assigned the identically named components of the `s2` structure. Other components are assigned by explicitly specifying them.
|
||||
- Another example performs an assignment with internal tables, using a table iteration with a `FOR` loop.
|
||||
-
|
||||
|
||||
<br>
|
||||
|
||||
@@ -465,6 +466,37 @@ DATA:
|
||||
END OF s2.
|
||||
|
||||
s1 = VALUE #( BASE CORRESPONDING #( s2 ) comp4 = 4 comp5 = 5 ).
|
||||
|
||||
DATA itab1 LIKE TABLE OF s1 WITH EMPTY KEY.
|
||||
DATA itab2 LIKE TABLE OF s2 WITH EMPTY KEY.
|
||||
|
||||
itab1 = VALUE #( ( comp1 = 1 comp2 = 2 comp3 = 3 comp4 = 4 comp5 = 5 )
|
||||
( comp1 = 10 comp2 = 20 comp3 = 30 comp4 = 40 comp5 = 50 )
|
||||
( comp1 = 100 comp2 = 200 comp3 = 300 comp4 = 400 comp5 = 500 ) ).
|
||||
|
||||
itab2 = VALUE #( ( comp1 = 7 comp2 = 8 comp3 = 9 )
|
||||
( comp1 = 70 comp2 = 80 comp3 = 90 )
|
||||
( comp1 = 700 comp2 = 800 comp3 = 900 ) ).
|
||||
|
||||
itab1 = VALUE #( BASE itab1 FOR wa IN itab2 ( CORRESPONDING #( wa ) ) ).
|
||||
|
||||
*Result:
|
||||
*COMP1 COMP2 COMP3 COMP4 COMP5
|
||||
*1 2 3 4 5
|
||||
*10 20 30 40 50
|
||||
*100 200 300 400 500
|
||||
*7 8 9 0 0
|
||||
*70 80 90 0 0
|
||||
*700 800 900 0 0
|
||||
|
||||
"Note: If BASE is not specified, the target table is initialized first.
|
||||
"itab1 = VALUE #( FOR wa IN itab2 ( CORRESPONDING #( wa ) ) ).
|
||||
|
||||
*Result:
|
||||
*COMP1 COMP2 COMP3 COMP4 COMP5
|
||||
*7 8 9 0 0
|
||||
*70 80 90 0 0
|
||||
*700 800 900 0 0
|
||||
```
|
||||
|
||||
</td>
|
||||
@@ -497,6 +529,12 @@ DATA(itab) = VALUE itab_type( ( col1 = 'a' col2 = 1 col3 = 30 )
|
||||
|
||||
DATA(it1) = VALUE itab_type( FOR wa IN itab ( col1 = wa-col1 && 'z'
|
||||
col2 = wa-col2 + 1 ) ).
|
||||
|
||||
*Result:
|
||||
*COL1 COL2 COL3
|
||||
*az 2 0
|
||||
*bbz 3 0
|
||||
*cccz 4 0
|
||||
```
|
||||
|
||||
</td>
|
||||
@@ -521,6 +559,11 @@ DATA(strtab) = VALUE string_table( LET mark = '!' IN
|
||||
( |abc{ mark }| )
|
||||
( |def{ mark }| )
|
||||
( |ghi{ mark }| ) ).
|
||||
|
||||
*Result:
|
||||
*abc!
|
||||
*def!
|
||||
*ghi!
|
||||
```
|
||||
|
||||
</td>
|
||||
@@ -1734,6 +1777,7 @@ ENDCASE.
|
||||
- The conditions for the table key components can be specified as follows:
|
||||
- Hash keys: Only the comparison operator `=` is allowed
|
||||
- Sorted key: `=`/`EQ`, `<>`/`NE`, `<`/`LT`, `>`/`GT`, `<=`/`LE`, `>=`/`GE`
|
||||
- When filtering using single values, you can also use `IS [NOT] INITIAL`.
|
||||
- Multiple comparisons can be combined using `AND`; boolean operators such as `NOT` or `OR` cannot be specified.
|
||||
- Notes on the filter table:
|
||||
- The line types of the source and filter table need not be identical.
|
||||
|
||||
@@ -1951,7 +1951,8 @@ SORT it BY VALUE abap_sortorder_tab( FOR wa IN comp_names ( name = condense( to_
|
||||
### Dynamic ABAP SQL Statements
|
||||
|
||||
```abap
|
||||
"Dynamic SELECT list
|
||||
"--------------------- Dynamic SELECT list ---------------------
|
||||
|
||||
DATA(select_list) = `CARRID, CONNID, FLDATE`.
|
||||
DATA fli_tab TYPE TABLE OF zdemo_abap_fli WITH EMPTY KEY.
|
||||
|
||||
@@ -1959,13 +1960,15 @@ SELECT (select_list)
|
||||
FROM zdemo_abap_fli
|
||||
INTO CORRESPONDING FIELDS OF TABLE @fli_tab.
|
||||
|
||||
"Dynamic FROM clause
|
||||
"--------------------- Dynamic FROM clause ---------------------
|
||||
|
||||
DATA(table) = 'ZDEMO_ABAP_FLI'.
|
||||
SELECT *
|
||||
FROM (table)
|
||||
INTO TABLE @fli_tab.
|
||||
|
||||
"Excursion: Compatible target data objects
|
||||
"--------------------- Excursion: Compatible target data objects ---------------------
|
||||
|
||||
"In the examples above, the data object/type is created statically.
|
||||
|
||||
"Creating an anonymous data object with a CREATE DATA statement
|
||||
@@ -1994,35 +1997,44 @@ SELECT *
|
||||
FROM (table)
|
||||
INTO TABLE NEW @DATA(dref_tab).
|
||||
|
||||
"Dynamic WHERE clause
|
||||
"--------------------- Dynamic WHERE clause ---------------------
|
||||
|
||||
"The example includes a WHERE clause that is created as an internal
|
||||
"table with a character-like row type.
|
||||
DATA(where_clause) = VALUE string_table( ( `CARRID = 'LH'` )
|
||||
( `OR` )
|
||||
( `CARRID = 'AA'` ) ).
|
||||
|
||||
"A string as an alternative
|
||||
"DATA(where_clause) = `CARRID = 'LH' OR CARRID = 'AA'`.
|
||||
|
||||
SELECT *
|
||||
FROM zdemo_abap_fli
|
||||
WHERE (where_clause)
|
||||
INTO TABLE NEW @DATA(tab_dyn_where).
|
||||
|
||||
"Dynamic ORDER BY clause
|
||||
"A string as an alternative
|
||||
DATA(where_clause_string) = `CARRID = 'LH' OR CARRID = 'AA'`.
|
||||
|
||||
SELECT *
|
||||
FROM zdemo_abap_fli
|
||||
WHERE (where_clause_string)
|
||||
INTO TABLE NEW @DATA(tab_dyn_where_str).
|
||||
|
||||
"--------------------- Dynamic ORDER BY clause ---------------------
|
||||
|
||||
SELECT *
|
||||
FROM zdemo_abap_fli
|
||||
ORDER BY (`FLDATE`)
|
||||
INTO TABLE NEW @DATA(tab_dyn_order).
|
||||
|
||||
"SELECT statement with miscellaneous dynamic specifications
|
||||
"----- SELECT statement with miscellaneous dynamic specifications -----
|
||||
|
||||
SELECT (`CARRID, CONNID, FLDATE`)
|
||||
FROM (`ZDEMO_ABAP_FLI`)
|
||||
WHERE (`CARRID <> ``AA```)
|
||||
ORDER BY (`FLDATE`)
|
||||
INTO TABLE NEW @DATA(tab_dyn_misc).
|
||||
|
||||
"Further dynamic specifications in other ABAP SQL statements
|
||||
"--------------------- Dynamic INSERT statement ---------------------
|
||||
|
||||
"Creating a structure to be inserted into the database table
|
||||
SELECT SINGLE *
|
||||
FROM (table)
|
||||
@@ -2031,13 +2043,97 @@ dref_struc->('CARRID') = 'YZ'.
|
||||
|
||||
INSERT (table) FROM @dref_struc->*.
|
||||
|
||||
"--------------------- Dynamic UPDATE statement ---------------------
|
||||
|
||||
dref_struc->('CURRENCY') = 'EUR'.
|
||||
UPDATE (table) FROM @dref_struc->*.
|
||||
|
||||
"--------------------- Dynamic MODIFY statement ---------------------
|
||||
|
||||
dref_struc->('SEATSOCC') = 10.
|
||||
MODIFY (table) FROM @dref_struc->*.
|
||||
|
||||
"--------------------- Dynamic DELETE statement ---------------------
|
||||
|
||||
DELETE FROM (table) WHERE (`CARRID = 'YZ'`).
|
||||
|
||||
"--------------------- Dynamic UPDATE ... SET ... statement ---------------------
|
||||
|
||||
"Inserting demo data into the database table to work with
|
||||
TYPES carr_tab TYPE TABLE OF zdemo_abap_carr WITH EMPTY KEY.
|
||||
INSERT ('ZDEMO_ABAP_CARR') FROM TABLE @( VALUE carr_tab( ( carrid = 'WX' carrname = 'WX Airways' )
|
||||
( carrid = 'XY' carrname = 'Air XY' )
|
||||
( carrid = 'YZ' carrname = 'YZ Airlines' ) ) ).
|
||||
|
||||
"Note that erroneous dynamic specifications can lead to runtime errors
|
||||
"In the following example, the final inverted comma is missing in the dynamic
|
||||
"set clause.
|
||||
DATA(set_clause) = `CURRCODE = 'EUR`.
|
||||
DATA(where_cl) = `CARRID = 'WX' OR CARRID = 'XY' OR CARRID = 'YZ'`.
|
||||
|
||||
TRY.
|
||||
UPDATE ('ZDEMO_ABAP_CARR') SET (set_clause) WHERE (where_cl).
|
||||
CATCH cx_sy_dynamic_osql_syntax INTO DATA(error).
|
||||
DATA(error_text) = error->get_text( ).
|
||||
ENDTRY.
|
||||
|
||||
"Correcting the dynamic specification
|
||||
"The example sets the value for a component for all entries.
|
||||
"The example additionally specifies a (dynamic) WHERE clause
|
||||
"to restrict the range of entries where the update is performed.
|
||||
"The database table is also specified dynamically.
|
||||
set_clause = `CURRCODE = 'EUR'`.
|
||||
|
||||
UPDATE ('ZDEMO_ABAP_CARR') SET (set_clause) WHERE (where_cl).
|
||||
|
||||
"--------------------- Dynamic UPDATE ... INDICATORS ... statement ---------------------
|
||||
|
||||
"The statement changes values of specific fields without overwriting existing values of
|
||||
"other fields.
|
||||
|
||||
"Notes on the example:
|
||||
"- A structured type is created with the WITH INDICATORS addition.
|
||||
"- An internal table from which to update a database table is created.
|
||||
"- The table includes the indicator structure comp_ind.
|
||||
"- The table is populated, and two components are flagged as
|
||||
" to be updated.
|
||||
"- Other fields remain unchanged. Note that key fields must be
|
||||
" included in ind_tab (indicator setting for key fields has
|
||||
" no effect).
|
||||
"- The UPDATE statement includes dynamically specified
|
||||
" indicator syntax. Additionally, the database table is specified
|
||||
" dynamically.
|
||||
|
||||
"Structured type with WITH INDICATORS addition
|
||||
TYPES ind_wa TYPE zdemo_abap_carr WITH INDICATORS comp_ind TYPE abap_bool.
|
||||
|
||||
DATA ind_tab TYPE TABLE OF ind_wa.
|
||||
|
||||
"Filling internal table; only CURRCODE and URL should be updated
|
||||
ind_tab = VALUE #( ( carrid = 'WX'
|
||||
carrname = 'WX Airways'
|
||||
currcode = 'USD'
|
||||
url = 'some_url_wx'
|
||||
comp_ind-currcode = abap_true
|
||||
comp_ind-url = abap_true )
|
||||
( carrid = 'XY'
|
||||
carrname = 'Air XY'
|
||||
currcode = 'USD'
|
||||
url = 'some_url_xy'
|
||||
comp_ind-currcode = abap_true
|
||||
comp_ind-url = abap_true )
|
||||
( carrid = 'YZ'
|
||||
carrname = 'YZ Airlines'
|
||||
currcode = 'USD'
|
||||
url = 'some_url_yz'
|
||||
comp_ind-currcode = abap_true
|
||||
comp_ind-url = abap_true ) ).
|
||||
|
||||
DATA(dyn_ind) = `SET STRUCTURE comp_ind`.
|
||||
|
||||
UPDATE ('ZDEMO_ABAP_CARR') FROM TABLE @ind_tab INDICATORS (dyn_ind).
|
||||
|
||||
DELETE FROM ('ZDEMO_ABAP_CARR') WHERE (where_cl).
|
||||
```
|
||||
|
||||
<p align="right"><a href="#top">⬆️ back to top</a></p>
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
- [Units of Measurement](#units-of-measurement)
|
||||
- [Programmatic ABAP Test Cockpit (ATC) Check](#programmatic-abap-test-cockpit-atc-check)
|
||||
- [Handling Number Ranges](#handling-number-ranges)
|
||||
- [Programmatically Releasing APIs](#programmatically-releasing-apis)
|
||||
|
||||
|
||||
This ABAP cheat sheet contains a selection of [released](https://help.sap.com/doc/abapdocu_cp_index_htm/CLOUD/en-US/index.htm?file=abenreleased_api_glosry.htm) ABAP classes that are available 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). It serves as a quick introduction, along with code snippets to explore the functionality in action.
|
||||
@@ -515,6 +516,115 @@ DATA(random_num2) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( )
|
||||
max = 1000 )->get_next( ).
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
The following example explores the generation of arbitraty numeric values.
|
||||
- It uses dynamic programming techniques. Find more information in the [Dynamic Programming](06_Dynamic_Programming.md) cheat sheet.
|
||||
- The class names are constructed dynamically. They all begin with `CL_ABAP_RANDOM_`.
|
||||
- An object is created dynamically based on the constructed class name.
|
||||
- This object is assigned the result of a dynamic method call. The error handling is included as the `min` and `max` parameters are not available for all methods.
|
||||
- The `get_next` method returns an appropriately typed data object, e.g. in case of `CL_ABAP_RANDOM_DECFLOAT34`, a data object of type `decfloat34` is returned. As a generic returning parameter is not possible, the example uses a data object of type `string`. So, the value returned is converted to type `string`. Note that are special conversion rules (e.g. the minus character for negative values are added at the end by default).
|
||||
- The resulting string values are added to an internal table for display purposes.
|
||||
- The example also includes static method calls.
|
||||
|
||||
|
||||
```abap
|
||||
CLASS zcl_some_class DEFINITION
|
||||
PUBLIC
|
||||
FINAL
|
||||
CREATE PUBLIC .
|
||||
|
||||
PUBLIC SECTION.
|
||||
INTERFACES if_oo_adt_classrun.
|
||||
PROTECTED SECTION.
|
||||
PRIVATE SECTION.
|
||||
ENDCLASS.
|
||||
|
||||
CLASS zcl_some_class IMPLEMENTATION.
|
||||
METHOD if_oo_adt_classrun~main.
|
||||
|
||||
TYPES: BEGIN OF random_values,
|
||||
class TYPE string,
|
||||
random_value TYPE string,
|
||||
END OF random_values.
|
||||
DATA random_value_table TYPE TABLE OF random_values WITH EMPTY KEY.
|
||||
|
||||
DATA(cl_name_parts) = VALUE string_table( ( `DECFLOAT16` )
|
||||
( `DECFLOAT34` )
|
||||
( `FLOAT` )
|
||||
( `INT` )
|
||||
( `INT8` )
|
||||
( `PACKED` )
|
||||
( `PACKED_DEC` ) ).
|
||||
|
||||
LOOP AT cl_name_parts INTO DATA(wa).
|
||||
|
||||
IF wa CS `PACKED_DEC`.
|
||||
FIND PCRE `\d` IN wa.
|
||||
IF sy-subrc <> 0.
|
||||
DELETE cl_name_parts INDEX sy-tabix.
|
||||
DO 14 TIMES.
|
||||
APPEND wa && sy-index TO cl_name_parts.
|
||||
ENDDO.
|
||||
CONTINUE.
|
||||
ENDIF.
|
||||
ENDIF.
|
||||
|
||||
DATA(cl_name) = `CL_ABAP_RANDOM_` && wa.
|
||||
DATA oref TYPE REF TO object.
|
||||
|
||||
TRY.
|
||||
CALL METHOD (cl_name)=>create
|
||||
EXPORTING
|
||||
seed = cl_abap_random=>seed( )
|
||||
min = 1
|
||||
max = 1000
|
||||
RECEIVING
|
||||
prng = oref.
|
||||
CATCH cx_sy_dyn_call_param_not_found.
|
||||
CALL METHOD (cl_name)=>create
|
||||
EXPORTING
|
||||
seed = cl_abap_random=>seed( )
|
||||
RECEIVING
|
||||
prng = oref.
|
||||
ENDTRY.
|
||||
|
||||
DATA value_conv2string TYPE string.
|
||||
|
||||
CALL METHOD oref->('GET_NEXT') RECEIVING value = value_conv2string.
|
||||
|
||||
APPEND VALUE #( class = cl_name random_value = value_conv2string ) TO random_value_table.
|
||||
ENDLOOP.
|
||||
|
||||
out->write( random_value_table ).
|
||||
|
||||
DATA(a) = cl_abap_random_decfloat16=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(b) = cl_abap_random_decfloat34=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(c) = cl_abap_random_float=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(d) = cl_abap_random_int=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(e) = cl_abap_random_int8=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(f) = cl_abap_random_packed=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(g) = cl_abap_random_packed=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(h) = cl_abap_random_packed_dec1=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(i) = cl_abap_random_packed_dec2=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(j) = cl_abap_random_packed_dec3=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(k) = cl_abap_random_packed_dec4=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(l) = cl_abap_random_packed_dec5=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(m) = cl_abap_random_packed_dec6=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(n) = cl_abap_random_packed_dec7=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(o) = cl_abap_random_packed_dec8=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(p) = cl_abap_random_packed_dec9=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(q) = cl_abap_random_packed_dec10=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(r) = cl_abap_random_packed_dec11=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(s) = cl_abap_random_packed_dec12=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(t) = cl_abap_random_packed_dec13=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
DATA(u) = cl_abap_random_packed_dec14=>create( seed = cl_abap_random=>seed( ) )->get_next( ).
|
||||
|
||||
ENDMETHOD.
|
||||
|
||||
ENDCLASS.
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -4326,3 +4436,54 @@ ENDTRY.
|
||||
|
||||
<p align="right"><a href="#top">⬆️ back to top</a></p>
|
||||
|
||||
## Programmatically Releasing APIs
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td> Class </td> <td> Details/Code Snippet </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> <code>CL_ABAP_API_STATE</code> </td>
|
||||
<td>
|
||||
|
||||
- You can use the class to release APIs programmatically. Note that you can also achieve this using ADT tools.
|
||||
- Find more information in the class documentation.
|
||||
- The code snippets uses various methods offered by the class and illustrates the following aspects: creating an instance of the API state handler for a specified API (a demo class is inserted), releasing the API for ABAP for Cloud Development (by also specifying a transport request), retrieving release information, and deleting the release state for the specified API again.
|
||||
|
||||
<br>
|
||||
|
||||
```abap
|
||||
TRY.
|
||||
DATA(api_state) = cl_abap_api_state=>create_instance( api_key = VALUE #( object_type = 'CLAS' object_name = 'ZCL_DEMO_TEST' ) ).
|
||||
|
||||
api_state->release( use_in_cloud_development = abap_true
|
||||
use_in_key_user_apps = abap_false
|
||||
request = 'SOME_TR_REQ' ).
|
||||
|
||||
DATA(rel_info) = api_state->get_release_info( ).
|
||||
|
||||
DATA(is_released) = api_state->is_released( use_in_cloud_development = abap_true
|
||||
use_in_key_user_apps = abap_false ).
|
||||
|
||||
IF is_released = abap_true.
|
||||
api_state->delete_release_state( request = 'SOME_TR_REQ' ).
|
||||
|
||||
rel_info = api_state->get_release_info( ).
|
||||
|
||||
is_released = api_state->is_released( use_in_cloud_development = abap_true
|
||||
use_in_key_user_apps = abap_false ).
|
||||
|
||||
ENDIF.
|
||||
|
||||
CATCH cx_abap_api_state INTO DATA(error).
|
||||
DATA(error_text) = error->get_text( ).
|
||||
ENDTRY.
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
<p align="right"><a href="#top">⬆️ back to top</a></p>
|
||||
|
||||
Reference in New Issue
Block a user