ABAP COND und SWITCH: Bedingte Ausdrücke inline

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Die Ausdrücke COND und SWITCH ermöglichen bedingte Wertzuweisungen inline, ohne separate IF- oder CASE-Blöcke. Sie liefern einen Wert zurück und können überall verwendet werden, wo ein Wert erwartet wird.

COND – Bedingte Ausdrücke (wie IF)

Der COND-Ausdruck prüft Bedingungen und gibt den entsprechenden Wert zurück.

Syntax

COND <typ>(
WHEN <bedingung1> THEN <wert1>
[ WHEN <bedingung2> THEN <wert2> ]
[ ELSE <standardwert> ]
)

Beispiele für COND

1. Einfache Bedingung

DATA: lv_age TYPE i VALUE 25.
" Klassisch mit IF
DATA: lv_status TYPE string.
IF lv_age >= 18.
lv_status = 'Erwachsen'.
ELSE.
lv_status = 'Minderjährig'.
ENDIF.
" Modern mit COND
DATA(lv_status2) = COND string(
WHEN lv_age >= 18 THEN 'Erwachsen'
ELSE 'Minderjährig'
).

2. Mehrere Bedingungen

DATA: lv_score TYPE i VALUE 75.
DATA(lv_grade) = COND string(
WHEN lv_score >= 90 THEN 'Sehr gut'
WHEN lv_score >= 80 THEN 'Gut'
WHEN lv_score >= 70 THEN 'Befriedigend'
WHEN lv_score >= 60 THEN 'Ausreichend'
ELSE 'Nicht bestanden'
).
WRITE: / 'Note:', lv_grade. " Befriedigend

3. COND in Berechnungen

DATA: lv_quantity TYPE i VALUE 150.
" Rabattstaffel
DATA(lv_discount) = COND decfloat16(
WHEN lv_quantity >= 100 THEN '0.15' " 15%
WHEN lv_quantity >= 50 THEN '0.10' " 10%
WHEN lv_quantity >= 10 THEN '0.05' " 5%
ELSE '0.00'
).
DATA(lv_price) = 100 * ( 1 - lv_discount ).

4. COND mit komplexen Bedingungen

DATA: lv_age TYPE i VALUE 25,
lv_member TYPE abap_bool VALUE abap_true.
DATA(lv_ticket_price) = COND i(
WHEN lv_age < 6 THEN 0 " Kinder frei
WHEN lv_age < 18 OR lv_age >= 65 THEN 10 " Ermäßigt
WHEN lv_member = abap_true THEN 15 " Mitglieder
ELSE 20 " Normalpreis
).

5. COND für Struktur-Felder

TYPES: BEGIN OF ty_result,
status TYPE string,
message TYPE string,
END OF ty_result.
DATA: lv_code TYPE i VALUE 200.
DATA(ls_result) = COND ty_result(
WHEN lv_code = 200 THEN VALUE #( status = 'OK' message = 'Erfolgreich' )
WHEN lv_code = 404 THEN VALUE #( status = 'ERROR' message = 'Nicht gefunden' )
WHEN lv_code = 500 THEN VALUE #( status = 'ERROR' message = 'Serverfehler' )
ELSE VALUE #( status = 'UNKNOWN' message = 'Unbekannter Code' )
).

6. COND mit LET (lokale Variablen)

DATA(lv_message) = COND string(
LET today = sy-datum
age = 30
IN
WHEN today+4(2) = '12' THEN |Dezember, { age } Jahre alt|
ELSE |Normaler Monat, { age } Jahre alt|
).

7. COND mit THROW (Exception auslösen)

DATA: lv_divisor TYPE i VALUE 0.
DATA(lv_result) = COND i(
WHEN lv_divisor <> 0 THEN 100 / lv_divisor
ELSE THROW cx_sy_zerodivide( )
).

SWITCH – Wertbasierte Verzweigung (wie CASE)

Der SWITCH-Ausdruck vergleicht einen Wert mit mehreren Möglichkeiten.

Syntax

SWITCH <typ>( <operand>
WHEN <wert1> THEN <ergebnis1>
[ WHEN <wert2> THEN <ergebnis2> ]
[ ELSE <standardwert> ]
)

Beispiele für SWITCH

1. Einfacher SWITCH

DATA: lv_day TYPE i VALUE 3.
" Klassisch mit CASE
DATA: lv_name TYPE string.
CASE lv_day.
WHEN 1. lv_name = 'Montag'.
WHEN 2. lv_name = 'Dienstag'.
WHEN 3. lv_name = 'Mittwoch'.
WHEN OTHERS. lv_name = 'Unbekannt'.
ENDCASE.
" Modern mit SWITCH
DATA(lv_name2) = SWITCH string( lv_day
WHEN 1 THEN 'Montag'
WHEN 2 THEN 'Dienstag'
WHEN 3 THEN 'Mittwoch'
WHEN 4 THEN 'Donnerstag'
WHEN 5 THEN 'Freitag'
WHEN 6 THEN 'Samstag'
WHEN 7 THEN 'Sonntag'
ELSE 'Ungültig'
).

2. SWITCH mit mehreren Werten pro WHEN

DATA: lv_month TYPE i VALUE 7.
DATA(lv_season) = SWITCH string( lv_month
WHEN 3 OR 4 OR 5 THEN 'Frühling'
WHEN 6 OR 7 OR 8 THEN 'Sommer'
WHEN 9 OR 10 OR 11 THEN 'Herbst'
WHEN 12 OR 1 OR 2 THEN 'Winter'
ELSE 'Ungültiger Monat'
).

3. SWITCH für Status-Codes

DATA: lv_status TYPE c LENGTH 1 VALUE 'A'.
DATA(lv_description) = SWITCH string( lv_status
WHEN 'A' THEN 'Aktiv'
WHEN 'I' THEN 'Inaktiv'
WHEN 'P' THEN 'Ausstehend'
WHEN 'C' THEN 'Abgeschlossen'
WHEN 'X' THEN 'Storniert'
ELSE 'Unbekannt'
).

4. SWITCH mit Strukturen

TYPES: BEGIN OF ty_config,
color TYPE string,
size TYPE i,
enabled TYPE abap_bool,
END OF ty_config.
DATA: lv_mode TYPE string VALUE 'DARK'.
DATA(ls_config) = SWITCH ty_config( lv_mode
WHEN 'LIGHT' THEN VALUE #( color = 'white' size = 12 enabled = abap_true )
WHEN 'DARK' THEN VALUE #( color = 'black' size = 14 enabled = abap_true )
WHEN 'HIGH_CONTRAST' THEN VALUE #( color = 'yellow' size = 16 enabled = abap_true )
ELSE VALUE #( color = 'gray' size = 12 enabled = abap_false )
).

5. SWITCH für Enumerations

TYPES: BEGIN OF ENUM ty_order_status,
new,
processing,
shipped,
delivered,
cancelled,
END OF ENUM ty_order_status.
DATA: lv_status TYPE ty_order_status VALUE ty_order_status-shipped.
DATA(lv_icon) = SWITCH string( lv_status
WHEN ty_order_status-new THEN '📝'
WHEN ty_order_status-processing THEN '⚙️'
WHEN ty_order_status-shipped THEN '📦'
WHEN ty_order_status-delivered THEN '✅'
WHEN ty_order_status-cancelled THEN '❌'
).

6. SWITCH mit THROW

DATA: lv_action TYPE string VALUE 'INVALID'.
DATA(lv_result) = SWITCH string( lv_action
WHEN 'CREATE' THEN 'Erstellen'
WHEN 'UPDATE' THEN 'Aktualisieren'
WHEN 'DELETE' THEN 'Löschen'
ELSE THROW cx_parameter_invalid( parameter = 'ACTION' )
).

COND vs. SWITCH

AspektCONDSWITCH
VergleichBeliebige BedingungenEin Operand gegen Werte
EntsprichtIF…ELSEIF…ELSECASE…WHEN…ENDCASE
FlexibilitätHöher (komplexe Bedingungen)Einfacher bei Wertevergleich
LesbarkeitBei komplexen BedingungenBei vielen Einzelwerten
" COND: Für Bereiche und komplexe Bedingungen
DATA(lv_category) = COND string(
WHEN lv_age < 18 THEN 'Kind'
WHEN lv_age < 65 THEN 'Erwachsener'
ELSE 'Senior'
).
" SWITCH: Für diskrete Werte
DATA(lv_day_name) = SWITCH string( lv_day_number
WHEN 1 THEN 'Montag'
WHEN 2 THEN 'Dienstag'
" ...
).

Verschachtelung

DATA: lv_type TYPE string VALUE 'CUSTOMER',
lv_active TYPE abap_bool VALUE abap_true.
DATA(lv_label) = SWITCH string( lv_type
WHEN 'CUSTOMER' THEN COND #(
WHEN lv_active = abap_true THEN 'Aktiver Kunde'
ELSE 'Inaktiver Kunde'
)
WHEN 'SUPPLIER' THEN COND #(
WHEN lv_active = abap_true THEN 'Aktiver Lieferant'
ELSE 'Inaktiver Lieferant'
)
ELSE 'Unbekannt'
).

In Methodenaufrufen

" Direkt als Parameter
CALL METHOD lo_logger->log(
iv_level = COND #( WHEN lv_error = abap_true THEN 'ERROR' ELSE 'INFO' )
iv_message = |Status: { lv_status }|
).
" Als Rückgabewert
METHODS get_status_text
RETURNING VALUE(rv_text) TYPE string.
METHOD get_status_text.
rv_text = SWITCH #( mv_status
WHEN 'A' THEN 'Aktiv'
WHEN 'I' THEN 'Inaktiv'
ELSE 'Unbekannt'
).
ENDMETHOD.

Wichtige Hinweise / Best Practice

  • Verwenden Sie COND für Bereichsprüfungen und komplexe Bedingungen.
  • Verwenden Sie SWITCH für diskrete Wertevergleiche (wie Enums, Status-Codes).
  • ELSE ist optional – ohne ELSE wird bei Nicht-Treffer der Initialwert zurückgegeben.
  • THROW ermöglicht das Auslösen von Exceptions als Ergebnis.
  • Kombinieren Sie mit VALUE für Strukturen und Tabellen.
  • Vermeiden Sie zu tiefe Verschachtelung – nutzen Sie bei Komplexität Methoden.
  • # leitet den Typ aus dem Kontext ab (z.B. bei Zuweisungen).
  • Nutzen Sie LET für lokale Hilfsvariablen innerhalb des Ausdrucks.