Sentencia CASE en ABAP: Bifurcaciones múltiples para código más claro

Kategorie
ABAP-Statements
Veröffentlicht
Autor
Johannes

La sentencia CASE es una estructura de control para bifurcaciones múltiples en ABAP. Ofrece una alternativa a menudo más clara que una larga cadena de sentencias IF...ELSEIF...ELSE...ENDIF, especialmente cuando el flujo del programa depende de cuál de varios valores específicos y discretos tiene una única variable (o expresión).

Se verifica el valor de un operando y luego se ejecuta el bloque de código que corresponde a ese valor.

Sintaxis

CASE <operando>.
WHEN <valor1> [OR <valor1a> OR <valor1b> ...].
" Bloque de instrucciones 1
" Se ejecuta si <operando> = <valor1> O <valor1a> O <valor1b> ...
[Instrucciones...]
WHEN <valor2> [OR <valor2a> ...].
" Bloque de instrucciones 2
" Se ejecuta si <operando> = <valor2> O <valor2a> ...
" Y ninguna condición WHEN anterior coincidió.
[Instrucciones...]
" ... más ramas WHEN ...
[WHEN OTHERS. " Rama opcional para todos los demás casos
" Bloque de instrucciones 'Otros'
" Se ejecuta si <operando> NO coincide con ninguno de los valores
" en las ramas WHEN anteriores.
[Instrucciones...]]
ENDCASE.
  • CASE <operando>: Inicia la estructura. <operando> es la variable o expresión cuyo valor se verifica.
  • WHEN <valor>: Define un caso posible (una bifurcación). <valor> es un valor constante (por ejemplo, un literal como 'A', 123 o una constante) con el que se compara el <operando>.
  • OR <valorX>: Opcional. Permite especificar múltiples valores para los cuales se ejecuta el mismo bloque de instrucciones.
  • Bloque de instrucciones: El bloque de código ABAP que se ejecuta cuando el valor del <operando> coincide con uno de los valores en la rama WHEN.
  • WHEN OTHERS: Una rama opcional que captura todos los valores que no fueron cubiertos por ninguna de las ramas WHEN anteriores. Es una buena práctica incluir esta rama frecuentemente para manejar valores inesperados.
  • ENDCASE: Cierra obligatoriamente la estructura CASE.

Funcionamiento y flujo

  1. El valor del <operando> se determina una vez.
  2. Este valor se compara secuencialmente (de arriba hacia abajo) con los valores en las ramas WHEN.
  3. Tan pronto como el valor del operando coincide con un valor en una rama WHEN, se ejecuta el bloque de instrucciones correspondiente.
  4. Importante: Después de ejecutar este bloque, el control salta inmediatamente a la instrucción después de ENDCASE. No se verifican ni ejecutan más ramas WHEN dentro de la misma estructura CASE - “el primer WHEN coincidente gana”.
  5. Si ninguna de las ramas WHEN coincide, se ejecuta el bloque WHEN OTHERS (si existe).
  6. Si ninguna de las ramas WHEN coincide y no hay bloque WHEN OTHERS, no se ejecuta ninguno de los bloques dentro de la estructura CASE, y el programa continúa después de ENDCASE.

Diferencia con IF...ELSEIF...

  • CASE: Ideal cuando se verifica un valor contra múltiples valores fijos individuales. A menudo más legible y corto.
  • IF...ELSEIF...: Más flexible para condiciones complejas, verificaciones de rango (>, <), combinaciones (AND, OR) o cuando se deben verificar diferentes variables en las condiciones.

Alternativa moderna: El operador SWITCH (desde ABAP 7.40)

Para asignaciones basadas en el valor de una variable, existe el operador SWITCH, que ofrece una sintaxis inline más compacta:

DATA(descripcion) = SWITCH tipo_adicional( medio_transporte
WHEN 'B' THEN 'Bicicleta'
WHEN 'A' THEN 'Auto'
WHEN 'U' THEN 'Autobús'
ELSE 'Desconocido' ).

Sin embargo, CASE sigue siendo la sentencia estándar para controlar bloques de instrucciones.

Ejemplos

1. CASE para un código de estado (carácter)

DATA document_status TYPE c LENGTH 1.
document_status = 'R'. " R=Released, B=Blocked, N=New
CASE document_status.
WHEN 'N'.
WRITE / 'El documento es nuevo y no ha sido procesado.'.
WHEN 'R'.
WRITE / 'El documento está liberado.'. " Este bloque se ejecuta
WHEN 'B'.
WRITE / 'El documento está bloqueado.'.
WHEN OTHERS.
WRITE / 'Advertencia: Estado de documento desconocido:', document_status.
ENDCASE.

2. CASE para números de mes con OR

DATA current_month TYPE i.
current_month = sy-datum+4(2). " Extrae el mes de la fecha del sistema
CASE current_month.
WHEN 1 OR 2 OR 3.
WRITE / 'Primer trimestre'.
WHEN 4 OR 5 OR 6.
WRITE / 'Segundo trimestre'. " Este bloque se ejecuta en abril
WHEN 7 OR 8 OR 9.
WRITE / 'Tercer trimestre'.
WHEN 10 OR 11 OR 12.
WRITE / 'Cuarto trimestre'.
WHEN OTHERS.
WRITE / '¡Mes extraído inválido!'. " No debería ocurrir
ENDCASE.

3. CASE para entrada de usuario

DATA user_command TYPE sy-ucomm. " Campo del sistema para códigos OK
user_command = 'SAVE'.
CASE user_command.
WHEN 'SAVE'.
WRITE / 'Acción: Ejecutando guardado.'.
" ... Código para guardar ...
WHEN 'BACK' OR 'EXIT' OR 'CANCEL'.
WRITE / 'Acción: Atrás o Cancelar.'.
LEAVE TO SCREEN 0. " Acción de ejemplo
WHEN OTHERS.
WRITE / 'Acción: Comando desconocido o no manejado.'.
ENDCASE.

4. CASE sin WHEN OTHERS

DATA flag TYPE c LENGTH 1 VALUE 'X'.
CASE flag.
WHEN 'A'.
WRITE / 'Flag es A'.
WHEN 'B'.
WRITE / 'Flag es B'.
ENDCASE.
" Como flag = 'X' y no existe WHEN OTHERS, no se ejecuta ningún bloque.
WRITE / 'Después del bloque CASE.'.

Notas importantes / Mejores prácticas

  • CASE es muy útil para mejorar la legibilidad en comparaciones de un operando con muchos valores fijos.
  • Usa la rama WHEN OTHERS para asegurar que tu programa responda de forma robusta a valores inesperados o no manejados explícitamente.
  • Recuerda la lógica “First Match Wins”: Solo se ejecuta la primera rama WHEN coincidente.
  • No olvides el ENDCASE final.