ABAP Enumerations : Énumérations type-safe

Catégorie
ABAP-Statements
Publié
Auteur
Johannes

Les Enumerations (énumérations) sont des constantes type-safe qui définissent un ensemble fixe de valeurs. Elles remplacent les CONSTANTS libres et offrent une vérification par le compilateur, une meilleure lisibilité et maintenabilité.

Syntaxe

TYPES: BEGIN OF ENUM <enum_name> [ BASE TYPE <type_base> ] [ STRUCTURE <nom_structure> ],
<valeur1> [ VALUE <n> ],
<valeur2> [ VALUE <n> ],
...
END OF ENUM <enum_name> [ STRUCTURE <nom_structure> ].

Principe de base

  • Les enumerations définissent un ensemble fermé de valeurs
  • Chaque valeur reçoit automatiquement une valeur Integer (0, 1, 2, …)
  • Les variables du type enum ne peuvent accepter que des valeurs valides
  • Vérification par le compilateur empêche les affectations invalides

Exemples

1. Enumeration simple

" Définir l'enumeration
TYPES: BEGIN OF ENUM ty_traffic_light,
red,
yellow,
green,
END OF ENUM ty_traffic_light.
" Déclarer une variable
DATA: lv_light TYPE ty_traffic_light.
" Affecter une valeur
lv_light = red.
" Utiliser dans les conditions
CASE lv_light.
WHEN red.
WRITE: / 'Stop !'.
WHEN yellow.
WRITE: / 'Attention !'.
WHEN green.
WRITE: / 'Avancer !'.
ENDCASE.

2. Comparaison : Enumeration vs. Constantes

" === ANCIEN : Constantes libres (sujet aux erreurs) ===
CONSTANTS: c_status_new TYPE c VALUE 'N',
c_status_approved TYPE c VALUE 'A',
c_status_rejected TYPE c VALUE 'R'.
DATA: lv_status TYPE c.
lv_status = 'X'. " Valeur invalide - pas d'erreur de compilation !
" === NOUVEAU : Enumeration (type-safe) ===
TYPES: BEGIN OF ENUM ty_status,
new,
approved,
rejected,
END OF ENUM ty_status.
DATA: lv_status2 TYPE ty_status.
lv_status2 = approved. " OK
" lv_status2 = 'X'. " ERREUR DE SYNTAXE ! Seules les valeurs enum autorisées

3. Enumeration avec STRUCTURE

" Avec STRUCTURE pour accès qualifié
TYPES: BEGIN OF ENUM ty_order_status STRUCTURE order_status,
open,
processing,
shipped,
delivered,
cancelled,
END OF ENUM ty_order_status STRUCTURE order_status.
DATA: lv_status TYPE ty_order_status.
" Accès qualifié via structure
lv_status = order_status-processing.
CASE lv_status.
WHEN order_status-open.
WRITE: / 'Commande ouverte'.
WHEN order_status-processing.
WRITE: / 'En traitement'.
WHEN order_status-shipped.
WRITE: / 'Expédiée'.
WHEN order_status-delivered.
WRITE: / 'Livrée'.
WHEN order_status-cancelled.
WRITE: / 'Annulée'.
ENDCASE.

4. Valeurs explicites

" Standard : Valeurs automatiques 0, 1, 2, ...
TYPES: BEGIN OF ENUM ty_auto,
val_a, " = 0
val_b, " = 1
val_c, " = 2
END OF ENUM ty_auto.
" Affecter des valeurs explicites
TYPES: BEGIN OF ENUM ty_http_status STRUCTURE http_status BASE TYPE i,
ok VALUE 200,
created VALUE 201,
bad_request VALUE 400,
unauthorized VALUE 401,
not_found VALUE 404,
server_error VALUE 500,
END OF ENUM ty_http_status STRUCTURE http_status.
DATA: lv_http TYPE ty_http_status.
lv_http = http_status-not_found.
WRITE: / 'Statut HTTP:', CONV i( lv_http ). " 404

5. BASE TYPE

" Enumeration basée sur String
TYPES: BEGIN OF ENUM ty_color STRUCTURE color BASE TYPE string,
red VALUE `#FF0000`,
green VALUE `#00FF00`,
blue VALUE `#0000FF`,
white VALUE `#FFFFFF`,
black VALUE `#000000`,
END OF ENUM ty_color STRUCTURE color.
DATA: lv_color TYPE ty_color.
lv_color = color-blue.
" Extraire la valeur
DATA(lv_hex) = CONV string( lv_color ).
WRITE: / 'Code couleur:', lv_hex. " #0000FF

6. Enumeration dans les classes

CLASS lcl_order DEFINITION.
PUBLIC SECTION.
" Enumeration comme type de classe
TYPES: BEGIN OF ENUM ty_status STRUCTURE status,
draft,
submitted,
approved,
rejected,
END OF ENUM ty_status STRUCTURE status.
METHODS: constructor,
set_status IMPORTING iv_status TYPE ty_status,
get_status RETURNING VALUE(rv_status) TYPE ty_status,
approve,
reject.
PRIVATE SECTION.
DATA: mv_status TYPE ty_status.
ENDCLASS.
CLASS lcl_order IMPLEMENTATION.
METHOD constructor.
mv_status = status-draft.
ENDMETHOD.
METHOD set_status.
mv_status = iv_status.
ENDMETHOD.
METHOD get_status.
rv_status = mv_status.
ENDMETHOD.
METHOD approve.
IF mv_status = status-submitted.
mv_status = status-approved.
ENDIF.
ENDMETHOD.
METHOD reject.
IF mv_status = status-submitted.
mv_status = status-rejected.
ENDIF.
ENDMETHOD.
ENDCLASS.
" Utilisation
DATA(lo_order) = NEW lcl_order( ).
lo_order->set_status( lcl_order=>status-submitted ).
lo_order->approve( ).
DATA(lv_current) = lo_order->get_status( ).
IF lv_current = lcl_order=>status-approved.
WRITE: / 'Commande approuvée'.
ENDIF.

7. Enumeration dans SWITCH/COND

TYPES: BEGIN OF ENUM ty_weekday STRUCTURE weekday,
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
END OF ENUM ty_weekday STRUCTURE weekday.
DATA: lv_day TYPE ty_weekday VALUE weekday-friday.
" Avec SWITCH
DATA(lv_type) = SWITCH string( lv_day
WHEN weekday-saturday OR weekday-sunday THEN 'Week-end"
ELSE 'Jour de semaine"
).
" Avec COND
DATA(lv_message) = COND string(
WHEN lv_day = weekday-monday THEN 'Début de semaine"
WHEN lv_day = weekday-friday THEN 'Presque le week-end !"
WHEN lv_day = weekday-saturday OR lv_day = weekday-sunday THEN 'Libre !"
ELSE 'Jour normal"
).
WRITE: / lv_type. " Jour de semaine
WRITE: / lv_message. " Presque le week-end !

8. Enumeration avec VALUE

TYPES: BEGIN OF ENUM ty_priority STRUCTURE priority,
low,
medium,
high,
critical,
END OF ENUM ty_priority STRUCTURE priority.
TYPES: BEGIN OF ty_task,
id TYPE i,
name TYPE string,
priority TYPE ty_priority,
END OF ty_task.
" Initialiser la structure avec enumeration
DATA(ls_task) = VALUE ty_task(
id = 1
name = 'Tâche importante"
priority = priority-high
).
" Table avec enumerations
DATA: lt_tasks TYPE TABLE OF ty_task.
lt_tasks = VALUE #(
( id = 1 name = 'Correction bug' priority = priority-critical )
( id = 2 name = 'Fonctionnalité' priority = priority-medium )
( id = 3 name = 'Documentation' priority = priority-low )
).
" Filtrer par priorité
LOOP AT lt_tasks INTO DATA(ls_t) WHERE priority >= priority-high.
WRITE: / ls_t-id, ls_t-name.
ENDLOOP.

9. Itérer sur les valeurs enum

TYPES: BEGIN OF ENUM ty_size STRUCTURE size,
xs,
s,
m,
l,
xl,
xxl,
END OF ENUM ty_size STRUCTURE size.
" Parcourir toutes les valeurs (avec conversion Integer)
DO.
DATA(lv_size) = CONV ty_size( sy-index - 1 ).
" Vérifier si valeur valide (dans la plage)
IF lv_size > size-xxl.
EXIT.
ENDIF.
WRITE: / 'Taille:', lv_size.
ENDDO.

10. Enumeration dans les interfaces

INTERFACE lif_document.
TYPES: BEGIN OF ENUM ty_doc_type STRUCTURE doc_type,
invoice,
credit_memo,
delivery_note,
quotation,
END OF ENUM ty_doc_type STRUCTURE doc_type.
METHODS: get_type RETURNING VALUE(rv_type) TYPE ty_doc_type.
ENDINTERFACE.
CLASS lcl_invoice DEFINITION.
PUBLIC SECTION.
INTERFACES: lif_document.
ENDCLASS.
CLASS lcl_invoice IMPLEMENTATION.
METHOD lif_document~get_type.
rv_type = lif_document=>doc_type-invoice.
ENDMETHOD.
ENDCLASS.

11. Convertir enum en String

TYPES: BEGIN OF ENUM ty_payment STRUCTURE payment,
cash,
credit_card,
bank_transfer,
paypal,
END OF ENUM ty_payment STRUCTURE payment.
DATA: lv_payment TYPE ty_payment VALUE payment-credit_card.
" Nom de l'enum comme String (Reflection)
DATA(lo_type) = CAST cl_abap_enumdescr(
cl_abap_typedescr=>describe_by_data( lv_payment )
).
" Tous les membres avec noms
LOOP AT lo_type->members INTO DATA(ls_member).
WRITE: / ls_member-name, '=', ls_member-value.
ENDLOOP.
" Sortie :
" CASH = 0
" CREDIT_CARD = 1
" BANK_TRANSFER = 2
" PAYPAL = 3

12. Exemple pratique : Machine à états

CLASS lcl_document_workflow DEFINITION.
PUBLIC SECTION.
TYPES: BEGIN OF ENUM ty_state STRUCTURE state,
draft,
pending_review,
approved,
published,
archived,
END OF ENUM ty_state STRUCTURE state.
METHODS: constructor,
submit RETURNING VALUE(rv_success) TYPE abap_bool,
approve RETURNING VALUE(rv_success) TYPE abap_bool,
publish RETURNING VALUE(rv_success) TYPE abap_bool,
archive RETURNING VALUE(rv_success) TYPE abap_bool,
get_state RETURNING VALUE(rv_state) TYPE ty_state,
get_available_actions RETURNING VALUE(rt_actions) TYPE string_table.
PRIVATE SECTION.
DATA: mv_state TYPE ty_state.
ENDCLASS.
CLASS lcl_document_workflow IMPLEMENTATION.
METHOD constructor.
mv_state = state-draft.
ENDMETHOD.
METHOD submit.
IF mv_state = state-draft.
mv_state = state-pending_review.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD approve.
IF mv_state = state-pending_review.
mv_state = state-approved.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD publish.
IF mv_state = state-approved.
mv_state = state-published.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD archive.
IF mv_state = state-published.
mv_state = state-archived.
rv_success = abap_true.
ENDIF.
ENDMETHOD.
METHOD get_state.
rv_state = mv_state.
ENDMETHOD.
METHOD get_available_actions.
rt_actions = SWITCH #( mv_state
WHEN state-draft THEN VALUE #( ( `Submit` ) )
WHEN state-pending_review THEN VALUE #( ( `Approve` ) ( `Reject` ) )
WHEN state-approved THEN VALUE #( ( `Publish` ) )
WHEN state-published THEN VALUE #( ( `Archive` ) )
ELSE VALUE #( )
).
ENDMETHOD.
ENDCLASS.

Enum vs. Domain vs. Constantes

AspectEnumerationDomainConstantes
Type-safetyOui (Compilateur)Oui (DDIC)Non
PortéeLocale ou GlobaleGlobale (DDIC)Locale ou Globale
Vérification valeurCompile-timeRuntimeAucune
TextesManuelTable de valeursAucun
UsageLogique moderneChamps DBCode legacy

Remarques importantes / Bonnes pratiques

  • Utiliser STRUCTURE pour accès qualifié (status-approved au lieu de juste approved).
  • Les enumerations sont type-safe – les valeurs invalides entraînent des erreurs de syntaxe.
  • BASE TYPE pour les enumerations non basées sur Integer (par ex. String).
  • VALUE explicite uniquement si nécessaire (par ex. codes statut HTTP, mapping vers valeurs externes).
  • Les enumerations remplacent les constantes libres pour une meilleure maintenabilité.
  • cl_abap_enumdescr pour Reflection (lire les noms).
  • Combinez avec SWITCH et CASE pour des branchements propres.
  • Les enumerations peuvent être définies dans CLASS et INTERFACE.
  • Les comparaisons avec =, <>, <, > sont possibles (basées sur la valeur ordinale).
  • Idéal pour les Machines à états, champs de statut et options configurables.