Manejo de mensajes en ABAP: Sentencia MESSAGE

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

El manejo de mensajes en ABAP permite la salida estructurada de mensajes de usuario y sistema. Con la sentencia MESSAGE y las clases de mensajes se pueden crear mensajes consistentes y multilingues.

Tipos de mensajes

TipoNombreComportamiento
AAbend (Abortar)El programa termina
EErrorEntrada bloqueada
WWarning (Advertencia)Confirmacion posible
IInformationMensaje emergente
SStatus (Exito)Barra de estado
XExitPrograma termina con dump

Sintaxis

" Con clase de mensaje y numero
MESSAGE e001(zmessages).
" Con variables
MESSAGE e002(zmessages) WITH lv_value1 lv_value2.
" Dinamicamente
MESSAGE ID 'ZMESSAGES' TYPE 'E' NUMBER '001'.
" Guardar en variable
MESSAGE e001(zmessages) INTO DATA(lv_message).

Ejemplos

1. Mensajes simples

" Mensaje de exito en barra de estado
MESSAGE s001(zmessages).
" 'Operacion realizada con exito'
" Mensaje de error
MESSAGE e002(zmessages).
" 'Error en el procesamiento'
" Advertencia
MESSAGE w003(zmessages).
" 'Atencion: Los datos han sido modificados'
" Informacion (emergente)
MESSAGE i004(zmessages).
" 'Por favor tenga en cuenta las indicaciones'

2. Mensajes con variables

" Texto del mensaje: "Cliente & fue creado"
MESSAGE s010(zmessages) WITH lv_kunnr.
" Texto del mensaje: "Pedido & Posicion & fue modificado"
MESSAGE s011(zmessages) WITH lv_vbeln lv_posnr.
" Hasta 4 variables posibles
MESSAGE e012(zmessages) WITH lv_var1 lv_var2 lv_var3 lv_var4.

3. Guardar mensaje en variable

" No mostrar mensaje, sino guardarlo
MESSAGE e001(zmessages) INTO DATA(lv_message).
" Con variables
MESSAGE e010(zmessages) WITH lv_kunnr INTO lv_message.
" sy-msgty, sy-msgid, sy-msgno se establecen
WRITE: / 'Tipo:', sy-msgty,
/ 'Clase:', sy-msgid,
/ 'Numero:', sy-msgno,
/ 'Texto:', lv_message.

4. Mensajes dinamicos

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.
" Salida dinamica
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2.
" O con INTO
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2
INTO DATA(lv_text).

5. Mensajes desde excepciones

TRY.
" Codigo que lanza excepcion
DATA(lo_processor) = NEW zcl_processor( ).
lo_processor->process( ).
CATCH cx_root INTO DATA(lx_error).
" Texto de excepcion como mensaje
MESSAGE lx_error TYPE 'E'.
" O en barra de estado
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

6. DISPLAY LIKE para apariencia de barra de estado

" Mensaje de error como mensaje de estado (sin emergente)
MESSAGE e001(zmessages) DISPLAY LIKE 'S'.
" Exito en barra de estado con icono de error
MESSAGE s001(zmessages) DISPLAY LIKE 'E'.
" Informacion mostrada como advertencia
MESSAGE i001(zmessages) DISPLAY LIKE 'W'.

7. Clase de mensajes como constantes

CLASS zcl_messages DEFINITION.
PUBLIC SECTION.
CONSTANTS:
" Clase de mensaje
c_msgid TYPE sy-msgid VALUE 'ZMYAPP',
" Numeros de mensaje
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.
" Uso
zcl_messages=>show_success( 'Cliente 1000' ).
DATA(lv_msg) = zcl_messages=>get_message(
iv_msgno = zcl_messages=>c_error_not_found
iv_var1 = 'Pedido'
).

8. BAPIRET2 para mensajes de retorno

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.
" Mensaje desde variables sy-msg*
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.
" Uso
DATA(lo_collector) = NEW zcl_message_collector( ).
lo_collector->add_success( 'Procesamiento iniciado' ).
lo_collector->add_error(
iv_msgid = 'ZMYAPP'
iv_msgno = '002'
iv_var1 = 'Cliente 1000'
).
IF lo_collector->has_errors( ).
" Manejo de errores
ENDIF.

9. Leer texto de mensaje programaticamente

" Leer texto de mensaje desde T100
SELECT SINGLE text FROM t100
WHERE sprsl = @sy-langu
AND arbgb = 'ZMYAPP'
AND msgnr = '001'
INTO @DATA(lv_text).
" O con modulo de funcion
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 en Reports (AT SELECTION-SCREEN)

REPORT zmessage_demo.
PARAMETERS: p_kunnr TYPE kunnr.
" Verificacion al ingresar
AT SELECTION-SCREEN ON p_kunnr.
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @p_kunnr
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Mensaje de error - Cursor permanece en el campo
MESSAGE e010(zmyapp) WITH p_kunnr.
ENDIF.
START-OF-SELECTION.
" Mensaje de exito
MESSAGE s001(zmyapp).

11. Message con RAISING en metodos

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.
" Empaquetar mensaje en excepcion
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.
" Uso
TRY.
DATA(ls_customer) = lo_service->get_customer( '0000001000' ).
CATCH zcx_not_found INTO DATA(lx_error).
MESSAGE lx_error TYPE 'E'.
ENDTRY.

12. Mensajes ALV

" Mostrar mensajes en ALV
DATA: lo_alv TYPE REF TO cl_salv_table,
lt_messages TYPE bapiret2_t.
" Recopilar mensajes
APPEND VALUE bapiret2( type = 'S' message = 'Cargado con exito' ) TO lt_messages.
APPEND VALUE bapiret2( type = 'W' message = '10 registros omitidos' ) TO lt_messages.
" Crear ALV y mostrar mensajes
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. Crear protocolo de mensajes

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.
" Guardar en Application Log
" Ver: Application Logging (BAL)
ENDMETHOD.
ENDCLASS.

14. Mensajes multilingues

" Clase de mensaje ZMYAPP en SE91:
" - Mensaje 001: DE: "Datensatz & wurde gespeichert"
" - Mensaje 001: EN: "Record & has been saved"
" Salida dependiente del idioma (automatica)
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 en 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).
" Verificar cliente
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @ls_order-customer_id
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Devolver mensaje de error 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.

Variables de sistema sy-msg*

VariableDescripcion
sy-msgidClase de mensaje
sy-msgtyTipo de mensaje
sy-msgnoNumero de mensaje
sy-msgv1 - sy-msgv4Variables 1-4

Notas importantes / Mejores practicas

  • Clases de mensaje (SE91) para textos consistentes y traducibles.
  • Tipo S con DISPLAY LIKE ‘E’ para errores sin bloqueo de entrada.
  • INTO para guardar en lugar de mostrar mensajes.
  • BAPIRET2 para colecciones de mensajes en APIs.
  • Excepciones en lugar de MESSAGE para componentes reutilizables.
  • Maximo 4 variables por mensaje (&, &, &, &).
  • Mantener textos de mensaje en SE91, no codificar en duro.
  • Multilingue mediante traduccion en SE91.
  • En RAP usar clases de mensaje especiales (IF_ABAP_BEHV_MESSAGE).
  • Combinar con Application Logging para protocolos persistentes.