ABAP Message Handling: MESSAGE Statement

kategorie
ABAP-Statements
Veröffentlicht
autor
Johannes

Message Handling in ABAP ermöglicht die strukturierte Ausgabe von Benutzer- und Systemnachrichten. Mit dem MESSAGE-Statement und Nachrichtenklassen können konsistente, mehrsprachige Meldungen erstellt werden.

Nachrichtentypen

TypNameVerhalten
AAbbruch (Abend)Programm wird beendet
EFehler (Error)Eingabe blockiert
WWarnung (Warning)Bestätigung möglich
IInformationPopup-Meldung
SStatus (Success)Statusleiste
XExitProgramm mit Dump beenden

Syntax

" Mit Nachrichtenklasse und Nummer
MESSAGE e001(zmessages).
" Mit Variablen
MESSAGE e002(zmessages) WITH lv_value1 lv_value2.
" Dynamisch
MESSAGE ID 'ZMESSAGES' TYPE 'E' NUMBER '001'.
" In Variable speichern
MESSAGE e001(zmessages) INTO DATA(lv_message).

Beispiele

1. Einfache Nachrichten

" Erfolgsmeldung in Statusleiste
MESSAGE s001(zmessages).
" 'Operation erfolgreich durchgeführt'
" Fehlermeldung
MESSAGE e002(zmessages).
" 'Fehler bei der Verarbeitung'
" Warnung
MESSAGE w003(zmessages).
" 'Achtung: Daten wurden geändert'
" Information (Popup)
MESSAGE i004(zmessages).
" 'Bitte beachten Sie die Hinweise'

2. Nachrichten mit Variablen

" Nachrichtentext: "Kunde & wurde angelegt"
MESSAGE s010(zmessages) WITH lv_kunnr.
" Nachrichtentext: "Bestellung & Position & wurde geändert"
MESSAGE s011(zmessages) WITH lv_vbeln lv_posnr.
" Bis zu 4 Variablen möglich
MESSAGE e012(zmessages) WITH lv_var1 lv_var2 lv_var3 lv_var4.

3. Nachricht in Variable speichern

" Nachricht nicht anzeigen, sondern speichern
MESSAGE e001(zmessages) INTO DATA(lv_message).
" Mit Variablen
MESSAGE e010(zmessages) WITH lv_kunnr INTO lv_message.
" sy-msgty, sy-msgid, sy-msgno werden gesetzt
WRITE: / 'Typ:', sy-msgty,
/ 'Klasse:', sy-msgid,
/ 'Nummer:', sy-msgno,
/ 'Text:', lv_message.

4. Dynamische Nachrichten

DATA: lv_msgid TYPE sy-msgid VALUE 'ZMESSAGES',
lv_msgty TYPE sy-msgty VALUE 'E',
lv_msgno TYPE sy-msgno VALUE '001',
lv_msgv1 TYPE sy-msgv1,
lv_msgv2 TYPE sy-msgv2.
" Dynamische Ausgabe
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2.
" Oder mit INTO
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2
INTO DATA(lv_text).

5. Nachrichten aus Exceptions

TRY.
" Code der Exception wirft
DATA(lo_processor) = NEW zcl_processor( ).
lo_processor->process( ).
CATCH cx_root INTO DATA(lx_error).
" Exception-Text als Nachricht
MESSAGE lx_error TYPE 'E'.
" Oder in Statusleiste
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

6. DISPLAY LIKE für Statusleisten-Optik

" Fehlermeldung als Status-Nachricht (kein Popup)
MESSAGE e001(zmessages) DISPLAY LIKE 'S'.
" Erfolg in Statusleiste mit Error-Icon
MESSAGE s001(zmessages) DISPLAY LIKE 'E'.
" Information als Warnung dargestellt
MESSAGE i001(zmessages) DISPLAY LIKE 'W'.

7. Nachrichtenklasse als Konstanten

CLASS zcl_messages DEFINITION.
PUBLIC SECTION.
CONSTANTS:
" Nachrichtenklasse
c_msgid TYPE sy-msgid VALUE 'ZMYAPP',
" Nachrichtennummern
c_success_saved TYPE sy-msgno VALUE '001',
c_error_not_found TYPE sy-msgno VALUE '002',
c_error_no_auth TYPE sy-msgno VALUE '003',
c_warning_duplicate TYPE sy-msgno VALUE '004'.
CLASS-METHODS: show_success
IMPORTING iv_object TYPE string.
CLASS-METHODS: show_error
IMPORTING iv_message TYPE string.
CLASS-METHODS: get_message
IMPORTING iv_msgno TYPE sy-msgno
iv_var1 TYPE clike OPTIONAL
iv_var2 TYPE clike OPTIONAL
RETURNING VALUE(rv_text) TYPE string.
ENDCLASS.
CLASS zcl_messages IMPLEMENTATION.
METHOD show_success.
MESSAGE s001(zmyapp) WITH iv_object.
ENDMETHOD.
METHOD show_error.
MESSAGE ID c_msgid TYPE 'E' NUMBER c_error_not_found
WITH iv_message.
ENDMETHOD.
METHOD get_message.
MESSAGE ID c_msgid TYPE 'S' NUMBER iv_msgno
WITH iv_var1 iv_var2
INTO rv_text.
ENDMETHOD.
ENDCLASS.
" Verwendung
zcl_messages=>show_success( 'Kunde 1000' ).
DATA(lv_msg) = zcl_messages=>get_message(
iv_msgno = zcl_messages=>c_error_not_found
iv_var1 = 'Bestellung'
).

8. BAPIRET2 für Rückgabenachrichten

TYPES: ty_messages TYPE STANDARD TABLE OF bapiret2 WITH EMPTY KEY.
CLASS zcl_message_collector DEFINITION.
PUBLIC SECTION.
METHODS: add_success
IMPORTING iv_message TYPE string.
METHODS: add_error
IMPORTING iv_msgid TYPE sy-msgid
iv_msgno TYPE sy-msgno
iv_var1 TYPE clike OPTIONAL
iv_var2 TYPE clike OPTIONAL.
METHODS: add_from_sy.
METHODS: has_errors
RETURNING VALUE(rv_result) TYPE abap_bool.
METHODS: get_messages
RETURNING VALUE(rt_messages) TYPE ty_messages.
METHODS: display_all.
PRIVATE SECTION.
DATA: mt_messages TYPE ty_messages.
ENDCLASS.
CLASS zcl_message_collector IMPLEMENTATION.
METHOD add_success.
APPEND VALUE bapiret2(
type = 'S'
message = iv_message
) TO mt_messages.
ENDMETHOD.
METHOD add_error.
DATA: lv_text TYPE string.
MESSAGE ID iv_msgid TYPE 'E' NUMBER iv_msgno
WITH iv_var1 iv_var2
INTO lv_text.
APPEND VALUE bapiret2(
type = 'E'
id = iv_msgid
number = iv_msgno
message = lv_text
message_v1 = iv_var1
message_v2 = iv_var2
) TO mt_messages.
ENDMETHOD.
METHOD add_from_sy.
" Nachricht aus sy-msg* Variablen
APPEND VALUE bapiret2(
type = sy-msgty
id = sy-msgid
number = sy-msgno
message_v1 = sy-msgv1
message_v2 = sy-msgv2
message_v3 = sy-msgv3
message_v4 = sy-msgv4
) TO mt_messages.
ENDMETHOD.
METHOD has_errors.
rv_result = xsdbool( line_exists( mt_messages[ type = 'E' ] ) OR
line_exists( mt_messages[ type = 'A' ] ) ).
ENDMETHOD.
METHOD get_messages.
rt_messages = mt_messages.
ENDMETHOD.
METHOD display_all.
LOOP AT mt_messages INTO DATA(ls_msg).
WRITE: / ls_msg-type, ls_msg-message.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
" Verwendung
DATA(lo_collector) = NEW zcl_message_collector( ).
lo_collector->add_success( 'Verarbeitung gestartet' ).
lo_collector->add_error(
iv_msgid = 'ZMYAPP'
iv_msgno = '002'
iv_var1 = 'Kunde 1000'
).
IF lo_collector->has_errors( ).
" Fehlerbehandlung
ENDIF.

9. Nachrichtentext programmatisch lesen

" Nachrichtentext aus T100 lesen
SELECT SINGLE text FROM t100
WHERE sprsl = @sy-langu
AND arbgb = 'ZMYAPP'
AND msgnr = '001'
INTO @DATA(lv_text).
" Oder mit Funktionsbaustein
DATA: lv_message TYPE string.
CALL FUNCTION 'MESSAGE_TEXT_BUILD'
EXPORTING
msgid = 'ZMYAPP'
msgnr = '001'
msgv1 = 'Variable1'
msgv2 = 'Variable2'
IMPORTING
message_text_output = lv_message.
WRITE: / lv_message.

10. MESSAGE in Reports (AT SELECTION-SCREEN)

REPORT zmessage_demo.
PARAMETERS: p_kunnr TYPE kunnr.
" Prüfung bei Eingabe
AT SELECTION-SCREEN ON p_kunnr.
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @p_kunnr
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Fehlermeldung - Cursor bleibt auf Feld
MESSAGE e010(zmyapp) WITH p_kunnr.
ENDIF.
START-OF-SELECTION.
" Erfolgsmeldung
MESSAGE s001(zmyapp).

11. Message mit RAISING in Methoden

CLASS zcl_customer_service DEFINITION.
PUBLIC SECTION.
METHODS: get_customer
IMPORTING iv_kunnr TYPE kunnr
RETURNING VALUE(rs_customer) TYPE kna1
RAISING zcx_not_found.
ENDCLASS.
CLASS zcl_customer_service IMPLEMENTATION.
METHOD get_customer.
SELECT SINGLE * FROM kna1
WHERE kunnr = @iv_kunnr
INTO @rs_customer.
IF sy-subrc <> 0.
" Nachricht in Exception verpacken
MESSAGE e010(zmyapp) WITH iv_kunnr INTO DATA(lv_dummy).
RAISE EXCEPTION TYPE zcx_not_found
MESSAGE ID sy-msgid
NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
ENDMETHOD.
ENDCLASS.
" Verwendung
TRY.
DATA(ls_customer) = lo_service->get_customer( '0000001000' ).
CATCH zcx_not_found INTO DATA(lx_error).
MESSAGE lx_error TYPE 'E'.
ENDTRY.

12. ALV Nachrichten

" Nachrichten in ALV anzeigen
DATA: lo_alv TYPE REF TO cl_salv_table,
lt_messages TYPE bapiret2_t.
" Nachrichten sammeln
APPEND VALUE bapiret2( type = 'S' message = 'Erfolgreich geladen' ) TO lt_messages.
APPEND VALUE bapiret2( type = 'W' message = '10 Datensätze übersprungen' ) TO lt_messages.
" ALV erstellen und Nachrichten anzeigen
TRY.
cl_salv_table=>factory(
IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_messages
).
lo_alv->display( ).
CATCH cx_salv_msg.
ENDTRY.

13. Nachrichtenprotokoll erstellen

CLASS zcl_message_log DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ty_log_entry,
timestamp TYPE timestampl,
type TYPE sy-msgty,
id TYPE sy-msgid,
number TYPE sy-msgno,
text TYPE string,
END OF ty_log_entry,
ty_log TYPE STANDARD TABLE OF ty_log_entry WITH EMPTY KEY.
METHODS: log_message
IMPORTING iv_type TYPE sy-msgty
iv_id TYPE sy-msgid
iv_number TYPE sy-msgno
iv_var1 TYPE clike OPTIONAL
iv_var2 TYPE clike OPTIONAL.
METHODS: get_log
RETURNING VALUE(rt_log) TYPE ty_log.
METHODS: save_to_db.
PRIVATE SECTION.
DATA: mt_log TYPE ty_log.
ENDCLASS.
CLASS zcl_message_log IMPLEMENTATION.
METHOD log_message.
DATA: lv_text TYPE string.
MESSAGE ID iv_id TYPE iv_type NUMBER iv_number
WITH iv_var1 iv_var2
INTO lv_text.
GET TIME STAMP FIELD DATA(lv_timestamp).
APPEND VALUE #(
timestamp = lv_timestamp
type = iv_type
id = iv_id
number = iv_number
text = lv_text
) TO mt_log.
ENDMETHOD.
METHOD get_log.
rt_log = mt_log.
ENDMETHOD.
METHOD save_to_db.
" In Anwendungs-Log speichern
" Siehe: Application Logging (BAL)
ENDMETHOD.
ENDCLASS.

14. Mehrsprachige Nachrichten

" Nachrichtenklasse ZMYAPP in SE91:
" - Nachricht 001: DE: "Datensatz & wurde gespeichert"
" - Nachricht 001: EN: "Record & has been saved"
" Sprachabhängige Ausgabe (automatisch)
SET LOCALE LANGUAGE 'D'.
MESSAGE s001(zmyapp) WITH '1000' INTO DATA(lv_de).
" -> "Datensatz 1000 wurde gespeichert"
SET LOCALE LANGUAGE 'E'.
MESSAGE s001(zmyapp) WITH '1000' INTO DATA(lv_en).
" -> "Record 1000 has been saved"

15. RAP: Messages in Behavior Implementation

CLASS lhc_order DEFINITION INHERITING FROM cl_abap_behavior_handler.
PRIVATE SECTION.
METHODS validate_customer FOR VALIDATE ON SAVE
IMPORTING keys FOR Order~validateCustomer.
ENDCLASS.
CLASS lhc_order IMPLEMENTATION.
METHOD validate_customer.
READ ENTITIES OF zi_order IN LOCAL MODE
ENTITY Order
FIELDS ( customer_id )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order).
" Kunde prüfen
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @ls_order-customer_id
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Fehlermeldung über Reported zurückgeben
APPEND VALUE #(
%tky = ls_order-%tky
) TO failed-order.
APPEND VALUE #(
%tky = ls_order-%tky
%element-customer_id = if_abap_behv=>mk-on
%msg = NEW zcm_order_messages(
severity = if_abap_behv_message=>severity-error
textid = zcm_order_messages=>customer_not_found
customer = ls_order-customer_id
)
) TO reported-order.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

sy-msg* Systemvariablen

VariableBeschreibung
sy-msgidNachrichtenklasse
sy-msgtyNachrichtentyp
sy-msgnoNachrichtennummer
sy-msgv1 - sy-msgv4Variablen 1-4

Wichtige Hinweise / Best Practice

  • Nachrichtenklassen (SE91) für konsistente, übersetzbare Texte.
  • Typ S mit DISPLAY LIKE ‘E’ für Fehler ohne Eingabeblockierung.
  • INTO zum Speichern statt Anzeigen von Nachrichten.
  • BAPIRET2 für Nachrichtensammlungen in APIs.
  • Exceptions statt MESSAGE für wiederverwendbare Komponenten.
  • Maximal 4 Variablen pro Nachricht (&, &, &, &).
  • Nachrichtentexte in SE91 pflegen, nicht hartcodieren.
  • Mehrsprachigkeit durch Übersetzung in SE91.
  • In RAP spezielle Message-Klassen (IF_ABAP_BEHV_MESSAGE) verwenden.
  • Kombinieren Sie mit Application Logging für persistente Protokolle.