10 häufigste ABAP Cloud Fehler und wie du sie vermeidest (2025)

kategorie
Best Practices
Veröffentlicht
autor
Johannes

Der Umstieg von Classic ABAP auf ABAP Cloud bringt viele Herausforderungen mit sich. Neue Regeln, eingeschränkte APIs und moderne Syntax können selbst erfahrene ABAP-Entwickler ins Stolpern bringen.

In diesem Artikel zeigen wir die 10 häufigsten Fehler, die ABAP Cloud Entwickler machen - mit praktischen Lösungen und Code-Beispielen, damit du diese Fallstricke von Anfang an vermeidest.


1. ❌ Verwendung von nicht-released APIs und Objekten

Das Problem

In ABAP Cloud darfst du nur Released APIs verwenden. Der Zugriff auf interne SAP-Tabellen, Funktionsbausteine oder Klassen ohne Released-Status führt zu Syntaxfehlern.

Typischer Fehler

" ❌ FALSCH: Direkter Zugriff auf SAP-Tabelle
SELECT * FROM mara
INTO TABLE @DATA(lt_materials).

Fehler: MARA is not released for ABAP Cloud

✅ Lösung

Verwende CDS Views mit Released Status oder Released APIs:

" ✅ RICHTIG: Released CDS View verwenden
SELECT * FROM I_Product
INTO TABLE @DATA(lt_products).
" Oder: Released API verwenden
DATA(lo_api) = cl_some_released_api=>get_instance( ).
DATA(lt_materials) = lo_api->get_materials( ).

💡 So findest du Released APIs

  1. ABAP Development Tools (ADT): Verwende Ctrl+Shift+A → Suche nach Objekten → Filter “API State: Released”
  2. SAP API Business Hub: api.sap.com
  3. Released Objects Browser: Transaktion SOTS_REGISTRY (in kompatiblen Systemen)

Tipp: In ADT zeigen Released Objekte einen grünen Haken in der Objektliste.


2. ❌ SELECT * statt expliziter Feldliste

Das Problem

SELECT * ist in ABAP Cloud nicht erlaubt. Du musst immer explizit angeben, welche Felder du lesen willst.

Typischer Fehler

" ❌ FALSCH
SELECT * FROM I_Customer
INTO TABLE @DATA(lt_customers).

Fehler: SELECT * is not allowed in ABAP Cloud

✅ Lösung

Gib alle Felder explizit an:

" ✅ RICHTIG: Explizite Feldliste
SELECT CustomerID, CustomerName, Country
FROM I_Customer
INTO TABLE @DATA(lt_customers).
" Oder: FIELDS wenn du viele Felder brauchst
SELECT CustomerID,
CustomerName,
Country,
City,
PostalCode
FROM I_Customer
INTO TABLE @DATA(lt_customers).

💡 Warum?

  • Performance: Nur benötigte Daten werden übertragen
  • Wartbarkeit: Explizite Feldlisten sind besser lesbar
  • Stabilität: Änderungen an der Tabelle brechen deinen Code nicht

3. ❌ FORM/PERFORM statt Methoden verwenden

Das Problem

Subroutinen mit FORM und PERFORM sind in ABAP Cloud verboten. Du musst objektorientiert mit Klassen und Methoden arbeiten.

Typischer Fehler

" ❌ FALSCH: Subroutinen
FORM calculate_total USING pv_amount TYPE p
CHANGING pv_total TYPE p.
pv_total = pv_amount * '1.19'.
ENDFORM.
PERFORM calculate_total USING lv_amount
CHANGING lv_total.

Fehler: FORM/PERFORM is not allowed in ABAP Cloud

✅ Lösung

Verwende Klassen mit Methoden:

" ✅ RICHTIG: Klasse mit Methode
CLASS lcl_calculator DEFINITION.
PUBLIC SECTION.
CLASS-METHODS calculate_total
IMPORTING iv_amount TYPE p
RETURNING VALUE(rv_total) TYPE p.
ENDCLASS.
CLASS lcl_calculator IMPLEMENTATION.
METHOD calculate_total.
rv_total = iv_amount * '1.19'.
ENDMETHOD.
ENDCLASS.
" Verwendung
DATA(lv_total) = lcl_calculator=>calculate_total( lv_amount ).

💡 Best Practice

  • Verwende lokale Klassen (lcl_) für interne Logik
  • Verwende globale Klassen (zcl_, ycl_) für wiederverwendbare Komponenten
  • Nutze statische Methoden für Utility-Funktionen

4. ❌ Fehlende Exception Behandlung bei Table Expressions

Das Problem

Table Expressions wie lt_table[ key = value ] werfen eine Exception, wenn der Eintrag nicht gefunden wird. Ohne TRY-CATCH führt das zu einem Shortdump.

Typischer Fehler

" ❌ FALSCH: Keine Exception Behandlung
DATA(ls_customer) = lt_customers[ customer_id = lv_id ].
" Wenn nicht gefunden: CX_SY_ITAB_LINE_NOT_FOUND → Shortdump!

✅ Lösung 1: TRY-CATCH

" ✅ RICHTIG: Mit Exception Handling
TRY.
DATA(ls_customer) = lt_customers[ customer_id = lv_id ].
" Verarbeitung
CATCH cx_sy_itab_line_not_found.
" Fehlerbehandlung
ls_customer = VALUE #( customer_id = 0 name = 'Unbekannt' ).
ENDTRY.

✅ Lösung 2: OPTIONAL

" ✅ RICHTIG: Mit OPTIONAL (keine Exception)
DATA(ls_customer) = VALUE #( lt_customers[ customer_id = lv_id ] OPTIONAL ).
IF ls_customer IS INITIAL.
" Nicht gefunden
ENDIF.

✅ Lösung 3: DEFAULT

" ✅ RICHTIG: Mit DEFAULT-Wert
DATA(ls_customer) = VALUE #( lt_customers[ customer_id = lv_id ]
DEFAULT VALUE #( customer_id = 0 name = 'Nicht gefunden' ) ).

💡 Wann was verwenden?

  • TRY-CATCH: Wenn Nicht-Finden ein Fehlerfall ist
  • OPTIONAL: Wenn Nicht-Finden normal ist (dann prüfen mit IS INITIAL)
  • DEFAULT: Wenn du einen Standardwert brauchst

5. ❌ Fehlender Strict Mode in RAP Behavior Definitions

Das Problem

Der Strict Mode (strict ( 2 )) in RAP sorgt für Best-Practice-Validierung. Ohne ihn werden Fehler erst zur Laufzeit erkannt.

Typischer Fehler

" ❌ FALSCH: Kein Strict Mode
managed implementation in class zbp_i_travel unique;
define behavior for ZI_Travel alias Travel
{
create;
update;
delete;
}

✅ Lösung

Füge Strict Mode hinzu:

" ✅ RICHTIG: Mit Strict Mode
managed implementation in class zbp_i_travel unique;
strict ( 2 ); // <- Wichtig!
define behavior for ZI_Travel alias Travel
persistent table ztravel
lock master
authorization master ( instance )
{
create;
update;
delete;
}

💡 Was macht Strict Mode?

  • Syntax-Prüfungen: Erzwingt Best Practices
  • Pflichtangaben: z.B. persistent table, lock master
  • Zukunftssicher: Bereitet auf neue ABAP-Versionen vor
  • Level 2: Strengste Validierung (empfohlen für neue Entwicklungen)

Immer verwenden! Es gibt keinen Grund, Strict Mode wegzulassen.


6. ❌ CONCATENATE statt String Templates

Das Problem

CONCATENATE ist veraltet (obsolete). String Templates sind moderner, lesbarer und mächtiger.

Typischer Fehler

" ❌ FALSCH: CONCATENATE (veraltet)
DATA lv_message TYPE string.
CONCATENATE 'Kunde' lv_customer_id 'wurde aktiviert'
INTO lv_message SEPARATED BY space.

✅ Lösung

Verwende String Templates:

" ✅ RICHTIG: String Template
DATA(lv_message) = |Kunde { lv_customer_id } wurde aktiviert|.
" Mit Formatierung
DATA(lv_price) = |Preis: { lv_amount CURRENCY = lv_currency }|.
" Mit Datumsformatierung
DATA(lv_date) = |Datum: { lv_timestamp TIMESTAMP = ISO }|.
" Mit Padding
DATA(lv_padded) = |{ lv_id WIDTH = 10 ALIGN = RIGHT PAD = '0' }|.
" Ergebnis: "0000000042"

💡 Vorteile von String Templates

  • Lesbar: Klar strukturiert
  • Mächtig: Integrierte Formatierung
  • Modern: Best Practice in ABAP Cloud
  • Kürzer: Weniger Code

7. ❌ READ TABLE statt Table Expressions

Das Problem

READ TABLE ist nicht verboten, aber veraltet. Table Expressions sind kürzer und moderner.

Typischer Fehler

" ❌ NICHT IDEAL: READ TABLE
DATA ls_customer TYPE ty_customer.
READ TABLE lt_customers INTO ls_customer WITH KEY customer_id = lv_id.
IF sy-subrc = 0.
" Verarbeitung
ENDIF.

✅ Lösung

Verwende Table Expression:

" ✅ BESSER: Table Expression mit TRY-CATCH
TRY.
DATA(ls_customer) = lt_customers[ customer_id = lv_id ].
" Verarbeitung
CATCH cx_sy_itab_line_not_found.
" Nicht gefunden
ENDTRY.
" Oder mit OPTIONAL
DATA(ls_customer) = VALUE #( lt_customers[ customer_id = lv_id ] OPTIONAL ).
IF ls_customer IS NOT INITIAL.
" Verarbeitung
ENDIF.

💡 Vorteile

  • Inline-Deklaration: Kein separates DATA nötig
  • Kürzer: Eine Zeile statt drei
  • Modern: Best Practice in ABAP Cloud

Hinweis: READ TABLE funktioniert noch, aber Table Expressions sind die Zukunft.


8. ❌ Dynpro-Entwicklung statt SAP Fiori

Das Problem

Dynpro (klassische SAP GUI) ist in ABAP Cloud nicht mehr möglich. Die UI muss mit SAP Fiori gebaut werden.

Typischer Fehler

" ❌ FALSCH: Dynpro verwenden
CALL SCREEN 100.
MODULE status_0100 OUTPUT.
SET PF-STATUS 'MAIN'.
SET TITLEBAR 'TITLE'.
ENDMODULE.

Fehler: Dynpro ist in ABAP Cloud nicht verfügbar

✅ Lösung

Verwende RAP + SAP Fiori Elements:

" ✅ RICHTIG: RAP Business Object mit Service Binding
" 1. CDS View (Datenmodell)
@EndUserText.label: 'Customer View'
define root view entity ZC_Customer
as projection on ZI_Customer
{
key CustomerId,
CustomerName,
Email,
Status
}
" 2. Behavior Definition
projection;
strict ( 2 );
define behavior for ZC_Customer
{
use create;
use update;
use delete;
}
" 3. Service Definition
@EndUserText.label: 'Customer Service'
define service ZUI_CUSTOMER_O4 {
expose ZC_Customer as Customer;
}
" 4. Service Binding (OData V4 - UI)
" Typ: OData V4 - UI
" → Automatisch Fiori Elements App!

💡 Vorteile von Fiori

  • Modern: Responsive, Touch-optimiert
  • Cloud-ready: Läuft überall (Browser, Tablet, Mobile)
  • Wartungsarm: Fiori Elements generiert UI automatisch
  • Konsistent: Einheitliches SAP-Erlebnis

Tipp: Nutze SAP Fiori Elements - die UI wird aus deinem RAP-Modell automatisch generiert!


9. ❌ Fehlende COMMIT ENTITIES bei EML-Operationen

Das Problem

EML (Entity Manipulation Language) Operationen wie MODIFY ENTITIES benötigen ein explizites COMMIT, sonst werden Änderungen nicht gespeichert.

Typischer Fehler

" ❌ FALSCH: Kein COMMIT
MODIFY ENTITIES OF zi_travel
ENTITY Travel
UPDATE FIELDS ( Status )
WITH VALUE #( ( TravelId = lv_id Status = 'A' ) ).
" Änderungen gehen verloren! ❌

✅ Lösung

Verwende COMMIT ENTITIES:

" ✅ RICHTIG: Mit COMMIT
MODIFY ENTITIES OF zi_travel
ENTITY Travel
UPDATE FIELDS ( Status )
WITH VALUE #( ( TravelId = lv_id Status = 'A' ) )
FAILED DATA(failed)
REPORTED DATA(reported).
" WICHTIG: COMMIT nicht vergessen!
COMMIT ENTITIES
RESPONSE OF zi_travel
FAILED DATA(commit_failed)
REPORTED DATA(commit_reported).
IF commit_failed IS INITIAL.
" Erfolgreich gespeichert
ENDIF.

💡 Best Practice

  • Immer COMMIT ENTITIES nach MODIFY ENTITIES
  • Prüfe FAILED und REPORTED auf Fehler
  • In Behavior Implementations kein COMMIT (Framework macht das)
  • Nur in externem Code (z.B. Reports, Klassen) COMMIT verwenden

10. ❌ Performance-Probleme durch fehlende CDS Associations

Das Problem

Joins in ABAP-Code statt CDS Associations führt zu schlechter Performance und unlesbarem Code.

Typischer Fehler

" ❌ FALSCH: Joins in ABAP
SELECT c~customer_id, c~name, o~order_id, o~order_date
FROM ztab_customers AS c
INNER JOIN ztab_orders AS o
ON c~customer_id = o~customer_id
WHERE c~status = 'ACTIVE'
INTO TABLE @DATA(lt_result).
" Dann manuell aggregieren, filtern, etc.
LOOP AT lt_result INTO DATA(ls_result).
" Komplexe Logik
ENDLOOP.

✅ Lösung

Verwende CDS Views mit Associations:

/* ✅ RICHTIG: CDS View mit Association */
@AbapCatalog.sqlViewName: 'ZVCUSTOMER'
@EndUserText.label: 'Customer with Orders'
define view Z_Customer
as select from ztab_customers as c
association [0..*] to ztab_orders as _Orders
on c.customer_id = _Orders.customer_id
{
key c.customer_id as CustomerId,
c.name as CustomerName,
c.status as Status,
/* Association exposen */
_Orders
}
" Verwendung in ABAP
SELECT FROM Z_Customer
FIELDS CustomerId, CustomerName
WHERE Status = 'ACTIVE'
INTO TABLE @DATA(lt_customers).
" Bei Bedarf Orders laden (Lazy Loading)
SELECT FROM Z_Customer
FIELDS CustomerId,
\_Orders-OrderId,
\_Orders-OrderDate
WHERE Status = 'ACTIVE'
INTO TABLE @DATA(lt_customer_orders).

💡 Vorteile

  • Performance: DB macht Joins (nicht ABAP)
  • Wiederverwendbar: Association kann in allen Views genutzt werden
  • Lazy Loading: Orders nur laden, wenn gebraucht
  • Lesbar: Klare Datenmodellierung

Faustregel: Joins gehören in CDS Views, nicht in ABAP-Code!


🎯 Zusammenfassung: Die 10 häufigsten ABAP Cloud Fehler

#FehlerLösung
1Nicht-released APIs verwendenNur Released CDS Views & APIs
2SELECT *Explizite Feldliste
3FORM/PERFORMKlassen mit Methoden
4Fehlende Exception BehandlungTRY-CATCH, OPTIONAL, DEFAULT
5Kein Strict Modestrict ( 2 ) in BDEF
6CONCATENATEString Templates |...|
7READ TABLETable Expressions lt_table[ key ]
8DynproRAP + Fiori Elements
9Kein COMMITCOMMIT ENTITIES nach EML
10Joins in ABAPCDS Associations

🛠️ Praktische Tipps zur Fehlervermeidung

1. Nutze ABAP Development Tools (ADT)

  • Eclipse mit ADT erkennt ABAP Cloud Fehler sofort
  • Syntax-Highlighting für Released/Nicht-Released Objekte
  • Quick Fixes für viele Fehler

2. Aktiviere ATC Checks

ABAP Test Cockpit prüft Code auf ABAP Cloud Konformität:

" In ADT: Rechtsklick auf Objekt → Run As → ABAP Test Cockpit

3. Verwende Code Templates

In ADT: Ctrl+Space für Code-Vorlagen

  • trycatch → TRY-CATCH Block
  • loop → LOOP mit Table Expression
  • method → Methodendefinition

4. Lerne von SAP-Beispielen

5. Migration-Tools nutzen

Für Migrationen von Classic ABAP:

  • Custom Code Migration App (Fiori App im System)
  • ABAP Test Cockpit mit Cloud Checks
  • SAP BTP ABAP Environment Migration Tool

📚 Weiterführende Ressourcen

Auf abapcloud.com:

Externe Ressourcen:


✅ Checkliste: ABAP Cloud Code Review

Bevor du Code committest, prüfe:

  • Nur Released APIs verwendet?
  • Keine SELECT * Statements?
  • Keine FORM/PERFORM?
  • Table Expressions mit Exception Handling?
  • Strict Mode in BDEFs aktiviert?
  • String Templates statt CONCATENATE?
  • Moderne Syntax (VALUE, CORRESPONDING, etc.)?
  • Bei EML: COMMIT ENTITIES vorhanden?
  • Fiori statt Dynpro?
  • CDS Associations statt Joins in ABAP?

Wenn alle Punkte ✅ sind: Dein Code ist ABAP Cloud ready! 🎉


💬 Dein häufigster ABAP Cloud Fehler?

Welchen Fehler machst du am häufigsten? Fehlt ein wichtiger Fehler in dieser Liste? Teile deine Erfahrungen in den Kommentaren!

Viel Erfolg bei der ABAP Cloud Entwicklung! 🚀