Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Comprehensive ABAP development skill for SAP systems. Use when writing ABAP code, working with internal tables, structures, ABAP SQL, object-oriented programming, RAP (RESTful Application Programming Model), CDS views, EML statements, ABAP Cloud development, string processing, dynamic programming, RTTI/RTTC, field symbols, data references, exception handling, or ABAP unit testing. Covers both classic ABAP and modern ABAP for Cloud Development patterns.
.claude/skills/secondsky-sap-abap/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 220% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 305% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 501% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 436% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 391% | 0% |
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.
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.
abap" 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.
abap" 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" 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.
abap" 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 ).
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.
abapTRY. 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( ) ).
abap" 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.
abap" 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.
This skill includes 28 comprehensive reference files covering all aspects of ABAP development:
references/skill-reference-guide.md - Complete guide to all reference filesreferences/internal-tables.md - Complete table operationsreferences/abap-sql.md - Comprehensive SQL referencereferences/object-orientation.md - Classes and interfacesreferences/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 techniquesabap" 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.
abapDATA(result) = NEW zcl_builder( ) ->set_name( `Test` ) ->set_value( 123 ) ->build( ).
abap" 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" 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...TO
When targeting ABAP 7.40 systems, replace 7.50+ syntax with these patterns:
abap" 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
Cause: Table expression access to non-existent line Solution: Use OPTIONAL, DEFAULT, or check with line_exists( )
Cause: Division by zero Solution: Check divisor before operation
Cause: Invalid substring access or array bounds Solution: Validate offset and length before access
Cause: String cannot be converted to number Solution: Validate input format before conversion
Cause: Dereferencing unbound reference Solution: Check IS BOUND before dereferencing
All content based on SAP official ABAP Cheat Sheets:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 6,405 | 4,457 | -30% | 1 | 1 | 0% | 1,131 | 5,558 | +391% | 0 | 0 | — |
case-02 | fail→pass | 10,892 | 6,697 | -39% | 1 | 1 | 0% | 1,904 | 6,099 | +220% | 0 | 0 | — |
case-03 | pass→pass | 10,082 | 6,728 | -33% | 1 | 1 | 0% | 1,979 | 6,086 | +208% | 0 | 0 | — |
case-04 | pass→pass | 11,776 | 7,836 | -33% | 1 | 1 | 0% | 2,293 | 6,361 | +177% | 0 | 0 | — |
case-05 | fail→pass | 8,246 | 8,562 | +4% | 1 | 1 | 0% | 1,603 | 6,498 | +305% | 0 | 0 | — |
case-06 | pass→pass | 4,166 | 3,854 | -7% | 1 | 1 | 0% | 723 | 5,405 | +648% | 0 | 0 | — |
case-07 | pass→pass | 5,304 | 4,564 | -14% | 1 | 1 | 0% | 1,006 | 5,612 | +458% | 0 | 0 | — |
case-08 | pass→pass | 4,371 | 3,078 | -30% | 1 | 1 | 0% | 637 | 5,328 | +736% | 0 | 0 | — |
case-09 | pass→pass | 4,682 | 4,936 | +5% | 1 | 1 | 0% | 795 | 5,313 | +568% | 0 | 0 | — |
case-10 | pass→pass | 5,601 | 4,954 | -12% | 1 | 1 | 0% | 915 | 5,763 | +530% | 0 | 0 | — |
case-11 | pass→pass | 3,867 | 4,421 | +14% | 1 | 1 | 0% | 720 | 5,544 | +670% | 0 | 0 | — |
case-12 | pass→pass | 6,470 | 4,756 | -26% | 1 | 1 | 0% | 1,125 | 5,681 | +405% | 0 | 0 | — |
case-13 | pass→pass | 5,482 | 3,891 | -29% | 1 | 1 | 0% | 911 | 5,450 | +498% | 0 | 0 | — |
case-14 | fail→pass | 4,964 | 3,389 | -32% | 1 | 1 | 0% | 881 | 5,298 | +501% | 0 | 0 | — |
case-15 | pass→pass | 5,415 | 3,288 | -39% | 1 | 1 | 0% | 859 | 5,200 | +505% | 0 | 0 | — |
case-16 | fail→pass | 5,352 | 3,511 | -34% | 1 | 1 | 0% | 1,013 | 5,427 | +436% | 0 | 0 | — |
case-17 | pass→pass | 4,606 | 4,664 | +1% | 1 | 1 | 0% | 842 | 5,562 | +561% | 0 | 0 | — |
case-18 | pass→pass | 6,523 | 5,963 | -9% | 1 | 1 | 0% | 1,324 | 5,788 | +337% | 0 | 0 | — |
case-19 | pass→pass | 8,856 | 4,938 | -44% | 1 | 1 | 0% | 1,751 | 5,739 | +228% | 0 | 0 | — |
case-20 | fail→fail | 11,883 | 10,542 | -11% | 1 | 1 | 0% | 2,371 | 7,096 | +199% | 0 | 0 | — |
case-21 | fail→fail | 15,018 | 10,054 | -33% | 1 | 1 | 0% | 2,472 | 6,529 | +164% | 0 | 0 | — |
case-22 | fail→fail | 13,539 | 12,054 | -11% | 1 | 1 | 0% | 2,358 | 7,180 | +204% | 0 | 0 | — |
case-23 | fail→fail | 15,830 | 16,160 | +2% | 1 | 1 | 0% | 3,124 | 7,964 | +155% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +17 percentage points is the difference between those two pass rates over the 23 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.