
Sap Abap
- 719 installs
- 399 repo stars
- Updated August 4, 2026
- secondsky/sap-skills
sap-abap is an enterprise agent skill that authors, refactors, and reviews ABAP for SAP ERP and S/4HANA for developers who implement reports, CDS views, RFC calls, and custom business logic in SAP landscapes.
About
sap-abap is a secondsky/sap-skills agent skill focused on ABAP development inside SAP ERP and S/4HANA enterprise systems. It guides authoring and refactoring of reports, classes, Core Data Services views, RFC and BAPI integrations, and custom business logic that runs on SAP application servers. Developers reach for sap-abap when extending standard SAP processes, building internal ALV reports, exposing OData through CDS, or calling remote function modules from custom code. The skill suits consultants and in-house SAP developers who need agent assistance that respects SAP naming, transport, and landscape conventions rather than generic backend patterns.
- ABAP syntax and OO patterns
- CDS views and data access
- RFC/BAPI integration
- S/4HANA extension development
- Enterprise SAP coding standards
Sap Abap by the numbers
- 719 all-time installs (skills.sh)
- +63 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #515 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/secondsky/sap-skills --skill sap-abapAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 719 |
|---|---|
| repo stars | ★ 399 |
| Last updated | August 4, 2026 |
| Repository | secondsky/sap-skills ↗ |
How do you write ABAP reports for SAP S/4HANA?
Author, refactor, and review ABAP for SAP ERP/S4HANA: reports, classes, CDS views, RFC/BAPI calls, and custom business logic inside enterprise landscapes.
Who is it for?
SAP developers and consultants working in ERP or S/4HANA who need ABAP authoring, refactoring, and review for reports, CDS, and RFC integrations.
Skip if: Greenfield Node, Java, or Python microservices with no SAP ERP or S/4HANA system connection.
When should I use this skill?
A SAP ERP or S/4HANA task requires ABAP code for reports, CDS views, classes, or RFC/BAPI business logic.
What you get
ABAP source for reports, classes, CDS views, and RFC/BAPI integration modules ready for transport
- ABAP source code
- CDS view definitions
- RFC/BAPI integration modules
Files
SAP ABAP Development Skill
Related Skills
- sap-abap-cds: Use when developing CDS views for ABAP-backed Fiori applications or defining data models with annotations
- sap-btp-cloud-platform: Use when working with ABAP Environment on BTP or deploying ABAP applications to the cloud
- sap-cap-capire: Use when connecting ABAP systems with CAP applications or integrating with OData services
- sap-fiori-tools: Use when building Fiori applications with ABAP backends or consuming OData services from ABAP systems
- sap-api-style: Use when documenting ABAP APIs or following SAP API documentation standards
When to Use This Skill
Use this skill when writing or reviewing ABAP code, modernizing classic ABAP to ABAP Cloud-compatible patterns, working with RAP or EML, implementing ABAP SQL, designing unit tests, or troubleshooting language/runtime behavior across supported ABAP releases.
Version Compatibility
This skill covers ABAP syntax from 7.40 SP08 through ABAP Cloud. Features requiring a higher release are annotated with inline comments in code examples using the format " [7.xx+] or noted in reference files. The table below summarizes the key version boundaries.
| Feature | 7.40 SP02 | 7.40 SP05 | 7.40 SP08 | 7.50 | 7.51 | 7.52 | 7.54 |
|---|---|---|---|---|---|---|---|
Inline declarations DATA(...) | x | x | x | x | x | x | x |
| Constructor operators (VALUE, NEW, CONV, COND, SWITCH, REF, EXACT, CAST) | x | x | x | x | x | x | x |
Table expressions itab[...] | x | x | x | x | x | x | x |
| String templates | x | x | x | x | x | x | x |
WITH EMPTY KEY | x | x | x | x | x | x | x |
line_exists(), line_index() | x | x | x | x | x | x | x |
ABAP SQL: @ host variables | x | x | x | x | x | x | |
| ABAP SQL: comma-separated lists | x | x | x | x | x | x | |
| ABAP SQL: SQL expressions in SELECT | x | x | x | x | x | x | |
CORRESPONDING operator | x | x | x | x | x | x | |
Table comprehensions (FOR) | x | x | x | x | x | x | |
LET expressions | x | x | x | x | x | x | |
REDUCE operator | x | x | x | x | x | ||
FILTER operator | x | x | x | x | x | ||
BASE addition | x | x | x | x | x | ||
LOOP AT ... GROUP BY | x | x | x | x | x | ||
ABAP SQL: dbtab~* in SELECT | x | x | x | x | x | ||
ABAP SQL: RIGHT OUTER JOIN | x | x | x | x | x | x | |
| CDS views with parameters | x | x | x | x | x | ||
| `FINAL(...)` inline declaration | x | x | x | x | |||
| Host expressions `@( expr )` | x | x | x | x | |||
| `UNION` in SELECT | x | x | x | x | |||
| `IS INSTANCE OF` / `CASE TYPE OF` | x | x | x | x | |||
| `int8` type | x | x | x | x | |||
| CDS table functions | x | x | x | x | |||
| CDS access control (implicit) | x | x | x | x | |||
| `$session.user/client/system_language` | x | x | x | x | |||
| Test seams (`TEST-SEAM`) | x | x | x | x | |||
| Common Table Expressions (`WITH`) | x | x | x | ||||
| `OFFSET` in SELECT | x | x | x | ||||
| `UPPER`/`LOWER` in CDS | x | x | x | ||||
| Enumerated types | x | x | x | ||||
| Internal tables as data source `FROM @itab` | x | x | |||||
| `WITH PRIVILEGED ACCESS` | x | x | |||||
| `utclong` type and functions | x |
On a 7.40 system: Replace any FINAL(...) with DATA(...), and avoid 7.50+ features marked in bold above. Most modern ABAP syntax (VALUE, NEW, CONV, inline declarations, table expressions, REDUCE, FILTER, GROUP BY) is available since 7.40 SP08.
Table of Contents
- Version Compatibility
- Quick Reference
- Bundled Resources
- Common Patterns
- Error Catalog
- Performance Tips
- Source Documentation
Quick Reference
Data Types and Declarations
" Elementary types
DATA num TYPE i VALUE 123.
DATA txt TYPE string VALUE `Hello`.
DATA flag TYPE abap_bool VALUE abap_true.
" Inline declarations
DATA(result) = some_method( ).
FINAL(immutable) = `constant value`. " [7.50+] Use DATA(...) on 7.40
" Structures
DATA: BEGIN OF struc,
id TYPE i,
name TYPE string,
END OF struc.
" Internal tables
DATA itab TYPE TABLE OF string WITH EMPTY KEY.
DATA sorted_tab TYPE SORTED TABLE OF struct WITH UNIQUE KEY id.
DATA hashed_tab TYPE HASHED TABLE OF struct WITH UNIQUE KEY id.Internal Tables - Essential Operations
" Create with VALUE
itab = VALUE #( ( col1 = 1 col2 = `a` )
( col1 = 2 col2 = `b` ) ).
" Read operations
DATA(line) = itab[ 1 ]. " By index
DATA(line2) = itab[ col1 = 1 ]. " By key
READ TABLE itab INTO wa INDEX 1.
READ TABLE itab ASSIGNING FIELD-SYMBOL(<fs>) WITH KEY col1 = 1.
" Modify operations
MODIFY TABLE itab FROM VALUE #( col1 = 1 col2 = `updated` ).
itab[ 1 ]-col2 = `changed`.
" Loop processing
LOOP AT itab ASSIGNING FIELD-SYMBOL(<line>).
<line>-col2 = to_upper( <line>-col2 ).
ENDLOOP.
" Delete
DELETE itab WHERE col1 > 5.
DELETE TABLE itab FROM VALUE #( col1 = 1 ).ABAP SQL Essentials
" SELECT into table
SELECT * FROM dbtab INTO TABLE @DATA(result_tab). " @ syntax: 7.40 SP05+
" SELECT with conditions
SELECT carrid, connid, fldate " comma syntax: 7.40 SP05+
FROM zdemo_abap_fli
WHERE carrid = 'LH'
INTO TABLE @DATA(flights).
" Aggregate functions
SELECT carrid, COUNT(*) AS cnt, AVG( price ) AS avg_price
FROM zdemo_abap_fli
GROUP BY carrid
INTO TABLE @DATA(stats).
" JOIN operations
SELECT a~carrid, a~connid, b~carrname
FROM zdemo_abap_fli AS a
INNER JOIN zdemo_abap_carr AS b ON a~carrid = b~carrid
INTO TABLE @DATA(joined).
" Modification statements
INSERT dbtab FROM @struc.
UPDATE dbtab FROM @struc.
MODIFY dbtab FROM TABLE @itab.
DELETE FROM dbtab WHERE condition.Constructor Expressions
" VALUE - structures and tables
DATA(struc) = VALUE struct_type( comp1 = 1 comp2 = `text` ).
DATA(itab) = VALUE itab_type( ( a = 1 ) ( a = 2 ) ( a = 3 ) ).
" NEW - create instances
DATA(dref) = NEW i( 123 ).
DATA(oref) = NEW zcl_my_class( param = value ).
" CORRESPONDING - structure/table mapping
target = CORRESPONDING #( source ).
target = CORRESPONDING #( source MAPPING target_field = source_field ).
" COND/SWITCH - conditional values
DATA(text) = COND string( WHEN flag = abap_true THEN `Yes` ELSE `No` ).
DATA(result) = SWITCH #( code WHEN 1 THEN `A` WHEN 2 THEN `B` ELSE `X` ).
" CONV - type conversion
DATA(dec) = CONV decfloat34( 1 / 3 ).
" FILTER - table filtering
DATA(filtered) = FILTER #( itab WHERE status = 'A' ).
" REDUCE - aggregation
DATA(sum) = REDUCE i( INIT s = 0 FOR wa IN itab NEXT s = s + wa-amount ).Object-Oriented ABAP
" Class definition
CLASS zcl_example DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS constructor IMPORTING iv_name TYPE string.
METHODS get_name RETURNING VALUE(rv_name) TYPE string.
CLASS-METHODS factory RETURNING VALUE(ro_instance) TYPE REF TO zcl_example.
PRIVATE SECTION.
DATA mv_name TYPE string.
ENDCLASS.
CLASS zcl_example IMPLEMENTATION.
METHOD constructor.
mv_name = iv_name.
ENDMETHOD.
METHOD get_name.
rv_name = mv_name.
ENDMETHOD.
METHOD factory.
ro_instance = NEW #( `Default` ).
ENDMETHOD.
ENDCLASS.
" Interface implementation
CLASS zcl_impl DEFINITION PUBLIC.
PUBLIC SECTION.
INTERFACES zif_my_interface.
ENDCLASS.Exception Handling
TRY.
DATA(result) = risky_operation( ).
CATCH cx_sy_zerodivide INTO DATA(exc).
DATA(msg) = exc->get_text( ).
CATCH cx_root INTO DATA(any_exc).
" Handle any exception
CLEANUP.
" Cleanup code
ENDTRY.
" Raising exceptions
RAISE EXCEPTION TYPE zcx_my_exception
EXPORTING textid = zcx_my_exception=>error_occurred.
" With COND/SWITCH
DATA(val) = COND #( WHEN valid THEN result
ELSE THROW zcx_my_exception( ) ).String Processing
" Concatenation
DATA(full) = first && ` ` && last.
txt &&= ` appended`.
" String templates
DATA(msg) = |Name: { name }, Date: { date DATE = ISO }|.
" Functions
DATA(upper) = to_upper( text ).
DATA(len) = strlen( text ).
DATA(found) = find( val = text sub = `search` ).
DATA(replaced) = replace( val = text sub = `old` with = `new` occ = 0 ).
DATA(parts) = segment( val = text index = 2 sep = `,` ).
" FIND/REPLACE statements
FIND ALL OCCURRENCES OF pattern IN text RESULTS DATA(matches).
REPLACE ALL OCCURRENCES OF old IN text WITH new.Dynamic Programming
" Field symbols
FIELD-SYMBOLS <fs> TYPE any.
ASSIGN struct-component TO <fs>.
ASSIGN struct-(comp_name) TO <fs>. " Dynamic component
" Data references
DATA dref TYPE REF TO data.
dref = REF #( variable ).
CREATE DATA dref TYPE (type_name).
dref->* = value.
" RTTI - Get type information
DATA(tdo) = cl_abap_typedescr=>describe_by_data( dobj ).
DATA(components) = CAST cl_abap_structdescr( tdo )->components.
" RTTC - Create types dynamically
DATA(elem_type) = cl_abap_elemdescr=>get_string( ).
CREATE DATA dref TYPE HANDLE elem_type.---
Bundled Resources
This skill includes 28 comprehensive reference files covering all aspects of ABAP development:
Related Skills
- sap-abap-cds: For CDS view development and ABAP Cloud data modeling
- sap-btp-cloud-platform: For ABAP Environment setup and BTP deployment
- sap-cap-capire: For CAP service integration and ABAP system connections
- sap-fiori-tools: For Fiori application development with ABAP backends
- sap-api-style: For API documentation standards and best practices
Quick Access
- Reference Guide:
references/skill-reference-guide.md- Complete guide to all reference files - Internal Tables:
references/internal-tables.md- Complete table operations - ABAP SQL:
references/abap-sql.md- Comprehensive SQL reference - Object Orientation:
references/object-orientation.md- Classes and interfaces
Development Topics
references/constructor-expressions.md- VALUE, NEW, COND, REDUCEreferences/rap-eml.md- RAP and EML operationsreferences/cds-views.md- CDS view developmentreferences/string-processing.md- String functions and regexreferences/unit-testing.md- ABAP Unit frameworkreferences/performance.md- Optimization techniques- ... and 18 more specialized references
---
Common Patterns
Safe Table Access (Avoid Exceptions)
" Using VALUE with OPTIONAL
DATA(line) = VALUE #( itab[ key = value ] OPTIONAL ).
" Using VALUE with DEFAULT
DATA(line) = VALUE #( itab[ 1 ] DEFAULT VALUE #( ) ).
" Check before access
IF line_exists( itab[ key = value ] ).
DATA(line) = itab[ key = value ].
ENDIF.Functional Method Chaining
DATA(result) = NEW zcl_builder( )
->set_name( `Test` )
->set_value( 123 )
->build( ).FOR Iteration Expressions
" Transform table
DATA(transformed) = VALUE itab_type(
FOR wa IN source_itab
( id = wa-id name = to_upper( wa-name ) ) ).
" With WHERE
DATA(filtered) = VALUE itab_type(
FOR wa IN source WHERE ( status = 'A' )
( wa ) ).
" With INDEX INTO
DATA(numbered) = VALUE itab_type(
FOR wa IN source INDEX INTO idx
( line_no = idx data = wa ) ).ABAP Cloud Compatibility
" Use released APIs only
DATA(uuid) = cl_system_uuid=>create_uuid_x16_static( ).
DATA(date) = xco_cp=>sy->date( )->as( xco_cp_time=>format->iso_8601_extended )->value.
DATA(time) = xco_cp=>sy->time( )->as( xco_cp_time=>format->iso_8601_extended )->value.
" Output in cloud (if_oo_adt_classrun)
out->write( result ).
" Avoid: sy-datum, sy-uzeit, DESCRIBE TABLE, WRITE, MOVE...TOABAP 7.40 Compatibility
When targeting ABAP 7.40 systems, replace 7.50+ syntax with these patterns:
" Instead of FINAL (7.50+):
FINAL(value) = `constant`. " 7.50+
DATA(value) = `constant`. " 7.40 compatible
" Instead of host expressions (7.50+):
SELECT * FROM dbtab WHERE col = @( lv_val ). " 7.50+
SELECT * FROM dbtab WHERE col = @lv_val. " 7.40 compatible
" Instead of UNION (7.50+):
SELECT a FROM tab1 UNION SELECT a FROM tab2. " 7.50+
" Use two separate SELECTs on 7.40 and combine in ABAP:
SELECT a FROM tab1 INTO TABLE @DATA(r1).
SELECT a FROM tab2 INTO TABLE @DATA(r2).
DATA(combined) = VALUE itab_type( FOR l1 IN r1 ( l1 )
FOR l2 IN r2 ( l2 ) ).
" Instead of IS INSTANCE OF (7.50+):
IF oref IS INSTANCE OF zcl_my_class. " 7.50+
" 7.40 alternative — use typed CAST with exception handling:
TRY.
DATA(lo) = CAST zcl_my_class( oref ). " 7.40+
CATCH cx_sy_move_cast_error.
" oref is not compatible with zcl_my_class
ENDTRY.
" Instead of CTEs WITH (7.51+):
WITH +cte AS ( SELECT ... ) SELECT ... " 7.51+
" Use subqueries or temporary tables on 7.40---
Error Catalog
CX_SY_ITAB_LINE_NOT_FOUND
Cause: Table expression access to non-existent line Solution: Use OPTIONAL, DEFAULT, or check with line_exists( )
CX_SY_ZERODIVIDE
Cause: Division by zero Solution: Check divisor before operation
CX_SY_RANGE_OUT_OF_BOUNDS
Cause: Invalid substring access or array bounds Solution: Validate offset and length before access
CX_SY_CONVERSION_NO_NUMBER
Cause: String cannot be converted to number Solution: Validate input format before conversion
CX_SY_REF_IS_INITIAL
Cause: Dereferencing unbound reference Solution: Check IS BOUND before dereferencing
---
Performance Tips
1. Use SORTED/HASHED tables for frequent key access 2. Prefer field symbols over work areas in loops for modification 3. Use PACKAGE SIZE for large SELECT results 4. Avoid SELECT in loops - use FOR ALL ENTRIES or JOINs 5. Use secondary keys for different access patterns 6. Minimize CORRESPONDING calls - explicit assignments are faster
---
Source Documentation
All content based on SAP official ABAP Cheat Sheets:
- Repository: https://github.com/SAP-samples/abap-cheat-sheets
- SAP Help (latest): https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm
- SAP Help (7.40): https://help.sap.com/doc/abapdocu_740_index_htm/7.40/en-US/index.htm
- ABAP Release News: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/33_ABAP_Release_News.md
SAP ABAP Development Skill
Comprehensive ABAP development skill for SAP systems covering classic ABAP and modern ABAP Cloud development patterns.
Capability Index
| Capability | Status |
|---|---|
| Commands | 1: /abap-cloud-review |
| Agents | 0 |
| Hooks | No |
| MCP | No |
| LSP | No |
| Source Freshness | last_verified: 2026-04-02; ABAP Cloud released API checks require project/system evidence. |
| Verification | npm run validate; production ABAP system checks pending unless explicitly documented. |
Skill Overview
This skill provides extensive knowledge for ABAP development including:
- Internal Tables: Standard, sorted, hashed tables; keys; operations; LOOP, READ, MODIFY
- ABAP SQL: SELECT, INSERT, UPDATE, DELETE, JOINs, CTEs, hierarchies, aggregate functions
- Object-Oriented ABAP: Classes, interfaces, inheritance, polymorphism, design patterns
- Constructor Expressions: VALUE, NEW, CONV, CORRESPONDING, COND, SWITCH, REDUCE, FILTER
- Dynamic Programming: Field symbols, data references, RTTI, RTTC
- String Processing: String functions, templates, FIND, REPLACE, regex
- RAP (RESTful Application Programming Model): EML statements, BDEF, handler methods
- CDS View Entities: Annotations, associations, expressions
- ABAP Unit Testing: Test classes, assertions, test doubles
- Exception Handling: TRY-CATCH, exception classes, messages
- ABAP Cloud Development: Released APIs, restrictions, migration patterns
- Authorization: AUTHORITY-CHECK, CDS access control, DCL
- ABAP Dictionary: Data elements, domains, structures, table types
- Generative AI: ABAP AI SDK, LLM integration
Auto-Trigger Keywords
This skill activates when discussing:
ABAP Language
- ABAP, ABAP code, ABAP program, ABAP class, ABAP method
- DATA, TYPES, CONSTANTS, FIELD-SYMBOLS
- IF, CASE, LOOP, DO, WHILE, ENDLOOP, ENDIF
- SELECT, INSERT, UPDATE, DELETE, MODIFY
- TRY, CATCH, RAISE EXCEPTION, CLEANUP
- CLASS, INTERFACE, METHOD, ENDCLASS
Internal Tables
- internal table, itab, TABLE OF, STANDARD TABLE, SORTED TABLE, HASHED TABLE
- APPEND, INSERT, READ TABLE, MODIFY TABLE, DELETE
- LOOP AT, FIELD-SYMBOL, ASSIGNING, INTO
- table key, secondary key, WITH KEY
- FOR, REDUCE, FILTER
- GROUP BY, GROUP SIZE, WITHOUT MEMBERS
Constructor Expressions
- VALUE, NEW, CONV, CORRESPONDING, CAST, REF
- COND, SWITCH, EXACT
- REDUCE, FILTER, FOR
- constructor expression, inline declaration
- OPTIONAL, DEFAULT, BASE
Object Orientation
- ABAP OO, class definition, class implementation
- inheritance, INHERITING FROM, REDEFINITION
- interface, INTERFACES, ALIASES
- CREATE OBJECT, instantiation, factory method
- PUBLIC SECTION, PRIVATE SECTION, PROTECTED SECTION
- event, RAISE EVENT, SET HANDLER
- factory pattern, singleton, strategy pattern
RAP and Modern ABAP
- RAP, RESTful Application Programming Model
- EML, Entity Manipulation Language
- MODIFY ENTITIES, READ ENTITIES, COMMIT ENTITIES
- BDEF, behavior definition, handler method, saver method
- managed, unmanaged, draft
- %cid, %control, %tky, mapped, failed, reported
- global authorization, instance authorization
CDS Views
- CDS, Core Data Services, CDS view entity
- define view entity, association, composition
- annotation, @UI, @Semantics
- input parameter, $session
- DCL, access control, define role
ABAP SQL
- ABAP SQL, SELECT, FROM, WHERE, INTO TABLE
- INNER JOIN, LEFT OUTER JOIN, RIGHT OUTER JOIN
- GROUP BY, HAVING, ORDER BY
- aggregate function, COUNT, SUM, AVG, MIN, MAX
- FOR ALL ENTRIES, subquery, CTE
- HIERARCHY, HIERARCHY_DESCENDANTS, HIERARCHY_ANCESTORS
Dynamic Programming
- field symbol, ASSIGN, UNASSIGN, IS ASSIGNED
- data reference, REF TO, CREATE DATA, dereference
- RTTI, RTTC, cl_abap_typedescr, cl_abap_structdescr
- dynamic SQL, dynamic method call
- CASTING, BIT-NOT, BIT-AND
String Processing
- string, string template, string function
- FIND, REPLACE, CONCATENATE, SPLIT
- to_upper, to_lower, strlen, substring
- PCRE, regular expression, regex, pattern matching
Numeric Operations
- numeric, calculation, arithmetic
- cl_abap_bigint, cl_abap_rational
- ROUND, CEIL, FLOOR, TRUNC
- decfloat16, decfloat34
- ipow, sqrt, exp, log
Testing
- ABAP Unit, test class, FOR TESTING
- cl_abap_unit_assert, assert_equals
- test double, mock, stub, injection
- RISK LEVEL, DURATION
Exception Handling
- exception, TRY, CATCH, ENDTRY
- RAISE EXCEPTION, THROW
- cx_root, cx_static_check, cx_dynamic_check
- exception class, get_text
ABAP Cloud
- ABAP Cloud, ABAP for Cloud Development
- released API, XCO library
- SAP BTP ABAP Environment
- cloud-ready, upgrade-stable
Authorization
- AUTHORITY-CHECK, authorization object
- ACTVT, activity code
- access control, DCL, role
- pfcg_auth, aspect
ABAP Dictionary
- data element, domain, structure
- table type, database table
- DDIC, dictionary type
- CDS simple type, CDS enum
Generative AI
- AI SDK, generative AI, LLM
- cl_aic_islm_compl_api_factory
- intelligent scenario, prompt template
- Joule, ABAP AI
Errors and Debugging
- sy-subrc, sy-tabix, sy-index
- runtime error, dump, exception
- CX_SY_ZERODIVIDE, CX_SY_ITAB_LINE_NOT_FOUND
- debugging, breakpoint
Directory Structure
sap-abap/
├── SKILL.md # Main skill file with quick reference
├── README.md # This file (keywords for discoverability)
└── references/ # Detailed reference files (28 files)
├── abap-dictionary.md # DDIC objects, types
├── abap-sql.md # ABAP SQL comprehensive guide
├── amdp.md # ABAP Managed Database Procedures
├── authorization.md # Authorization checks, DCL
├── bits-bytes.md # Binary operations, CASTING
├── builtin-functions.md # String, numeric, table functions
├── cds-views.md # CDS view entities
├── cloud-development.md # ABAP Cloud specifics
├── constructor-expressions.md # Constructor operators
├── date-time.md # Date, time, timestamps, XCO
├── design-patterns.md # Factory, Singleton, Strategy
├── dynamic-programming.md # RTTI, RTTC, field symbols
├── exceptions.md # Exception handling
├── generative-ai.md # AI SDK integration
├── internal-tables.md # Complete table operations
├── numeric-operations.md # Math functions, big integers
├── object-orientation.md # OO programming patterns
├── performance.md # Database, internal table optimization
├── program-flow.md # IF, CASE, LOOP, DO, WHILE
├── rap-eml.md # RAP and EML reference
├── released-classes.md # Released API catalog
├── sap-luw.md # Logical Unit of Work, transactions
├── sql-hierarchies.md # CTE hierarchies, navigators
├── string-processing.md # String functions and regex
├── table-grouping.md # GROUP BY loops
├── unit-testing.md # ABAP Unit framework
├── where-conditions.md # WHERE clause patterns
└── xml-json.md # XML/JSON processingUsage
Ask Claude about any ABAP development topic:
- "How do I create a sorted internal table with multiple keys?"
- "What's the syntax for EML CREATE operations in RAP?"
- "Show me how to use CORRESPONDING with field mapping"
- "How do I handle exceptions in ABAP?"
- "What's the difference between ABAP Cloud and classic ABAP?"
- "How do I implement the factory pattern in ABAP?"
- "What are the released classes for date/time in ABAP Cloud?"
- "How do I integrate generative AI in ABAP?"
Source Documentation
Content based on official SAP ABAP Cheat Sheets:
- Repository: https://github.com/SAP-samples/abap-cheat-sheets
- SAP Help: https://help.sap.com/doc/abapdocu_latest_index_htm/latest/en-US/index.htm
Version
- Skill Version: 2.1.0
- Last Updated: 2025-11-23
- ABAP Release: Latest (7.5x / Cloud)
- Reference Files: 28
- Source Coverage: 91% (31 of 34 source files)
---
License
GPL-3.0 License - See LICENSE file in repository root.
ABAP Dictionary - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/26_ABAP_Dictionary.md
---
Data Elements
Define elementary and reference data types:
" Data element based on built-in type
TYPES ty_dtel1 TYPE zdemo_abap_dtel_pr.
DATA char3_dtel TYPE zdemo_abap_dtel_pr.
" Data element based on domain
TYPES ty_dtel2 TYPE zdemo_abap_dtel_do.
DATA char1_dtel TYPE zdemo_abap_dtel_do.
" Data element with reference type
TYPES ty_dtel3 TYPE zdemo_abap_dtel_ref.
DATA char10_dtel_ref TYPE zdemo_abap_dtel_ref.---
Domains
Define reusable technical and semantic properties:
- Standalone dictionary objects
- Cannot be used directly with
TYPESandDATA - Support value ranges for input validation
- Multiple data elements can reference same domain
---
Structures
Flat Structure Definition
@EndUserText.label : 'Demo flat DDIC structure'
@AbapCatalog.enhancement.category : #NOT_EXTENSIBLE
define structure zdemo_abap_struc_flat {
chars : abap.char(3);
num : abap.int4;
cuky : abap.cuky;
@Semantics.amount.currencyCode : 'zdemo_abap_struc_flat.cuky'
curr : abap.curr(8,2);
id : zdemo_abap_dtel_pr;
flag : zdemo_abap_dtel_do;
}Deep Structure Definition
@EndUserText.label : 'Demo deep DDIC structure'
define structure zdemo_abap_struc_deep {
bt_elem1 : abap.char(5);
bt_elem2 : abap.int4;
dref1 : reference to abap.char(3);
oref1 : reference to cl_abap_math;
struc1 : zdemo_abap_tab1;
struc2 : include zdemo_abap_carr;
struc3 : include zdemo_abap_fli with suffix _in;
tab1 : string_table;
}Component Types Supported
- Elementary types (built-in and data elements)
- Reference types (data/object references)
- Structured types (other structures, database tables)
- Include structures with optional suffixes
- Table types
---
Table Types
ABAP Usage
TYPES ty_tab_elem TYPE zdemo_abap_tt_str.
TYPES ty_tab_struc TYPE zdemo_abap_tt_so.
DATA tab_elem1 TYPE ty_tab_elem.
DATA tab_struct1 TYPE ty_tab_struc.RTTI for Table Types
DATA(tdo_table_type) = CAST cl_abap_tabledescr(
cl_abap_typedescr=>describe_by_name( 'ZDEMO_ABAP_TT_SO' ) ).
DATA(table_keys) = tdo_table_type->get_keys( ).
DATA(table_key_aliases) = tdo_table_type->get_key_aliases( ).---
Database Tables
Definition
@EndUserText.label : 'Demo DDIC database table'
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #RESTRICTED
define table zdemo_abap_tabl1 {
key client : abap.clnt not null;
key num : abap.int4 not null;
chars : abap.char(5);
id : zdemo_abap_dtel_pr;
str : abap.string(0);
cuky : abap.cuky;
@Semantics.amount.currencyCode : 'zdemo_abap_tabl1.cuky'
curr : abap.curr(8,2);
}With Included Structure
define table zdemo_abap_tabl2 {
key client : abap.clnt not null;
key key_field : abap.int4 not null;
include zdemo_abap_struc_flat;
}Key Requirements
- Must have primary key with unique field combinations
- Key fields require
NOT NULLflag - Cannot use
stringorrawstringfor keys - First column typically uses
clntfor client-dependency
ABAP Usage
DATA struc_from_dbtab TYPE zdemo_abap_tabl1.
struc_from_dbtab = VALUE #( num = 1 chars = 'abcde' ).
MODIFY zdemo_abap_tabl1 FROM @struc_from_dbtab.
DATA itab_from_dbtab TYPE TABLE OF zdemo_abap_tabl1 WITH EMPTY KEY.
SELECT * FROM zdemo_abap_tabl1 INTO TABLE @itab_from_dbtab.---
CDS Simple Types
TYPES ty_cds_simple TYPE zdemo_abap_cds_type.
DATA dobj_w_simple_type TYPE zdemo_abap_cds_type.---
CDS Enumerated Types
TYPES ty_cds_enum TYPE zdemo_abap_cds_enum.
DATA dobj_w_enum_type TYPE zdemo_abap_cds_enum.
" Convert to enum
DATA(conv_enum) = CONV zdemo_abap_cds_enum( 'X' ).
" Handle invalid value
TRY.
DATA(result) = CONV zdemo_abap_cds_enum( 'INVALID' ).
CATCH cx_sy_conversion_no_enum_value INTO DATA(error).
" Handle error
ENDTRY.---
Predefined Types
DATA a TYPE int1. " 1-byte integer
DATA b TYPE int2. " 2-byte integer
DATA c TYPE int4. " 4-byte integer
DATA d TYPE d16n. " Decimal 16
DATA e TYPE d34n. " Decimal 34
DATA f TYPE datn. " Date (internal)
DATA g TYPE timn. " Time (internal)
DATA h TYPE utcl. " UTC long timestamp
DATA is_true TYPE abap_boolean.
is_true = abap_true.---
Released APIs Query
SELECT ReleasedObjectType, ReleasedObjectName, ReleaseState
FROM i_apisforclouddevelopment
WHERE releasestate = 'RELEASED'
AND ( ReleasedObjectType = 'DTEL' OR ReleasedObjectType = 'DOMA' )
ORDER BY ReleasedObjectType, ReleasedObjectName
INTO TABLE @DATA(released_dtel_doma).ABAP SQL - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/03_ABAP_SQL.md
Version Note: Features annotated with [7.xx+] require the specified ABAP release.All unmarked features are available from 7.40 SP05+. Key version boundaries:
- @ host variables, comma syntax, SQL expressions: 7.40 SP05+- dbtab~*, inline declarations in INTO: 7.40 SP08+- RIGHT OUTER JOIN: 7.40 SP05+- Host expressions@(...),UNION: 7.50+
-WITH(CTEs),OFFSET,UPPER/LOWER/CONCAT_WITH_SPACE/LEFT/RIGHT: 7.51+
- FROM @itab (internal table as data source): 7.52+Table of Contents
1. SELECT Statement Syntax 2. Basic SELECT Operations 3. JOIN Operations 4. Aggregate Functions 5. Subqueries 6. Common Table Expressions (CTE) 7. Data Modification 8. Performance Tips
---
SELECT Statement Syntax
SELECT [SINGLE|DISTINCT]
select_list
FROM source
[WHERE condition]
[GROUP BY fields]
[HAVING condition]
[ORDER BY fields]
INTO|APPENDING target
[UP TO n ROWS]
[OFFSET n].---
Basic SELECT Operations
SELECT INTO
" Into structure (single row)
SELECT SINGLE * FROM zdemo_abap_carr INTO @DATA(carrier).
" Into internal table
SELECT * FROM zdemo_abap_carr INTO TABLE @DATA(carriers).
" Into existing table (appending)
SELECT * FROM zdemo_abap_carr APPENDING TABLE @carriers.
" Into existing table (overwriting)
SELECT * FROM zdemo_abap_carr INTO TABLE @carriers.
" With PACKAGE SIZE (for large results)
SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(flights) PACKAGE SIZE 100.
" Process package
CLEAR flights.
ENDSELECT.
" UP TO n ROWS
SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(first_10) UP TO 10 ROWS.
" OFFSET (skip rows) " [7.51+]
SELECT * FROM zdemo_abap_fli INTO TABLE @DATA(page2)
UP TO 10 ROWS OFFSET 10.Field Selection
" All fields
SELECT * FROM zdemo_abap_carr INTO TABLE @DATA(all_fields).
" Specific fields
SELECT carrid, carrname, url FROM zdemo_abap_carr INTO TABLE @DATA(some_fields).
" With alias
SELECT carrid AS carrier_id, carrname AS name FROM zdemo_abap_carr
INTO TABLE @DATA(aliased).
" Literals
SELECT carrid, 'Carrier' AS type FROM zdemo_abap_carr INTO TABLE @DATA(with_literal).
" Expressions
SELECT carrid, price * quantity AS total FROM zdemo_abap_fli
INTO TABLE @DATA(calculated).---
WHERE Conditions
Comparison Operators
" Equal, not equal
WHERE carrid = 'LH'
WHERE carrid <> 'LH'
WHERE carrid NE 'LH'
" Greater/less than
WHERE price > 1000
WHERE price >= 1000
WHERE price < 500
WHERE price <= 500
" BETWEEN
WHERE price BETWEEN 100 AND 500
" IN list
WHERE carrid IN ( 'LH', 'AA', 'UA' )
" LIKE (pattern matching)
WHERE carrname LIKE 'Luft%' " Starts with 'Luft'
WHERE carrname LIKE '%Airlines' " Ends with 'Airlines'
WHERE carrname LIKE '%Air%' " Contains 'Air'
WHERE code LIKE 'A_C' " Single character wildcard
" IS NULL / IS NOT NULL
WHERE description IS NULL
WHERE description IS NOT NULL
" IS INITIAL / IS NOT INITIAL
WHERE field IS INITIAL
WHERE field IS NOT INITIALLogical Operators
" AND
WHERE carrid = 'LH' AND connid = '0400'
" OR
WHERE carrid = 'LH' OR carrid = 'AA'
" NOT
WHERE NOT carrid = 'LH'
WHERE carrid NOT IN ( 'LH', 'AA' )
WHERE carrname NOT LIKE '%Express%'
" Combined
WHERE ( carrid = 'LH' OR carrid = 'AA' ) AND fldate > '20240101'FOR ALL ENTRIES
" Prerequisites: Source table must not be empty!
IF source_itab IS NOT INITIAL.
SELECT * FROM dbtab
FOR ALL ENTRIES IN @source_itab
WHERE key_field = @source_itab-id
INTO TABLE @DATA(result).
ENDIF.
" Multiple conditions
SELECT * FROM flights
FOR ALL ENTRIES IN @flight_keys
WHERE carrid = @flight_keys-carrid
AND connid = @flight_keys-connid
INTO TABLE @DATA(matched_flights).Subqueries
Subquery Types
" EXISTS subquery
SELECT * FROM zdemo_abap_carr AS c
WHERE EXISTS ( SELECT * FROM zdemo_abap_fli AS f
WHERE f~carrid = c~carrid )
INTO TABLE @DATA(carriers_with_flights).
" NOT EXISTS
SELECT * FROM zdemo_abap_carr AS c
WHERE NOT EXISTS ( SELECT * FROM zdemo_abap_fli AS f
WHERE f~carrid = c~carrid )
INTO TABLE @DATA(carriers_without_flights).
" IN subquery
SELECT * FROM zdemo_abap_carr
WHERE carrid IN ( SELECT carrid FROM zdemo_abap_fli
WHERE price > 500 )
INTO TABLE @DATA(expensive_carriers).
" Scalar subquery
SELECT carrid, carrname,
( SELECT COUNT(*) FROM zdemo_abap_fli AS f
WHERE f~carrid = c~carrid ) AS flight_count
FROM zdemo_abap_carr AS c
INTO TABLE @DATA(with_counts).---
Aggregate Functions
" COUNT
SELECT COUNT(*) FROM zdemo_abap_fli INTO @DATA(total_count).
SELECT COUNT( DISTINCT carrid ) FROM zdemo_abap_fli INTO @DATA(carrier_count).
" SUM
SELECT SUM( price ) FROM zdemo_abap_fli WHERE carrid = 'LH' INTO @DATA(sum_price).
" AVG
SELECT AVG( price ) FROM zdemo_abap_fli INTO @DATA(avg_price).
" MIN / MAX
SELECT MIN( fldate ) FROM zdemo_abap_fli INTO @DATA(first_flight).
SELECT MAX( fldate ) FROM zdemo_abap_fli INTO @DATA(last_flight).
" Combined aggregates
SELECT carrid,
COUNT(*) AS flight_count,
SUM( seatsmax ) AS total_seats,
AVG( price ) AS avg_price,
MIN( fldate ) AS first_date,
MAX( fldate ) AS last_date
FROM zdemo_abap_fli
GROUP BY carrid
INTO TABLE @DATA(carrier_stats).
" HAVING clause (filter on aggregates)
SELECT carrid, COUNT(*) AS cnt
FROM zdemo_abap_fli
GROUP BY carrid
HAVING COUNT(*) > 10
INTO TABLE @DATA(active_carriers).---
JOIN Operations
INNER JOIN
SELECT a~carrid, a~connid, b~carrname
FROM zdemo_abap_fli AS a
INNER JOIN zdemo_abap_carr AS b ON a~carrid = b~carrid
INTO TABLE @DATA(flights_with_carrier).
" Multiple conditions
SELECT f~*, c~carrname " [7.40 SP08+] f~*
FROM zdemo_abap_fli AS f
INNER JOIN zdemo_abap_carr AS c
ON f~carrid = c~carrid
INTO TABLE @DATA(joined).LEFT OUTER JOIN
" Returns all from left, matched from right (or NULL)
SELECT c~carrid, c~carrname, f~connid, f~fldate
FROM zdemo_abap_carr AS c
LEFT OUTER JOIN zdemo_abap_fli AS f
ON c~carrid = f~carrid
INTO TABLE @DATA(carriers_with_optional_flights).RIGHT OUTER JOIN
" RIGHT OUTER JOIN " [7.40 SP05+]
" Returns all from right, matched from left (or NULL)
SELECT c~carrid, c~carrname, f~connid, f~fldate
FROM zdemo_abap_fli AS f
RIGHT OUTER JOIN zdemo_abap_carr AS c
ON c~carrid = f~carrid
INTO TABLE @DATA(all_carriers).CROSS JOIN
" Cartesian product " [7.51+]
SELECT a~id AS a_id, b~id AS b_id
FROM table_a AS a
CROSS JOIN table_b AS b
INTO TABLE @DATA(cross_product).Multiple Joins
SELECT f~carrid, f~connid, c~carrname, p~cityto
FROM zdemo_abap_fli AS f
INNER JOIN zdemo_abap_carr AS c ON f~carrid = c~carrid
INNER JOIN zdemo_abap_conn AS p ON f~carrid = p~carrid
AND f~connid = p~connid
INTO TABLE @DATA(complete_info).---
Sorting and Grouping
ORDER BY
SELECT * FROM zdemo_abap_fli
ORDER BY carrid, fldate
INTO TABLE @DATA(sorted).
SELECT * FROM zdemo_abap_fli
ORDER BY price DESCENDING
INTO TABLE @DATA(by_price_desc).
SELECT * FROM zdemo_abap_fli
ORDER BY carrid ASCENDING, price DESCENDING
INTO TABLE @DATA(mixed_sort).
" Order by alias
SELECT carrid, COUNT(*) AS cnt
FROM zdemo_abap_fli
GROUP BY carrid
ORDER BY cnt DESCENDING
INTO TABLE @DATA(by_count).
" PRIMARY KEY ordering
SELECT * FROM zdemo_abap_fli
ORDER BY PRIMARY KEY
INTO TABLE @DATA(by_pk).GROUP BY
SELECT carrid, COUNT(*) AS flight_count
FROM zdemo_abap_fli
GROUP BY carrid
INTO TABLE @DATA(grouped).
SELECT carrid, connid,
COUNT(*) AS cnt,
SUM( seatsmax ) AS total_seats
FROM zdemo_abap_fli
GROUP BY carrid, connid
INTO TABLE @DATA(grouped_multi).---
Common Table Expressions (CTE)
[7.51+] WITH statements require ABAP 7.51 or higher. On 7.40, use subqueriesor temporary tables instead.
" WITH ... AS
WITH
+flights AS (
SELECT carrid, connid, COUNT(*) AS cnt
FROM zdemo_abap_fli
GROUP BY carrid, connid ),
+carriers AS (
SELECT carrid, carrname
FROM zdemo_abap_carr )
SELECT f~carrid, c~carrname, f~cnt
FROM +flights AS f
INNER JOIN +carriers AS c ON f~carrid = c~carrid
INTO TABLE @DATA(result).
" Chained CTEs
WITH
+step1 AS (
SELECT * FROM tab1 WHERE col1 = 'A' ),
+step2 AS (
SELECT * FROM +step1 WHERE col2 > 100 )
SELECT * FROM +step2 INTO TABLE @DATA(final_result).---
CASE Expressions
" Simple CASE
SELECT carrid,
CASE carrid
WHEN 'LH' THEN 'Lufthansa'
WHEN 'AA' THEN 'American Airlines'
ELSE 'Other'
END AS carrier_name
FROM zdemo_abap_fli
INTO TABLE @DATA(with_case).
" Searched CASE
SELECT carrid, price,
CASE
WHEN price < 500 THEN 'Budget'
WHEN price < 1000 THEN 'Economy'
WHEN price < 2000 THEN 'Business'
ELSE 'First Class'
END AS category
FROM zdemo_abap_fli
INTO TABLE @DATA(categorized).---
Built-in SQL Functions
String Functions
SELECT
CONCAT( first_name, last_name ) AS full_name,
CONCAT_WITH_SPACE( first_name, last_name, 1 ) AS spaced_name, " [7.51+]
LENGTH( description ) AS desc_length,
LEFT( code, 2 ) AS prefix, " [7.51+]
RIGHT( code, 2 ) AS suffix, " [7.51+]
SUBSTRING( text, 1, 10 ) AS excerpt,
UPPER( name ) AS upper_name, " [7.51+]
LOWER( name ) AS lower_name, " [7.51+]
LTRIM( text, ' ' ) AS left_trimmed,
RTRIM( text, ' ' ) AS right_trimmed,
REPLACE( text, 'old', 'new' ) AS replaced,
LPAD( code, 10, '0' ) AS padded
FROM some_table
INTO TABLE @DATA(string_results).Numeric Functions
SELECT
ABS( amount ) AS absolute,
CEIL( value ) AS ceiling,
FLOOR( value ) AS floor_val,
ROUND( price, 2 ) AS rounded,
DIV( total, count ) AS integer_div,
MOD( number, 10 ) AS remainder,
DIVISION( amount, 3, 2 ) AS precise_div
FROM some_table
INTO TABLE @DATA(numeric_results).Date/Time Functions
SELECT
DATS_IS_VALID( fldate ) AS is_valid,
DATS_DAYS_BETWEEN( date1, date2 ) AS day_diff,
DATS_ADD_DAYS( fldate, 7 ) AS plus_week,
DATS_ADD_MONTHS( fldate, 1 ) AS plus_month,
EXTRACT_YEAR( fldate ) AS year,
EXTRACT_MONTH( fldate ) AS month,
EXTRACT_DAY( fldate ) AS day
FROM zdemo_abap_fli
INTO TABLE @DATA(date_results).COALESCE and NULL Handling
SELECT
COALESCE( description, 'No description' ) AS desc,
COALESCE( price, 0 ) AS price_or_zero,
CASE WHEN field IS NULL THEN 'N/A' ELSE field END AS handled
FROM some_table
INTO TABLE @DATA(null_handled).---
Data Modification
INSERT
" Single row
INSERT zdemo_abap_carr FROM @( VALUE #( carrid = 'XX' carrname = 'Test' ) ). " [7.50+]
" From structure
INSERT dbtab FROM @struc.
" Multiple rows
INSERT zdemo_abap_carr FROM TABLE @itab.
" Check sy-subrc: 0 = success, 4 = duplicate key
IF sy-subrc <> 0.
" Handle error
ENDIF.UPDATE
" Update with SET
UPDATE zdemo_abap_carr
SET carrname = 'New Name', url = 'new_url'
WHERE carrid = 'XX'.
" From structure
UPDATE dbtab FROM @struc.
" From table
UPDATE dbtab FROM TABLE @itab.
" sy-dbcnt contains number of updated rowsMODIFY (Insert or Update)
" Single row
MODIFY dbtab FROM @struc.
" Multiple rows
MODIFY dbtab FROM TABLE @itab.
" Inserts if key doesn't exist, updates if it doesDELETE
" With WHERE
DELETE FROM zdemo_abap_carr WHERE carrid = 'XX'.
" From structure (by key)
DELETE dbtab FROM @struc.
" From table
DELETE dbtab FROM TABLE @itab.
" All rows (caution!)
DELETE FROM dbtab.---
INDICATORS for Partial Updates
" Only update specific fields based on indicator structure
DATA: struc TYPE zdemo_abap_struc,
ind TYPE zdemo_abap_struc_indicators.
struc-carrid = 'XX'.
struc-carrname = 'Updated Name'.
ind-carrname = abap_true. " Only update carrname
UPDATE dbtab FROM @struc INDICATORS SET STRUCTURE ind.---
Client Handling
" USING CLIENT (specific client)
SELECT * FROM dbtab
USING CLIENT @( '100' ) " [7.50+]
INTO TABLE @DATA(client100_data).
" USING ALL CLIENTS (cross-client)
SELECT * FROM dbtab
USING ALL CLIENTS
INTO TABLE @DATA(all_clients_data).
" Note: Requires authorization---
Performance Tips
1. Select only needed fields - avoid SELECT 2. Use appropriate indexes - check execution plan 3. Limit result sets - use UP TO n ROWS when appropriate 4. Use JOINs instead of nested SELECTs 5. FOR ALL ENTRIES - ensure table is not empty 6. Avoid client-dependent SELECT in loops 7. Use aggregates in database - not in ABAP 8. Package processing* for large data sets
ABAP Managed Database Procedures (AMDP) - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/12_AMDP.md
---
Overview
AMDP is a class-based framework for managing database procedures and functions that execute on SAP HANA using SQLScript.
---
AMDP Class Structure
CLASS zcl_amdp_demo DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
TYPES tab_type TYPE STANDARD TABLE OF dbtab WITH EMPTY KEY.
METHODS amdp_procedure
IMPORTING VALUE(param) TYPE i
EXPORTING VALUE(result) TYPE tab_type.
ENDCLASS.---
AMDP Procedures
Declaration
METHODS amdp_meth
IMPORTING VALUE(num) TYPE i
EXPORTING VALUE(tab) TYPE tab_type.Implementation
METHOD amdp_meth
BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING db_object.
tab = SELECT * FROM db_object WHERE id = :num;
ENDMETHOD.Key Additions
| Addition | Purpose |
|---|---|
BY DATABASE PROCEDURE | Designates as database procedure |
FOR HDB | Specifies SAP HANA database |
LANGUAGE SQLSCRIPT | Defines programming language |
OPTIONS READ-ONLY | Required for ABAP Cloud |
USING db_object | Specifies accessible database objects |
---
AMDP Table Functions
For AMDP Methods (Internal Use)
METHODS amdp_func
IMPORTING VALUE(num) TYPE i
RETURNING VALUE(tab) TYPE tab_type.
METHOD amdp_func
BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING db_object.
RETURN SELECT * FROM db_object WHERE id = :num;
ENDMETHOD.For CDS Table Functions
CLASS-METHODS table_func FOR TABLE FUNCTION some_cds_table_func.CDS Definition:
define table function some_cds_table_func
with parameters
p_param : abap.char(3)
returns {
client : abap.clnt;
field1 : abap.char(5);
field2 : abap.int4;
}
implemented by method amdp_class=>table_func;---
AMDP Scalar Functions
For AMDP Methods
METHODS get_max_value
IMPORTING VALUE(category) TYPE c LENGTH 2
RETURNING VALUE(max_val) TYPE i.
METHOD get_max_value
BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING some_table.
SELECT MAX(amount) INTO max_val
FROM some_table
WHERE category = :category;
ENDMETHOD.For CDS Scalar Functions
CLASS-METHODS calc_percentage FOR SCALAR FUNCTION zdemo_scalar_func.
METHOD calc_percentage
BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY.
result = num / total * 100;
ENDMETHOD.CDS Definition:
define scalar function zdemo_scalar_func
with parameters
num : numeric,
total : type of num
returns abap.dec( 8, 2 )---
ABAP Cloud Requirements
Read-Only Enforcement
METHOD amdp_meth
BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY " Mandatory in ABAP Cloud
USING ...Client-Safe AMDP
METHODS select_entries
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
IMPORTING VALUE(carrid) TYPE c LENGTH 2
EXPORTING VALUE(tab) TYPE tab_type.Client Handling Options
| Option | Purpose |
|---|---|
CDS SESSION CLIENT DEPENDENT | Client-dependent via session variables |
CLIENT INDEPENDENT | Client-independent data sources |
---
Calling AMDP Scalar Functions
METHOD select_with_scalar
BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING some_table, zcl_amdp=>get_max_value.
result_tab = SELECT carrid, connid, amount
FROM some_table
WHERE amount = "ZCL_AMDP=>GET_MAX_VALUE"( category => :category );
ENDMETHOD.---
Complete Example
CLASS zcl_amdp_demo DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_amdp_marker_hdb.
TYPES flight_tab TYPE TABLE OF zdemo_flight WITH EMPTY KEY.
" Scalar function
METHODS get_max_fltime
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
IMPORTING VALUE(carrid) TYPE c LENGTH 2
RETURNING VALUE(max_fltime) TYPE i.
" Procedure using scalar function
METHODS select_max_flights
AMDP OPTIONS READ-ONLY CDS SESSION CLIENT DEPENDENT
IMPORTING VALUE(carrid) TYPE c LENGTH 2
EXPORTING VALUE(flights) TYPE flight_tab.
ENDCLASS.
CLASS zcl_amdp_demo IMPLEMENTATION.
METHOD get_max_fltime
BY DATABASE FUNCTION
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING zdemo_flight.
SELECT MAX(fltime) INTO max_fltime
FROM zdemo_flight
WHERE carrid = :carrid;
ENDMETHOD.
METHOD select_max_flights
BY DATABASE PROCEDURE
FOR HDB
LANGUAGE SQLSCRIPT
OPTIONS READ-ONLY
USING zdemo_flight, zcl_amdp_demo=>get_max_fltime.
flights = SELECT carrid, connid, fltime
FROM zdemo_flight
WHERE fltime = "ZCL_AMDP_DEMO=>GET_MAX_FLTIME"( carrid => :carrid );
ENDMETHOD.
ENDCLASS.---
Best Practices
1. Use AMDP only when necessary - prefer ABAP SQL when possible 2. Always use OPTIONS READ-ONLY for ABAP Cloud 3. Specify USING clause for all accessed database objects 4. Handle client dependency appropriately 5. Test SQLScript logic in database development tools 6. Document complex procedures for maintainability
Authorization Checks - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/25_Authorization_Checks.md
---
AUTHORITY-CHECK Statement
Basic Syntax
AUTHORITY-CHECK OBJECT 'ZAUTH_OBJ'
ID id1 FIELD val1
ID id2 FIELD val2
ID id3 DUMMY
... .Practical Example
AUTHORITY-CHECK OBJECT 'ZAUTH_OBJ'
ID 'ZAUTH_CTRY' FIELD 'US'
ID 'ACTVT' FIELD '03'.
IF sy-subrc = 0.
out->write( `US/03: Allowed` ).
ELSE.
out->write( `US/03: Not allowed` ).
ENDIF.Key Characteristics
- Object name must be uppercase literal (ABAP Cloud)
- Supports 1-10 authorization field IDs
DUMMYbypasses checks on specific fields- Return codes:
sy-subrc = 0(allowed),sy-subrc = 4(denied)
---
Standard Activity Codes (ACTVT)
| Code | Activity |
|---|---|
| 01 | Create |
| 02 | Change/Update |
| 03 | Display |
| 06 | Delete |
---
CDS Access Control
View Entity Annotation
@AccessControl.authorizationCheck: #CHECK
define view entity ZDEMO_ABAP_FLSCH_VE_AUTH
as select from zdemo_abap_flsch
{
key carrid,
key connid,
countryfr,
...
}Authorization Options
| Option | Description |
|---|---|
#NOT_REQUIRED | Full access granted |
#CHECK | Warning if access control missing |
#MANDATORY | Access control required |
#NOT_ALLOWED | Access control prohibited |
Access Control Role (DCL)
@EndUserText.label: 'Test'
@MappingRole: true
define role ZCDS_ACC_CTRL {
grant
select
on
ZDEMO_ABAP_FLSCH_VE_AUTH
where
(countryfr) = aspect pfcg_auth(zauth_obj, zauth_ctry, ACTVT = '03');
}---
RAP Authorization Control
Global Authorization
Restricts operations independently of instance state:
METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION
IMPORTING REQUEST requested_authorizations FOR some_bdef
RESULT result.Implementation:
METHOD get_global_authorizations.
IF requested_authorizations-%create = if_abap_behv=>mk-on.
AUTHORITY-CHECK OBJECT 'ZAUTH_OBJ'
ID 'ZAUTH_FIELD' DUMMY
ID 'ACTVT' FIELD '01'.
result-%create = COND #( WHEN sy-subrc = 0
THEN if_abap_behv=>auth-allowed
ELSE if_abap_behv=>auth-unauthorized ).
ENDIF.
ENDMETHOD.Instance Authorization
Evaluates permissions based on entity instance:
METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION
IMPORTING keys REQUEST requested_authorizations FOR some_bdef
RESULT result.---
Important Notes
- ABAP SQL bypasses database authorization checks
- Programmer must implement authorization explicitly
- Both global and instance authorization can operate simultaneously
PRIVILEGEDmode circumvents authorization when necessary
---
Best Practices
1. Always check authorization before data modifications 2. Use CDS access control for read operations 3. Implement RAP authorization for transactional scenarios 4. Document authorization objects and their usage 5. Test with different user profiles
Bits and Bytes - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/09_Bits_and_Bytes.md
---
Hexadecimal Data Type
" Byte string (hexadecimal)
DATA hex TYPE x LENGTH 4 VALUE 'CDFFC8FF'.---
Bitwise Operations
BIT-NOT Operator
DATA hex TYPE x LENGTH 4 VALUE 'CDFFC8FF'.
hex = BIT-NOT hex.Other Bitwise Operators
" BIT-AND
result = hex1 BIT-AND hex2.
" BIT-OR
result = hex1 BIT-OR hex2.
" BIT-XOR
result = hex1 BIT-XOR hex2.---
Casting with Field Symbols
Interpret data in memory under different types:
DATA hex TYPE x LENGTH 4 VALUE '32003700'.
FIELD-SYMBOLS: <num> TYPE i,
<text> TYPE c.
ASSIGN hex TO <num> CASTING.
ASSIGN hex TO <text> CASTING.
cl_demo_output=>new(
)->write_data( hex
)->write_data( <num>
)->write_data( <text> )->display( ).---
Type Conversion
" Character to numeric triggers hex transformation
DATA: text TYPE c LENGTH 2 VALUE '27',
num TYPE i.
num = text.---
Byte String Operations
" Concatenate byte strings
DATA: xstr1 TYPE xstring VALUE '0A0B',
xstr2 TYPE xstring VALUE '0C0D',
result TYPE xstring.
result = xstr1 && xstr2.
" Length of byte string
DATA(len) = xstrlen( xstr1 ).---
Best Practices
1. Use CASTING for low-level type reinterpretation 2. Handle endianness when working with binary data 3. Use xstring for variable-length byte sequences 4. Check lengths when manipulating byte data
ABAP Built-in Functions - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/24_Builtin_Functions.md
Version Note:utclongfunctions (utclong_current,utclong_add,utclong_diff)
require 7.54+. All other built-in functions are available from 7.40 SP02+.
---
String Functions
Length Functions
" String length (includes trailing blanks for variable-length)
DATA(len) = strlen( text ).
" Character count (excludes trailing blanks)
DATA(chars) = numofchar( text ).
" XString length
DATA(xlen) = xstrlen( xstring_var ).Search and Find Functions
" Find substring offset (-1 if not found)
DATA(pos) = find( val = text sub = 'search' ).
" Find with options
DATA(pos2) = find( val = text sub = 'search' off = 5 occ = 2 ).
" Find and return offset plus match length
DATA(end_pos) = find_end( val = text sub = 'search' ).
" Find any character from set
DATA(any_pos) = find_any_of( val = text sub = 'aeiou' ).
" Find character NOT in set
DATA(not_pos) = find_any_not_of( val = text sub = 'aeiou' ).Boolean Search Functions
" Check if contains substring
IF contains( val = text sub = 'search' ).
" Found
ENDIF.
" Contains with regex (PCRE)
IF contains( val = text pcre = '[0-9]+' ).
" Contains numbers
ENDIF.
" Check pattern match
IF matches( val = text regex = '^[A-Z]{2}[0-9]{4}$' ).
" Matches pattern
ENDIF.Extraction Functions
" Extract substring by position
DATA(sub) = substring( val = text off = 5 len = 10 ).
" Extract after/before delimiter
DATA(after) = substring_after( val = text sub = ':' ).
DATA(before) = substring_before( val = text sub = ':' ).
" Extract from/to (inclusive)
DATA(from) = substring_from( val = text sub = 'start' ).
DATA(to) = substring_to( val = text sub = 'end' ).
" Extract segment by delimiter
DATA(seg) = segment( val = 'a,b,c,d' index = 2 sep = ',' ). " Result: bTransformation Functions
" Case conversion
DATA(upper) = to_upper( text ).
DATA(lower) = to_lower( text ).
" Camelcase conversion
DATA(mixed) = to_mixed( val = 'HELLO_WORLD' sep = '_' ). " HelloWorld
DATA(under) = from_mixed( val = 'HelloWorld' sep = '_' ). " hello_world
" Reverse string
DATA(rev) = reverse( text ).
" Character substitution
DATA(trans) = translate( val = text from = 'abc' to = 'xyz' ).Replacement Functions
" Replace substring
DATA(rep) = replace( val = text sub = 'old' with = 'new' ).
" Replace all occurrences
DATA(rep_all) = replace( val = text sub = 'old' with = 'new' occ = 0 ).
" Replace with regex
DATA(rep_regex) = replace( val = text pcre = '[0-9]+' with = '#' ).
" Insert at position
DATA(ins) = insert( val = text sub = 'INSERT' off = 5 ).Escape Function
" Escape for URL
DATA(url_esc) = escape( val = text format = cl_abap_format=>e_url ).
" Escape for JSON
DATA(json_esc) = escape( val = text format = cl_abap_format=>e_json_string ).
" Escape for string template
DATA(tmpl_esc) = escape( val = text format = cl_abap_format=>e_string_tpl ).Other String Functions
" Repeat string
DATA(repeated) = repeat( val = 'ab' occ = 3 ). " ababab
" Condense blanks
DATA(condensed) = condense( val = ' a b c ' ). " a b c
DATA(no_blanks) = condense( val = ' a b c ' del = ' ' ). " abc
" Shift characters
DATA(left) = shift_left( val = text sub = ' ' ).
DATA(right) = shift_right( val = text places = 3 ).
" Join table lines
DATA(joined) = concat_lines_of( table = string_tab sep = ',' ).
" Levenshtein distance
DATA(dist) = distance( val1 = 'kitten' val2 = 'sitting' ).
" Count occurrences
DATA(cnt) = count( val = text sub = 'a' ).
DATA(cnt_any) = count_any_of( val = text sub = 'aeiou' ).---
Numeric Functions
Basic Math Functions
" Absolute value
DATA(abs_val) = abs( -5 ). " 5
" Sign (-1, 0, or 1)
DATA(sign_val) = sign( -5 ). " -1
" Rounding
DATA(ceil_val) = ceil( CONV decfloat34( '3.2' ) ). " 4
DATA(floor_val) = floor( CONV decfloat34( '3.8' ) ). " 3
DATA(trunc_val) = trunc( CONV decfloat34( '3.8' ) ). " 3
DATA(frac_val) = frac( CONV decfloat34( '3.8' ) ). " 0.8
" Round with precision
DATA(rounded) = round( val = CONV decfloat34( '3.14159' ) dec = 2 ). " 3.14
DATA(rescaled) = rescale( val = amount prec = 2 ).Power and Root Functions
" Integer power
DATA(pow) = ipow( base = 2 exp = 10 ). " 1024
" Square root
DATA(sqrt_val) = sqrt( 16 ). " 4Min/Max Functions
" Multiple arguments
DATA(min_val) = nmin( val1 = a val2 = b val3 = c ).
DATA(max_val) = nmax( val1 = a val2 = b val3 = c ).Trigonometric Functions
" Standard trigonometric
DATA(sin_val) = sin( angle ).
DATA(cos_val) = cos( angle ).
DATA(tan_val) = tan( angle ).
" Inverse trigonometric
DATA(asin_val) = asin( value ).
DATA(acos_val) = acos( value ).
DATA(atan_val) = atan( value ).
" Hyperbolic
DATA(sinh_val) = sinh( value ).
DATA(cosh_val) = cosh( value ).
DATA(tanh_val) = tanh( value ).Logarithmic and Exponential
" Natural logarithm
DATA(log_val) = log( value ).
" Base 10 logarithm
DATA(log10_val) = log10( value ).
" Exponential (e^x)
DATA(exp_val) = exp( value ).Special Math Functions
" Factorial
DATA(fact) = factorial( n ).
" Binomial coefficient
DATA(binom) = binomial( n = 10 k = 3 ).---
Table Functions
" Count table lines
DATA(line_count) = lines( itab ).
" Check if line exists
IF line_exists( itab[ key = value ] ).
" Line found
ENDIF.
" Get line index
DATA(idx) = line_index( itab[ key = value ] ).---
Logical Functions
" Returns 'X' or '' (string type)
DATA(bool_str) = boolc( condition ).
" Returns 'X' or '' (type c length 1) - use with abap_true/abap_false
DATA(bool_c) = xsdbool( condition ).
IF xsdbool( a > b ) = abap_true.
" Condition is true
ENDIF.---
Timestamp Functions
" Get current UTC timestamp
DATA(ts) = utclong_current( ).
" Add time to timestamp
DATA(ts_add) = utclong_add(
val = ts
days = 1
hours = 2
minutes = 30
seconds = 0
).
" Calculate difference (returns seconds as decfloat34)
DATA(diff) = utclong_diff( high = ts2 low = ts1 ).---
ABAP SQL Functions
Available in SELECT statements:
Numeric SQL Functions
SELECT
div( field1, 10 ) AS int_division,
division( field1, field2, 2 ) AS dec_division,
mod( field1, 10 ) AS modulo,
abs( field1 ) AS absolute,
ceil( field1 ) AS ceiling,
floor( field1 ) AS floor_val,
round( field1, 2 ) AS rounded
FROM dbtab
INTO TABLE @DATA(result).String SQL Functions
SELECT
initcap( name ) AS proper_case,
instr( text, 'search' ) AS position,
locate( text, 'search' ) AS locate_pos,
locate_regexpr( pcre = '[0-9]+' IN text ) AS regex_pos,
length( text ) AS len,
left( text, 5 ) AS left_chars,
right( text, 5 ) AS right_chars,
ltrim( text, ' ' ) AS left_trimmed,
rtrim( text, ' ' ) AS right_trimmed,
upper( text ) AS upper_case,
lower( text ) AS lower_case,
concat( field1, field2 ) AS concatenated,
replace( text, 'old', 'new' ) AS replaced,
substring( text, 1, 5 ) AS sub_str
FROM dbtab
INTO TABLE @DATA(result).Date/Time SQL Functions
SELECT
extract_year( date_field ) AS year,
extract_month( date_field ) AS month,
extract_day( date_field ) AS day,
dayname( date_field ) AS day_name,
monthname( date_field ) AS month_name,
weekday( date_field ) AS week_day,
days_between( date1, date2 ) AS days_diff,
add_days( date_field, 30 ) AS future_date,
add_months( date_field, 3 ) AS future_month,
utcl_current( ) AS current_ts,
utcl_add_seconds( ts_field, 3600 ) AS ts_plus_hour
FROM dbtab
INTO TABLE @DATA(result).Conversion SQL Functions
SELECT
unit_conversion( quantity = qty, source_unit = uom, target_unit = 'KG' ) AS converted,
currency_conversion( amount = amt, source_currency = curr, target_currency = 'USD' ) AS usd_amt,
uuid( ) AS new_uuid
FROM dbtab
INTO TABLE @DATA(result).---
Best Practices
1. Use built-in functions instead of custom implementations 2. Prefer SQL functions for database operations (pushdown) 3. Use xsdbool( ) for comparisons with abap_true/abap_false 4. Use lines( ) instead of DESCRIBE TABLE for count 5. Use line_exists( ) for existence checks instead of READ TABLE 6. Combine functions for complex string operations
CDS View Entities - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/15_CDS_View_Entities.md
---
Basic Syntax
@AbapCatalog.sqlViewName: 'ZSQL_VIEW'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
@EndUserText.label: 'Demo CDS View'
define view entity ZDemo_CDS_View
as select from zdemo_table as Source
{
key Source.key_field as KeyField,
Source.field1 as Field1,
Source.field2 as Field2
}---
Field Selection
define view entity ZDemo_Fields
as select from zdemo_table
{
key key_field, // Direct field
field1 as AliasName, // With alias
'Literal' as LiteralField, // Literal value
123 as NumericLiteral, // Numeric literal
abap.dats'20240101' as DateLiteral, // Date literal
$session.user as CurrentUser, // Session variable
$session.client as Client
}---
Expressions
Cast Expressions
cast( amount as abap.dec(15,2) ) as CastedAmount,
cast( quantity as abap.int4 ) as CastedQuantity,
cast( text as abap.char(100) ) as CastedTextArithmetic Expressions
price * quantity as TotalAmount,
amount / 100 as AmountPercentage,
value1 + value2 as Sum,
value1 - value2 as DifferenceCase Expressions
// Simple CASE
case status
when 'A' then 'Active'
when 'I' then 'Inactive'
else 'Unknown'
end as StatusText,
// Searched CASE
case
when amount > 1000 then 'High'
when amount > 100 then 'Medium'
else 'Low'
end as AmountCategoryCoalesce
coalesce( nullable_field, 'Default' ) as FieldWithDefault,
coalesce( amount, 0 ) as AmountOrZero---
Built-in Functions
String Functions
concat( first_name, last_name ) as FullName,
concat_with_space( first_name, last_name, 1 ) as SpacedName,
substring( text, 1, 10 ) as Excerpt,
length( description ) as DescLength,
left( code, 2 ) as Prefix,
right( code, 2 ) as Suffix,
upper( name ) as UpperName,
lower( name ) as LowerName,
ltrim( text, ' ' ) as LeftTrimmed,
rtrim( text, ' ' ) as RightTrimmed,
replace( text, 'old', 'new' ) as ReplacedText,
instr( text, 'pattern' ) as PatternPositionNumeric Functions
abs( amount ) as AbsoluteAmount,
ceil( value ) as Ceiling,
floor( value ) as FloorValue,
round( price, 2 ) as RoundedPrice,
div( total, count ) as IntegerDivision,
mod( number, 10 ) as Remainder,
division( amount, 3, 2 ) as PreciseDivisionDate/Time Functions
dats_is_valid( date_field ) as IsValidDate,
dats_days_between( date1, date2 ) as DaysDiff,
dats_add_days( date_field, 7 ) as DatePlusWeek,
dats_add_months( date_field, 1 ) as DatePlusMonth,
$session.system_date as TodayType Conversion
cast( char_field as abap.numc(10) ) as NumericString,
cast( amount as abap.fltp ) as FloatingPoint---
Aggregate Functions
define view entity ZDemo_Aggregates
as select from zdemo_table
{
key category,
count(*) as TotalCount,
count( distinct status ) as UniqueStatuses,
sum( amount ) as TotalAmount,
avg( price ) as AveragePrice,
min( date_field ) as FirstDate,
max( date_field ) as LastDate
}
group by category---
Joins
Inner Join
define view entity ZDemo_InnerJoin
as select from zdemo_header as Header
inner join zdemo_item as Item
on Header.header_id = Item.header_id
{
key Header.header_id,
key Item.item_id,
Header.description,
Item.quantity
}Left Outer Join
define view entity ZDemo_LeftJoin
as select from zdemo_header as Header
left outer join zdemo_item as Item
on Header.header_id = Item.header_id
{
key Header.header_id,
Header.description,
Item.item_id,
Item.quantity
}Multiple Joins
define view entity ZDemo_MultiJoin
as select from zdemo_header as Header
inner join zdemo_item as Item
on Header.header_id = Item.header_id
left outer join zdemo_text as Text
on Item.item_id = Text.item_id
{
// fields
}---
Associations
Definition
define view entity ZDemo_Associations
as select from zdemo_header as Header
association [1..*] to zdemo_item as _Items
on Header.header_id = _Items.header_id
association [0..1] to zdemo_status as _Status
on Header.status = _Status.status_code
{
key Header.header_id,
Header.description,
Header.status,
// Expose associations
_Items,
_Status
}Cardinalities
association [0..1] to Target // Optional, single
association [1] to Target // Mandatory, single
association [1..*] to Target // One or more
association [0..*] to Target // Zero or more (default)
association [*] to Target // Same as [0..*]Path Expressions
// Access associated fields
_Status.description as StatusDescription,
_Items.quantity as ItemQuantity---
Annotations
CDS Annotations
@AbapCatalog.sqlViewName: 'ZSQLVIEW'
@AbapCatalog.preserveKey: true
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #NOT_REQUIRED
// or #CHECK, #PRIVILEGED_ONLY
@EndUserText.label: 'Human readable name'Element Annotations
define view entity ZDemo_Annotations
as select from zdemo_table
{
@EndUserText.label: 'Customer ID'
@EndUserText.quickInfo: 'Unique customer identifier'
key customer_id as CustomerId,
@Semantics.amount.currencyCode: 'CurrencyCode'
amount as Amount,
@Semantics.currencyCode: true
currency as CurrencyCode,
@Semantics.unitOfMeasure: true
unit as Unit,
@Semantics.quantity.unitOfMeasure: 'Unit'
quantity as Quantity
}UI Annotations
@UI: {
headerInfo: {
typeName: 'Order',
typeNamePlural: 'Orders',
title: { value: 'OrderId' }
}
}
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
key order_id as OrderId---
Input Parameters
define view entity ZDemo_Parameters
with parameters
p_date : abap.dats,
p_category : abap.char(10)
as select from zdemo_table
{
key id,
description,
$parameters.p_date as ParameterDate,
$parameters.p_category as ParameterCategory
}
where category = $parameters.p_category
and date_field >= $parameters.p_dateCalling with Parameters
SELECT * FROM zdemo_parameters( p_date = '20240101', p_category = 'A' )
INTO TABLE @DATA(result).---
Composition and Hierarchy
// Root entity
define root view entity ZDemo_Root
as select from zdemo_root
composition [0..*] of ZDemo_Child as _Children
{
key root_id,
description,
_Children
}
// Child entity
define view entity ZDemo_Child
as select from zdemo_child
association to parent ZDemo_Root as _Root
on $projection.root_id = _Root.root_id
{
key root_id,
key child_id,
description,
_Root
}---
Extension Views
// Extend existing view
extend view entity ZExisting_View with
{
Source.additional_field as AdditionalField,
'Literal' as NewLiteral
}---
ABAP Consumption
SELECT
" Direct select
SELECT * FROM zdemo_cds_view INTO TABLE @DATA(result).
" With association path
SELECT *, \_Items-quantity FROM zdemo_header
INTO TABLE @DATA(with_items).
" With parameters
SELECT * FROM zdemo_params( p_date = @lv_date )
INTO TABLE @DATA(parameterized).Association Access
" Follow association
SELECT * FROM zdemo_header
ASSOCIATION \_Items
INTO TABLE @DATA(items).---
Best Practices
1. Use view entities over classic CDS views 2. Define meaningful aliases for all fields 3. Expose associations for flexibility 4. Add semantic annotations for Fiori integration 5. Use parameters for flexible filtering 6. Document with @EndUserText annotations 7. Set appropriate authorization checks 8. Keep views focused and composable
ABAP Cloud Development - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/19_ABAP_for_Cloud_Development.md
---
Core Concepts
ABAP Cloud: Programming paradigm for cloud-ready, upgrade-stable solutions using restricted ABAP technology.
Key Restrictions:
- Limited to ABAP for Cloud Development language version
- Access restricted to released SAP APIs only
- ADT (ABAP Development Tools for Eclipse) is the only supported IDE
- RAP is the transactional programming model
---
Prohibited Syntax
" NOT allowed in ABAP Cloud
" Classic statements
MOVE source TO target. " Use: target = source.
DESCRIBE TABLE itab LINES count. " Use: count = lines( itab ).
GET REFERENCE OF var INTO dref. " Use: dref = REF #( var ).
" Classic UI
WRITE 'text'.
SELECTION-SCREEN ...
START-OF-SELECTION.
" Reports
REPORT ...
" Classic debugging
BREAK-POINT.
" Client handling
SELECT ... USING CLIENT ...
" Some sy-fields
DATA(date) = sy-datum. " Use XCO library
DATA(time) = sy-uzeit.
DATA(timestamp) = sy-timlo.---
Released APIs
Date and Time (XCO Library)
" Current date
DATA(date) = xco_cp=>sy->date( )->as( xco_cp_time=>format->iso_8601_extended )->value.
" Current time
DATA(time) = xco_cp=>sy->time( )->as( xco_cp_time=>format->iso_8601_extended )->value.
" Date calculations
DATA(tomorrow) = xco_cp=>sy->date( )->add( iv_day = 1 )->value.
DATA(next_month) = xco_cp=>sy->date( )->add( iv_month = 1 )->value.UUID Generation
" Generate UUID
DATA(uuid) = cl_system_uuid=>create_uuid_x16_static( ).
" As string format
TRY.
DATA(uuid_str) = cl_system_uuid=>convert_uuid_x16_static(
uuid = uuid ).
CATCH cx_uuid_error.
ENDTRY.Random Numbers
" Random integer
DATA(random) = cl_abap_random_int=>create(
seed = CONV i( sy-uzeit )
min = 1
max = 100 ).
DATA(number) = random->get_next( ).
" Probability distributions
DATA(prob) = cl_abap_prob_distribution=>get_instance( ).
DATA(normal) = prob->normal( mean = 50 stdev = 10 ).Output (if_oo_adt_classrun)
CLASS zcl_demo DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_demo IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
out->write( 'Hello from ABAP Cloud!' ).
out->write( data_object ).
out->write( itab ).
ENDMETHOD.
ENDCLASS.String Processing
" Available string functions
DATA(upper) = to_upper( text ).
DATA(lower) = to_lower( text ).
DATA(len) = strlen( text ).
DATA(found) = find( val = text sub = 'pattern' ).
DATA(result) = replace( val = text sub = 'old' with = 'new' occ = 0 ).
" String templates
DATA(formatted) = |Date: { xco_cp=>sy->date( )->value DATE = ISO }|.---
Released Table Types
" Available system types
DATA itab TYPE string_table.
DATA hash_tab TYPE string_hashed_table.
DATA xstr_tab TYPE xstring_table.---
Released Data Elements
" Available DDIC elements
DATA ts TYPE timestampl.
DATA country TYPE land1.
DATA bool TYPE abap_boolean.
DATA true_val TYPE abap_bool VALUE abap_true.---
RAP as Programming Model
" EML for data access
MODIFY ENTITIES OF zroot_entity
ENTITY root
CREATE FROM ...
MAPPED DATA(mapped)
FAILED DATA(failed)
REPORTED DATA(reported).
READ ENTITIES OF zroot_entity
ENTITY root
ALL FIELDS WITH VALUE #( ( key = 1 ) )
RESULT DATA(result).
COMMIT ENTITIES.---
Checking Cloud Readiness
In ADT
1. Right-click on class/object 2. Select "Run As" → "ABAP Test Cockpit" 3. Use check variant ABAP_CLOUD_READINESS 4. Review findings
Change Language Version
1. Open object properties 2. Go to "General" tab 3. Edit "ABAP Language Version" 4. Select "ABAP for Cloud Development" 5. Check for syntax errors
---
Migration Patterns
Date/Time
" Classic (not allowed)
DATA(date) = sy-datum.
DATA(time) = sy-uzeit.
" Cloud (use XCO)
DATA(date) = xco_cp=>sy->date( )->value.
DATA(time) = xco_cp=>sy->time( )->value.Table Line Count
" Classic (not allowed)
DESCRIBE TABLE itab LINES count.
" Cloud
DATA(count) = lines( itab ).Reference Creation
" Classic (not allowed)
GET REFERENCE OF var INTO dref.
" Cloud
dref = REF #( var ).Assignment
" Classic (not allowed)
MOVE source TO target.
" Cloud
target = source.Output
" Classic (not allowed)
WRITE 'text'.
" Cloud (in if_oo_adt_classrun)
out->write( 'text' ).---
Available CDS Objects
" Released CDS views
DATA tz TYPE i_timezone.
" Access via ABAP SQL
SELECT * FROM i_country INTO TABLE @DATA(countries).---
Release Contracts
| Contract | Meaning |
|---|---|
| C0 | Not released |
| C1 | Released for key user extensibility |
| C2 | Released for partner development |
| C3 | Released for SAP internal |
Use only C1 or higher in ABAP Cloud.
---
Best Practices
1. Use released APIs only - check release status before using 2. Use RAP for transactional scenarios 3. Use XCO library for date/time operations 4. Implement if_oo_adt_classrun for console output 5. Run ATC checks regularly with cloud readiness variant 6. Avoid sy-datum/sy-uzeit - use XCO alternatives 7. Use constructor expressions over obsolete syntax 8. Test in cloud environment before deployment
---
Supported Environments
- SAP BTP ABAP Environment
- SAP S/4HANA Cloud, public edition
- SAP S/4HANA Cloud, private edition
- SAP S/4HANA (on-premise) - opt-in
---
Documentation Links
ABAP Constructor Expressions - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/05_Constructor_Expressions.md
Version Note: All constructor operators (VALUE, NEW, CONV, COND, SWITCH, REF, EXACT,
CAST, CORRESPONDING) are available since 7.40 SP02. REDUCE and FILTER require
7.40 SP08. TheFINALinline declaration requires 7.50+ — useDATAon 7.40.
LET expressions require 7.40 SP05+. BASE, LINES OF, OPTIONAL/DEFAULT require 7.40 SP08+.
Table of Contents
1. VALUE Operator 2. NEW Operator 3. CONV Operator 4. CORRESPONDING Operator 5. COND Operator 6. SWITCH Operator 7. REDUCE Operator 8. FILTER Operator 9. LET Expressions 10. CAST Operator 11. REF Operator 12. ALPHA Conversion 13. EXACT Operator
---
VALUE Operator
Structures
" Create structure with values
DATA(struc) = VALUE zdemo_struc( id = 1 name = 'Test' ).
" With type inference
DATA struc TYPE zdemo_struc.
struc = VALUE #( id = 1 name = 'Test' ).
" Partial assignment (other fields initial)
struc = VALUE #( id = 1 ).
" Clear to initial
struc = VALUE #( ).Internal Tables
" Create populated table
DATA(itab) = VALUE zdemo_tab(
( id = 1 name = 'First' )
( id = 2 name = 'Second' )
( id = 3 name = 'Third' ) ).
" With BASE (append to existing)
itab = VALUE #( BASE itab
( id = 4 name = 'Fourth' ) ).
" LINES OF (copy from other table)
itab = VALUE #( BASE itab ( LINES OF other_tab ) ).
" From range (UNTIL/WHILE)
DATA(nums) = VALUE int_table(
FOR i = 1 UNTIL i > 10
( i ) ).
" With FOR from table
DATA(new_tab) = VALUE target_tab(
FOR wa IN source_tab
( id = wa-key name = wa-description ) ).
" FOR with WHERE
DATA(filtered) = VALUE target_tab(
FOR wa IN source WHERE ( active = abap_true )
( wa ) ).
" FOR with INDEX INTO
DATA(numbered) = VALUE target_tab(
FOR wa IN source INDEX INTO idx
( line_no = idx data = wa ) ).
" Nested FOR
DATA(product) = VALUE result_tab(
FOR a IN tab_a
FOR b IN tab_b
( a = a b = b ) ).Deep Structures
" Nested structure
DATA(deep) = VALUE deep_struc(
header = VALUE #( id = 1 name = 'Header' )
items = VALUE #(
( item_id = 10 desc = 'Item 1' )
( item_id = 20 desc = 'Item 2' ) ) ).OPTIONAL and DEFAULT
" OPTIONAL - return initial if not found
DATA(line) = VALUE #( itab[ id = 999 ] OPTIONAL ).
" DEFAULT - return specific value if not found
DATA(line) = VALUE #( itab[ id = 999 ] DEFAULT VALUE #( id = 0 name = 'Not found' ) ).---
NEW Operator
Create Objects
" Create instance
DATA(oref) = NEW zcl_my_class( ).
" With constructor parameters
DATA(oref) = NEW zcl_my_class( iv_name = 'Test' iv_value = 100 ).
" Anonymous instance in expression
IF NEW zcl_validator( )->is_valid( input ).
...
ENDIF.Create Data References
" Elementary types
DATA(dref_int) = NEW i( 42 ).
DATA(dref_str) = NEW string( 'Hello' ).
" Structures
DATA(dref_struc) = NEW zdemo_struc( id = 1 name = 'Test' ).
" Tables
DATA(dref_tab) = NEW zdemo_tab( ( id = 1 ) ( id = 2 ) ).---
CONV Operator
" Convert to specific type
DATA(str) = CONV string( some_char ).
DATA(int) = CONV i( '123' ).
DATA(dec) = CONV decfloat34( 1 / 3 ).
" With type inference
DATA result TYPE decfloat34.
result = CONV #( num1 / num2 ).
" Inline type conversion
process( CONV string( number ) ).---
CORRESPONDING Operator
Basic Mapping
" Map matching components
target = CORRESPONDING #( source ).
" With BASE (keep existing values)
target = CORRESPONDING #( BASE ( target ) source ).Field Mapping
" Explicit field mapping
target = CORRESPONDING #( source MAPPING
target_field = source_field
other_field = another_field ).
" EXCEPT - exclude fields
target = CORRESPONDING #( source EXCEPT field1 field2 ).Table Operations
" Map tables
target_tab = CORRESPONDING #( source_tab ).
" With DISCARDING DUPLICATES (for unique keys)
target_sorted = CORRESPONDING #( source_tab DISCARDING DUPLICATES ).DEEP and BASE Options
" DEEP - handle nested structures/tables
target = CORRESPONDING #( DEEP source ).
" DEEP BASE - keep existing nested data
target = CORRESPONDING #( DEEP BASE ( target ) source ).MAPPING FROM ENTITY / TO ENTITY
" RAP-specific mapping
struct = CORRESPONDING #( bdef_type MAPPING FROM ENTITY ).
bdef_type = CORRESPONDING #( struct MAPPING TO ENTITY ).
" USING CONTROL - respect %control flags
target = CORRESPONDING #( source USING CONTROL ).
" CHANGING CONTROL - populate %control
target = CORRESPONDING #( source CHANGING CONTROL ).---
COND Operator
" Simple condition
DATA(text) = COND string( WHEN flag = abap_true THEN 'Yes' ELSE 'No' ).
" Multiple conditions
DATA(grade) = COND string(
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 70 THEN 'C'
WHEN score >= 60 THEN 'D'
ELSE 'F' ).
" With complex expressions
DATA(result) = COND #(
WHEN table IS INITIAL THEN 'Empty'
WHEN lines( table ) = 1 THEN 'Single'
ELSE |{ lines( table ) } items| ).
" With THROW
DATA(value) = COND #(
WHEN valid THEN result
ELSE THROW zcx_validation_error( ) ).
" With LET (local variables)
DATA(msg) = COND #(
LET len = strlen( text ) IN
WHEN len > 100 THEN 'Long'
WHEN len > 50 THEN 'Medium'
ELSE 'Short' ).---
SWITCH Operator
" Value-based switch
DATA(text) = SWITCH string( code
WHEN 'A' THEN 'Active'
WHEN 'I' THEN 'Inactive'
WHEN 'D' THEN 'Deleted'
ELSE 'Unknown' ).
" With type inference
DATA result TYPE string.
result = SWITCH #( status
WHEN 1 THEN 'Open'
WHEN 2 THEN 'Closed'
ELSE 'Unknown' ).
" With THROW
DATA(value) = SWITCH #( code
WHEN 1 THEN 'One'
WHEN 2 THEN 'Two'
ELSE THROW zcx_invalid_code( ) ).---
CAST Operator
" Cast to subclass
DATA(subclass) = CAST zcl_subclass( super_ref ).
" Cast to interface
DATA(intf) = CAST zif_my_interface( oref ).
" For RTTI
DATA(class_desc) = CAST cl_abap_classdescr(
cl_abap_typedescr=>describe_by_object_ref( oref ) ).
" With TRY for safe casting
TRY.
DATA(specific) = CAST zcl_specific( general_ref ).
CATCH cx_sy_move_cast_error.
" Handle cast failure
ENDTRY.---
REF Operator
" Create reference to existing data
DATA text TYPE string VALUE 'Hello'.
DATA(dref) = REF #( text ).
" Inline creation
process( REF #( some_structure ) ).
" With explicit type
DATA(typed_ref) = REF string( text ).---
EXACT Operator
" Lossless conversion (raises exception on loss)
TRY.
DATA(exact_int) = EXACT i( decimal_value ).
CATCH cx_sy_conversion_lost.
" Precision would be lost
ENDTRY.
" With rounding
DATA(rounded) = EXACT decfloat34( value ) ##NEEDED.---
REDUCE Operator
Aggregation
" Sum
DATA(sum) = REDUCE i( INIT s = 0
FOR wa IN itab
NEXT s = s + wa-amount ).
" Concatenation
DATA(concat) = REDUCE string( INIT str = ``
FOR wa IN itab
NEXT str = str && wa-name && `, ` ).
" Maximum
DATA(max) = REDUCE i( INIT m = 0
FOR wa IN itab
NEXT m = COND #( WHEN wa-value > m THEN wa-value ELSE m ) ).
" Count with condition
DATA(count) = REDUCE i( INIT c = 0
FOR wa IN itab WHERE ( active = abap_true )
NEXT c = c + 1 ).Multiple Accumulators
DATA(stats) = REDUCE #(
INIT sum = 0 count = 0
FOR wa IN itab
NEXT sum = sum + wa-amount
count = count + 1 ).
" stats-sum and stats-count availableBuilding Tables
" Filter and transform
DATA(filtered) = REDUCE string_table(
INIT result = VALUE string_table( )
FOR wa IN source WHERE ( status = 'A' )
NEXT result = VALUE #( BASE result ( wa-name ) ) ).---
FILTER Operator
" Filter by condition
DATA(active) = FILTER #( itab WHERE status = 'A' ).
" Using secondary key (more efficient)
DATA(filtered) = FILTER #( itab USING KEY by_status WHERE status = 'A' ).
" EXCEPT - exclude matching
DATA(non_active) = FILTER #( itab EXCEPT WHERE status = 'A' ).
" With filter table (IN)
DATA filter_vals TYPE SORTED TABLE OF string WITH UNIQUE KEY table_line.
filter_vals = VALUE #( ( `A` ) ( `B` ) ).
DATA(matched) = FILTER #( itab IN filter_vals WHERE status = table_line ).
" With EXCEPT and filter table
DATA(not_matched) = FILTER #( itab EXCEPT IN filter_vals WHERE status = table_line ).---
LET Expressions
" Define local variables in expressions
DATA(result) = LET a = 10
b = 20
IN a + b.
" With COND
DATA(category) = COND #(
LET len = strlen( text )
upper = to_upper( text ) IN
WHEN len > 100 AND upper CS 'ERROR' THEN 'Critical'
WHEN len > 50 THEN 'Warning'
ELSE 'Info' ).
" In VALUE
DATA(items) = VALUE itab_type(
LET base_id = 100 IN
( id = base_id + 1 name = 'First' )
( id = base_id + 2 name = 'Second' ) ).---
ALPHA Conversion
" In string templates
" Add leading zeros
DATA(with_zeros) = |{ '1234' ALPHA = IN WIDTH = 10 }|. " 0000001234
" Remove leading zeros
DATA(no_zeros) = |{ '00001234' ALPHA = OUT }|. " 1234---
Best Practices
1. Use VALUE #( ) with type inference when target type is clear 2. Use OPTIONAL/DEFAULT for safe table access 3. Prefer CORRESPONDING over manual field-by-field copy 4. Use REDUCE for functional aggregation 5. Use FILTER for table filtering (with secondary keys when possible) 6. LET expressions improve readability for complex conditions 7. NEW for object creation, REF #( ) for references to existing data
Date and Time Processing - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/23_Date_and_Time.md
Version Note: Theutclongtype and its associated functions (utclong_current(),
utclong_add(),utclong_diff()) require 7.54+. On earlier releases, use
TIMESTAMP/TIMESTAMPLtypes withGET TIME STAMPandcl_abap_tstmpmethods.
Typesdandtand their operations are available in all releases.
---
Core Data Types
Type d (Date)
8-character date in yyyymmdd format.
DATA date TYPE d VALUE '20240101'.
DATA(date2) = CONV d( '20240202' ).
" Character-like access
DATA(year) = substring( val = date off = 0 len = 4 ).
DATA(month) = date+4(2).
DATA(day) = date+6(2).
" Modify components
date+4(2) = '10'. " Change month to OctoberType t (Time)
6-character time in hhmmss format (24-hour clock).
DATA time TYPE t VALUE '123456'.
DATA(hour) = time+0(2). " 12
DATA(minute) = time+2(2). " 34
DATA(second) = time+4(2). " 56Type utclong (UTC Timestamp)
Modern 8-byte UTC timestamp with 100 nanosecond precision. Recommended for ABAP Cloud.
DATA ts TYPE utclong VALUE '2024-01-01 15:30:00'.
DATA(current_ts) = utclong_current( ).Legacy Packed Timestamps
DATA ts_short TYPE timestamp. " yyyymmddhhmmss
DATA ts_long TYPE timestampl. " yyyymmddhhmmss.sssssss
GET TIME STAMP FIELD ts_short.---
Retrieving Current Values
ABAP Cloud Compatible
" Current date (UTC)
DATA(utc_date) = cl_abap_context_info=>get_system_date( ).
" Current time (UTC)
DATA(utc_time) = cl_abap_context_info=>get_system_time( ).
" Current timestamp
DATA(ts) = utclong_current( ).Using XCO Library
" Date with formatting
DATA(xco_date) = xco_cp=>sy->date( )->as( xco_cp_time=>format->iso_8601_extended )->value.
" Time with formatting
DATA(xco_time) = xco_cp=>sy->time( )->as( xco_cp_time=>format->iso_8601_basic )->value.---
Date Calculations
Basic Arithmetic
DATA date1 TYPE d VALUE '20240101'.
DATA date2 TYPE d VALUE '20231227'.
" Difference in days
DATA(days_diff) = date1 - date2. " Result: 5
" Add days
date1 = date1 + 30.XCO Date Operations
" Add to current date
DATA(future_date) = xco_cp=>sy->date( )->add(
iv_day = 5
iv_month = 1
iv_year = 0
)->as( xco_cp_time=>format->iso_8601_extended )->value.
" Subtract from current date
DATA(past_date) = xco_cp=>sy->date( )->subtract(
iv_day = 1
iv_month = 1
iv_year = 1
)->as( xco_cp_time=>format->iso_8601_extended )->value.
" Create specific date
DATA(specific) = xco_cp_time=>date(
iv_year = 2024
iv_month = 3
iv_day = 15
).---
Time Calculations
Basic Arithmetic
DATA time1 TYPE t VALUE '210000'.
DATA time2 TYPE t VALUE '040000'.
" Difference in seconds
DATA(time_diff) = time2 - time1.XCO Time Operations
DATA(time_plus) = xco_cp=>sy->time( )->add(
iv_hour = 1
iv_minute = 30
iv_second = 0
)->as( xco_cp_time=>format->iso_8601_extended )->value.---
UTC Timestamp Operations
Arithmetic with Built-in Functions
DATA ts TYPE utclong VALUE '2024-01-01 15:30:00'.
" Add time components
DATA(ts_add) = utclong_add( val = ts hours = 1 ).
DATA(ts_sub) = utclong_add( val = ts hours = -2 ).
DATA(ts_complex) = utclong_add(
val = ts
days = 1
hours = 2
minutes = 13
seconds = 53.12
).Calculating Differences
" Get difference in seconds (decfloat34)
DATA(diff_seconds) = utclong_diff( high = ts_high low = ts_low ).
" Get structured difference
cl_abap_utclong=>diff(
EXPORTING
high = ts_high
low = ts_low
IMPORTING
days = DATA(d)
hours = DATA(h)
minutes = DATA(m)
seconds = DATA(s)
).XCO Timestamp Operations
DATA(ts_ref) = xco_cp_time=>moment(
iv_year = '2024'
iv_month = '01'
iv_day = '01'
iv_hour = '12'
iv_minute = '00'
iv_second = '00'
).
DATA(ts_add) = ts_ref->add(
iv_day = 1
iv_month = 2
iv_year = 0
)->as( xco_cp_time=>format->iso_8601_extended )->value.
DATA(ts_sub) = ts_ref->subtract(
iv_hour = 1
iv_minute = 30
iv_second = 0
)->as( xco_cp_time=>format->iso_8601_extended )->value.---
Time Zone Handling
Get User Time Zone
TRY.
DATA(tz) = cl_abap_context_info=>get_user_time_zone( ).
CATCH cx_abap_context_info_error.
ENDTRY.
" XCO approach
DATA(tz_user) = xco_cp_time=>time_zone->user->value.
DATA(tz_utc) = xco_cp_time=>time_zone->utc->value.Convert Between UTC and Local
" UTC to local date/time
DATA ts_utc TYPE utclong VALUE '2024-11-03 05:30:00'.
CONVERT UTCLONG ts_utc
INTO DATE DATA(date_local)
TIME DATA(time_local)
TIME ZONE 'EST'.
" Local date/time to UTC
DATA date_local TYPE d VALUE '20240101'.
DATA time_local TYPE t VALUE '112458'.
CONVERT DATE date_local
TIME time_local
TIME ZONE 'EST'
INTO UTCLONG DATA(utc_ts).Packed Timestamp Conversions
" Timestamp to date/time
DATA ts_short TYPE timestamp.
GET TIME STAMP FIELD ts_short.
CONVERT TIME STAMP ts_short TIME ZONE 'EST'
INTO DATE DATA(dat) TIME DATA(tim).
" Date/time to timestamp
DATA ts_conv TYPE timestamp.
CONVERT DATE dat TIME tim
INTO TIME STAMP ts_conv TIME ZONE 'EST'.---
CL_ABAP_TSTMP Class
GET TIME STAMP FIELD DATA(tsa).
" Add seconds
DATA(tsb) = cl_abap_tstmp=>add( tstmp = tsa secs = 3600 ).
" Convert between types
DATA(ts_utclong) = cl_abap_tstmp=>tstmp2utclong( tsa ).
DATA(ts_from_utc) = cl_abap_tstmp=>utclong2tstmp_short( ts_utclong ).---
Unix Timestamps
" Get current Unix timestamp
DATA(unix_ts) = xco_cp=>sy->unix_timestamp( )->value.
" Create from specific moment
DATA(unix_custom) = xco_cp_time=>moment(
iv_year = '2024'
iv_month = '11'
iv_day = '03'
iv_hour = '07'
iv_minute = '12'
iv_second = '30'
)->get_unix_timestamp( )->value.
" Convert Unix timestamp to utclong
DATA(ts_from_unix) = utclong_add(
val = CONV utclong( '1970-01-01 00:00:00' )
seconds = 1730617950
).---
Date/Time in SQL
SELECT SINGLE FROM i_timezone
FIELDS
is_valid( @ti ) AS isvalid,
extract_year( @utc ) AS extr_year,
extract_month( @da ) AS extr_month,
extract_day( @utc ) AS extr_day,
dayname( @da ) AS day_name,
monthname( @utc ) AS month_name,
weekday( @utc ) AS week_day,
days_between( @utc, utclong`2024-02-25 08:14:26` ) AS days_bw,
add_days( @da, 2 ) AS add_days,
add_months( @utc, 3 ) AS add_months,
utcl_current( ) AS utcl_current,
utcl_add_seconds( @utc, 5 ) AS sec_add_utc
WHERE TimeZoneID = 'EST'
INTO @DATA(wa).---
String Templates
" Date formatting
DATA(d_str) = |Date: { cl_abap_context_info=>get_system_date( ) DATE = ISO }|.
" Time formatting
DATA(tm_str) = |Time: { cl_abap_context_info=>get_system_time( ) TIME = ISO }|.
" Timestamp formatting
DATA(ts_str) = |Timestamp: { utclong_current( ) TIMESTAMP = ISO }|.
" With timezone
DATA(tz_str) = |{ utclong_current( ) TIMEZONE = 'EST' COUNTRY = 'US ' }|.---
Format Conversions
Date Format (CL_ABAP_DATFM)
cl_abap_datfm=>conv_date_int_to_ext(
EXPORTING
im_datint = '20240202'
im_datfmdes = '6' " ISO 8601 format
IMPORTING
ex_datext = conv_date_str
).Time Format (CL_ABAP_TIMEFM)
cl_abap_timefm=>conv_time_int_to_ext(
EXPORTING
time_int = '123456'
format_according_to = cl_abap_timefm=>iso
IMPORTING
time_ext = conv_time_str " Result: 12:34:56
).---
Validation
TRY.
DATA(valid_date) = EXACT d( '20240231' ). " Feb 31 - invalid
CATCH cx_sy_conversion_no_date.
" Handle invalid date
ENDTRY.---
ABAP Cloud Restrictions
Avoid these system fields in ABAP Cloud:
sy-datum,sy-uzeitsy-timlo,sy-datlo- Other system-specific temporal fields
Use instead:
cl_abap_context_info=>get_system_date( )cl_abap_context_info=>get_system_time( )utclong_current( )- XCO library methods
Note: In SAP BTP ABAP Environment, time zone defaults to UTC.
---
Best Practices
1. Use utclong for modern timestamp handling 2. Use XCO library for fluent date/time APIs 3. Validate temporal data before calculations 4. Use CONVERT statements for timezone conversions 5. Avoid sy-datum/sy-uzeit in ABAP Cloud 6. Store timestamps in UTC and convert for display
OO Design Patterns - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/34_OO_Design_Patterns.md
---
Factory Method Pattern
Creates objects through a factory method instead of direct instantiation.
Interface Definition
INTERFACE lif_hello.
TYPES enum_langu TYPE i.
CONSTANTS: en TYPE enum_langu VALUE 1,
fr TYPE enum_langu VALUE 2.
METHODS say_hello RETURNING VALUE(hi) TYPE string.
ENDINTERFACE.Concrete Implementations
CLASS lcl_en DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES lif_hello.
ENDCLASS.
CLASS lcl_en IMPLEMENTATION.
METHOD lif_hello~say_hello.
hi = `Hi`.
ENDMETHOD.
ENDCLASS.
CLASS lcl_fr DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES lif_hello.
ENDCLASS.
CLASS lcl_fr IMPLEMENTATION.
METHOD lif_hello~say_hello.
hi = `Bonjour`.
ENDMETHOD.
ENDCLASS.Factory Class
CLASS lcl_hello_factory DEFINITION FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS create_hello
IMPORTING language TYPE lif_hello=>enum_langu
RETURNING VALUE(hello) TYPE REF TO lif_hello.
ENDCLASS.
CLASS lcl_hello_factory IMPLEMENTATION.
METHOD create_hello.
hello = SWITCH #( language
WHEN lif_hello=>en THEN NEW lcl_en( )
WHEN lif_hello=>fr THEN NEW lcl_fr( )
ELSE NEW lcl_en( ) ).
ENDMETHOD.
ENDCLASS.Usage
DATA(oref_en) = lcl_hello_factory=>create_hello( lif_hello=>en ).
DATA(hello_en) = oref_en->say_hello( ). " 'Hi'
DATA(oref_fr) = lcl_hello_factory=>create_hello( lif_hello=>fr ).
DATA(hello_fr) = oref_fr->say_hello( ). " 'Bonjour'---
Singleton Pattern
Ensures only one instance of a class exists.
CLASS zcl_singleton DEFINITION
PUBLIC FINAL CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS get_instance
RETURNING VALUE(ro_instance) TYPE REF TO zcl_singleton.
METHODS do_something.
PRIVATE SECTION.
CLASS-DATA go_instance TYPE REF TO zcl_singleton.
DATA mv_data TYPE string.
ENDCLASS.
CLASS zcl_singleton IMPLEMENTATION.
METHOD get_instance.
IF go_instance IS NOT BOUND.
go_instance = NEW #( ).
ENDIF.
ro_instance = go_instance.
ENDMETHOD.
METHOD do_something.
" Implementation
ENDMETHOD.
ENDCLASS.Usage
DATA(singleton1) = zcl_singleton=>get_instance( ).
DATA(singleton2) = zcl_singleton=>get_instance( ).
" singleton1 and singleton2 reference the same instance---
Strategy Pattern
Encapsulates interchangeable algorithms.
Strategy Interface
INTERFACE lif_sort_strategy.
METHODS sort
CHANGING ct_data TYPE STANDARD TABLE.
ENDINTERFACE.Concrete Strategies
CLASS lcl_bubble_sort DEFINITION.
PUBLIC SECTION.
INTERFACES lif_sort_strategy.
ENDCLASS.
CLASS lcl_bubble_sort IMPLEMENTATION.
METHOD lif_sort_strategy~sort.
" Bubble sort implementation
ENDMETHOD.
ENDCLASS.
CLASS lcl_quick_sort DEFINITION.
PUBLIC SECTION.
INTERFACES lif_sort_strategy.
ENDCLASS.
CLASS lcl_quick_sort IMPLEMENTATION.
METHOD lif_sort_strategy~sort.
" Quick sort implementation
ENDMETHOD.
ENDCLASS.Context Class
CLASS lcl_sorter DEFINITION.
PUBLIC SECTION.
METHODS constructor
IMPORTING io_strategy TYPE REF TO lif_sort_strategy.
METHODS set_strategy
IMPORTING io_strategy TYPE REF TO lif_sort_strategy.
METHODS execute_sort
CHANGING ct_data TYPE STANDARD TABLE.
PRIVATE SECTION.
DATA mo_strategy TYPE REF TO lif_sort_strategy.
ENDCLASS.
CLASS lcl_sorter IMPLEMENTATION.
METHOD constructor.
mo_strategy = io_strategy.
ENDMETHOD.
METHOD set_strategy.
mo_strategy = io_strategy.
ENDMETHOD.
METHOD execute_sort.
mo_strategy->sort( CHANGING ct_data = ct_data ).
ENDMETHOD.
ENDCLASS.Usage
DATA(sorter) = NEW lcl_sorter( NEW lcl_bubble_sort( ) ).
sorter->execute_sort( CHANGING ct_data = my_table ).
" Switch strategy at runtime
sorter->set_strategy( NEW lcl_quick_sort( ) ).
sorter->execute_sort( CHANGING ct_data = my_table ).---
Template Method Pattern
Defines algorithm skeleton, subclasses customize steps.
Abstract Base Class
CLASS lcl_data_processor DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS process FINAL. " Template method
PROTECTED SECTION.
METHODS: load_data ABSTRACT,
validate_data ABSTRACT,
transform_data ABSTRACT,
save_data ABSTRACT.
ENDCLASS.
CLASS lcl_data_processor IMPLEMENTATION.
METHOD process.
" Template method defines the algorithm structure
load_data( ).
validate_data( ).
transform_data( ).
save_data( ).
ENDMETHOD.
ENDCLASS.Concrete Implementation
CLASS lcl_csv_processor DEFINITION
INHERITING FROM lcl_data_processor.
PROTECTED SECTION.
METHODS: load_data REDEFINITION,
validate_data REDEFINITION,
transform_data REDEFINITION,
save_data REDEFINITION.
ENDCLASS.
CLASS lcl_csv_processor IMPLEMENTATION.
METHOD load_data.
" Load CSV-specific data
ENDMETHOD.
METHOD validate_data.
" CSV-specific validation
ENDMETHOD.
METHOD transform_data.
" CSV-specific transformation
ENDMETHOD.
METHOD save_data.
" CSV-specific save
ENDMETHOD.
ENDCLASS.---
Pattern Comparison
| Pattern | Purpose | Key Mechanism |
|---|---|---|
| Factory Method | Object creation abstraction | Factory method returns interface |
| Singleton | Single instance guarantee | Private constructor, static accessor |
| Strategy | Interchangeable algorithms | Runtime strategy selection |
| Template Method | Algorithm skeleton | Abstract methods for steps |
---
Best Practices
1. Factory Method: Use for complex object creation, multiple implementations 2. Singleton: Use sparingly, consider dependency injection 3. Strategy: Prefer over switch/case for behavior selection 4. Template Method: Use for algorithms with variable steps 5. Program to interfaces for flexibility 6. Favor composition over inheritance where appropriate
ABAP Dynamic Programming - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/06_Dynamic_Programming.md
---
Field Symbols
Declaration and Assignment
" Typed field symbol
FIELD-SYMBOLS <fs> TYPE string.
ASSIGN text TO <fs>.
" Generic field symbols
FIELD-SYMBOLS <any> TYPE any.
FIELD-SYMBOLS <data> TYPE data.
FIELD-SYMBOLS <table> TYPE ANY TABLE.
FIELD-SYMBOLS <struct> TYPE any.
" Inline declaration
ASSIGN text TO FIELD-SYMBOL(<inline_fs>).Static Assignment
" Assign data object
FIELD-SYMBOLS <fs> TYPE i.
DATA num TYPE i VALUE 100.
ASSIGN num TO <fs>.
<fs> = 200. " Modifies num
" Assign structure component
FIELD-SYMBOLS <comp> TYPE any.
ASSIGN struc-field TO <comp>.
" Assign internal table line
LOOP AT itab ASSIGNING FIELD-SYMBOL(<line>).
<line>-field = 'modified'.
ENDLOOP.
READ TABLE itab ASSIGNING <line> INDEX 1.Dynamic Assignment
" Dynamic component access
DATA(comp_name) = 'FIELD1'.
ASSIGN struc-(comp_name) TO FIELD-SYMBOL(<dynamic>).
" Fully dynamic
DATA: obj_name TYPE string VALUE 'STRUC',
fld_name TYPE string VALUE 'FIELD1'.
ASSIGN (obj_name)-(fld_name) TO <dynamic>.
" Dynamic table field
LOOP AT itab ASSIGNING <line>.
ASSIGN COMPONENT comp_name OF STRUCTURE <line> TO FIELD-SYMBOL(<value>).
IF sy-subrc = 0.
" Component found
ENDIF.
ENDLOOP.
" By index
ASSIGN COMPONENT 3 OF STRUCTURE struc TO <comp>.Checking Assignment
IF <fs> IS ASSIGNED.
" Field symbol points to data
ENDIF.
IF <fs> IS NOT ASSIGNED.
" Not assigned
ENDIF.
" Unassign
UNASSIGN <fs>.Casting
" Cast to specific type
ASSIGN dref->* TO <fs> CASTING TYPE string.
" Cast with type object
DATA(type) = cl_abap_typedescr=>describe_by_name( 'STRING' ).
ASSIGN dref->* TO <fs> CASTING TYPE HANDLE type.---
Data References
Declaration and Creation
" Typed reference
DATA dref TYPE REF TO string.
" Generic reference
DATA dref TYPE REF TO data.
" REF operator
DATA text TYPE string VALUE 'hello'.
dref = REF #( text ).
" NEW operator
dref = NEW string( 'created' ).
dref = NEW i( 42 ).
" CREATE DATA
CREATE DATA dref TYPE string.
CREATE DATA dref TYPE TABLE OF string.
CREATE DATA dref TYPE zdemo_struc.
" Dynamic type
CREATE DATA dref TYPE (type_name).
CREATE DATA dref TYPE TABLE OF (type_name).Dereferencing
" Direct access
DATA(value) = dref->*.
" Modification
dref->* = 'new value'.
" With field symbol
ASSIGN dref->* TO FIELD-SYMBOL(<fs>).
<fs> = 'modified'.
" Component access (structures)
DATA(comp_value) = dref->*-component.
dref->*-component = 'value'.Checking References
IF dref IS BOUND.
" Reference points to data
ENDIF.
IF dref IS NOT BOUND.
" Reference is initial
ENDIF.
IF dref IS INITIAL.
" Same as NOT BOUND
ENDIF.
" Clear reference
CLEAR dref.
FREE dref.---
RTTI (Run-Time Type Information)
Type Description Classes
" Get type descriptor
DATA(tdo) = cl_abap_typedescr=>describe_by_data( data_object ).
DATA(tdo) = cl_abap_typedescr=>describe_by_name( 'ZDEMO_STRUC' ).
DATA(tdo) = cl_abap_typedescr=>describe_by_data_ref( dref ).
DATA(tdo) = cl_abap_typedescr=>describe_by_object_ref( oref ).
" Type kind
DATA(kind) = tdo->kind.
" C = Class, E = Elementary, S = Structure, T = Table
" Type name
DATA(name) = tdo->get_relative_name( ).
DATA(abs_name) = tdo->absolute_name.Elementary Types (CL_ABAP_ELEMDESCR)
DATA(elem) = CAST cl_abap_elemdescr(
cl_abap_typedescr=>describe_by_data( some_var ) ).
DATA(type_kind) = elem->type_kind. " I, C, N, D, T, STRING, etc.
DATA(length) = elem->length.
DATA(decimals) = elem->decimals.
DATA(output_length) = elem->output_length.Structure Types (CL_ABAP_STRUCTDESCR)
DATA(struct_desc) = CAST cl_abap_structdescr(
cl_abap_typedescr=>describe_by_data( some_struct ) ).
" Get components
DATA(components) = struct_desc->components.
" Returns: name, type_kind, length, decimals, etc.
" Get component names
DATA(comp_names) = struct_desc->get_component_names( ).
" Get component type
DATA(comp_type) = struct_desc->get_component_type( 'FIELD1' ).Table Types (CL_ABAP_TABLEDESCR)
DATA(table_desc) = CAST cl_abap_tabledescr(
cl_abap_typedescr=>describe_by_data( some_itab ) ).
DATA(table_kind) = table_desc->table_kind.
" STANDARD, SORTED, HASHED
DATA(line_type) = table_desc->get_table_line_type( ).
DATA(key_info) = table_desc->get_keys( ).
DATA(key_components) = table_desc->key.Class Types (CL_ABAP_CLASSDESCR)
DATA(class_desc) = CAST cl_abap_classdescr(
cl_abap_typedescr=>describe_by_object_ref( oref ) ).
DATA(class_name) = class_desc->get_relative_name( ).
DATA(methods) = class_desc->methods.
DATA(attributes) = class_desc->attributes.
DATA(interfaces) = class_desc->interfaces.
DATA(superclass) = class_desc->get_super_class_type( ).Interface Types (CL_ABAP_INTFDESCR)
DATA(intf_desc) = CAST cl_abap_intfdescr(
cl_abap_typedescr=>describe_by_name( 'ZIF_MY_INTERFACE' ) ).
DATA(methods) = intf_desc->methods.
DATA(attributes) = intf_desc->attributes.---
RTTC (Run-Time Type Creation)
Create Elementary Types
" Built-in types
DATA(string_type) = cl_abap_elemdescr=>get_string( ).
DATA(int_type) = cl_abap_elemdescr=>get_i( ).
DATA(char_type) = cl_abap_elemdescr=>get_c( p_length = 10 ).
DATA(numc_type) = cl_abap_elemdescr=>get_n( p_length = 8 ).
DATA(packed_type) = cl_abap_elemdescr=>get_p( p_length = 8 p_decimals = 2 ).
" Create data with type handle
CREATE DATA dref TYPE HANDLE string_type.Create Structure Types
" Define components
DATA(components) = VALUE cl_abap_structdescr=>component_table(
( name = 'ID' type = cl_abap_elemdescr=>get_i( ) )
( name = 'NAME' type = cl_abap_elemdescr=>get_string( ) )
( name = 'AMOUNT' type = cl_abap_elemdescr=>get_p( p_length = 8 p_decimals = 2 ) ) ).
" Create structure type
DATA(struct_type) = cl_abap_structdescr=>create( components ).
" Create data
CREATE DATA dref TYPE HANDLE struct_type.
ASSIGN dref->* TO FIELD-SYMBOL(<struct>).
" Access components dynamically
ASSIGN COMPONENT 'NAME' OF STRUCTURE <struct> TO FIELD-SYMBOL(<name>).
<name> = 'Test'.Create Table Types
" From structure type
DATA(table_type) = cl_abap_tabledescr=>create(
p_line_type = struct_type
p_table_kind = cl_abap_tabledescr=>tablekind_std
p_unique = abap_false ).
" With key
DATA(sorted_table) = cl_abap_tabledescr=>create(
p_line_type = struct_type
p_table_kind = cl_abap_tabledescr=>tablekind_sorted
p_unique = abap_true
p_key = VALUE #( ( name = 'ID' ) ) ).
" Create table data
CREATE DATA dref TYPE HANDLE table_type.
ASSIGN dref->* TO FIELD-SYMBOL(<table>).---
Dynamic SQL
" Dynamic table name
DATA table_name TYPE string VALUE 'ZDEMO_TABLE'.
SELECT * FROM (table_name) INTO TABLE @DATA(result).
" Dynamic field list
DATA field_list TYPE string VALUE 'CARRID, CONNID, FLDATE'.
SELECT (field_list) FROM zdemo_fli INTO TABLE @DATA(fields).
" Dynamic WHERE clause
DATA where_clause TYPE string VALUE `CARRID = 'LH'`.
SELECT * FROM zdemo_fli WHERE (where_clause) INTO TABLE @DATA(filtered).
" Dynamic ORDER BY
DATA order_by TYPE string VALUE 'FLDATE DESCENDING'.
SELECT * FROM zdemo_fli ORDER BY (order_by) INTO TABLE @DATA(sorted).
" Fully dynamic
SELECT (field_list)
FROM (table_name)
WHERE (where_clause)
ORDER BY (order_by)
INTO TABLE @DATA(dynamic_result).---
Dynamic Method Calls
" Dynamic method name
DATA method_name TYPE string VALUE 'PROCESS'.
CALL METHOD oref->(method_name).
" With parameters
DATA(ptab) = VALUE abap_parmbind_tab(
( name = 'IV_INPUT' kind = cl_abap_objectdescr=>exporting value = REF #( input ) )
( name = 'RV_RESULT' kind = cl_abap_objectdescr=>returning value = REF #( result ) ) ).
CALL METHOD oref->(method_name) PARAMETER-TABLE ptab.
" Dynamic class instantiation
DATA class_name TYPE string VALUE 'ZCL_MY_CLASS'.
CREATE OBJECT oref TYPE (class_name).
" With constructor parameters
DATA(ctab) = VALUE abap_parmbind_tab(
( name = 'IV_PARAM' kind = cl_abap_objectdescr=>exporting value = REF #( param ) ) ).
CREATE OBJECT oref TYPE (class_name) PARAMETER-TABLE ctab.---
Dynamic Function Calls
DATA func_name TYPE string VALUE 'Z_MY_FUNCTION'.
DATA(ptab) = VALUE abap_func_parmbind_tab(
( name = 'IV_INPUT' kind = abap_func_exporting value = REF #( input ) )
( name = 'EV_OUTPUT' kind = abap_func_importing value = REF #( output ) )
( name = 'CT_TABLE' kind = abap_func_tables value = REF #( table ) ) ).
DATA(etab) = VALUE abap_func_excpbind_tab(
( name = 'NOT_FOUND' value = 1 )
( name = 'OTHERS' value = 99 ) ).
CALL FUNCTION func_name
PARAMETER-TABLE ptab
EXCEPTION-TABLE etab.
IF sy-subrc <> 0.
" Handle exception
ENDIF.---
Generic Types Reference
| Type | Description |
|---|---|
any | Any data type |
data | Any non-generic data type |
any table | Any internal table |
standard table | Standard table |
sorted table | Sorted table |
hashed table | Hashed table |
index table | Standard or sorted table |
clike | Character-like types |
csequence | Character sequence (c, string) |
numeric | Numeric types |
xsequence | Byte sequence (x, xstring) |
simple | Elementary non-deep types |
decfloat | Decimal floating point |
---
Best Practices
1. Check assignments before using field symbols 2. Check references before dereferencing 3. Use RTTI for type inspection 4. Use RTTC for dynamic type creation 5. Handle sy-subrc after dynamic operations 6. Validate dynamic names to prevent injection 7. Prefer static typing when possible for performance 8. Document dynamic code thoroughly
ABAP Exception Handling - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/27_Exceptions.md
---
Exception Class Hierarchy
All exception classes inherit from one of three abstract superclasses, all derived from CX_ROOT:
CX_STATIC_CHECK
- Must be handled locally or declared in procedure interface
- Compile-time static checks enforce handling
- Example:
CX_UUID_ERROR
" Declaration in method signature
METHODS get_uuid
RETURNING VALUE(uuid) TYPE sysuuid_x16
RAISING cx_uuid_error.
" Calling code must handle
TRY.
DATA(uuid) = get_uuid( ).
CATCH cx_uuid_error.
" Handle exception
ENDTRY.CX_DYNAMIC_CHECK
- For exceptions preventable through preconditions
- No compile-time enforcement
- Runtime checks only when exception is raised
- Example:
CX_SY_ZERODIVIDE
" Declaration (optional but recommended)
METHODS divide
IMPORTING num1 TYPE i num2 TYPE i
RETURNING VALUE(result) TYPE decfloat34
RAISING cx_sy_zerodivide.CX_NO_CHECK
- For errors that can occur anytime
- Always implicitly declared in all interfaces
- Cannot be prevented by checks
- Example: Memory shortage
---
Exception Class Components
Inherited Methods (from CX_ROOT)
" Get exception text
DATA(text) = exception->get_text( ).
" Get source position
exception->get_source_position(
IMPORTING
program_name = DATA(program)
include_name = DATA(include)
source_line = DATA(line) ).Common Attributes
textid: Key for exception text in T100 tableprevious: Reference to previous exception (chaining)is_resumable: Flag for resumable exceptions
---
TRY-CATCH Structure
Basic Syntax
TRY.
" Risky code
DATA(result) = 1 / 0.
CATCH cx_sy_zerodivide.
" Handle division by zero
ENDTRY.Multiple Exception Types
TRY.
" Code that might raise various exceptions
CATCH cx_sy_zerodivide cx_sy_arithmetic_overflow.
" Handle arithmetic errors
CATCH cx_sy_conversion_error.
" Handle conversion errors
CATCH cx_root.
" Handle any exception
ENDTRY.CATCH INTO (Get Exception Object)
TRY.
DATA(line) = itab[ 999 ].
CATCH cx_sy_itab_line_not_found INTO DATA(exc).
DATA(msg) = exc->get_text( ).
exc->get_source_position(
IMPORTING
program_name = DATA(prog)
source_line = DATA(line_no) ).
ENDTRY.Exception Hierarchy
" Use parent class to catch multiple child exceptions
TRY.
DATA(result) = 1 / 0.
CATCH cx_sy_arithmetic_error.
" Catches both CX_SY_ZERODIVIDE and CX_SY_ARITHMETIC_OVERFLOW
ENDTRY.---
Raising Exceptions
RAISE EXCEPTION TYPE
RAISE EXCEPTION TYPE cx_sy_zerodivide.With Exception Object
DATA(exc) = NEW cx_sy_zerodivide( ).
RAISE EXCEPTION exc.
" Inline
RAISE EXCEPTION NEW cx_sy_zerodivide( ).With Parameters
RAISE EXCEPTION TYPE zcx_my_error
EXPORTING
textid = zcx_my_error=>specific_error
param1 = 'value1'
param2 = 'value2'.In COND/SWITCH
DATA(result) = COND string(
WHEN valid THEN process( )
ELSE THROW zcx_validation_error( ) ).
DATA(value) = SWITCH #( code
WHEN 1 THEN 'A'
WHEN 2 THEN 'B'
ELSE THROW zcx_invalid_code( ) ).---
CLEANUP Block
Executes when exception raised but handled externally:
TRY.
TRY.
" Inner TRY
process_data( ).
CATCH cx_sy_zerodivide.
" Handle locally
CLEANUP.
" Cleanup when exception propagates out
cleanup_resources( ).
ENDTRY.
CATCH cx_sy_itab_line_not_found.
" Handle external exception
ENDTRY.CLEANUP INTO
CLEANUP INTO DATA(cleanup_exc).
DATA(exc_class) = cl_abap_classdescr=>get_class_name( cleanup_exc ).
" Perform cleanup based on exception type---
RETRY Statement
Exits CATCH block and restarts TRY block:
DATA retry_count TYPE i.
TRY.
result = risky_operation( ).
CATCH cx_sy_zerodivide.
retry_count += 1.
IF retry_count < 3.
RETRY. " Restart TRY block
ENDIF.
ENDTRY.---
Resumable Exceptions
Declaration
METHODS process
RAISING RESUMABLE(zcx_my_resumable_error).Raising Resumable
METHOD process.
IF error_condition.
RAISE RESUMABLE EXCEPTION TYPE zcx_my_resumable_error.
" Execution continues here if RESUME called
result = fallback_value.
ENDIF.
ENDMETHOD.CATCH BEFORE UNWIND
TRY.
process( ).
CATCH BEFORE UNWIND zcx_my_resumable_error INTO DATA(exc).
IF exc->is_resumable = abap_true.
log_warning( exc->get_text( ) ).
RESUME. " Continue after RAISE statement
ENDIF.
ENDTRY.In COND/SWITCH
DATA(value) = COND #(
WHEN condition THEN result
ELSE THROW RESUMABLE zcx_my_error( ) ).---
Exception Chaining (PREVIOUS)
TRY.
TRY.
RAISE EXCEPTION TYPE cx_sy_zerodivide.
CATCH cx_sy_zerodivide INTO DATA(inner).
RAISE EXCEPTION TYPE cx_sy_arithmetic_overflow
EXPORTING previous = inner.
ENDTRY.
CATCH cx_sy_arithmetic_overflow INTO DATA(outer).
" Access chain
DATA(current) = CAST cx_root( outer ).
WHILE current IS BOUND.
out->write( current->get_text( ) ).
current = current->previous.
ENDWHILE.
ENDTRY.---
Using Messages as Exception Texts
IF_T100_MESSAGE Interface
" Exception class with T100 messages
CLASS zcx_my_error DEFINITION INHERITING FROM cx_static_check.
PUBLIC SECTION.
INTERFACES if_t100_message.
CONSTANTS:
BEGIN OF error_001,
msgid TYPE symsgid VALUE 'ZMSG',
msgno TYPE symsgno VALUE '001',
attr1 TYPE scx_attrname VALUE '',
attr2 TYPE scx_attrname VALUE '',
attr3 TYPE scx_attrname VALUE '',
attr4 TYPE scx_attrname VALUE '',
END OF error_001.
ENDCLASS.IF_T100_DYN_MSG Interface (Recommended)
[7.50+]IF_T100_DYN_MSGand theMESSAGEaddition toRAISE EXCEPTION/THROW
require ABAP 7.50 or higher. On 7.40, useIF_T100_MESSAGEwith explicittextidinstead.
" With MESSAGE addition
RAISE EXCEPTION TYPE zcx_error
MESSAGE e002(zmsg).
" With placeholder values
RAISE EXCEPTION TYPE zcx_error
MESSAGE e003(zmsg) WITH 'value1' 'value2'.
" MESSAGE ID TYPE NUMBER WITH
RAISE EXCEPTION TYPE zcx_error
MESSAGE ID 'ZMSG' TYPE 'E' NUMBER '004'
WITH value1 value2.
" USING MESSAGE (from sy-msg* fields)
MESSAGE e005(zmsg) WITH 'param' INTO DATA(msg).
RAISE EXCEPTION TYPE zcx_error USING MESSAGE.In COND/SWITCH
DATA(result) = COND #(
WHEN valid THEN value
ELSE THROW zcx_error( MESSAGE e001(zmsg) ) ).
DATA(result) = SWITCH #( code
WHEN 1 THEN 'A'
ELSE THROW zcx_error(
MESSAGE ID 'ZMSG' TYPE 'E' NUMBER '002'
WITH code ) ).---
Runtime Errors
RAISE SHORTDUMP
" Force runtime error
RAISE SHORTDUMP TYPE cx_sy_zerodivide.In COND/SWITCH
DATA(result) = COND #(
WHEN valid THEN value
ELSE THROW SHORTDUMP zcx_critical_error( ) ).---
Assertions
" Assert condition - fails = runtime error ASSERTION_FAILED
ASSERT count > 0.
ASSERT table IS NOT INITIAL.
ASSERT ref IS BOUND.---
Common Exception Classes
| Exception | Cause | Prevention |
|---|---|---|
CX_SY_ZERODIVIDE | Division by zero | Check divisor |
CX_SY_ARITHMETIC_OVERFLOW | Numeric overflow | Use larger type |
CX_SY_ITAB_LINE_NOT_FOUND | Table line not found | Use OPTIONAL/DEFAULT |
CX_SY_RANGE_OUT_OF_BOUNDS | Invalid index/offset | Validate bounds |
CX_SY_CONVERSION_NO_NUMBER | Invalid number string | Validate input |
CX_SY_REF_IS_INITIAL | Dereference initial ref | Check IS BOUND |
CX_SY_CONVERSION_CODEPAGE | Character encoding error | Check encoding |
CX_SY_DYN_CALL_ILLEGAL_TYPE | Wrong parameter type | Check types |
CX_SY_MOVE_CAST_ERROR | Invalid CAST | Check type compatibility |
CX_UUID_ERROR | UUID generation failed | Handle appropriately |
---
RAP Messages (%msg)
" In RAP handler methods
reported-root = VALUE #( (
%tky = entity-%tky
%msg = new_message_with_text(
severity = if_abap_behv_message=>severity-error
text = 'Validation failed!' ) ) ).
" Severity levels
" if_abap_behv_message=>severity-error
" if_abap_behv_message=>severity-warning
" if_abap_behv_message=>severity-information
" if_abap_behv_message=>severity-success---
Best Practices
1. Choose appropriate exception category
CX_STATIC_CHECK: Must be handled explicitlyCX_DYNAMIC_CHECK: Preventable errorsCX_NO_CHECK: System errors
2. Use specific exception classes rather than CX_ROOT
3. Include meaningful information in exception text
4. Use PREVIOUS for exception chaining
5. Custom attributes should be READ-ONLY
6. Document exceptions in method signatures
7. Handle exceptions at appropriate level - not too early, not too late
Generative AI in ABAP - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/30_Generative_AI.md
Version Note: The ABAP AI SDK requires ABAP Cloud (SAP BTP ABAP Environment or
S/4HANA Cloud). Not available on 7.40 on-premise systems. FINAL(...) in examplesrequires 7.50+ — replace with DATA(...) on earlier releases.---
Overview
The ABAP AI SDK enables integration of large language models into ABAP applications through the Intelligent Scenario Lifecycle Management (ISLM) framework.
Prerequisites
- Administrative setup via ISLM documentation
- Creation of intelligent scenarios (ABAP repository objects)
- Definition of LLM and prompt templates
---
Basic Usage
Simple Execution
TRY.
FINAL(ai_api) = cl_aic_islm_compl_api_factory=>get(
)->create_instance( 'ZDEMO_ABAP_INT_SCEN' ).
FINAL(result) = ai_api->execute_for_string( `Tell me a joke.` ).
FINAL(completion) = result->get_completion( ).
CATCH cx_aic_api_factory cx_aic_completion_api INTO FINAL(error).
FINAL(error_text) = error->get_text( ).
ENDTRY.---
Parameter Configuration
FINAL(params) = ai_api->get_parameter_setter( ).
params->set_maximum_tokens( 500 ).
params->set_temperature( '0.5' ).---
Message-Based Prompting
FINAL(message_container) = ai_api->create_message_container( ).
" Set system role
message_container->set_system_role( `You are a professional translator` ).
" Add user message
message_container->add_user_message( `Can you translate German into English?` ).
" Execute with messages
FINAL(llm_answer) = ai_api->execute_for_messages( message_container
)->get_completion( ).---
Prompt Templates
FINAL(prompt_temp) = cl_aic_islm_prompt_tpl_factory=>get(
)->create_instance(
islm_scenario = islm_scenario
template_id = prompt_template ).
FINAL(prompt) = prompt_temp->get_prompt( ).---
Result Analytics
FINAL(llm_result) = ai_api->execute_for_string( prompt ).
" Token usage
FINAL(completion_tokens) = llm_result->get_completion_token_count( ).
FINAL(prompt_tokens) = llm_result->get_prompt_token_count( ).
" Runtime
FINAL(runtime_ms) = llm_result->get_runtime_ms( ).
" Get completion text
FINAL(completion) = llm_result->get_completion( ).---
Exception Handling
TRY.
" AI operations
CATCH cx_aic_api_factory INTO DATA(factory_error).
" Factory creation error
CATCH cx_aic_completion_api INTO DATA(completion_error).
" API execution error
CATCH cx_aic_prompt_template INTO DATA(template_error).
" Prompt template error
ENDTRY.---
Complete Example
CLASS zcl_ai_demo DEFINITION
PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_ai_demo IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
TRY.
" Create AI API instance
DATA(ai_api) = cl_aic_islm_compl_api_factory=>get(
)->create_instance( 'ZDEMO_AI_SCENARIO' ).
" Configure parameters
DATA(params) = ai_api->get_parameter_setter( ).
params->set_maximum_tokens( 1000 ).
params->set_temperature( '0.7' ).
" Create message container
DATA(messages) = ai_api->create_message_container( ).
messages->set_system_role( `You are a helpful assistant.` ).
messages->add_user_message( `Explain ABAP in one paragraph.` ).
" Execute and get result
DATA(result) = ai_api->execute_for_messages( messages ).
" Output results
out->write( result->get_completion( ) ).
out->write( |Tokens used: { result->get_completion_token_count( ) }| ).
out->write( |Runtime: { result->get_runtime_ms( ) }ms| ).
CATCH cx_aic_api_factory
cx_aic_completion_api INTO DATA(error).
out->write( |Error: { error->get_text( ) }| ).
ENDTRY.
ENDMETHOD.
ENDCLASS.---
Key Classes
| Class | Purpose |
|---|---|
CL_AIC_ISLM_COMPL_API_FACTORY | Factory for AI API instances |
CL_AIC_ISLM_PROMPT_TPL_FACTORY | Factory for prompt templates |
CX_AIC_API_FACTORY | Factory exception |
CX_AIC_COMPLETION_API | API execution exception |
CX_AIC_PROMPT_TEMPLATE | Template exception |
---
Documentation Links
- SAP Help: Joule for Developers, ABAP AI Capabilities
- SAP Help: Generative AI in ABAP Cloud
- GitHub: RAP120 - Build SAP Fiori Apps with ABAP Cloud and Joule
Numeric Operations - Complete Reference
Source: https://github.com/SAP-samples/abap-cheat-sheets/blob/main/29_Numeric_Operations.md
Version Note: Theint8type requires 7.50+.utclong_add()requires 7.54+.
Use typeiorpfor large integers on 7.40. All other numeric operations are
available from 7.40+.
---
Numeric Types
| Type | Description | Range |
|---|---|---|
i | 4-byte integer | -2,147,483,648 to 2,147,483,647 |
int8 | 8-byte integer | Extended range |
p | Packed decimal | 1-16 bytes, up to 14 decimals |
f | Binary floating point | 17 decimal places |
decfloat16 | Decimal floating point | 16 decimal places |
decfloat34 | Decimal floating point | 34 decimal places |
---
Arithmetic Operators
" Basic operators
result = a + b. " Addition
result = a - b. " Subtraction
result = a * b. " Multiplication
result = a / b. " Division
" Special operators
result = a DIV b. " Integer division (positive remainder)
result = a MOD b. " Modulo (positive remainder)
result = a ** b. " Exponentiation
" Calculation assignments
a += b. " a = a + b
a -= b. " a = a - b
a *= b. " a = a * b
a /= b. " a = a / b---
Numeric Functions
Rounding and Truncation
DATA(abs_val) = abs( -5 ). " 5
DATA(sign_val) = sign( -5 ). " -1
DATA(ceil_val) = ceil( '1.2' ). " 2
DATA(floor_val) = floor( '1.8' ). " 1
DATA(trunc_val) = trunc( '1.8' ). " 1
DATA(frac_val) = frac( '1.8' ). " 0.8
DATA(round_val) = round( val = '1.567' dec = 2 ). " 1.57Exponential and Logarithmic
DATA(sqrt_val) = sqrt( 16 ). " 4.0
DATA(ipow_val) = ipow( base = 2 exp = 10 ). " 1024
DATA(exp_val) = exp( 1 ). " e
DATA(log_val) = log( 10 ). " natural log
DATA(log10_val) = log10( 100 ). " 2.0Trigonometric
DATA(sin_val) = sin( '0.5' ).
DATA(cos_val) = cos( '0.5' ).
DATA(tan_val) = tan( '0.5' ).
DATA(asin_val) = asin( '0.5' ).
DATA(acos_val) = acos( '0.5' ).
DATA(atan_val) = atan( '0.5' ).Extremum
DATA(min_val) = nmin( val1 = 5 val2 = 3 val3 = 7 ). " 3
DATA(max_val) = nmax( val1 = 5 val2 = 3 val3 = 7 ). " 7---
Calculation Type Rules
Priority order (highest to lowest): 1. decfloat34 → result decfloat34 2. decfloat16 → result decfloat16 3. f → result f 4. p → result p (length 8, decimals 0) 5. int8 → result int8 6. Otherwise → i
---
Lossless Operations (EXACT)
TRY.
DATA(exact_int) = EXACT i( decimal_value ).
CATCH cx_sy_conversion_rounding.
" Precision would be lost
ENDTRY.---
Advanced Numeric Classes
CL_ABAP_BIGINT (Arbitrary Precision)
DATA(bigint1) = cl_abap_bigint=>factory_from_int8( 123456789 ).
DATA(bigint2) = cl_abap_bigint=>factory_from_int8( 987654321 ).
DATA(sum) = bigint1->add( bigint2 ).
DATA(product) = bigint1->mul( bigint2 ).
DATA(quotient) = bigint1->div( bigint2 ).
DATA(power) = bigint1->pow( 10 ).
DATA(sqrt) = bigint1->sqrt( ).
DATA(gcd) = bigint1->gcd( bigint2 ).CL_ABAP_RATIONAL (Exact Fractions)
DATA(rational) = cl_abap_rational=>factory_from_string( '1/3' ).
DATA(decimal) = rational->get_as_decfloat34( ).CL_ABAP_MATH (Constants)
DATA(pi) = cl_abap_math=>pi.
DATA(e) = cl_abap_math=>e.
DATA(max_int4) = cl_abap_math=>max_int4.
DATA(min_int4) = cl_abap_math=>min_int4.Random Numbers
" Random integer
DATA(random) = cl_abap_random_int=>create(
seed = CONV i( sy-uzeit )
min = 1
max = 100 ).
DATA(number) = random->get_next( ).
" Random float
DATA(random_f) = cl_abap_random_float=>create( seed = 42 ).
DATA(float_num) = random_f->get_next( ).---
Date/Time Calculations
Date Arithmetic
" Days between dates
DATA(days) = date2 - date1.
" Add days (XCO)
DATA(tomorrow) = xco_cp=>sy->date( )->add( iv_day = 1 )->value.
DATA(next_month) = xco_cp=>sy->date( )->add( iv_month = 1 )->value.Time Arithmetic
" Seconds between times
DATA(seconds) = time2 - time1.
" Extract components
DATA(hours) = seconds DIV 3600.
DATA(minutes) = ( seconds MOD 3600 ) DIV 60.
DATA(secs) = seconds MOD 60.Timestamp Operations
" Add to timestamp
DATA(new_ts) = utclong_add(
val = timestamp
days = 1
hours = 2 ).
" CL_ABAP_TSTMP
DATA(ts) = cl_abap_tstmp=>add(
tstmp = timestamp
secs = 3600 ).---
ABAP SQL Numeric Functions
SELECT
div( amount, 100 ) AS int_div,
division( amount, 3, 2 ) AS precise_div,
ceil( value ) AS ceiling,
floor( value ) AS floored,
mod( number, 10 ) AS remainder,
abs( value ) AS absolute,
round( price, 2 ) AS rounded
FROM table
INTO TABLE @result.Related skills
FAQ
Which SAP systems does sap-abap target?
sap-abap from secondsky/sap-skills targets SAP ERP and S/4HANA landscapes. The skill covers ABAP reports, classes, CDS views, RFC calls, BAPI integrations, and custom business logic on SAP application servers.
What ABAP artifacts can sap-abap help create?
sap-abap assists with ABAP reports, object-oriented classes, Core Data Services views, and RFC or BAPI integration code. Developers use it when extending standard SAP processes or building custom backend logic inside enterprise transports.