Curso de Cobol y PowerCobol

¿Cómo funciona EVALUATE de COBOL?

Capítulo 26: El condicional EVALUATE

Veamos otro condicional más de COBOL, el conocido como EVALUATE.

El condicional EVALUATE

El condicional EVALUATE de COBOL, puede ser de gran utilidad cuando necesitamos evaluar múltiples condiciones, que pueden llegar a ser repetitivas. También, puede reemplazar en múltiples casos al inexistente IF ELSE de COBOL y evitar en muchas ocasiones, los IF anidados del capítulo anterior.

Sintaxis del condicional EVALUATE de COBOL

La sintaxis de EVALUATE es muy parecida a la de un condicional SWITCH o MATCH que tienen otros lenguajes de programación. Para quién ya programe, esta sintaxis le será muy sencilla de entender, no obstante, hay que explicarla para quién no tenga más conocimientos en programación que los proporcionados en este curso.

EVALUATE valor o expresión

           WHEN valor o rango
           Bloque de código

           WHEN valor o rango
           Bloque de código

           WHEN valor o rango
           Bloque de código

		   ...

           WHEN OTHER
           Bloque de código alternativo

END-EVALUATE.

Si no entiendes esto, no te preocupes, ahora verás algunos ejemplos.

Empezamos el bloque EVALUATE con su palabra reservada. Le ponemos valor, variable o expresión que queremos evaluar y una serie de rangos WHEN que serían equivalentes a múltiples IF ELSE IF. Finalmente, tenemos el bloque OTHER que sería equivalente al ELSE. Si no se ejecuta ninguno de los WHEN (todos false), se ejecutará siempre el bloque OTHER, el cual, al igual que el ELSE, no tiene expresión, depende de que al menos, haya un bloque WHEN con cierta expresión.

El nivel 88 de COBOL con múltiples IF

Este código, es uno de los que utilicé en el capítulo 23, para utilizar el nivel 88. En este código, se evalúa con cada IF, cada una de los posibles valores o rangos contemplados en el nivel 88.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       01 Edad PIC 999 VALUE ZEROS.
           88 Joven VALUE 1 THRU 39.
           88 Maduro VALUE 40 THRU 65.
           88 Anciano VALUE 66 THRU 100.

       PROCEDURE DIVISION.
       CompruebaEdad.
      *> Se le solicita la edad al usuario.
       DISPLAY "Introduce tu edad: "
       ACCEPT EDAD.

      *> Se evalúan posibles valores.
       IF Joven THEN
           DISPLAY "Eres joven. " WITH NO ADVANCING
       END-IF

       IF Maduro THEN
           DISPLAY "Eres maduro. " WITH NO ADVANCING
       END-IF

       IF Anciano THEN
           DISPLAY "Eres anciano. " WITH NO ADVANCING
       END-IF

       DISPLAY "Tienes " Edad " años.".

       STOP RUN.
       END PROGRAM Capitulo26.

Sin embargo, hay otra forma de realizar esto. Veamos como funciona con EVALUATE.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 Edad PIC 999 VALUE ZEROS.

       PROCEDURE DIVISION.
       CompruebaEdad.
      *> Se le solicita la edad al usuario.
       DISPLAY "Introduce tu edad: "
       ACCEPT EDAD.

      *> Se evalúan posibles valores.

       EVALUATE Edad

           WHEN 1 THRU 39
           DISPLAY "Eres joven. " WITH NO ADVANCING

           WHEN 40 THRU 65
           DISPLAY "Eres maduro. " WITH NO ADVANCING

           WHEN 66 THRU 100
           DISPLAY "Eres anciano. " WITH NO ADVANCING

           WHEN OTHER
           DISPLAY "Edad incorrecta. " WITH NO ADVANCING

       END-EVALUATE.

       STOP RUN.
       END PROGRAM Capitulo26.

Crear un menú de opciones en COBOL con EVALUATE

Para construir un sencillo menú, puedes utilizar EVALUATE. Los menús, suelen ser malos de escribir con el condicional IF y más en COBOL, que no hay ELSE IF.

El siguiente ejemplo, te muestra un menú en la consola con cuatro opciones. Si pones un número entre el 1 y el 4, se ejecuta uno de los 4 bloques WHEN. En caso contrario, se ejecuta el WHEN OTHER.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 ValorMenu PIC 9 VALUE ZERO.

       PROCEDURE DIVISION.
       Opciones.
       DISPLAY "Por favor, introduzca un número" 
       " de opción y pulse ENTER:".
       
       DISPLAY "1 - Suma".
       DISPLAY "2 - Resta".
       DISPLAY "3 - Multiplicación".
       DISPLAY "4 - División".
       
       ACCEPT ValorMenu.
       
       Menu.
       EVALUATE ValorMenu 
           
           WHEN 1
             DISPLAY "Ha seleccionado la suma."
             
           WHEN 2
             DISPLAY "Ha seleccionado la resta."
             
           WHEN 3
             DISPLAY "Ha seleccionado la multiplicación."
             
           WHEN 4
             DISPLAY "Ha seleccionado la división."
             
           WHEN OTHER
             DISPLAY "Opción incorrecta."
       END-EVALUATE.

       STOP RUN.
       END PROGRAM Capitulo26.

¿Cómo podrías hacer esto con el condicional IF?

Aquí tienes un ejemplo.

Si lo hacemos así, aparentemente, está todo correcto. Si pongo la opción 1, funciona, pero cuando pongo cualquier otra opción, no funciona como debería.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 ValorMenu PIC 9 VALUE ZERO.

       PROCEDURE DIVISION.
       Opciones.
       DISPLAY "Por favor, introduzca un número"
       " de opción y pulse ENTER:".

       DISPLAY "1 - Suma".
       DISPLAY "2 - Resta".
       DISPLAY "3 - Multiplicación".
       DISPLAY "4 - División".

       ACCEPT ValorMenu.

       Menu.
       IF ValorMenu = 1 THEN
           DISPLAY "Ha seleccionado la suma."

           IF ValorMenu = 2 THEN
               DISPLAY "Ha seleccionado la resta."
             
             IF ValorMenu = 3 THEN
               DISPLAY "Ha seleccionado la multiplicación."
               
                 IF ValorMenu = 4 THEN
                 DISPLAY "Ha seleccionado la división."
                 
                 ELSE
                   DISPLAY "Opción incorrecta."
                 END-IF
             END-IF
           END-IF
       END-IF

       STOP RUN.
       END PROGRAM Capitulo26.
Por favor, introduzca un número de opción y pulse ENTER:
1 - Suma
2 - Resta
3 - Multiplicación
4 - División
1
Ha seleccionado la suma.

Ahora, pruebo el 3:

Por favor, introduzca un número de opción y pulse ENTER:
1 - Suma
2 - Resta
3 - Multiplicación
4 - División
3

¿Ves? no se está ejecutando el código más allá del primer IF. Esto es porque están anidados.

Primero, se evalúa el valor 1. Si se cumple, todo correcto. En cambio, si le pongo un 2, 3, 4 o cualquier otra cosa, puesto que la evaluación del primer IF, da false, se salta todo el código que tiene dentro, que son el resto de IF.

En estos casos, puedes hacer dos cosas, haces IF individuales, que pueden crear confusión o producir fallos si tenemos muchos o utilizar bien los IF anidados.

Antes de pasar a ver unos ejemplos con esto, debo indicarte que aquí el tema de los puntos para finalizar, puede jugarte malas pasadas. ¿Te has fijado en todos los END-IF? Ninguno tiene punto. Si se lo pones al primero, los tres siguientes, quedan fuera del código del IF y te dará error. De modo, que lo tengas en cuenta. Quizás debas dejar de poner puntos después del END-IF si lo hacías hasta ahora.

Pasemos a ver primero el ejemplo con los IF individuales:

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 ValorMenu PIC 9 VALUE ZERO.

       PROCEDURE DIVISION.
       Opciones.
       DISPLAY "Por favor, introduzca un número"
       " de opción y pulse ENTER:".

       DISPLAY "1 - Suma".
       DISPLAY "2 - Resta".
       DISPLAY "3 - Multiplicación".
       DISPLAY "4 - División".

       ACCEPT ValorMenu.

       Menu.
       IF ValorMenu = 1 THEN
         DISPLAY "Ha seleccionado la suma."
       END-IF
       
       IF ValorMenu = 2 THEN
         DISPLAY "Ha seleccionado la resta."
       END-IF
       
       IF ValorMenu = 3 THEN
         DISPLAY "Ha seleccionado la multiplicación."
       END-IF
               
       IF ValorMenu = 4 THEN
         DISPLAY "Ha seleccionado la división."
                 
       ELSE
         DISPLAY "Opción incorrecta."
       END-IF

       STOP RUN.
       END PROGRAM Capitulo26.

Ahora, tenemos 4 IF, el último, lleva un ELSE para contemplar cualquier valor diferente a 1, 2, 3 o 4.

Ahora, pruebo la opción 1, y funciona, solo que también me salta el ELSE. Esto es porque no están como conjunto. Primero, se evalúa si ValorMenu vale 1. Si es true, se ejecuta. Si es false, pasamos al siguiente. Hasta aquí todo bien. El problema, está en que si se cumple con el valor 1, 2 o 3, el valor 4 del último IF, da false, lo que hace, que se ejecute el código de su ELSE.

Por favor, introduzca un número de opción y pulse ENTER:
1 - Suma
2 - Resta
3 - Multiplicación
4 - División
1
Ha seleccionado la suma.
Opción incorrecta.

Pues ahora, veamos la segunda forma, que se trata de hacer un uso correcto de los IF anidados, los cuales, como puedes ver, no son fáciles de manejar.

Con esta técnica, anidamos una sucesión de posibles valores true, emulando a la perfección el comportamiento del IF ELSE.

Primero, se evalúa el primer IF. Si da false, se ejecuta su ELSE ¿Qué lleva el ELSE? El primer IF anidado. Y así hasta el último y acordándose de cerrar cada uno de ellos al final.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 ValorMenu PIC 9 VALUE ZERO.

       PROCEDURE DIVISION.
       Opciones.
       DISPLAY "Por favor, introduzca un número"
       " de opción y pulse ENTER:".

       DISPLAY "1 - Suma".
       DISPLAY "2 - Resta".
       DISPLAY "3 - Multiplicación".
       DISPLAY "4 - División".

       ACCEPT ValorMenu.

       Menu.
       IF ValorMenu = 1 THEN
       DISPLAY "Ha seleccionado la suma."
         
       ELSE   
         IF ValorMenu = 2 THEN
           DISPLAY "Ha seleccionado la resta."
             
         ELSE
           IF ValorMenu = 3 THEN
             DISPLAY "Ha seleccionado la multiplicación."
               
           ELSE
             IF ValorMenu = 4 THEN
               DISPLAY "Ha seleccionado la división."
                 
             ELSE
               DISPLAY "Opción incorrecta."
             END-IF
           END-IF
         END-IF
       END-IF

       STOP RUN.
       END PROGRAM Capitulo26.

Como puedes ver, es una estructura muy complicada y susceptible de fallos frente al EVALUATE. ¿Y si esto fuesen 20 opciones de menú?

También, se te podría ocurrir otra forma más de hacer esto con IF. Crear múltiples IF individuales, cada uno con su ELSE. El problema de esto, es que repites todo el código del ELSE una y otra vez. Además, de que no funcionaría como podríamos pensar.

⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo26.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
       77 ValorMenu PIC 9 VALUE ZERO.

       PROCEDURE DIVISION.
       Opciones.
       DISPLAY "Por favor, introduzca un número"
       " de opción y pulse ENTER:".

       DISPLAY "1 - Suma".
       DISPLAY "2 - Resta".
       DISPLAY "3 - Multiplicación".
       DISPLAY "4 - División".

       ACCEPT ValorMenu.

       Menu.
       IF ValorMenu = 1 THEN
         DISPLAY "Ha seleccionado la suma."
       ELSE  
         DISPLAY "Opción incorrecta." 
       END-IF
       
       IF ValorMenu = 2 THEN
         DISPLAY "Ha seleccionado la resta."
       ELSE
         DISPLAY "Opción incorrecta."
       END-IF
       
       IF ValorMenu = 3 THEN
         DISPLAY "Ha seleccionado la multiplicación."
       ELSE
         DISPLAY "Opción incorrecta."
       END-IF
       
       IF ValorMenu = 4 THEN
         DISPLAY "Ha seleccionado la división."
       ELSE
         DISPLAY "Opción incorrecta."
       END-IF

       STOP RUN.
       END PROGRAM Capitulo26.

En este caso, al darle un valor de 1, se cumple el primer IF. No obstante, el resto no y se ejecutan sus ELSE.

1 - Suma
2 - Resta
3 - Multiplicación
4 - División
1
Ha seleccionado la suma.
Opción incorrecta.
Opción incorrecta.
Opción incorrecta.

El punto y coma en COBOL

Para terminar el capítulo, te dejo una pequeña curiosidad de COBOL. Puedes utilizar el punto y coma, pero es ignorado por el compilador.

Esto no da error:

IDENTIFICATION DIVISION;.

Pero puedes demostrar que el punto y coma no finaliza nada, quitando el punto obligatorio de esta línea. Esto si que dará error:

IDENTIFICATION DIVISION;

Esto, para que lo utilice a quien le duela no cerrar instrucciones con punto y coma. No obstante, en los sitios donde se pone punto obligatorio, está muy sobrado y puede crear confusión.


Comentarios

Si te quedan dudas sobre el temario, sobre Cobol, o cualquier otra cosa relacionada o simplemente quieres agradecer, aquí tienes tu sitio para dejar tu granito de arena. Gracias por tus comentarios y por darle vida a este sitio web.

Programación Fácil YouTube

Suscríbete

Si te ha gustado este curso y crees que el trabajo merece la pena, te agradeceré eternamente que te suscribas a mi canal de YouTube para apoyarme y que pueda seguir haciendo cursos gratuitos.

Además, si te encanta la programación, tienes un montón más de cursos gratuitos para ver.

No solo eso, podrás participar enviándome comentarios con tus sugerencias para temas específicos o cursos completos o incluso las dudas que tengas y las intentaré ir resolviendo en los cursos que estén todavía abiertos.