Enumeraciones en ABAP: Tipos seguros para valores fijos

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

Las Enumeraciones (ENUM) son un tipo especial de datos en ABAP que definen un conjunto fijo de valores con nombre. Proporcionan seguridad de tipos y hacen que el codigo sea mas legible que las constantes clasicas.

Sintaxis

TYPES: BEGIN OF ENUM <nombre_enum> [ BASE TYPE <tipo_base> ] [ STRUCTURE <estructura> ],
<valor1> [ VALUE <valor> ],
<valor2> [ VALUE <valor> ],
...
END OF ENUM <nombre_enum>.

Propiedades

  • Tipo-seguro: Solo se permiten los valores definidos
  • Tipo base: Por defecto I (Integer), pero personalizable
  • Estructura opcional: Acceso a valores internos a traves de estructura
  • VALUE IS INITIAL: Primer valor se considera inicial

Ejemplos

1. Enumeracion simple

TYPES: BEGIN OF ENUM ty_status,
open,
in_process,
completed,
cancelled,
END OF ENUM ty_status.
DATA: lv_status TYPE ty_status.
lv_status = in_process.
IF lv_status = completed.
WRITE: / 'El pedido esta completado'.
ENDIF.

2. Enumeracion con estructura (para acceso a valores)

TYPES: BEGIN OF ENUM ty_priority STRUCTURE priority,
low,
medium,
high,
critical,
END OF ENUM ty_priority.
DATA: lv_prio TYPE ty_priority.
lv_prio = priority-high.
CASE lv_prio.
WHEN priority-low.
WRITE: / 'Prioridad baja'.
WHEN priority-medium.
WRITE: / 'Prioridad media'.
WHEN priority-high.
WRITE: / 'Prioridad alta'.
WHEN priority-critical.
WRITE: / 'Prioridad critica!'.
ENDCASE.

3. Enumeracion con valores especificos

TYPES: BEGIN OF ENUM ty_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.
DATA: lv_code TYPE ty_http_status.
lv_code = not_found.
WRITE: / 'Codigo HTTP:', lv_code. " Salida: 404

4. Enumeracion con tipo base CHAR

TYPES: BEGIN OF ENUM ty_document_type BASE TYPE c LENGTH 2
STRUCTURE doc_type,
invoice VALUE 'IV',
credit_memo VALUE 'CM',
debit_memo VALUE 'DM',
order VALUE 'OR',
END OF ENUM ty_document_type.
DATA: lv_type TYPE ty_document_type.
lv_type = doc_type-invoice.
WRITE: / 'Tipo de documento:', lv_type. " Salida: IV

5. VALUE IS INITIAL - Marcar primer valor como inicial

TYPES: BEGIN OF ENUM ty_approval_status STRUCTURE approval,
undefined VALUE IS INITIAL, " Este es el valor inicial!
pending,
approved,
rejected,
END OF ENUM ty_approval_status.
DATA: lv_approval TYPE ty_approval_status.
" lv_approval ya esta en 'undefined'
IF lv_approval = approval-undefined.
WRITE: / 'El estado aun no esta establecido'.
ENDIF.
" CLEAR tambien establece a 'undefined'
lv_approval = approval-approved.
CLEAR lv_approval.
" lv_approval ahora es de nuevo 'undefined'

6. Enumeracion en clases

CLASS zcl_order DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ENUM ty_order_status STRUCTURE status,
draft,
submitted,
approved,
rejected,
completed,
END OF ENUM ty_order_status.
METHODS:
constructor IMPORTING iv_id TYPE string,
set_status IMPORTING iv_status TYPE ty_order_status,
get_status RETURNING VALUE(rv_status) TYPE ty_order_status,
get_status_text RETURNING VALUE(rv_text) TYPE string.
PRIVATE SECTION.
DATA: mv_id TYPE string,
mv_status TYPE ty_order_status.
ENDCLASS.
CLASS zcl_order IMPLEMENTATION.
METHOD constructor.
mv_id = iv_id.
mv_status = status-draft.
ENDMETHOD.
METHOD set_status.
mv_status = iv_status.
ENDMETHOD.
METHOD get_status.
rv_status = mv_status.
ENDMETHOD.
METHOD get_status_text.
rv_text = SWITCH #( mv_status
WHEN status-draft THEN 'Borrador'
WHEN status-submitted THEN 'Enviado'
WHEN status-approved THEN 'Aprobado'
WHEN status-rejected THEN 'Rechazado'
WHEN status-completed THEN 'Completado'
).
ENDMETHOD.
ENDCLASS.

7. Enumeracion con metodos auxiliares

CLASS zcl_enum_helper DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ENUM ty_color STRUCTURE color,
red,
green,
blue,
yellow,
END OF ENUM ty_color.
CLASS-METHODS:
to_string
IMPORTING iv_color TYPE ty_color
RETURNING VALUE(rv_string) TYPE string,
from_string
IMPORTING iv_string TYPE string
RETURNING VALUE(rv_color) TYPE ty_color
RAISING cx_sy_conversion_no_enum_value.
ENDCLASS.
CLASS zcl_enum_helper IMPLEMENTATION.
METHOD to_string.
rv_string = SWITCH #( iv_color
WHEN color-red THEN 'ROJO'
WHEN color-green THEN 'VERDE'
WHEN color-blue THEN 'AZUL'
WHEN color-yellow THEN 'AMARILLO'
).
ENDMETHOD.
METHOD from_string.
rv_color = SWITCH #( to_upper( iv_string )
WHEN 'ROJO' THEN color-red
WHEN 'RED' THEN color-red
WHEN 'VERDE' THEN color-green
WHEN 'GREEN' THEN color-green
WHEN 'AZUL' THEN color-blue
WHEN 'BLUE' THEN color-blue
WHEN 'AMARILLO' THEN color-yellow
WHEN 'YELLOW' THEN color-yellow
ELSE THROW cx_sy_conversion_no_enum_value( )
).
ENDMETHOD.
ENDCLASS.

8. Enumeracion para maquinas de estado

CLASS zcl_workflow DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES: BEGIN OF ENUM ty_state STRUCTURE state,
initial VALUE IS INITIAL,
created,
submitted,
in_review,
approved,
rejected,
archived,
END OF ENUM ty_state.
METHODS:
transition
IMPORTING iv_new_state TYPE ty_state
RAISING zcx_invalid_transition,
get_allowed_transitions
RETURNING VALUE(rt_states) TYPE STANDARD TABLE OF ty_state
WITH EMPTY KEY.
PRIVATE SECTION.
DATA: mv_current_state TYPE ty_state.
METHODS is_valid_transition
IMPORTING iv_from TYPE ty_state
iv_to TYPE ty_state
RETURNING VALUE(rv_valid) TYPE abap_bool.
ENDCLASS.
CLASS zcl_workflow IMPLEMENTATION.
METHOD is_valid_transition.
" Definir transiciones validas
rv_valid = abap_false.
CASE iv_from.
WHEN state-initial.
rv_valid = xsdbool( iv_to = state-created ).
WHEN state-created.
rv_valid = xsdbool( iv_to = state-submitted ).
WHEN state-submitted.
rv_valid = xsdbool( iv_to = state-in_review OR
iv_to = state-rejected ).
WHEN state-in_review.
rv_valid = xsdbool( iv_to = state-approved OR
iv_to = state-rejected ).
WHEN state-approved.
rv_valid = xsdbool( iv_to = state-archived ).
WHEN state-rejected.
rv_valid = xsdbool( iv_to = state-archived OR
iv_to = state-created ).
ENDCASE.
ENDMETHOD.
METHOD transition.
IF NOT is_valid_transition( iv_from = mv_current_state
iv_to = iv_new_state ).
RAISE EXCEPTION TYPE zcx_invalid_transition.
ENDIF.
mv_current_state = iv_new_state.
ENDMETHOD.
METHOD get_allowed_transitions.
" Devolver todas las transiciones validas desde el estado actual
DATA(lt_all_states) = VALUE STANDARD TABLE OF ty_state(
( state-initial )
( state-created )
( state-submitted )
( state-in_review )
( state-approved )
( state-rejected )
( state-archived )
).
LOOP AT lt_all_states INTO DATA(lv_state).
IF is_valid_transition( iv_from = mv_current_state
iv_to = lv_state ).
APPEND lv_state TO rt_states.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.

9. Enumeracion en CDS Views (como valores de dominio)

En CDS Views se pueden definir valores fijos similares a enumeraciones:

@EndUserText.label: 'Estado del Pedido'
define type ZDE_OrderStatus : abap.char(1) enum {
Open = 'O';
InProcess = 'P';
Completed = 'C';
Cancelled = 'X';
}

Uso en un View:

define view entity ZI_Order as select from zorder {
key order_id,
@ObjectModel.text.element: ['StatusText']
cast(status as ZDE_OrderStatus) as Status,
case status
when 'O' then 'Abierto'
when 'P' then 'En Proceso'
when 'C' then 'Completado'
when 'X' then 'Cancelado'
end as StatusText
}

10. Conversion entre Enum e Integer

TYPES: BEGIN OF ENUM ty_level STRUCTURE level,
beginner, " = 0
intermediate," = 1
advanced, " = 2
expert, " = 3
END OF ENUM ty_level.
DATA: lv_level TYPE ty_level,
lv_int TYPE i.
" Enum a Integer
lv_level = level-advanced.
lv_int = CONV #( lv_level ). " = 2
" Integer a Enum (con CONV)
lv_int = 1.
lv_level = CONV #( lv_int ). " = intermediate
" Error si el valor esta fuera de rango!
TRY.
lv_int = 99.
lv_level = CONV #( lv_int ).
CATCH cx_sy_conversion_no_enum_value.
WRITE: / 'Valor de enum invalido'.
ENDTRY.

Resumen

AspectoDescripcion
Tipo basePor defecto I, personalizable con BASE TYPE
EstructuraAcceso a traves de STRUCTURE nombre
Valor inicialVALUE IS INITIAL para el primer valor
Valores especificosVALUE <valor> para valores personalizados
Seguridad de tiposSolo se permiten los valores definidos

Notas importantes / Mejores practicas

  • Usar Enums en lugar de constantes para valores fijos - mas seguro.
  • STRUCTURE permite acceso claro como estado-aprobado.
  • VALUE IS INITIAL debe usarse para representar “sin valor”.
  • El tipo base puede ser I, INT1, INT2, CHAR, etc.
  • Las Enums no se pueden extender - planear cuidadosamente.
  • Para serializacion (JSON, etc.): convertir a tipo base.
  • Enums son ideales para maquinas de estado y validaciones.
  • Excepcion CX_SY_CONVERSION_NO_ENUM_VALUE para valores invalidos.