ABAP Message Handling : Instruction MESSAGE

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

Message Handling en ABAP permet la sortie structuree de messages utilisateur et systeme. Avec l’instruction MESSAGE et les classes de messages, vous pouvez creer des messages coherents et multilingues.

Types de messages

TypeNomComportement
AAbandon (Abend)Le programme se termine
EErreur (Error)L’entree est bloquee
WAvertissement (Warning)Confirmation possible
IInformationMessage popup
SStatut (Success)Barre de statut
XExitTermine le programme avec dump

Syntaxe

" Avec classe de messages et numero
MESSAGE e001(zmessages).
" Avec variables
MESSAGE e002(zmessages) WITH lv_value1 lv_value2.
" Dynamique
MESSAGE ID 'ZMESSAGES' TYPE 'E' NUMBER '001'.
" Enregistrer dans une variable
MESSAGE e001(zmessages) INTO DATA(lv_message).

Exemples

1. Messages simples

" Message de succes dans la barre de statut
MESSAGE s001(zmessages).
" 'Operation effectuee avec succes"
" Message d'erreur
MESSAGE e002(zmessages).
" 'Erreur lors du traitement"
" Avertissement
MESSAGE w003(zmessages).
" 'Attention : Les donnees ont ete modifiees"
" Information (Popup)
MESSAGE i004(zmessages).
" 'Veuillez prendre note des informations"

2. Messages avec variables

" Texte du message : "Client & a ete cree"
MESSAGE s010(zmessages) WITH lv_kunnr.
" Texte du message : "Commande & Position & a ete modifiee"
MESSAGE s011(zmessages) WITH lv_vbeln lv_posnr.
" Jusqu'a 4 variables possibles
MESSAGE e012(zmessages) WITH lv_var1 lv_var2 lv_var3 lv_var4.

3. Enregistrer le message dans une variable

" Ne pas afficher le message, mais l'enregistrer
MESSAGE e001(zmessages) INTO DATA(lv_message).
" Avec variables
MESSAGE e010(zmessages) WITH lv_kunnr INTO lv_message.
" sy-msgty, sy-msgid, sy-msgno sont renseignes
WRITE: / 'Type:', sy-msgty,
/ 'Classe:', sy-msgid,
/ 'Numero:', sy-msgno,
/ 'Texte:', lv_message.

4. Messages dynamiques

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.
" Sortie dynamique
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2.
" Ou avec INTO
MESSAGE ID lv_msgid TYPE lv_msgty NUMBER lv_msgno
WITH lv_msgv1 lv_msgv2
INTO DATA(lv_text).

5. Messages depuis les exceptions

TRY.
" Code qui leve une exception
DATA(lo_processor) = NEW zcl_processor( ).
lo_processor->process( ).
CATCH cx_root INTO DATA(lx_error).
" Texte de l'exception comme message
MESSAGE lx_error TYPE 'E'.
" Ou dans la barre de statut
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.

6. DISPLAY LIKE pour l’apparence de la barre de statut

" Message d'erreur comme message de statut (pas de popup)
MESSAGE e001(zmessages) DISPLAY LIKE 'S'.
" Succes dans la barre de statut avec icone d'erreur
MESSAGE s001(zmessages) DISPLAY LIKE 'E'.
" Information affichee comme avertissement
MESSAGE i001(zmessages) DISPLAY LIKE 'W'.

7. Classe de messages comme constantes

CLASS zcl_messages DEFINITION.
PUBLIC SECTION.
CONSTANTS:
" Classe de messages
c_msgid TYPE sy-msgid VALUE 'ZMYAPP',
" Numeros de messages
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.
" Utilisation
zcl_messages=>show_success( 'Client 1000' ).
DATA(lv_msg) = zcl_messages=>get_message(
iv_msgno = zcl_messages=>c_error_not_found
iv_var1 = 'Commande"
).

8. BAPIRET2 pour les messages de retour

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 depuis les 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.
" Utilisation
DATA(lo_collector) = NEW zcl_message_collector( ).
lo_collector->add_success( 'Traitement demarre' ).
lo_collector->add_error(
iv_msgid = 'ZMYAPP"
iv_msgno = '002"
iv_var1 = 'Client 1000"
).
IF lo_collector->has_errors( ).
" Traitement des erreurs
ENDIF.

9. Lire le texte du message par programme

" Lire le texte du message depuis T100
SELECT SINGLE text FROM t100
WHERE sprsl = @sy-langu
AND arbgb = 'ZMYAPP"
AND msgnr = '001"
INTO @DATA(lv_text).
" Ou avec un module fonction
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 dans les reports (AT SELECTION-SCREEN)

REPORT zmessage_demo.
PARAMETERS: p_kunnr TYPE kunnr.
" Verification a la saisie
AT SELECTION-SCREEN ON p_kunnr.
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @p_kunnr
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Message d'erreur - le curseur reste sur le champ
MESSAGE e010(zmyapp) WITH p_kunnr.
ENDIF.
START-OF-SELECTION.
" Message de succes
MESSAGE s001(zmyapp).

11. Message avec RAISING dans les methodes

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.
" Encapsuler le message dans une 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.
" Utilisation
TRY.
DATA(ls_customer) = lo_service->get_customer( '0000001000' ).
CATCH zcx_not_found INTO DATA(lx_error).
MESSAGE lx_error TYPE 'E'.
ENDTRY.

12. Messages ALV

" Afficher les messages dans ALV
DATA: lo_alv TYPE REF TO cl_salv_table,
lt_messages TYPE bapiret2_t.
" Collecter les messages
APPEND VALUE bapiret2( type = 'S' message = 'Charge avec succes' ) TO lt_messages.
APPEND VALUE bapiret2( type = 'W' message = '10 enregistrements ignores' ) TO lt_messages.
" Creer l'ALV et afficher les messages
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. Creer un journal de messages

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.
" Enregistrer dans Application Logging
" Voir : Application Logging (BAL)
ENDMETHOD.
ENDCLASS.

14. Messages multilingues

" Classe de messages ZMYAPP dans SE91 :
" - Message 001 : DE : "Datensatz & wurde gespeichert"
" - Message 001 : EN : "Record & has been saved"
" Sortie dependante de la langue (automatique)
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 dans 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).
" Verifier le client
SELECT SINGLE kunnr FROM kna1
WHERE kunnr = @ls_order-customer_id
INTO @DATA(lv_kunnr).
IF sy-subrc <> 0.
" Retourner le message d'erreur 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 systeme sy-msg*

VariableDescription
sy-msgidClasse de messages
sy-msgtyType de message
sy-msgnoNumero de message
sy-msgv1 - sy-msgv4Variables 1-4

Remarques importantes / Bonnes pratiques

  • Classes de messages (SE91) pour des textes coherents et traduisibles.
  • Type S avec DISPLAY LIKE ‘E’ pour les erreurs sans blocage de saisie.
  • INTO pour enregistrer les messages au lieu de les afficher.
  • BAPIRET2 pour les collections de messages dans les APIs.
  • Exceptions au lieu de MESSAGE pour les composants reutilisables.
  • Maximum 4 variables par message (&, &, &, &).
  • Maintenir les textes de messages dans SE91, ne pas les coder en dur.
  • Multilinguisme par traduction dans SE91.
  • Dans RAP, utiliser des classes de messages speciales (IF_ABAP_BEHV_MESSAGE).
  • Combiner avec Application Logging pour les journaux persistants.