ABAP Message Handling: MESSAGE Statement

Category
ABAP-Statements
Published
Author
Johannes

Message Handling in ABAP enables structured output of user and system messages. With the MESSAGE statement and message classes, you can create consistent, multilingual messages.

Message Types

TypeNameBehavior
AAbendProgram terminates
EErrorInput blocked
WWarningConfirmation possible
IInformationPopup message
SStatus (Success)Status bar
XExitProgram terminates with dump

Syntax

" With message class and number
MESSAGE e001(zmessages).
" With variables
MESSAGE e002(zmessages) WITH lv_value1 lv_value2.
" Dynamic
MESSAGE ID 'ZMESSAGES' TYPE 'E' NUMBER '001'.
" Store in variable
MESSAGE e001(zmessages) INTO DATA(lv_message).

Examples

1. Simple Messages

" Success message in status bar
MESSAGE s001(zmessages).
" 'Operation completed successfully'
" Error message
MESSAGE e002(zmessages).
" 'Error during processing'
" Warning
MESSAGE w003(zmessages).
" 'Attention: Data has been changed'
" Information (Popup)
MESSAGE i004(zmessages).
" 'Please note the instructions'

2. Messages with Variables

" Message text: "Customer & was created"
MESSAGE s010(zmessages) WITH lv_kunnr.
" Message text: "Order & item & was changed"
MESSAGE s011(zmessages) WITH lv_vbeln lv_posnr.
" Up to 4 variables possible
MESSAGE e012(zmessages) WITH lv_var1 lv_var2 lv_var3 lv_var4.

3. Store Message in Variable

" Don't display message, store it instead
MESSAGE e001(zmessages) INTO DATA(lv_message).
" With variables
MESSAGE e010(zmessages) WITH lv_kunnr INTO lv_message.
" sy-msgty, sy-msgid, sy-msgno are set
WRITE: / 'Type:', sy-msgty,
/ 'Class:', sy-msgid,
/ 'Number:', sy-msgno,
/ 'Text:', lv_message.

4. Dynamic Messages

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.
" Dynamic output
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2.
" Or with INTO
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2
INTO DATA(lv_text).

5. Messages from Exceptions

TRY.
" Code that throws exception
DATA(lo_processor) = NEW zcl_processor( ).
lo_processor->process( ).
CATCH cx_root INTO DATA(lx_error).
" Exception text as message
MESSAGE lx_error TYPE 'E'.
" Or in status bar
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

6. DISPLAY LIKE for Status Bar Appearance

" Error message as status message (no popup)
MESSAGE e001(zmessages) DISPLAY LIKE 'S'.
" Success in status bar with error icon
MESSAGE s001(zmessages) DISPLAY LIKE 'E'.
" Information displayed as warning
MESSAGE i001(zmessages) DISPLAY LIKE 'W'.

7. Message Class as Constants

CLASS zcl_messages DEFINITION.
PUBLIC SECTION.
CONSTANTS:
" Message class
c_msgid TYPE sy-msgid VALUE 'ZMYAPP',
" Message numbers
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.
" Usage
zcl_messages=>show_success( 'Customer 1000' ).
DATA(lv_msg) = zcl_messages=>get_message(
iv_msgno = zcl_messages=>c_error_not_found
iv_var1 = 'Order'
).

8. BAPIRET2 for Return Messages

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.
" Message from sy-msg* variables
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.
" Usage
DATA(lo_collector) = NEW zcl_message_collector( ).
lo_collector->add_success( 'Processing started' ).
lo_collector->add_error(
iv_msgid = 'ZMYAPP'
iv_msgno = '002'
iv_var1 = 'Customer 1000'
).
IF lo_collector->has_errors( ).
" Error handling
ENDIF.

9. Read Message Text Programmatically

" Read message text from T100
SELECT SINGLE text FROM t100
WHERE sprsl = @sy-langu
AND arbgb = 'ZMYAPP'
AND msgnr = '001'
INTO @DATA(lv_text).
" Or with function module
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.
" Check on input
AT SELECTION-SCREEN ON p_kunnr.
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @p_kunnr
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Error message - cursor stays on field
MESSAGE e010(zmyapp) WITH p_kunnr.
ENDIF.
START-OF-SELECTION.
" Success message
MESSAGE s001(zmyapp).

11. Message with RAISING in Methods

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.
" Wrap message in exception
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.
" Usage
TRY.
DATA(ls_customer) = lo_service->get_customer( '0000001000' ).
CATCH zcx_not_found INTO DATA(lx_error).
MESSAGE lx_error TYPE 'E'.
ENDTRY.

12. 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).
" Check customer
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @ls_order-customer_id
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Return error message via Reported
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* System Variables

VariableDescription
sy-msgidMessage class
sy-msgtyMessage type
sy-msgnoMessage number
sy-msgv1 - sy-msgv4Variables 1-4

Important Notes / Best Practices

  • Message classes (SE91) for consistent, translatable texts.
  • Type S with DISPLAY LIKE ‘E’ for errors without input blocking.
  • INTO to store instead of display messages.
  • BAPIRET2 for message collections in APIs.
  • Exceptions instead of MESSAGE for reusable components.
  • Maximum 4 variables per message (&, &, &, &).
  • Maintain message texts in SE91, don’t hardcode.
  • Multilingual through translation in SE91.
  • In RAP, use special message classes (IF_ABAP_BEHV_MESSAGE).
  • Combine with Application Logging for persistent logs.