
Instr. de Variables
Daré cabida en esta sección a la explicación de todas las instrucciones
que hacen referencia a las variables y sus valores. Como todas, este grupo de instrucciones
tiene su vital importancia en la programación y son usadas habitualmente.
MOVE, es la instrucción que usaremos para enviar
datos de una variable a otra u otras. Lo que en realidad hace es que la una variable adquiera
un valor determinado, ya sea procedente de otra variable o bien desde un valor fijo o constante.
Estos son los dos formatos que posee:
Formato 1:
MOVE variable, valor
TOvariable, variable, variable, ....
Con el primer formato las variables que siguen al TO tomarán
el dato de la variable o del valor que le preceden. De todo se verá al final una serie
de ejemplos bien detallados. Siempre tendremos una serie de normas o restricciones para
asegurarnos de que los valores han pasado correctamente.
- Los campos numéricos siempre se van a alinear a la derecha, respetando la posición
del punto decimal si lo hubiera. Si la variable que recibe el campo es mas pequeña, evidentemente
se perderán los que no quepan y si es mas grande el resto se pondrá a ceros.
Si además el campo al que se mueven los datos es de edición,
al hacer el paso del valor, este a su vez se formateará con la edición declarada
en la WORKING.
Si son alfanuméricos la alineación se efectuará a
la izquierda a menos que se haya especificado en la WORKING, al
definirla, una justificación a la derecha (JUST RIGHT). Al igual
que en los numéricos si es mas pequeño se perderán los caracteres que no
quepan y si es mas grande el resto irá relleno de espacios en blanco.
| ...
WORKING-STORAGE SECTION.
77 NUMERO1 PIC 9(6).
77 NUMERO2 PIC 9(8)V99. 77 NUMERO3 PIC
ZZZ.ZZZ,ZZ. 77 TEXTO1
PIC X(15) VALUE "LENGUAJE
COBOL". 77 TEXTO2
PIC X(10). 77
TEXTO3 PIC
X(20) JUST RIGHT. ...
PROCEDURE DIVISION.
INICIO.
MOVE 1536 TO NUMERO1. MOVE
NUMERO1 TO NUMERO2 NUMERO3. MOVE
TEXTO1 TO TEXTO2 TEXTO3. ... |
|
Nota: Después de aplicar estas sentencias, éste sería el resultado:
NUMERO1=001536
NUMERO2=0000153600 (La coma decimal es virtual)
NUMERO3= 1.536,00
TEXTO1=LENGUAJE
COBOL TEXTO2=LENGUAJE
C TEXTO3=
LENGUAJE COBOL
|
Formato 2:
MOVE CORR Identificador1
TO Identificador2
Agregando CORR a la instrucción conseguimos mover de una sola vez un valor entre identificadores siempre
que los campos que contengan tengan el mismo nombre. Estos identificadores no pueden ir en niveles 66,
77 ni 88. El efecto es el mismo que si hicieramos tantos MOVE normales como campos iguales tuviera
el identificador. No es muy usual, pero si hay casos en los que puede ser razonable su uso.
No es necesario que tengan el mismo PIC, ni que estén en el mismo orden, solo que
coincidan en su nombre.
|
...
WORKING-STORAGE SECTION.
01 DATOS1. 02 NOMBRE PIC
X(30). 02
REGION PIC X(20). 02
PAIS PIC
X(15). 01 DATOS2. 02
PAIS PIC
X(10). 02
REGION PIC X(10). 02
NOMBRE PIC X(10).
...
PROCEDURE DIVISION.
INICIO.
MOVE "ANDRES MONTES"
TO NOMBRE IN DATOS1. MOVE
"ANDALUCIA" TO REGION IN DATOS1. MOVE
"ESPAÑA" TO PAIS IN DATOS1. MOVE
CORR DATOS1 TO DATOS2.
... | |
Nota: Para partir con unos valores,
primero los he movido a las variables del primer grupo (DATOS1). Después de aplicar el
MOVE CORR, el valor de las variables de DATOS2 sería:
DATOS2: PAIS=ESPAÑA REGION=ANDALUCIA NOMBRE=ANDRES MON
Fijaros que aunque el orden ni el tamaño era el mismo, el resultado
es el que queríamos.
|
INITIALIZE, se utiliza para inicializar variables
según su descripción, es decir pondrá a ceros todas las variables
numéricas o de edición y a espacios en blanco las alfabéticas y
alfanuméricas. No funciona con campos definidos como FILLER, (evidente). Y puede ser
muy útil para inicializar tablas completamente cuando nos referimos al nivel mas alto de la misma.
|
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(10) VALUE "HOLA MUNDO". 77 NUMERO
PIC 9(8) VALUE "12345678". ...
PROCEDURE DIVISION.
INICIO.
INITIALIZE TEXTO NUMERO.
... |
|
Nota: Después de hacer INITIALIZE
el valor de TEXTO será
igual a espacios y el de NUMERO igual a ceros.
Es el mismo resultado que utilizar MOVE haciendo uso de las CONSTANTES FIGURATIVAS que vimos
en la Introducción de los manuales:
MOVE
SPACES TO TEXTO. MOVE
ZEROS TO NUMERO.
El resultado es el mismo en ambos casos, pero en el segundo teníamos que saber
de que tipo eran las variables para moverles SPACES o ZEROS, mientras que en el primer
caso, es el compilador quien se encarga se saber el tipo de la variable.
|
INSPECT, esta sentencia se
utiliza para contar, reemplazar o contar y reemplazar caracteres o grupos de caracteres dentro
de un campo. Se puede contar las veces que aparece un caracter, o cambiar todos esos caracteres
por otros, etc ...
Esta instrucción tiene formatos diferentes según lo que se desee hacer, así
que vamos a ver cada uno de ellos por separado.
Formato 1:
INSPECT campo1
TALLYING
variable1 FOR (
CHARACTERS) ((
BEFORE/AFTER) INITIAL)
Cadena1
(ALL)(LEADING)
Cadena2 ...
(Se puede repetir de nuevo)
Este formato es el utilizado para contar el número de veces que aparece Identificador1
en el campo1 y guardará el valor en la variable1 que previamente hayamos definido en la WORKING.
- CHARACTERS, indica que cuente todos los caracteres del campo
incluso los espacios en blanco.
- ALL, indica que tiene que buscar en todos los caracteres
del campo, la cadena especificada en Cadena2.
- LEADING, indica que tiene que buscar la cadena especificada
en Cadena2, pero solo hasta que encontremos uno diferente, si nada mas empezar es diferente
el resultado sera directamente 0.
- BEFORE INITIAL, busca solo hasta que aparezca la cadena
especificada como Cadena1.
- AFTER INITIAL, empieza a buscar justo después de la
cadena especificada en Cadena1.
Veamos unos ejemplos para salir de dudas. Primero vamos a definir una
WORKING-STORAGE.
|
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8). ...
PROCEDURE DIVISION.
INICIO.
INSPECT TEXTO TALLYING CONTA FOR CHARACTERS.
... El valor de conta será de 15 que son los caracteres que tiene la variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR ALL "A".
... El valor de conta será de 2 que son las veces que aparece la letra A en la
variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR LEADING "A".
... El valor de conta será de 0 porque no aparece ninguna A en el primer
carácter de la variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR ALL "A"
BEFORE INITIAL "N".
... El valor de conta será de 1 que son las veces que aparece la letra A en la
variable TEXTO hasta la aparición del caracter N.
INSPECT TEXTO TALLYING CONTA FOR ALL "A"
AFTER INITIAL "G".
... El valor de conta será de 1 que son las veces que aparece la letra A en la
variable TEXTO, empezando a contar desde el caracter G.
|
Formato 2:
INSPECT campo1
REPLACING
variable1 CHARACTERS BY
Cambio1 ((
BEFORE/AFTER)
INITIAL) Cadena1
(ALL)(LEADING)(
FIRST) Cadena2...
(Se puede repetir de nuevo)
Con este formato podemos cambiar caracteres de Campo1, su funcionamiento es igual
que el anterior formato solo que en vez de contar reemplaza. Se ha incluido solo FIRST, que
indicaría que solo se reemplazaría la primera vez que coincidieran las
condiciones. El tamaño de la sustitución debe de ser igual al tamaño
sustituido, ya que la variable campo1 no puede cambiar su tamaño.
|
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8). ...
PROCEDURE DIVISION.
INICIO.
INSPECT TEXTO REPLACING CHARACTERS BY "H".
... El valor de TEXTO será "HHHHHHHHHHHHHHH", es decir cambia todos los
caracteres por el caracter H.
INSPECT TEXTO REPLACING ALL "A" BY "I".
... El valor de TEXTO será "PIGINI DE COBOL", es decir ha cambiado todas
las A por I.
INSPECT TEXTO REPLACING FIRST "A" BY "O".
... El valor de TEXTO será "POGINA DE COBOL", solo cambia la primera A por una O.
MOVE "PAGIPATOPETOPA" TO TEXTO.
INSPECT TEXTO REPLACING ALL "PA" BY "--"
AFTER INITIAL "G" BEFORE INITIAL "T".
... Complicando un poco mas, el valor de TEXTO despueés de la sentencia INSPECT
será PAGI--TOPETOPA, es decir se cambia todas las PA por -- pero empezando a buscar
a partir de la primera letra G y justo hasta la letra T.
MOVE "PAGIPATOPETOPA" TO TEXTO.
INSPECT TEXTO TALLYING CONTA FOR ALL "PA"
REPLACING ALL "TO" BY "PO" AFTER INITIAL "OP".
... Aquí hemos mezclado ambos formatos y el resultado es el siguiente. El valor de
CONTA es 3 que son las veces que aparece la cadena PA en TEXTO y después se ejecuta
el REPLACING y el resultado da que TEXTO vale PAGIPATOPEPOPA, ya que ha cambiado
todos los TO por PO pero después de la cadena OP.
|
Formato 3:
INSPECT campo1
CONVERTING
Identificador1 TO
Identificador2
((
BEFORE/AFTER) INITIAL)
Cadena1 ...
(Se puede repetir de nuevo)
Con este formato convertimos los caracteres que se especifiquen en identificador1 por los que
pongamos en identificador2, respetando el orden.
Veamos algunos ejemplos, se suele utilizar mucho para que al aceptar un campo nos de igual se
ha sido introducido en mayúsculas o en minúsculas ya que lo convertiriamos a
alguno de los formatos.
|
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
... PROCEDURE DIVISION. INICIO.
INSPECT TEXTO CONVERTING "AO"TO "12".
... El valor de TEXTO será "P1GIN1 DE C2B2L", convertirá todas
las A por 1 y todas las O por 2.
INSPECT TEXTO CONVERTING "
ABCDEFGHIJKLMNÑOPQRSTUVWXYZ" TO
"abcdefghijklmnñopqrstuvwxyz".
... El valor de TEXTO será "pagina de cobol" ya que ha convertido todas
las letras mayúsculas por minúsculas. |
Para finalizar con el comando INSPECT, decir que es un comando muy particular y cada uno
deberá decidir en cada momento y con que situaciones utilizarlo.
STRING, se utiliza para unir o concatenar campos o partes
de estos y el resultado almacenarlo en otro campo. En la unión se pueden incluir
tanto variables como literales o constantes de texto.
STRING campo1, literal1
DELIMITED
BY (campo2, literal2)(SIZE)
INTO Campo3
(WITH
POINTER Identificador1)
(
ON OVERFLOW Sentencia1)
(
NOT ON OVERFLOW Sentencia2)
- DELIMITED BY, indica hasta donde vamos a "coger"
del campo para concatenar sin contar ese caracter o cadena que se especifique en campo2 o
literal2, es decir si tenemos un campo con un valor = "HOLA" y especificamos
DELIMITED BY "L" a la hora de la concatenación nos hubiera cogido
solo el HO, ya que al encontrarse la primera L hubiera parado.
- SIZE, indica que se pasará todo el contenido del campo1
o literal1 sin limitaciones.
- INTO, con esto indicamos en que variable se guardará el
resultado, campo3.
- WITH POINTER, si incluimos esta cláusula el valor de identificador1
será en la posición en que empezará a contener datos la variable que recibe el STRING.
Ese identificador1 debe estar definido como binario. Por defecto el valor es 1.
- ON OVERFLOW, se ejecutaría Sentencia1 si hubiera habido un
error al hacer la concatenación, por ejemplo si se especifica Identificador1 con
un valor superior al tamaño del Campo3.
- NOT ON OVERFLOW, se ejecutará Sentencia2 si no existe error
en la operación.
Vamos a ver unos ejemplos y además vamos a comparar como se hubiera hecho utilizando la
Working si no existiera el STRING.
|
...
WORKING-STORAGE SECTION.
01 LAFECHA.
02 FILLER PIC X(7) VALUE "HOY ES ".
02 LDIA PIC Z9.
02 FILLER PIC X(4) VALUE " DE ".
02 LMES PIC X(10).
02 FILLER PIC X(4) VALUE "DE ".
02 LANIO PIC 9999.
01 FECHA.
02 DIA PIC 99 VALUE 22.
02 MES PIC 99 VALUE 06.
02 ANIO PIC 9999 VALUE 2001.
01 CONSTRING PIC X(40).
01 TABLAMES.
02 FILLER PIC X(30) VALUE "ENERO FEBRERO MARZO
".
02 FILLER PIC X(30) VALUE "ABRIL MAYO JUNIO
".
02 FILLER PIC X(30) VALUE "JULIO AGOSTO SEPTIEMBRE".
02 FILLER PIC X(30) VALUE "OCTUBRE NOVIEMBREDICIEMBRE ".
01 LATABLA REDEFINES TABLAMES.
02 TMES PIC X(10) OCCURS 12 TIMES.
01 PUNTO PIC 9(4) BINARY.
...
PROCEDURE DIVISION.
INICIO.
MOVE DIA TO LDIA.
MOVE TMES (MES) TO LMES.
MOVE ANIO TO LANIO.
STRING "HOY ES " DIA " DE "
TMES (MES) " DE " ANIO
DELIMITED BY SIZE INTO CONSTRING.
...
|
El valor de LAFECHA sería: HOY ES 22 DE JUNIO DE 2001.
El valor de CONSTRING sería: HOY ES 22 DE JUNIO DE 2001.
Fijaros que el resultado es el mismo pero en cambio gracias a STRING
no hemos tenido que definir ninguna linea en la WORKING
ni tampoco tener que mover campos de unas variables a otras.
La cláusula DELIMITED BY se ha puesto al final porque dicha
cláusula se aplica a todos los campos que la preceden, si hubieramos querido coger otra
limitación para un campo en concreto habría que haberlo especificado, por ejemplo
vamos a afinar mas el ejemplo y conseguir que entre el mes JUNIO y el DE no exista mas
que un espacio. En el ejemplo anterior ha unido los 10 caracteres que tiene la variable TMES.
|
STRING "HOY ES " DIA " DE "
DELIMITED BY SIZE TMES (MES) DELIMITED BY " "
" DE " ANIO DELIMITED BY SIZE INTO CONSTRING.
|
El valor que tendrá ahora CONSTRING será el siguiente: HOY ES 22 DE JUNIO DE 2001.
Como veis la diferencia está en los espacios que le sobran al mes, que al poner DELIMITED BY "
" los ha evitado porque solo ha concatenado hasta que ha encontrado el primer caracter en blanco.
|
MOVE 4 TO PUNTO.
STRING "HOY ES " DIA " DE " DELIMITED BY SIZE
TMES (MES) DELIMITED BY " "
" DE " ANIO DELIMITED
BY SIZE INTO CONSTRING
WITH POINTER PUNTO. |
El valor que tendrá ahora CONSTRING será el siguiente:
HOY ES 22 DE JUNIO DE 2001.
Es decir habrá empezado a concatenar a partir de la posición
4 del campo CONSTRING. Si el valor de CONSTRING previamente era espacios habría
dejado 3 espacios en blanco y si hubiera sido cualquier otro hubiera respetado los 3 primeros caracteres que tuviera.
UNSTRING, hace exactamente lo contrario de que hemos
visto que hacía STRING, es decir divide el contenido de un campo en otros.
UNSTRING campo1, literal1
DELIMITED BY
(campo2, literal2)(ALL)
OR
(campo2, literal2)(ALL)
(Se puede repetir de nuevo)
INTO
Campo3, Campo4, ....
(
DELIMITER Identificador1)
(
COUNT Identificador2)
(Se puede repetir de nuevo)
(WITH POINTER
Identificador3)
(TALLYING
Identificador4)
(
ON OVERFLOW Sentencia1)
(
NOT ON OVERFLOW Sentencia2)
- DELIMITED BY, indica el límite hasta donde vamos cogiendo
el campo1 para partirlo. Igual que en STRING, solo que con la función
a la inversa.
- OR, es igual que DELIMITED y se utiliza
si hay varios delimitadores sobre los que buscar.
- INTO, indica en que campo o campos se guardará la información
que vaya fragmentando.
- DELIMITER, va a contener en cada caso el elemento separador, si hemos
incluido en DELIMITED varios, Identificador1 guardará el carácter
que de los elegidos ha sido el causante de la fragmentación.
- COUNT, cuenta el número de caracteres incluidos en la fragmentación.
- DELIMITER y COUNT, se podrán usar si se ha especificado
DELIMITED. Podemos usar tantos DELIMITER y COUNT
como campos se vayan a crear en la fragmentación.
- TALLYING, si especificamos esta opción la instrucción nos
guardará en Identificador4 el número de campos que se han utilizado en la fragmentación.
- POINTER, indica desde que posición va a ser examinado el campo
que desea desfragmentar, por defecto su valor es 1, es decir desde el primer caracter.
- ON OVERFLOW, se ejecutaría Sentencia1 si hubiera habido un
error al hacer la operación.
- NOT ON OVERFLOW, se ejecutará Sentencia2 si no existe error
en la operación.
Vamos a hacer lo contrario de antes y conseguir una fecha numérica de una frase con la fecha:
|
...
WORKING-STORAGE SECTION.
01 LAFECHA PIC
X(30) VALUE "HOY ES 22 DE JUNIO DE
2001". 01 FECHA. 02
DIA PIC 99. 02
MES PIC 99. 02
ANIO PIC 9999. 01
CONSTRING PIC X(40). 01 TABLAMES. 02
FILLER PIC X(30) VALUE "ENERO
FEBRERO MARZO
". 02
FILLER PIC X(30) VALUE "ABRIL
MAYO JUNIO
". 02
FILLER PIC X(30) VALUE "JULIO
AGOSTO SEPTIEMBRE". 02
FILLER PIC X(30) VALUE "OCTUBRE
NOVIEMBREDICIEMBRE ". 01 LATABLA
REDEFINES TABLAMES. 02
TMES PIC X(10) OCCURS 12 TIMES. 01
CONTA PIC 99. 01 PALABRAS
PIC 99. 01 LETRAS PIC 99. 01
TEXTOS. 02
TEXTO1 PIC X(20). 02
TEXTO2 PIC X(20). 02
TEXTO3 PIC X(20). 02
TEXTO4 PIC X(20). 02
ELMES PIC X(10). ... PROCEDURE DIVISION.
INICIO. UNSTRING
LAFECHA DELIMITED BY " " INTO
TEXTO1 TEXTO2 DIA TEXTO3 ELMES
COUNT LETRAS TEXTO4 ANIO.
PERFORM
VARYING CONTA FROM 1 BY 1 UNTIL
ELMES = TMES (CONTA) OR CONTA = 12 TALLYING
PALABRAS END-PERFORM ...
|
El valor de LAFECHA era: HOY ES 22 DE JUNIO DE 2001.
Después de aplicar las instrucciones siguientes el contenido de los campos sería
el siguiente:
- TEXTO1 = HOY
- TEXTO2 = ES
- TEXTO3 = DE
- TEXTO4 = DE
- ELMES = JUNIO
- DIA = 22
- ANIO = 2001
- FECHA = 22062001
- LETRAS = 5
- PALABRAS = 7
La variable PALABRAS nos ha guardado el número de variables utilizadas en la fragmentación,
en este caso 7. La variable LETRAS ha guardado el número de caracteres que ha cogido en
la separación que ha guardado en ELMES, que han sido 5 (JUNIO). Podiamos haber puesto un
COUNT para cada una.
El PERFORM de después lo hemos hecho para encontrar en la tabla la
posición que ocupaba el nombre del mes y así poder construir la variable FECHA completa
en númerico.
Vamos a hacer un ejemplo de como podríamos separar un nombre completo, por ejemplo
para el nuevo modelo de la Seguridad Social (en España) y el sistema R.E.D.:
|
...
WORKING-STORAGE SECTION.
01 TEXTO PIC
X(30) VALUE "MONTES ROBLES, ANDRES". 01 APELLI1
PIC X(20). 01 APELLI2
PIC X(20). 01 NOMBRE PIC
X(20). 01
SEPARA PIC X. 01 SEGURIDAD. 02
AP1 PIC XX. 02
AP2 PIC XX. 02
NOM PIC X. ... PROCEDURE DIVISION.
INICIO. UNSTRING
TEXTO DELIMITED BY " " OR ",
" INTO
APELLI1 APELLI2 NOMBRE.
Aquí conseguimos separar cada apellido y el nombre en campos diferentes. (APELLI1, APELLI2,
NOMBRE)
MOVE APELLI1 TO AP1 MOVE APELLI2 TO AP2
MOVE NOMBRE TO NOM.
...
Aquí la variable SEGURIDAD tendría el valor: MOROA. Válido para el sistema RED.
|
|
|