The MESSAGE statement is used to:
- Display messages: Communicate information, success messages, warnings, or error messages to the user (usually in the status bar, a popup window, or in the log).
- Influence program flow: Depending on the message type (see below), the statement can interrupt the current processing step, abort the entire transaction, or even trigger a runtime error (dump).
By default, messages are not stored as text directly in the code, but are centrally maintained in message classes (transaction SE91). This enables easy translation and maintenance.
Syntax
The most common form looks like this:
MESSAGE <type><nr>(<class>) [WITH <value1> <value2> <value3> <value4>] " Fill placeholders [RAISING <exception_class>] " Raise exception (in FMs/methods) [INTO <variable>]. " Store message text in variable (instead of displaying)There is also a (less commonly recommended) form for ad-hoc text literals:
MESSAGE <literal_text> TYPE <type>.Components
-
<type>(Message type): A single letter that determines the behavior. This is the most important part!I: Information - Displays the message (often a popup). Program waits for confirmation (Enter/OK) and then continues.S: Success - Displays the message in the status bar of the next screen. Program continues immediately.W: Warning - Displays a warning (often a popup or status bar). Input fields often remain ready. Program waits for confirmation and then continues. Context-dependent.E: Error - Displays an error message. Usually interrupts the current processing step (e.g., PAI module,START-OF-SELECTION). Input fields are often made ready for input again. Does not terminate the entire program.A: Abend (Abort) - Displays the message and immediately aborts the entire transaction! Performs a database rollback. Use very carefully!X: eXit (Dump) - Causes a runtime error (short dump). The message is displayed in the dump. For severe, unexpected program errors.
-
<nr>: The three-digit message number (as a literal or variable) from the message class (000-999). -
(<class>): The ID of the message class (literal or variable, e.g.,'ZMYMSG') from transactionSE91, where message<nr>is defined. This part can be omitted if a default message class has been globally declared in the program withREPORT ... MESSAGE-ID .... -
WITH <value1> ... <value4>(Optional): This allows you to pass up to four values (variables, literals) that replace the placeholders&1,&2,&3,&4in the message text. A simple&is filled sequentially with the values.- Example text in SE91:
Material &1 for plant &2 not found. - Call:
MESSAGE E005(ZMAT) WITH lv_matnr lv_werks.
- Example text in SE91:
-
RAISING <exception_class>(Optional): Only meaningful in function modules and methods. Raises a class-based exception in addition to the message, which the caller can catch withTRY ... CATCH. Enables structured error handling. -
INTO <variable>(Optional): The message is not displayed. Instead, the fully formatted message text is written to the character-like<variable>. The program continues immediately. Useful for logging.
Message Classes (SE91)
Using message classes is standard and offers advantages:
- Translation: Messages can be centrally translated.
- Maintenance: Texts can be changed in one place.
- Reuse: The same messages can be used by different programs.
- Context: Use of placeholders (
&,&1…).
System Fields
After displaying a message (not with INTO), system fields like sy-msgid (class), sy-msgty (type), sy-msgno (number), and sy-msgv1 to sy-msgv4 (values from WITH) are filled. Note: sy-subrc is not reliably set by MESSAGE itself to indicate success/failure – the logic primarily results from the message type (E, A, X).
Examples
" Assumption: Message class ZMSG exists" NNo | Text" ----|--------------------------------------" 001 | Processing completed successfully." 002 | Material &1 could not be locked." 003 | Please enter an order number." 004 | Date &1 is in the past. Continue?" 005 | Internal error (&1) occurred in routine &2! Abort!
DATA lv_matnr TYPE matnr VALUE 'M-01'.DATA lv_date TYPE d VALUE sy-datum - 1.DATA lv_text TYPE string.
" Success message (Type S - appears in status bar of next screen)MESSAGE s001(ZMSG).
" Error message (Type E - usually stops current block)IF lv_matnr IS INITIAL. MESSAGE e003(ZMSG). RETURN. " Explicit exit necessary if not in PAI etc.ENDIF.
" Warning (Type W - User must confirm)IF lv_date < sy-datum. MESSAGE w004(ZMSG) WITH lv_date. " Program pauses here until user confirms.ENDIF.
" Information (Type I - User must confirm)MESSAGE i002(ZMSG) WITH lv_matnr.
" Abort (Type A - Transaction is terminated!) - USE VERY CAREFULLY* MESSAGE a005(ZMSG) WITH sy-subrc 'MY_ROUTINE'.
" Write message to variable (Type S - not displayed)MESSAGE s001(ZMSG) INTO lv_text.WRITE: / 'Message in variable:', lv_text.Important Notes / Best Practice
- Use message classes for all messages that need to be translated or appear multiple times.
- Choose the message type (
I,S,W,E,A,X) consciously, depending on how the program should react. - Be extremely sparing with types
A(abort) andX(dump). They are intended for severe, unrecoverable errors. - Use the
WITHaddition to give the user context-specific information (values, field names, etc.) in the message. - In function modules and methods, prefer
RAISINGwith exception classes overMESSAGE E...for clean error communication to the caller.