Curso de Cobol y PowerCobol

Reasignación con MOVE

Capítulo 18: Reasignar valores a variables con MOVE

¿Que es reasignar un valor a una variable?

Reasignar un valor a una variable, es la acción de sustituir un valor por otro.

En el símil de las cajas (otra vez, las cajas sirven para muchos ejemplos), tu cliente te ha pedido una caja llena de tazas rojas, preparas el paquete y le pones las tazas dentro (asignar un valor o inicializar la variable) no obstante, antes de que se la envíes, se arrepiente y te dice que prefiere tazas de color blanco, vacías el contenido de la caja y le almacenas las nuevas tazas (reasignar valor a la variable).

cajas de cartón

Reasignar valores a variables es algo tan fácil de hacer en los lenguajes de programación más modernos, que puede que ni te enteres del concepto al principio, cuando empiezas a programar. Ya que normalmente, la reasignación de una variable se hace simplemente así: NombreVariable = 10. Utilizamos el operador = y algunos pasan por alto lo que se produce.

Reasignar un valor a una variable en COBOL

En COBOL, te darás más cuenta, ya que la reasignación de valores a variables se hace con dos verbos, MOVE y TO los cuales se traducen como 'mover a' en español.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
      *> Variables para datos de usuario.
           01 Nombre PIC X(16) VALUE SPACES.
           01 Apellidos PIC X(32) VALUE SPACES.
           01 Edad PIC X(3) VALUE SPACES.

       PROCEDURE DIVISION.
      *> Se reasignan y muestran valores.
       ReasignaValores.
           DISPLAY Nombre.
           MOVE "Laura" TO Nombre.
           DISPLAY Nombre.

           STOP RUN.
       END PROGRAM Capitulo18.

En la consola, nos aparece una línea en blanco, correspondiente al DISPLAY de la línea 16, en el cuál, Nombre todavía tiene la asignación inicial de SPACES.

En la línea 17, se hace la reasignación y se le da un nuevo valor a la variable Nombre, con lo que el último DISPLAY, ya muestra el nuevo valor.

Laura

Si asignamos un valor incorrecto a las variables, en algunos casos lo salva COBOL automáticamente. Por ejemplo, vamos a asignar un valor numérico a la variable de tipo texto.

MOVE 100 TO Nombre.
100

Realmente, este tipo de dato, lo toma como un string con un número dentro, así: "100".

Si intentas hacer lo contrario, el resultado es algo raro.

01 Numero PIC 9(16) VALUE ZEROES.
MOVE "Laura" TO Numero.
00000000000Laura

Esto está bien por parte de COBOL, ya que puede salvar en unos cuantos casos que el programa compile. No obstante, ten cuidado y piensa en lo que haces para evitar este tipo de incoherencias.

En la pestaña "Issues" (problemas en español) de la consola, puedes ver que se generan dos warning:

Se esperaba un valor numérico y 'Numero' se ha definido aquí como PIC 9(16).

numeric value is expected
'Numero' defined here as PIC 9(16)

La reasignación de números se hace igual. Un nuevo valor, sustituye al anterior, no se suma.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION..
           01 Numero PIC 999 VALUE 50.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE "100" TO Numero.
           DISPLAY Numero.

           STOP RUN.
       END PROGRAM Capitulo18.
100

El flujo de ejecución de COBOL

El flujo de ejecución es la forma en que se lee un programa. En el caso de COBOL, en flujo sin alterar (ya verás que es esto en otro capítulo), se lee de izquierda a derecha y de arriba a abajo.

El compilador primero lee las variables, después entra en la PROCEDURE DIVISION y empieza a leer línea por línea.

Entonces, sabemos que si vamos realizando acciones que sobrescriban a otras como la reasignación de valores, las que vengan más adelante, serán las que se queden. Como la vida misma.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION..
           01 Numero PIC 999 VALUE 50.

       PROCEDURE DIVISION.
       ReasignaValores.
           DISPLAY Numero.
           MOVE 100 TO Numero.
           DISPLAY Numero.
           MOVE 200 TO Numero.
           DISPLAY Numero.

           STOP RUN.
       END PROGRAM Capitulo18.

Cuando llega al primer DISPLAY, Numero aun vale 50. En el siguiente, se ha realizado ya la primera reasignación. Se imprime 100. Finalmente, en el último DISPLAY, también ha cambiado, esta vez por 200.

50
100
200

Puede que para muchos sea algo evidente, pero si no has programado nunca puede que no tanto, por eso creo conveniente detenerme de vez en cuando a explicar estas cosas.

Volvamos al tema anterior, lo de reasignar valores incorrectos a las variables para hacer unas pruebas.

La primera, es intentar sumar un valor numérico en un string un número.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero PIC 9(5) VALUE 50.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE "100" TO Numero.
           DISPLAY Numero.

           ADD 100 TO Numero.
           DISPLAY Numero.

           STOP RUN.
       END PROGRAM Capitulo18.

Pese a los warning que me muestra en "Issues", no falla. Hace bien la operación matemática.

00100
00200

No obstante, aquí tienes un fallo que podemos cometer por maltratar los tipos de datos.

Pongamos que asignas un valor de string como "hola", que no contiene ningún número y en el programa intentamos realizar una operación aritmética. En un principio, almacena Hola sin dar error.

Pero finalmente, intenta realizar la suma de "Hola" + 10 y ahí es donde ya se va todo a ...

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 9(5) VALUE 50.
           01 Numero2 PIC 9(5) VALUE 10.
           01 Resultado PIC 9(5) VALUE ZERO.


       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE "Hola" TO Numero1.
           DISPLAY Numero1.

           COMPUTE Resultado = Numero1 + Numero2.
           DISPLAY Resultado.
           STOP RUN.

       END PROGRAM Capitulo18.

El Hola, me lo imprime bien, entre comillas y debajo es donde ocurre el error, en el COMPUTE. 'Numero1' no es numérico: '0Hola' (básicamente, que el valor '0Hola' no es un valor numérico y se queda el compilador alucinando al intentar sumar eso a un número).

0Hola
libcob: test.cbl: 18: 'Numero1' not numeric: '0Hola'

Como puedes ver, que tenga cierta flexibilidad, a veces es bueno y otras conduce a errores por utilizar mal las cosas, así que mi consejo, es que cuando utilices MOVE, lo hagas siempre teniendo en cuenta el tipo de dato de las variables implicadas, ahí también la importancia que los nombres de las variables sean lo más descriptivas posibles con el valor que van a contener.

Más cosas. Tienes que tener en cuenta el tamaño del PICTURE al utilizar MOVE, ya que si asignas un dato que no quepa en el PICTURE va a ser truncado y truncado, es sinónimo de pérdida de datos y pérdida de datos, pues... mal, vamos.

Por ejemplo, aquí tengo un PICTURE de cinco dígitos, intento asignar un número de seis y lo que pasa es que el dígito que sobra, se pierde. En este caso me quedo con 02035. He perdido el 1.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 9(5) VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE "102035" TO Numero1.
           DISPLAY Numero1.

           STOP RUN.

       END PROGRAM Capitulo18.
02035

Esto no acaba aquí, ya que la cosa se complica bastante, vendrán muchas cosas a tener en cuenta, te iré contando todas las curiosidades y posibilidades que pueda. Aquí una más:

Podemos asignar un valor de cero a una variable numérica o dejar una variable de texto en blanco con MOVE:

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 9(5) VALUE ZERO.
           01 Texto1 PIC X(5) VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE ZEROS TO Numero1.
           DISPLAY Numero1.

           MOVE SPACES TO Texto1.
           DISPLAY Texto1.

           STOP RUN.

       END PROGRAM Capitulo18.
00000

Otra más. Tenemos el siguiente número decimal. Dos dígitos enteros y dos decimales.

MOVE 150.63 TO Numero1.
DISPLAY Numero1.
⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 99V99 VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE 150.63 TO Numero1.
           DISPLAY Numero1.

           STOP RUN.

       END PROGRAM Capitulo18.

Si la parte entera es mayor que el PICTURE, en este caso un dígito más, se trunca por la izquierda, se pierde el 1 de 150.

50.63

En cambio, si los decimales son más de los que admite el PICTURE, se pierden por la derecha.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 999V9 VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE 150.63 TO Numero1.
           DISPLAY Numero1.

           STOP RUN.

       END PROGRAM Capitulo18.
150.6

Cuando intentamos asignar un valor decimal a una variable entera, ocurre que se pierden los decimales.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC 999999 VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE 150.630 TO Numero1.
           DISPLAY Numero1.

           STOP RUN.

       END PROGRAM Capitulo18.
000150

Si intentas pasar un decimal a una variable alfanumérica te va a dar error.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Numero1 PIC XXXXXX VALUE ZERO.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE 150.630 TO Numero1.
           DISPLAY Numero1.

           STOP RUN.

       END PROGRAM Capitulo18.

Declaración MOVE inválida.

invalid MOVE statement

Podemos asignar un valor repetido con MOVE ALL. Lo que hace es decirle que asigne a cada espacio de carácter del PICTURE, el carácter que hay entre comillas. Este puede ser cualquier carácter.

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 Password PIC X(15) VALUE SPACES.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE ALL "*" TO Password.
           DISPLAY Password.

           STOP RUN.

       END PROGRAM Capitulo18.
***************

Además, puedes crear un patrón de repetición con más de un carácter:

⁠⁠       IDENTIFICATION DIVISION.
       PROGRAM-ID. Capitulo18.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       FILE SECTION.
       WORKING-STORAGE SECTION.
           01 QQ PIC X(15) VALUE SPACES.

       PROCEDURE DIVISION.
       ReasignaValores.
           MOVE ALL "T." TO QQ.
           DISPLAY QQ.

           STOP RUN.

       END PROGRAM Capitulo18.
T.T.T.T.T.T.T.T

Vamos a dejar MOVE un poco. Creo que ya es mucha información para un solo capítulo y además iremos utilizándolo más veces lo largo del curso.

No intentes memorizar todo lo que te enseño en el curso. La mente funciona como un diccionario de programación (claves y valores). Las claves son las cosas que asocias a un conocimiento (valor), si solo guardas valores como en un array, olvidarás gran parte que no utilices. Mi recomendación, es que tomes descansos adecuados, que hagas tus propias pruebas con mis ejemplos y que te guardes este curso para consultarlo más adelante o que tomes apuntes.


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.