Está en la página 1de 91

MANUAL DE COBOL

CONTENIDO CURSO DE COBOL

CAPITULO I INTRODUCCIÓN Y GENERALIDADES

INTRODUCCIÓN
TIPOS DE DATOS
TIPOS DE PALABRAS
ÁREAS DE TRABAJO
TIPOS DE CONSTANTES

CAPITULO II ESTRUCTURA DEL COBOL

IDENTIFICATION DIVISION
ENVIRONMENT DIVISION
DATA DIVISION
PROCEDURE DIVISION

CAPITULO III VERBOS DE ENTRADA/SALIDA/ASIGNACIÓN/UTILITARIOS

DISPLAY
ACCEPT
MOVE

CAPITULO IV VERBOS ARITMETICOS

ADD
SUBTRACT
MULTIPLY
DIVIDE
COMPUTE

CAPITULO V CONDICIONALES

IF

Elaborado por Sergio Oswaldo Rojas Bernal Página 1


MANUAL DE COBOL

EVALUATE

CAPITULO VI VERBOS DE CONTROL

PERFORM
o BÁSICO
o ANIDADOS
o TIMES
o UNTIL
o THRU
o VARYING
o COMBINADO
o LINEA
 TIMES
 UNTIL
 VARYING

CAPITULO VII FORMATOS DE EDICION

MASCARAS

CAPITULO VIII TABLAS DE MEMORIA

OCCURS
DEPENDING ON
ORDENAMIENTOS
BUSQUEDAS

CAPITULO IX ARCHIVOS SECUENCIALES

OPEN
CLOSE
READ
WRITE
REWRITE

Elaborado por Sergio Oswaldo Rojas Bernal Página 2


MANUAL DE COBOL

LINEAS DE BALANCE
BUSQUEDAS EN ARCHIVOS

CAPITULO X ARCHIVOS INDEXADOS

OPEN
CLOSE
READ
WRITE
REWRITE
START
DELETE

CAPITULO XI SUBPROGRAMACION
CALL
LINK
COPY

CAPITULO XII BUSQUEDAS EN ARCHIVOS

SIMPLES
LINEAS DE BALANCES

Elaborado por Sergio Oswaldo Rojas Bernal Página 3


MANUAL DE COBOL

CURSO DE COBOL

CAPITULO INTRODUCCIÓN Y GENERALIDADES

INTRODUCCION

C COMMAND
O
B BUSINESS
O ORIENTED
L LANGUAJE

HISTORIA

1959
1974 ANSI
1985 RMCOBOL/85
1991 COBOL ENTERPRISE (HOST)
2002 (COBOL ANSI-2002)
2007 Se esta preparando una nueva versión.

Existen varios compiladores que permiten emplear COBOL como lenguaje de


scripting y de servicio Web, También existen compiladores que permiten generar
código COBOL para la plataforma .NET Y EJB(Enterprise Java Beans).

REAL COBOL
COBOL-I
COBOL-II
MICROFOCUS COBOL
VICOBOL.

TIPOS DE DATOS

TIPO DATO FORMATO LONGITUD VALORES

Elaborado por Sergio Oswaldo Rojas Bernal Página 4


MANUAL DE COBOL

ALFABETICOS A 256 car. A..Z, a..z


NUMERICOS 9 18 dig. 0..9
ALFANUMERICO X 256 car. A..Z, a..z,0..9,
S caracteres
especiales.

TIPOS DE PALABRAS

USUARIO
30 Caracteres máximo
No caracteres especiales (-)

EJM:
LEER-ARCHIVO-MAESTRO

-CONTADOR
CONTADOR-

RESERVADAS
READ, DISPLAY, MOVE,…etc.

ÁREAS DE TRABAJO

A Columnas 8 a la 11
B Columnas 12 a la 72

1-6 Enumeración automática de las líneas


7 *-
73-80 No se utilizan

TIPOS DE CONSTANTES

ALFABETICAS
NUMERICAS
ALFANUMERICAS

Elaborado por Sergio Oswaldo Rojas Bernal Página 5


MANUAL DE COBOL

FIGURATIVAS
ZERO
ZEROS 0
ZERUES

SPACE
SPACES  Espacios en blanco

LOW-VALUES  Valores Nulos


HIGH-VALUES  Máximo valor

ALL

QUOTTE  Comilla Sencilla (‘)


QUOTTES  Comilla Doble (“)

Elaborado por Sergio Oswaldo Rojas Bernal Página 6


MANUAL DE COBOL

CAPITULO II ESTRUCTURA DEL COBOL

IDENTIFICATION DIVISION
ENVIRONMENT DIVISION
DATA DIVISION
PROCEDURE DIVISION

8
IDENTIFICATION DIVISION.
PROGRAM-ID. Nombre del programa.
AUTHOR. Nombre del autor.
INSTALLATION. Lugar donde está instalado.
DATE-WRITTEN. Fecha de creación.
DATE-COMPILED. (Fecha de compilación.)
REMARKS. Comentarios.

EJM:
8
IDENTIFICATION DIVISION.
PROGRAM-ID. PRUEBA.
AUTHOR. SERGIO OSWALDO ROJAS BERNAL.
INSTALLATION. BBVA COLOMBIA.
DATE-WRITTEN. 23-AGO-2010.
DATE-COMPILED.
REMARKS. PROGRAMA QUE GENERA UNA PRUEBA DE COBOL.

8 12
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.

Elaborado por Sergio Oswaldo Rojas Bernal Página 7


MANUAL DE COBOL

SOURCE-COMPUTER. Ordenador donde se escribió el fuente.


OBJECT-COMPUTER. Ordenador donde se ejecuta el objeto.
SPECIAL-NAMES. Cambiar valores para constantes del lenguaje,
pueden variar en cada compilador.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT [OPTIONAL] Nombre-de-archivo
ASSIGN TO Tipo-de-dispositivo
ORGANIZATION IS Tipo de organizacion
ACCESS MODE IS Mode de acceso al fichero
RECORD KEY IS Clave del registro
ALTERNATE RECORD KEY IS Claves alternativas registro
WITH DUPLICATES
FILE STATUS IS Variable de estado del fichero.

Para la linea de SPECIAL-NAMES el uso mas habitual es el de cambiar el punto


decimal usado por los ingleses por la coma y asi poder especificar los puntos para
los miles, su formato sería el siguiente:

SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.

También podríamos cambiar el valor del símbolo de la moneda con:

CURRENCY SIGN IS literal , suele ser un solo caracter y no puede coincidir con
ninguno de los que usamos para definir las variables, es decir ni A,ni Z,ni 9,ni -,ni
+,ni X, etc...

EJM:
8 12
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. IBM 390.
OBJECT-COMPUTER. IBM 390.
SPECIAL-NAMES.

Elaborado por Sergio Oswaldo Rojas Bernal Página 8


MANUAL DE COBOL

DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT NOMINA ASSIGN TO DISK “DATOS”
ORGANIZATION IS SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS VAR-ESTADO.

Elaborado por Sergio Oswaldo Rojas Bernal Página 9


MANUAL DE COBOL

8 12
DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
LINKAGE SECTION.
COMMUNICATION SECTION.
SCREEN SECTION.
REPORT SECTION.

Niveles : 01 y 77
Subniveles : 02..49
Subnivel : 88 nombres de condición

8 12
FILE SECTION.
FD Nombre del fichero.
BLOCK CONTAINS Numero de registros por bloque RECORDS
RECORD CONTAINS Número de caracteres por registro
CHARACTERS
LABEL RECORD Etiqueta de registro
DATA RECORD Nombre del registro.
01 Nombre del registro.
02 CAMPO 1.
02 CAMPO 2.
02 CAMPO 3.
02 CAMPO 4.
.
.
02 CAMPO n.

8 12
WORKING-STORAGE SECTION.
01 VAR-ENTERA PIC 9(8) VALUE ZEROS.

Elaborado por Sergio Oswaldo Rojas Bernal Página 10


MANUAL DE COBOL

01 VAR-ENTERA PIC 99999999 VALUE ZEROS.


01 VAR-ALFABE PIC A(30) VALUE SPACES.
01 VAR-ALFANU PIC X(50) VALUE SPACES
01 RAYA PIC X(80) VALUE ALL ‘-‘.
01 VAR-REAL PIC 9(8)V99 VALUE ZEROS.
01 VAR-REAL2 PIC 9(8)V9(2) VALUE ZEROS.
01 VAR-SIGNO PIC S9(8)V99 VALUE ZEROS.
77 IVA PIC 9V99 VALUE 0.16.

LINKAGE SECTION.
01 PAR-FECHA PIC 9(8).
01 PAR-SALDO PIC S9(8)V99.

COMMUNICATION SECTION.
SCREEN SECTION.
REPORT SECTION.

Elaborado por Sergio Oswaldo Rojas Bernal Página 11


MANUAL DE COBOL

8 12
PROCEDURE DIVISION (USING Variable, Variable ...).
DECLARATIVES.
Nombre-seccionSECTION.
USE AFTER ERROR PROCEDURE ON tipo.
Nombre-parrafo.
Sentencias.
.....
END DECLARATIVES.
Nombre-seccion SECTION.
Nombre-parrafo.
Sentencias.

PROCEDURE DIVISION (USING Variable, Variable ...).


Cuando especificamos USING en la linea de PROCEDURE DIVISION , después
deberemos de dar los nombres de variables que hayamos definido en la LINKAGE
SECTION, para compartir en el programa, lo que nos indicará que éste ha sido
llamado por otro programa y que esas variables traerán un valor procedente del
programa llamador, que a su vez utilizó la instrucción CALL con las mismas
variables.

Se pondrían tantos párrafos y secciones como quisieramos controlar, siempre


teniendo en cuenta que ésta se acaba cuando se indique END DECLARATIVES.
Si no quisieramos utilizar ésta sección, podriamos de igual manera controlar los
errores en nuestro programa preguntando siempre por la variable de error de cada
fichero que se definió como FILE STATUS en la FILE-CONTROL.

PROCEDURE DIVISION.
INICIO.
Instrucción1
nstrucción2
Instrucción3
Instrucción-n
STOP RUN.

Elaborado por Sergio Oswaldo Rojas Bernal Página 12


MANUAL DE COBOL

CAPITULO III VERBOS DE


ENTRADA/SALIDA/ASIGNACIÓN Y UTILITARIOS

ACCEPT: Verbo de Entrada

Formato para aceptar datos del sistema o variables de entorno.

ACCEPT variable FROM (DATE, DAY, DAY-OF-WEEK, TIME, CENTURY-


DATE, CENTURY-DAY, ESCAPE-KEY,

Según la opción escogida, así será el valor que contendrá la variable usada,
una vez completada la sentencia. Veamos cada una de las opciones:

DATE, devuelve la fecha en formato AAMMDD, por lo que la variable


debe de estar definida con PIC 9(6).
CENTURY-DATE, igual que DATE, pero acepta la fecha con 8
dígitos en formato SSAAMMDD. Definir con PIC 9(8).
DAY, devuelve el año y el día del año en que estamos con el formato
AADDD, siendo el valor 1, para el 1 de Enero y así sucesivamente.
Debe de estar definida con PIC 9(5).
CENTURY-DAY, igual que DAY, pero acepta 4 dígitos para el año,
quedando el formato AAAADDD. Definir con PIC 9(7).
DAY-OF-WEEK, devuelve un dígito que indica el día de la semana,
siendo 1 el Lunes, 2 el Martes, ... Aquí, la variable debe de estar
definida como PIC 9.
TIME, devuelve la hora con formato HHMMSSMM, la variable debe
de estar como PIC 9(8).
ESCAPE-KEY, devuelve el código de la tecla de excepción pulsada,
debe de estar definida con PIC 99 y según el compilador los valores
pueden ser distintos, pero los básicos suelen ser los mismos, por
ejemplo: ENTER=13, FLECHA ARRIBA=52, FLECHA-ABAJO=53 y
las teclas de función desde F01 hasta F8 tomarían los valores del 1
al 8, TAB=9.
EJEMPLO:
ACCEPT VAR-ENTERA
ACCEPT VAR-FECHA FROM DATE

Elaborado por Sergio Oswaldo Rojas Bernal Página 13


MANUAL DE COBOL

ACCEPT VAR-HORA FROM TIME

DISPLAY: Verbo de salida

DISPLAY variable, literal CLAUSULAS ... LINE, COL, SIZE, HIGH, LOW,
REVERSE, BEEP, BLINK, ERASE.

DISPLAY ‘REGISTROS LEIDOS : ‘


DISPLAY VAR-ENTERA

MOVE, Verbo de Asignación


.

Formato:

MOVE variable, valor TO variable, variable, variable, ....

EJEMPLO:
A=B

MOVE B TO A

A= 0

MOVE 0 TO A
MOVE ZEROS TO A

INITIALIZE, se utiliza para inicializar variables según su tipo, 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.
WORKING-STORAGE SECTION.
01 CANCEN1-REG.
10 EL1LOT-EMISORA PIC X(10).

Elaborado por Sergio Oswaldo Rojas Bernal Página 14


MANUAL DE COBOL

10 EL1LOT-FECHA-ALTASOP PIC X(10).


10 EL1LOT-NORDEN-SOPORTE PIC S9(5).
10 EL1LOT-NUM-LOTE PIC S9(5).
10 EL1LOT-COD-CLASE-SERV PIC X(3).
10 EL1LOT-TIPO-LOTE PIC X(1).
10 EL1LOT-CLAS-LOTE PIC X(1).
10 EL1LOT-IDENT-CIA PIC X(10).
10 EL1LOT-NOMBRE-CIA PIC X(16).
10 EL1LOT-COD-ENTI-REC PIC X(8).
10 EL1LOT-RUTYTRAN-ACH PIC X(10).
10 EL1LOT-DESCR-TRANS PIC X(10).
10 EL1LOT-IND-RESP-OPS PIC X(2).
10 EL1LOT-MOTIVODEVO PIC X(8).
10 EL1LOT-DISCR-DATA PIC X(20).
10 EL1LOT-COD-EST-LOT PIC X(2).
10 EL1LOT-FECALTA PIC X(10).
10 EL1LOT-FECPROC PIC X(10).
10 EL1LOT-FECEFECT PIC X(10).
10 EL1LOT-FECENVIO PIC X(10).
10 EL1LOT-FECDEVOL PIC X(10).
10 EL1LOT-NUM-REGS PIC S9(8).

PROCEDURE DIVISION.
INICIO.
INITIALIZE CANCEN1-REG.

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:

Elaborado por Sergio Oswaldo Rojas Bernal Página 15


MANUAL DE COBOL

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.

EJEMPLO:
WORKING-STORAGE SECTION.
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.

Elaborado por Sergio Oswaldo Rojas Bernal Página 16


MANUAL DE COBOL

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.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8)....
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.

WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8).
...

Elaborado por Sergio Oswaldo Rojas Bernal Página 17


MANUAL DE COBOL

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 despué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:

Elaborado por Sergio Oswaldo Rojas Bernal Página 18


MANUAL DE COBOL

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 convertiríamos 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.

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.

Elaborado por Sergio Oswaldo Rojas Bernal Página 19


MANUAL DE COBOL

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.

EJEMPLO:

STRING "HOY ES " VAR-DIA " DE " VAR-MES " DE "


VAR-ANO
DELIMITED BY SIZE
INTO VAR-ENCADENA

Obtendriamos en VAR-ENCADENA:
HOY ES 16 DE AGOSTO DE 2010
.

Elaborado por Sergio Oswaldo Rojas Bernal Página 20


MANUAL DE COBOL

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.

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

Elaborado por Sergio Oswaldo Rojas Bernal Página 21


MANUAL DE COBOL

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.

WORKING-STORAGE SECTION.
01 LAFECHA PIC X(30) VALUE "HOY ES 16 DE AGOSTO DE 2010".
01 TEXTOS.
02 TEXTO1 PIC X(20).
02 TEXTO2 PIC X(20).
02 DIA
02 TEXTO3 PIC X(20).
02 ELMES PIC X(10).
02 TEXTO4 PIC X(20).
02 ELAÑO PIC X(10).

PROCEDURE DIVISION.
INICIO.
UNSTRING LAFECHA DELIMITED BY " "
INTO TEXTO1 TEXTO2 DIA TEXTO3
ELMES COUNT LETRAS TEXTO4 ANIO.

Elaborado por Sergio Oswaldo Rojas Bernal Página 22


MANUAL DE COBOL

REDEFINES.

Esta cláusula permite dar a un campo o a un área de memoria mas


de un nombre y mas de un formato. Su formato es el siguiente:
nombre de dato-1
REDEFINES nombre de dato-2
FILLER

La cláusula REDEFINES ha de ser la primera que siga al nombre de


datos.

Los campos nombre de dato-1 y campos nombre de dato-2 han de


estar declarados al mismo nivel, pero no a nivel 88.

La redefinición de un campo compuesto se hace inmediatamente


después del último de los campos elementales que forman parte de
aquel.

Esta cláusula va a permitir poder inicializar una tabla en el momento


de declararla.

WORKING-STORAGE SECTION.
01 VAR-FECHA PIC X(10).
01 VAR-FECHA-PAR REDEFINES VAR-FECHA.
02 AÑO PIC 9(4).
02 FILLER PIC X(1).
02 MES PIC 9(2).
02 FILLER PIC X(1).
02 DIA PIC 9(2).

Elaborado por Sergio Oswaldo Rojas Bernal Página 23


MANUAL DE COBOL

CAPITULO IV VERBOS ARITMETICOS

ADD
SUBTRACT
MULTIPLY
DIVIDE
COMPUTE

ADD: Suma

FORMATOS:
12
1.- ADD variable1 variable 2.... TO variable (ROUNDED) (ON SIZE
ERROR ) instrucción NOT ON SIZE ERROR instrucción
END-ADD

2.- ADD variable1 variable 2... GIVING variable (ROUNDED) (ON SIZE
ERROR ) instrucción NOT ON SIZE ERROR instrucción
END-ADD

A= A + B

ADD B TO A

A = A + B + 10 + J

ADD J 10 B TO A

A = B + J + C + D + 10

ADD 10 D C J B GIVING A

SUBTRACT: Resta

Elaborado por Sergio Oswaldo Rojas Bernal Página 24


MANUAL DE COBOL

FORMATOS:

1.- SUBTRACT variable1 variable 2... FROM variable (ROUNDED) (ON


SIZE ERROR ) instrucción NOT ON SIZE ERROR instrucción
END-SUBTRACT

2.- SUBTRACT variable1 variable 2... FROM variable GIVING variable


(ROUNDED) (ON SIZE ERROR) instrucción NOT ON SIZE ERROR
instrucción
END-SUBTRACT

A= A - B

SUBTRACT B FROM A

A = A - B - 10 - J

SUBTRACT J 10 B FROM A

A = B - J - C - D - 10

SUBTRACT 10 D C J FROM B GIVING A

MULTIPLAY: Multiplicación.

FORMATOS:

1.- MULTIPLY variable BY variable ( ROUNDED) (ON SIZE ERROR )


instrucción NOT ON SIZE ERROR instrucción

Elaborado por Sergio Oswaldo Rojas Bernal Página 25


MANUAL DE COBOL

END-MULTIPLY

2.- MULTIPLY variable ó literal BY variable ó literal GIVING variable


(ROUNDED) (ON SIZE ERROR ) instrucción NOT ON SIZE ERROR
instrucción
END-MULTIPLY

A= A * B

MULTIPLY B BY A

C= A * B

MULTIPLY B BY A GIVING C

Elaborado por Sergio Oswaldo Rojas Bernal Página 26


MANUAL DE COBOL

DIVIDE: División

FORMATOS:

1.- DIVIDE variable ó literal INTO variable (ROUNDED) (ON SIZE


ERROR ) instrucción (REMAINDER ) variable NOT ON SIZE ERROR
instrucción
END-DIVIDE

2.- DIVIDE variable ó literal (BY ó INTO) variable ó literal GIVING


variable (ROUNDED) (REMAINDER ) variable (ON SIZE ERROR )
instrucción
NOT ON SIZE ERROR instrucción
END-DIVIDE

A= A / B

DIVIDE B INTO A

C= A / B

DIVIDE B INTO A GIVING C

C = A / B; Residuo en R

DIVIDE B INTO A GIVING C REMAINDER R

*Usando el BY

A= A / B

DIVIDE A BY B GIVING A

Elaborado por Sergio Oswaldo Rojas Bernal Página 27


MANUAL DE COBOL

C= A / B

DIVIDE A BY B GIVING C

C = A / B; Residuo en R

DIVIDE A BY B GIVING C REMAINDER R

Elaborado por Sergio Oswaldo Rojas Bernal Página 28


MANUAL DE COBOL

COMPUTE: Combinación de operadores aritméticos.

COMPUTE , con ésta orden podemos realizar todos los cálculos aritméticos
posibles en una sola instrucción, utilizando los operadores +(suma) -(resta)
*(multiplicación) /(división) **(potenciación), además de utilizar paréntesis
para especificar mejor la operación a realizar.

FORMATO:

1.- COMPUTE variable (ROUNDED) = expresión aritmética (ON


SIZE ERROR) instrucción NOT ON SIZE ERROR instrucción
END-COMPUTE

Jerarquías:

1. ()
2. **
3. * /
4. +-

Elaborado por Sergio Oswaldo Rojas Bernal Página 29


MANUAL DE COBOL

CAPITULO V CONDICIONALES

CONDICIONALES

1. IF

La sentencia IF toma una decisión referente a la acción a ejecutar en un


programa, basándose en el resultado, verdadero o falso, de una condición. Su
formato es:
acción-1 acción-2
IF condición [THEN]
ELSE [END-IF]
NEXT SENTENCE NEXT SENTENCE

El ámbito de la sentencia IF finaliza de cualquiera de las formas siguientes:

1- Por un punto.
2- Por la cláusula END-IF.

TIPOS DE IF
CLASE
SIGNO
RELACION
NOMBRES DE CONDICION
ANIDADOS

Elaborado por Sergio Oswaldo Rojas Bernal Página 30


MANUAL DE COBOL

CLASE: Nos permiten saber el contenido de un identificador o variable

Permiten saber si un campo es numérico o alfabético.


NUMERIC
nombre datos IS [NOT]
ALPHABETIC
ALPHABETIC-UPPER
ALPHABETIC-LOWER

SIGNO:
Permiten determinar si el valor de un campo numérico de una expresión
aritmética es positivo, negativo o cero. El formato general es el siguiente:
nombre datos POSITIVE
IS [NOT] NEGATIVE
expr-aritmetica ZERO

RELACION:

El formato general para formar un condición de relación es:


[NOT] >
[NOT] <
nombre dato-1 nombre dato-1
[NOT] =
literal IS literal
[NOT] GREATER THAN
expr-aritmetica expr-aritmetica
[NOT] LESS THAN
[NOT] EQUAL TO

Condiciones combinadas.

Una condición combinada esta formada por un conjunto de


condiciones simples unidas por los operadores OR y AND. El formato
es el siguiente:
AND
condición simple condición simple
OR

Elaborado por Sergio Oswaldo Rojas Bernal Página 31


MANUAL DE COBOL

Nombres de Condición:

Permiten probar si un nombre de condición al que se le ha asociado


un determinado valor, coincide con el valor del campo de datos del
cual depende.

ANIDADOS:
Las sentencias IF...THEN pueden estar anidadas. Esto quiere decir que
como acción-1 o acción-2, de acuerdo con el formato, puede escribirse otra
sentencia IF.

La estructura presentada a continuación, aparece con bastante frecuencia y


es por lo que la damos un tratamiento por separado. Esta estructura es
consecuencia del anidamiento de sentencias IF.
IF condición-1
.
sentencias-1
.
ELSE IF condición-2
.
sentencias-2
.
ELSE IF condición-3
.
sentencias-3
.
ELSE
.
sentencias-n
.
[END-IF]

2. EVALUATE

EVALUATE identificador/valor lógico ALSO identificador/valor lógico


WHEN valor/nom-con Sent1 ALSO valor/nom-con Sent1
WHEN valor/nom-con Sent2 ALSO valor/nom-con Sent2
WHEN valor/nom-con Sent3 ALSO valor/nom-con Sent3

WHEN OTHER ALSO ANY

Elaborado por Sergio Oswaldo Rojas Bernal Página 32


MANUAL DE COBOL

END-EVALUATE

EJEMPLO
EVALUATE TIPO
WHEN 1 MOVE ‘C’ TO VAR-DESCRI
WHEN 2 MOVE ‘T’ TO VAR-DESCRI
WHEN 3 MOVE ‘N’ TO VAR-DESCRI
WHEN OTHER DISPLAY “ERROR DE TIPO’
END-EVALUATE

EVALUATE EDAD ALSO SEXO


WHEN 18 ALSO ‘M’ ADD 1 TO CON-MUJERES
WHEN 18 ALSO ‘H’ ADD 1 TO CON-HOMBRES
WHEN 30 ALSO ANY ADD 1 TO CON-EDAD-30
WHEN OTHER ADD 1 TO CON-OTROS
END-EVALUATE

EVALUATE TRUE
WHEN MUJER ADD 1 TO CON-MUJERES
WHEN HOMBRE ADD 1 TO CON-HOMBRES
WHEN OTHER ADD 1 TO CON-OTROS
END-EVALUATE

CAPITULO VI VERBOS DE CONTROL

PERFORM
CALL
LINK

PERFORM

La sentencia PERFORM es utilizada para transferir explícitamente el control a


uno o mas procedimientos y devolver el control implícitamente, cuando la

Elaborado por Sergio Oswaldo Rojas Bernal Página 33


MANUAL DE COBOL

ejecución del procedimiento especificado, finalice.

La sentencia PERFORM se puede utilizar para controlar la ejecución de una o


mas sentencias, las cuales están dentro del ámbito de la sentencia PERFORM.

Los tipos de PERFORM que maneja el COBOL son:

BÁSICO
ANIDADOS
TIMES
UNTIL
THRU
VARYING
COMBINADO
LINEA
o TIMES
o UNTIL
o VARYING

BASICO

8 12
PROCEDURE DIVISION.
Nombre-Perform.
Sentencia1
Sentencia1
Sentencia1
Sentencia-n.

EJEMPLO:

8 12
000223-ARMA-REG-SOL.
MOVE SAP-
CANAL TO SOL-COD-CAN

Elaborado por Sergio Oswaldo Rojas Bernal Página 34


MANUAL DE COBOL

MOVE SAP-FEC-SOL-ULTI TO SOL-FEC-SOL


INITIALIZE VARIABLES-FECHA
MOVE '2' TO WS-OPC-FEC
MOVE SAP-FECINI TO WS-FEC-08. .

Elaborado por Sergio Oswaldo Rojas Bernal Página 35


MANUAL DE COBOL

ANIDADO
o Dentro del ámbito de una sentencia PERFORM, puede
especificarse otra sentencia PERFORM, aunque hay que tener
presentes las siguientes reglas:
o 1- El procedimiento PERFORM ejecutado desde el ámbito
de otro PERFORM debe ser totalmente exterior o totalmente
interior a este.
o 2- Los ámbitos de dos PERFORM se pueden solapar
cuando las sentencias de llamada para su ejecución están
fuera de estos ámbitos.
o 3- Las sentencias PERFORM pueden ser anidadas
libremente.
o 4- Un procedimiento PERFORM puede llamarse asimismo,
esto es, la recursividad esta permitida.

EJEMPLO:

8 12
PROCEDURE DIVISION.
MAINLINE.
PERFORM 010000-INICIO
PERFORM 020000-PROCESO
PERFORM 030000-FIN
. STOP RUN.
.

Elaborado por Sergio Oswaldo Rojas Bernal Página 36


MANUAL DE COBOL

TIMES

Cuando se emplea este formato, la sentencia PERFORM ejecuta el número


de veces especificado por entero o por nombre de datos.

FORMATO:

PERFORM procedimiento |entero | TIMES


|variable|

EJEMPLO:

PERFORM LEER 5 TIMES

PERFORM LEER K TIMES

LEER.
Sentencia-1
Sentencia-2
Sentencia-n.

Elaborado por Sergio Oswaldo Rojas Bernal Página 37


MANUAL DE COBOL

UNTIL

Ejecuta el PERFORM mientras que la condición sea falsa; cuando la


condición sea verdadera suspende la ejecución del Perform y continua el
programa.

FORMATO:

PERFORM procedimiento [WITH TEST] |BEFORE | UNTIL Condición


|AFTER|

EJEMPLO:

PERFORM LEER UNTIL X > 5

LEER.
ADD 1 TO X
Sentencia-2
Sentencia-n.

Elaborado por Sergio Oswaldo Rojas Bernal Página 38


MANUAL DE COBOL

THRU

Permite ejecutar una serie de perform’s en forma consecutiva, entre


procedimiento-1 y procedimiento-2, incluyendo ambos.

FORMATO:

PERFORM procedimiento-1 [THRU procedimiento-2]

EJEMPLO:

PROCEDURE DIVISION.
INICIO.
PERFORM M1
PERFORM M2 THRU M5
PERFORM M3
STOP RUN.

M1.
Sentencias.

M2.
Sentencias.
AA1.
Sentencias.
BJ2.
Sentencias.
FD3.
Sentencias.
JK4.
Sentencias.
M5.
Sentencias.
M3.
Sentencias.

VARYING

Elaborado por Sergio Oswaldo Rojas Bernal Página 39


MANUAL DE COBOL

BEFORE
PERFORM procedimiento-1 WITH TEST
AFTER
nombre dato-1 nombre dato-2 nombre dato-3
VARYING FROM literal BY
nombre indice-1 nombre indice-2 nombre indice-3

UNTIL condición-1
nombre dato-4 nombre dato-5 nombre dato-6
AFTER FROM literal-2 BY
nombre indice-4 nombre indice-5 nombre indice-6

UNTIL condición-2

Realiza el PERFORM de la siguiente forma:

1- El nombre dato-1 y el nombre dato-4 se inicializan a los valores


respectivos que siguen a cada FROM.
2- Se evalúa la condición-1. Si es cierta, se da por finalizada la
ejecución de la sentencia PERFORM y se pasa a la
sentencia siguiente en el programa. Si es falsa se pasa al punto
3.
3- Se evalúa la condición-2. Si es cierta, el nombre dato-4 se
inicializa al valor especificado por literal-2 o nombre dato-4 que
sigue a FROM, también se suma a nombre dato-1 el valor
especificado por nombre dato-3 que sigue a BY y se continua en
el punto 2. Si es falsa se pasa al punto 4.
4- Se ejecutan las sentencias entre procedimiento-1 y
procedimiento-2, si ha sido especificado.
5- Se suma a nombre dato-4 el valor especificado por nombre
dato-6 que sigue a BY, y se vuelve al punto 3.

Los nombres dato y/o pueden ser enteros o reales, positivos o negativos y
cero excepto los nombres de índice que deben ser enteros.

EJEMPLO:

Elaborado por Sergio Oswaldo Rojas Bernal Página 40


MANUAL DE COBOL

Hacer la suma de todos los elementos de una tabla de 2 dimensiones.

01 TABLA.
05 FILAS OCCURS 10 TIMES.
10 COLUMNAS OCCURS 10 TIMES PIC 99.

PROCEDURE DIVISION.
INICIO.
................ PERFORM SUMA VARYING INDICE1
FROM 1 BY 1
UNTIL INDICE1 > 10
AFTER INDICE2
FROM 1 BY 1
UNTIL INDICE2 > 10.
.....................
SUMA.
ADD COLUMNAS ( INDICE1, INDICE2 ) TO ACUMULADOR.

Nota: El Orden con que se incrementa el Acumulador es el Sgte.

ADD COLUMNAS ( 1, 1 ) TO ACUMULADOR.


( 1, 2 ) TO ACUMULADOR.
( 1, 3 ) TO ACUMULADOR.
.
( 1, 10 ) TO ACUMULADOR.
( 2, 1 ) TO ACUMULADOR.
( 2, 2 ) TO ACUMULADOR.
( 2, 3 ) TO ACUMULADOR.
.
( 2, 10 ) TO ACUMULADOR.
.

( 10, 1 ) TO ACUMULADOR.
( 10, 2 ) TO ACUMULADOR.
( 10, 3 ) TO ACUMULADOR.
.

Elaborado por Sergio Oswaldo Rojas Bernal Página 41


MANUAL DE COBOL

( 10, 10) TO ACUMULADOR.

Elaborado por Sergio Oswaldo Rojas Bernal Página 42


MANUAL DE COBOL

COMBINADOS

o THRU CON VARYING


BEFORE
PERFORM procedimiento-1 [THRU procedimiento-2] WITH TEST
AFTER
nombre dato-1 nombre dato-2 nombre dato-3
VARYING FROM literal BY
nombre indice-1 nombre indice-2 nombre indice-3

UNTIL condición

o THRU CON UNTIL

BEFORE
PERFORM procedimiento-1 [THRU procedimiento-2] WITH TEST
AFTER

UNTIL condición

Elaborado por Sergio Oswaldo Rojas Bernal Página 43


MANUAL DE COBOL

EN LINEA

o UNTIL EN LINEA

FORMATO:
BEFORE
PERFORM WITH TEST UNTIL condición
AFTER
{sentencia} ...
END-PERFORM

Cuando se emplea este formato, la sentencia PERFORM ejecuta el


conjunto de sentencias que hay entre PERFORM y END-PERFORM hasta
que la condición sea verdad. Un punto, como final de alguna de las
sentencias de esta estructura, daría lugar a un error, ya que se entendería
como final de la sentencia PERFORM.

EJEMPLO:

021100-INICIALIZA-MAPA.
MOVE 1 TO WRK-IND-X
PERFORM UNTIL WRK-IND-X > 10
MOVE SPACES TO SAP-SELEC(WRK-IND-X)
SAP-LINEA(WRK-IND-X)
ADD 1 TO WRK-IND-X
END-PERFORM
SET CAA-88-ACCION-TERMINAL TO TRUE
SET CAA-88-ESTADO-CONTIN TO TRUE
MOVE 100 TO VAR-NUM.

VARYING EN LINEA

Elaborado por Sergio Oswaldo Rojas Bernal Página 44


MANUAL DE COBOL

FORMATO:
BEFORE nombre dato-1 nombre dato-2
PERFORM WITH TEST VARYING FROM literal
AFTER nombre indice-1 nombre indice-2
nombre dato-3
BY UNTIL condición
nombre indice-3

La ejecución, si no se ha especificado la opción TEST AFTER, se realiza de


la forma siguiente:
1- El nombre dato-1 se inicializa al valor especificado por
literal o nombre dato-2 que sigue a FROM.
2- Se evalúa la condición. Si es cierta, se da por finalizada
la
ejecución de la sentencia PERFORM y se pasa a la
sentencia siguiente en el programa. Si es falsa se pasa
al punto 3.
3- Se ejecutan las sentencias entre PERFORM y
END-PERFORM.
4- Se suma a nombre dato-1 el valor especificado por
nombre dato-3 que sigue a BY, y se vuelve al punto 2.

EJEMPLO:

021100-INICIALIZA-MAPA.
MOVE 1O TO WRK-IND
PERFORM VARYING X FROM 1 BY 1 UNTIL X > 5
MOVE SPACES TO SAP-LINEA(X)
END-PERFORM
SET CAA-88-ACCION-TERMINAL TO TRUE
SET CAA-88-ESTADO-CONTIN TO TRUE
MOVE 100 TO VAR-NUM.
TIMES EN LINEA

Cuando se emplea este formato, la sentencia PERFORM ejecuta el numero


de veces especificado por entero o por nombre de datos, el conjunto de
sentencias que hay entre PERFORM y END-PERFORM. Un punto, como
final de alguna de las sentencias de esta estructura, daría lugar a un error,

Elaborado por Sergio Oswaldo Rojas Bernal Página 45


MANUAL DE COBOL

ya que se entendería como final de la sentencia PERFORM.

entero
PERFORM TIMES {sentencia}..... END-PERFORM
nombre datos

EJEMPLO:

021100-INICIALIZA-MAPA.
MOVE 1 TO X
PERFORM 5 TIMES
MOVE SPACES TO SAP-LINEA(X)
ADD 1 TO X
END-PERFORM
SET CAA-88-ACCION-TERMINAL TO TRUE
SET CAA-88-ESTADO-CONTIN TO TRUE
MOVE 100 TO VAR-NUM.

CAPITULO VII FORMATOS DE EDICION

Se utilizan para presentar de una forma clara por pantalla o por la impresora los
campos o datos numéricos.

El significado de cada uno de estos caracteres es el siguiente:

Elaborado por Sergio Oswaldo Rojas Bernal Página 46


MANUAL DE COBOL

Z Representa una cifra del 0 al 9. Si la cifra a escribir se corresponde


con un 0 no significativo, se escribe en su lugar un espacio en blanco.
* Representa una cifra del 0 al 9. Si la cifra a escribir se corresponde
con un 0 no significativo, se escribe en su lugar un *.
Los caracteres Z y * no pueden ir precedidos, pero si seguidos del
carácter 9.
El punto hace que se inserte un punto decimal para separar la parte
. entera de la parte decimal.
, La coma hace que se inserte este mismo carácter en el lugar que se
indica en la especificación de formato.

La cláusula DECIMAL-POINT IS COMMA en la ENVIRONMENT


DIVISION, permite invertir el papel del punto y la coma en las
especificaciones de formato en la edición.
B Permite que se inserte un espacio en blanco en el lugar que se indica
en la especificación de formato.
0 Permite que se inserte un cero en el lugar de que se indica en la
especificación de formato.
/ Permite que se inserte una barra en el lugar de que se indica en la
especificación de formato.
CR Símbolo bancario indicativo de crédito. Solo puede colocarse a la
derecha de la especificación de formato. CR aparece sobre la línea
que se imprime si el valor es negativo. Si el valor es positivo
aparecerán en su lugar 2 espacios en blanco.
DB Símbolo bancario indicativo de débito. Solo puede colocarse a la
derecha de la especificación de formato. DB aparece sobre la línea
que se imprime si el valor es negativo. Si el valor es positivo
aparecerán en su lugar 2 espacios en blanco.
$ Un carácter $ colocado en el primer lugar en la especificación de
formato, permite la aparición de este carácter en el lugar indicado.
+ Un carácter + colocado en primer o ultimo lugar en la especificación
de formato, permite la aparición de un + para valores positivos y de un
- para valores negativos en el lugar indicado.
- Un carácter + colocado en primer o ultimo lugar en la especificación
de formato, permite la aparición de un espacio en blanco para valores
positivos o un - para valores negativos en el lugar indicado.

Elaborado por Sergio Oswaldo Rojas Bernal Página 47


MANUAL DE COBOL

$$.. La aparición en una especificación de formato de n caracteres $,


. permite editar un valor de n-1 cifras. Si la cifra a escribir se
corresponde con un 0 no significativo, se escribe en su lugar un
espacio en blanco, excepto a la izquierda de la primera cifra
significativa que se inserta un carácter $.
++.. La aparición en una especificación de formato de n caracteres +,
. permite editar un valor de n-1 cifras. Si la cifra a escribir se
corresponde con un 0 no significativo, se escribe en su lugar un
espacio en blanco, excepto a la izquierda de la primera cifra
significativa que se inserta un carácter + para los valores positivos o
un - para los valores negativos.
-- La aparición en una especificación de formato de n caracteres +,
permite editar un valor de n-1 cifras. Si la cifra a escribir se
corresponde con un 0 no significativo, se escribe en su lugar un
espacio en blanco, excepto a la izquierda de la primera cifra
significativa que se inserta un carácter - para los valores negativos.

CAPITULO VIII TABLAS DE MEMORIA

DEFINICION

Es un conjunto de valores almacenados en posición de almacenamiento


consecutivo y con un nombre de dato asignado. La referencia a un elemento
especifico de la tabla se hace mediante el uso de un sólo nombre con un
subíndice que identifica la posición de un elemento en particular.
CLAUSULA OCCURS:

Elaborado por Sergio Oswaldo Rojas Bernal Página 48


MANUAL DE COBOL

Define el tamaño de la tabla. No puede aparecer en líneas a nivel 01, ni 77, ni 88.
FORMATO A:
OCCURS entero1 [TIMES]

FORMATO B:
OCCURS entero1 [TIMES] PIC ...

Ejemplo:
Crea una tabla de 5 elementos y cada elemento compuesto por 2 campos con la
picture indicada.

01 TABLA.
05 ELEMENTO OCCURS 5.
10 N-VENDEDOR PIC XXX.
10 TOTAL-VENDIDO PIC 9(6).

Ejemplo:
Crea una tabla de 100 elementos de 2 caracteres numéricos.

01 TABLA.
05 ELEMENTOS OCCURS 100 PIC 99.

01 TABLA.
05 ELEMENTOS OCCURS 100 PIC 99 VALUE ZERO.

CLAUSULA REDEFINES EN TABLAS

FUNCION:

Elaborado por Sergio Oswaldo Rojas Bernal Página 49


MANUAL DE COBOL

Redefine una zona de memoria:


Obligatoriamente debe siempre ir después del campo que redefinimos
Tiene que llevar el mismo número de nivel que el campo que redefinimos.
No puede ponerse una cláusula REDEFINES junto con una instrucción OCCURS.

FORMATO:
número-de-nivel nombre-dato1 REDEFINES nombre-dato2

Ejemplo:
Redefinimos un campo alfanumérico en una tabla en la que cada elemento es un
mes del alto.
01 MESES.
05 NOMBRE-MESES
10 FILLER PIC X(9) VALUE "ENERO ".
10 FILLER PIC X(9) VALUE "MARZO ".
.
.
.
10 FILLER PIC X(9) VALUE "DICIEMBRE".
05 TABLA-MESES REDEFINE NOMBRE-MESES.
10 MES PIC X(9) OCCURS 12 TIMES.

INSTRUCCION MOVE EN TABLAS


El uso de la instrucción MOVE TABLA TO ..... da como resultado el movimiento de
todos sus elementos. Para referenciar un elemento de la tabla se indica el nombre
de dicho elemento y el índice entre paréntesis separado por un espacio.

Elaborado por Sergio Oswaldo Rojas Bernal Página 50


MANUAL DE COBOL

Cuando hacemos referencia a un grupo de elementos se consideran


alfanuméricos para propósitos del MOVE.
Ejemplo:
Mover un elemento de la tabla a una variable.
01 TABLA.
05 ELEMENTO OCCURS 50 TIMES.
10 ELE1 PIC 9(6)V99.
10 ELE2 PIC 9(6)V99.
.
.
.
MOVE ELE1 ( 34 ) TO IMPORTE.

Ejemplo:
Mover las letras de la A a la F a una tabla.
01 TABLA.
05 LETRAS OCCURS 6 TIMES PIC X.
.
.
.
MOVE "ABCDEF" TO TABLA.

TABLAS DE VARIAS DIMENSIONES

El concepto de DIMENSIÓN se refiere a categorias por medio de las cuales los


datos son organizados dentro de las tablas.
Puede haber tablas de hasta 7 dimensiones. La forma de referenciar un elemento
es por medio de tantos subíndices como sea la dimensión de la tabla, separados
por espacios.

Elaborado por Sergio Oswaldo Rojas Bernal Página 51


MANUAL DE COBOL

Ejemplo:
Crear un tabla que tenga 5 departamentos y dentro de cada departamento 5
vendedores con sus ventas.
01 TABLA-DEPARTAMENTOS.
05 DEPARTAMENTOS OCCURS 5 TIMES.
10 VENTAS OCCURS 5 TIMES PIC 9(7).

Preguntar si el vendedor 5 del departamento 1 ha vendido más de $ 25.000.

IF VENTAS ( 1, 5 ) > 25.000

TABLAS VARIABLES

Se dice que una tabla es variable cuando su tamaño varía de una ejecución a otra.

FORMATO:
OCCURS entero-1 TO entero-2 TIMES DEPENDING ON numero-datos

El campo entero-1 y entero-2 son el mínimo y el máximo número de elementos


que puede contener la tabla, dependiendo del valor que tenga numero-datos.

Ejemplo:
Una tabla que tenga de 100 a 200 elementos según el número de artículos
existentes.
01 TABLA.
05 ARTICULOS OCCURS 100 TO 200 DEPENDING ON
N-ARTICULOS.

Elaborado por Sergio Oswaldo Rojas Bernal Página 52


MANUAL DE COBOL

PERFORM VARYING EN EL MANEJO DE TABLAS

FUNCION:
Se utiliza para hacer recorridos por los elementos de una tabla.
EJEMPLO:
Hacer la suma de todos los elementos de una tabla de 2 dimensiones.
01 TABLA.
05 FILAS OCCURS 10 TIMES.
10 COLUMNAS OCCURS 10 TIMES PIC 99.

PROCEDURE DIVISION.
INICIO.
................
PERFORM SUMA VARYING INDICE1
FROM 1 BY 1 UNTIL INDICE1 > 10
AFTER INDICE2 FROM 1 BY 1 UNTIL INDICE2 > 10.
.....................
SUMA.
ADD COLUMNAS ( INDICE1, INDICE2 ) TO ACUMULADOR.

Nota: El Orden con que se incrementa el Acumulador es el Sgte.

ADD COLUMNAS ( 1, 1 ) TO ACUMULADOR.


( 1, 2 ) TO ACUMULADOR.
( 1, 3 ) TO ACUMULADOR.
.
( 1, 10 ) TO ACUMULADOR.
( 2, 1 ) TO ACUMULADOR.
( 2, 2 ) TO ACUMULADOR.
( 2, 3 ) TO ACUMULADOR.
.
( 2, 10 ) TO ACUMULADOR.
.
( 10, 1 ) TO ACUMULADOR.
( 10, 2 ) TO ACUMULADOR.
( 10, 3 ) TO ACUMULADOR.

Elaborado por Sergio Oswaldo Rojas Bernal Página 53


MANUAL DE COBOL

.
( 10, 10) TO ACUMULADOR.

Elaborado por Sergio Oswaldo Rojas Bernal Página 54


MANUAL DE COBOL

TABLAS INDEXADAS

FUNCION:
Nos permite indexar una tabla para posteriormente hacer búsquedas sin
necesidad de recorrerla entera.
FORMATO:
ASCENDING
OCCURS entero TIMES KEY IS dato-1 [dato2...]
DESCENDING

[INDEXED BY indice-1 [indice-2...]]

La opción ASCENDING o DESCENDING KEY IS sólo se utiliza en el caso de que


la tabla se encuentre ordenada por una o varias claves.
La opción INDEXED BY indica el o los índices que vayamos a utilizar, son
obligatorios en caso de utilizar la instrucción SEARCH.
Los índices-1 e índice-2, si se ponen hay que declararlos en la
WORKING-STORAGE SECTION como USAGE IS INDEX.

Ejemplo:
01 CAMPOS.
05 INDICE USAGE IS INDEX.
01 TABLA.
05 ELEMENTOS OCCURS 10 INDEXED BY INDICE.

INSTRUCCION SET

Elaborado por Sergio Oswaldo Rojas Bernal Página 55


MANUAL DE COBOL

FUNCION:
Para inicializar índices o cambiar su contenido. Sólo los declarados como USAGE
INDEX.
FORMATO:
TO entero
SET indice UP BY
DOWN BY variable

El parámetro TO inicializa el índice al valor que pongamos en entero o variable.


El parámetro UP BY suma al índice el valor que pongamos en entero o variable.
El parámetro DOWN BY resta al índice el valor que pongamos en entero o
variable.

Ejemplo:
Inicializar el indice en 2.
SET INDICE TO 2.

Ejemplo:
Restar 3 al indice.
SET INDICE DOWN BY 3.

INSTRUCCION SEARCH

FUNCION:

Elaborado por Sergio Oswaldo Rojas Bernal Página 56


MANUAL DE COBOL

Sirve para buscar un elemento o varios en una tabla. Esta opción puede ser
utilizada con subíndices pero es mucho mas lenta.
FORMATO:
índice
SEARCH identificador VARYING AT END acción-1
variable

WHEN condición-1 acción-2


[WHEN condición-2 acción-3 ]

El identificador es el elemento de la tabla donde se va a hacer la búsqueda.


AT END acción-1 es lo que tiene que hacer en caso de que la tabla se haya
terminado y el elemento no lo haya localizado.
Condición-1 y opcionalmente condición-2 son las condiciones que tienen que
cumplir un determinado elemento de la tabla al cual se está buscando.
La opción VARYING índice, hace que el varíe el índice de indexación de la tabla.
Ejemplo:
Hacer un DISPLAY de el precio del pan.
01 CAMPOS.
05 INDICE USAGE INDEX.
......................
01 TABLA-ARTICULOS.
05 ARTICULOS OCCURS 50 TIMES PIC X(10) INDEXED BY
INDICE.

01 TABLA-PRECIOS.
05 PRECIOS OCCURS 50 TIMES PIC 9(5).
.......................................
PROCEDURE DIVISION.
INICIO.
............
SEARCH ARTICULOS AT END PERFORM ART-INEXISTENTE
WHEN ARTICULOS ( INDICE ) = "PAN "

Elaborado por Sergio Oswaldo Rojas Bernal Página 57


MANUAL DE COBOL

DISPLAY PRECIOS ( INDICE ).

Elaborado por Sergio Oswaldo Rojas Bernal Página 58


MANUAL DE COBOL

CAPITULO IX ARCHIVOS SECUENCIALES

DEFINICION:

De ésta organización se deriva el formato del fichero, SEQUENTIAL si los


registros se graban secuencialmente conforme se dan entrada sin importar si
están o no repetidos, un ejemplo claro son los archivos de impresora, todos los
listados son secuenciales.

Cláusula SELECT para ficheros secuenciales:

SELECT [OPTIONAL] nombre-fichero-1ASSIGN TO dispositivo

ORGANIZATION IS [RECORD]
SEQUENTIAL
LINE

[ACCESS MODE IS SEQUENTIAL]

[FILE STATUS IS nombre-de-dato]

Cláusula SELECT es aqui donde especificamos el nombre lógico que va a tener el


fichero dentro del programa, suele ser una palabra que identifique lo mas claro
posible el contenido del fichero, por ejemplo ARTICULOS, PROVEEDORES,
CLIENTES.

Cláusula OPTIONAL si indicamos esta opción al hacer un OPEN I-O, si el archivo


no existe, se crea. Con lo cual nos evitamos tener que abrirlo como OUTPUT y
cerrarlo, antes de poder utilizarlo por primera vez.

Cláusula ASSIGN aqui especificamos el tipo de dispositivo, si es una impresora


PRINTER, si es un fichero sobre el que vamos a grabar RANDOM o DISC, se
pueden utilizar otros como INPUT, INPUT-OUTPUT, CASSETTE, MAGNETIC-
TAPE, pero sin duda los mas utilizados son los dos primeros para identificar si el
fichero utilizará una salida impresa o se utilizará sobre disco.

Cláusula ORGANIZATION aqui indicamos la organización de los registros de

Elaborado por Sergio Oswaldo Rojas Bernal Página 59


MANUAL DE COBOL

nuestro fichero, Donde debe ser SEQUENTIAL

Si se omite la cláusula ORGANIZATION se asume organización secuencial y si se


omite la cláusula ACCESS se asume acceso secuencial.

La organización RECORD SEQUENTIAL, se refiere a un fichero secuencial


estándar. En este, la longitud de cada registro se especifica por dos bytes que
preceden al propio registro. La organización LINE SEQUENTIAL, es la opción por
defecto, y hace que cada registro vaya seguido de un carácter fin de línea que
actúa como delimitador.

En la cláusula SELECT también se puede especificar el fichero como un fichero en


múltiples carretes de cinta magnética, mediante la frase ASSIGN TO MULTIPLE
REEL FILE nombre-externo-del-fichero.

FILE SECTION.
En esta sección describiremos los campos que van a componer el registro de cada
uno de los archivos con los que vamos a trabajar, ésta sería su sintaxis:

Cláusula FD para ficheros secuenciales:


8 12
FD nombre del fichero

Elaborado por Sergio Oswaldo Rojas Bernal Página 60


MANUAL DE COBOL

LABEL RECORD
[RECORDING MODE IS]
[BLOCK CONTAINS]
[RECORD CONTAINS]
[DATA RECORD IS]

Cláusula FD nombre del fichero que previamente habiamos descrito en la


cláusula SELECT de la INPUT-OUTPUT SECTION en la ENVIRONMENT
DIVISION.

Cláusula BLOCK CONTAINS cuando queremos que por cada bloque en


disco se graben mas de un registro, aqui especificamos el número de ellos
que va a contener cada bloque, (512, 1024), si no se especifica se supone
que cada registro va a ocupar un bloque de memoria, o bien será el propio
compilador el que haga el cálculo mas apropiado.

Cláusula RECORD CONTAINS el número de caracteres que tiene el


registro sumando todos sus campos, puede ser fija o variable. Si es fija
utilizamos un valor y si es variable un rango desde hasta, si no se espicifica
será el propio compilador quien la determine.

Cláusula LABEL RECORD puede tener dos valores STANDARD u


OMITTED , el primer caso indica que cada vez que se accede a un registro
el compilador hará las comprobaciones estandares descritas por el propio
compilador y en el segundo éstas serán omitidas. Para el caso de los
ficheros de datos en disco se suele poner STANDARD y cuando el fichero
es de impresora se indica OMITTED.

Cláusula DATA RECORD debido a que un mismo fichero puede tener


varias descripciones de registro, aqui indicamos los nombre de éstas que
deberán estar descritas a nivel 01. Normalmente no se utiliza y casi siempre
se suele utilizar una sola descripción por fichero, por lo que no suele
aparecer en casi ningún programa.

Sentencia OPEN:

Elaborado por Sergio Oswaldo Rojas Bernal Página 61


MANUAL DE COBOL

La operación de abrir un fichero, establece una comunicación entre el área de E/S


asociada a ese fichero y el dispositivo externo que lo soporta, comprueba las
etiquetas en los ficheros de entrada y las crea para los ficheros de salida, y sitúa el
puntero de lectura-escritura en el primer registro o al final del fichero dependiendo
del modo en que se haya abierto el fichero.

Formato 1:
NO REWIND
OPEN INPUT fichero-1 REVERSED WITH ...
LOCK

Formato 2:

NO REWIND
OPEN OUTPUT fichero-1 REVERSED WITH ...
LOCK

Formato 3:

OPEN I-O {fichero-3 [WITH LOCK ]}...

Formato 4:

OPEN EXTEND {fichero-4 [WITH LOCK ]}...

EJEMPLO

OPEN INPUT NOMINA


OPEN OUTPUT CARGOS
OPEN I-O SALDOS
OPEN EXTEND SALIDAS

Si el fichero esta almacenado en un soporte que permite la operación de rebobinar


y se especifica la cláusula REVERSED, los datos para una sentencia READ

Elaborado por Sergio Oswaldo Rojas Bernal Página 62


MANUAL DE COBOL

quedan disponibles en orden inverso, esto es, comenzando por el ultimo. La


cláusula NO REWIND hace que el carrete de cinta no se rebobine. Esto puede ser
muy útil cuando en una cinta hay múltiples ficheros.

Si se especifica la frase WITH LOCK, el efecto es equivalente a especificar LOCK


MODE EXCLUSIVE en la sentencia SELECT correspondiente a este fichero, esto
es, el fichero no puede ser compartido por otros procesos.

Un fichero abierto en modo OUTPUT es implícitamente un fichero no compartible.


Para que mas de un proceso puedan compartir un fichero hay que abrirlo en modo
I-O.

Cuando se especifica la cláusula INPUT, se abre el fichero especificado para leer.


El puntero de lectura se sitúa en el primer registro. Si el fichero no existe se
produce un error.

Cuando se especifica la cláusula OUTPUT, se abre el fichero especificado para


escribir. Si el fichero que se abre existe, se destruye su contenido actual
creándose así de nuevo. Si no se existe se crea.

Cuando se especifica la cláusula I-O, se abre el fichero especificado para leer y


escribir. El puntero de lectura-escritura se sitúa en el primer registro. Si este no
existe se crea. En este caso una operación de lectura daría lugar a una condición
de fin de fichero y una operación de escritura daría lugar a un error. Este modo no
se puede utilizar con una organización LINE SEQUENTIAL.

Cuando se especifica la cláusula EXTEND, significa que se van añadir datos a un


fichero con modo de acceso secuencial. De esta forma podemos añadir mas
registros a un fichero existente. Si el fichero no existe se crea.

Sentencia CLOSE.

Esta sentencia finaliza el proceso de uno o varios ficheros.


REEL NO REWIND
CLOSE fichero-1 WITH
...
UNIT LOCK

Elaborado por Sergio Oswaldo Rojas Bernal Página 63


MANUAL DE COBOL

EJEMPLO

CLOSE NOMINA
CLOSE CARGOS
CLOSE SALDOS SALIDAS

Cada fichero abierto por medio de una sentencia OPEN, debe ser cerrado por una
sentencia CLOSE bien cuando finaliza el programa o bien cuando se desea abrirlo
de modo diferente. Una sentencia CLOSE puede cerrar uno o mas ficheros.

Las opciones REEL y UNIT se utilizan con cintas magnéticas y discos magnéticos
respectivamente para indicar que le fichero tratado es multivolumen.

La opción NO REWIND se utiliza para anular la operación de rebobinado que se


produce normalmente al cerrar un fichero contenido en cinta magnética.

La opción WITH LOCK hace que el fichero cerrado no pueda volverse a abrir
durante el resto de la ejecución del proceso en cuestión.

Elaborado por Sergio Oswaldo Rojas Bernal Página 64


MANUAL DE COBOL

Sentencia WRITE:

Cuando se ejecuta esta sentencia se efectúa una operación de salida o de


escritura de un registro lógico con destino a un fichero de salida o de entrada-
salida. Estas transferencias de información se hacen a través del área de memoria
asignada al fichero aunque esta operación es transparente al usuario.

WRITE registro [FROM nombre-dato-1]

nombre-de-dato-2 [LINE[S]]
BEFORE entero [LINE[S]]
ADVANCING PAGE
AFTER
TAB
FORMFEED

END-OF-PAGE
AT sentencia-1
EOP

END-OF-PAGE
NOT AT sentencia-1
EOP

[END-WRITE]

Registro identifica el nombre del registro lógico que se desea escribir. Este estará
declarado en la FILE SECTION o en la DATA DIVISION. El fichero asociado debe
abrirse en modo OUTPUT o EXTENDED.

Si se especifica la opción FROM, primero se mueve el contenido del campo


referenciado por nombre-de-dato-1 al campo referenciado por registro y a
continuación se efectúa la operación de escribir.

Las opciones BEFORE o AFTER ADVANCING se aplican solamente a ficheros de


salida impresos e indican, escribir el registro antes de (BEFORE) o después de
(AFTER) avanzar, entero o nombre-de-dato-1 líneas, pagina (PAGE o
FORMFEED), o tabulación vertical (TAB).

Elaborado por Sergio Oswaldo Rojas Bernal Página 65


MANUAL DE COBOL

Nombre mnemónico es un nombre creado por el programador con el fin de


asociarlo en el párrafo SPECIAL-NAMES a una palabra reservada COBOL.

Si se especifica END-OF-PAGE o su equivalente EOP, debe especificarse la


cláusula LINAGE en la descripción del fichero (FD) en el cual estamos
escribiendo. EOP es una condición que es cierta cuando se alcanza el final de la
pagina lógica, en cuyo caso se ejecuta sentencia-1.

Sentencia-1 y sentencia-2 son sentencias imperativas, esto es, no condicionales.

Cuando en la descripción de un fichero se utiliza la cláusula LINAGE no se puede


utilizar ADVANCING nombre-nemonico.

END-WRITE solo se puede utilizar con END-OF-PAGE y sirve para delimitar el


ámbito de la sentencia WRITE.

Si el tipo de organización es RECORD SEQUENTIAL y en la sentencia WRITE no


se utiliza la opción ADVANCING, se asume el avance automático equivalente a
haber especificado, BEFORE ADVANCING 1 LINE.

EJEMPLO

WRITE REG-NOMINA END-WRITE

WRITE REG-NOMINA FROM TITULO-1 AFTER PAGE END-WRITE

WRITE REG-NOMINA FROM DETALLE AFTER 1 END-WRITE.

Sentencia READ:

Cuando se ejecuta esta sentencia se deja disponible un registro lógico en el área


de entrada, para ser procesado.

READ fichero RECORD [INTO nombre de dato] [WITH [NO] LOCK]


[AT END sentencia-1]

Elaborado por Sergio Oswaldo Rojas Bernal Página 66


MANUAL DE COBOL

[NOT AT END sentencia-2]


[END-READ]

Fichero es el nombre simbólico del fichero del cual se quiere leer un registro. Este
fichero tiene que ser abierto en modo INPUT o I-O.

Cuando se abre el fichero el puntero de lectura-escritura apunta al primer registro


a leer y cada vez que se ejecuta una sentencia READ se lee un registro y el
puntero de lectura-escritura avanza para apuntar al siguiente registro a leer.

Si se especifica la opción INTO, la sentencia READ además de dejar disponible un


registro lógico en el área de entrada, esto es, en el registro de entrada esta
definido en la FD, mueve el contenido de este registro al área de datos
especificada por nombre de datos.

La opción INTO no puede ser utilizada cuando el fichero contiene registros de


varios tipos.

La frase AT END es una condición que es cierta cuando al ejecutarse una


sentencia READ se detecta el final del fichero, en cuyo caso se ejecuta la
sentencia-1. Si la condición resulta ser falsa, entonces se ejecuta, después de
haberse realizado la operación de lectura, la sentencia-2, si la frase NOT AT END
ha sido especificada, y se pasa a la sentencia siguiente.

Sentencia-1 y sentencia-2 son sentencias imperativas, esto es, no


condicionales.

Aunque la frase AT END sea opcional, debe especificarse cuando se acceda


secuencialmente a los registros de un fichero, para poder detectar cuando se llega
al final del mismo.

END-READ delimita el ámbito de la sentencia READ

En un fichero secuencial abierto en modo INPUT, la sentencia READ o READ


WITH LOCK no puede leer un registro en modo exclusivo.

En un fichero abierto en modo I-O con LOCK MODE AUTOMATIC, a menos que
se especifique la opción WITH NO LOCK, cada registro en el momento de leerse
es exclusivo, no compartido, siendo liberado cuando finaliza la lectura.

Elaborado por Sergio Oswaldo Rojas Bernal Página 67


MANUAL DE COBOL

En un fichero abierto en modo I-O con LOCK MODE MANUAL, cada registro en el
momento de leerse no es exclusivo a menos que se especifique la opción WITH
LOCK en la sentencia READ.

EJEMPLO:

READ SALDOS AT END MOVE 1 TO FDA


NOT AT END PERFORM CALCULOS
END-READ

READ SALDOS INTO REG-SALIDA AT END MOVE 1 TO FDA


NOT AT END PERFORM CALCULOS
END-READ

Elaborado por Sergio Oswaldo Rojas Bernal Página 68


MANUAL DE COBOL

Modificar un registro secuencial:

Si el fichero se abre en modo I-O, es posible modificar el ultimo registro leído por
medio de la sentencia REWRITE, la cual presentamos a continuación.

Sentencia REWRITE.

Este sentencia permite reemplazar un registro existente en un fichero en disco por


otro registro.

REWRITE registro [FROM nombre-de-dato]


[END-REWRITE]

Registro es el nombre de un registro lógico especificado en la FILE SECTION de


la DATA DIVISON. El fichero asociado con este registro debe ser un fichero
residente en disco y abierto en modo I-O.

El numero de caracteres del registro a reemplazar debe ser igual al numero de


caracteres del registro que lo va a reemplazar.

Para ficheros en los que el modo de acceso es secuencial la ultima sentencia


ejecutada antes de la ejecución de la sentencia REWRITE, debe ser una
sentencia READ. El registro reemplazado será lógicamente el registro leído.

La posición indicada por el puntero de lectura-escritura será la misma después de


haber ejecutado una sentencia REWRITE.

EJEMPLO:

REWRITE REG-SALDOS FROM –REG-DATOS END-REWRITE

Elaborado por Sergio Oswaldo Rojas Bernal Página 69


MANUAL DE COBOL

CAPITULO X ARCHIVOS INDEXADOS

DEFINICION

Un fichero indexado es un fichero con organización secuencial indexada. La


organización secuencial indexada o de índices es un modelo de almacenamiento
de datos que se apoya en una tabla de índices que actúa como índice y en un
fichero de datos.

SELECT [OPTIONAL] nombre-fichero-1 ASSIGN TO DISK

entero-1 AREA
RESERVE ALTERNATE
NO AREAS

ORGANIZATION IS INDEXED

SEQUENTIAL
ACCESS MODE IS RANDOM
DYNAMIC

nombre dato-1
RECORD KEY IS
clave-m = nombre dato-4,[nombre dato-5] ...

nombre dato-1
ALTERNATE RECORD KEY IS
clave-m = nombre dato-6,[nombre dato-7] ...

[LOCK MODE IS modo-de-cierre]


[FILE STATUS IS nombre-de-dato-3]

Cláusula SELECT es aqui donde especificamos el nombre lógico que va a tener el


fichero dentro del programa, suele ser una palabra que identifique lo mas claro
posible el contenido del fichero, por ejemplo ARTICULOS, PROVEEDORES,
CLIENTES.

Cláusula OPTIONAL si indicamos esta opción al hacer un OPEN I-O, si el archivo

Elaborado por Sergio Oswaldo Rojas Bernal Página 70


MANUAL DE COBOL

no existe, se crea. Con lo cual nos evitamos tener que abrirlo como OUTPUT y
cerrarlo, antes de poder utilizarlo por primera vez.

Cláusula ASSIGN aqui especificamos el tipo de dispositivo, si es una impresora


PRINTER, si es un fichero sobre el que vamos a grabar RANDOM o DISC, se
pueden utilizar otros como INPUT, INPUT-OUTPUT, CASSETTE, MAGNETIC-
TAPE, pero sin duda los mas utilizados son los dos primeros para identificar si el
fichero utilizará una salida impresa o se utilizará sobre disco. Para identificar
ficheros utilizados para clasificar utilizaremos SORT.

Cláusula ORGANIZATION aqui indicamos la organización de los registros de


nuestro fichero, INDEXED. Es la mas utilizada e identifica a ficheros que sus
registros son accesibles mediante una clave unica e irrepetible o por varias que
pueden estar duplicadas, cualquier fichero de mantenimiento, por ejemplo de
ARTICULOS, podría ser INDEXED, y cada código será único para cada artículo y
con el nos iremos a su posición y podremos ver todos los demas datos que hagan
referencia al registro.

Existe también para los archivos de texto, tipo AUTOEXEC.BAT la posibilidad de


asignarlos directamente especificando LINE SEQUENTIAL en ésta clausula.

Cláusula ACCESS MODE indica el modo de acceso al fichero, puede ser


SEQUENTIAL, RANDOM o DYNAMIC, si no se especifica ninguno o si el fichero
es SEQUENTIAL entiende que el modo será SEQUENTIAL.
RANDOM indica que accederemos a el aleatoriamente por su clave y DYNAMIC
(la mas utilizada) con la que podremos acceder al fichero en el modo que
queramos dentro del programa, unas veces secuencialmente, si nos interesa,
otras veces por su clave.

Cláusula RECORD KEY se utiliza solo si el fichero es indexado y en el decimos


cual es el nombre de la clave por la cual accederemos a los registros. Esta deberá
ser alfanúmerica y tendrá que estar especificada en la FD del fichero. Si el archivo
fuera RELATIVE, esta clausula se sustituiría por RELATIVE KEY e indicará el
número de registro del fichero, deberá estar declarado en la WORKING-
STORAGE SECTION como una variable numérica sin signo.

Cláusula ALTERNATE RECORD KEY solo para ficheros indexados e identifican


una o mas claves alternadas para nuestros registros, por ejemplo en un fichero de
clientes cuya clave principal sería el código, podríamos asignar como clave

Elaborado por Sergio Oswaldo Rojas Bernal Página 71


MANUAL DE COBOL

alternativa el NIF, y podríamos acceder a el por las dos claves, bien por código o
bien por NIF, será también alfanumérico y deberá también estar declarado en la
FD. Si aparece WITH DUPLICATES, indica que ésta clave alternativa pudiera
estar duplicada, por ejemplo si hubieramos escogido como clave alternada
además del NIF, el Nombre del cliente, podría darse el caso de que dos clientes
tuvieran el mismo nombre.

Cláusula FILE STATUS aqui damos un nombre de una variable que


especificaremos en la WORKING como un campo alfanumérico de dos caracteres
donde el programa depositará el código de error que ocurra en el fichero,
dependiendo del valor nosotros podremos operar o hacer alguna acción en
concreto.

Elaborado por Sergio Oswaldo Rojas Bernal Página 72


MANUAL DE COBOL

Sentencia OPEN:

Para ficheros indexados el formato de esta sentencia es el siguiente:

INPUT
OUTPUT
OPEN{{ [WITH LOCK]}...}
I-O

EJEMPLO

OPEN INPUT NOMINA


OPEN OUTPUT CARGOS
OPEN I-O SALDOS

Sentencia CLOSE:

Para ficheros indexados el formato de esta sentencia es el siguiente:

CLOSE fichero-1 [WITH LOCK] [fichero-2 [WITH LOCK] ] ...

EJEMPLO

CLOSE NOMINA
CLOSE CARGOS
CLOSE SALDOS SALIDAS

Sentencia READ:

Para ficheros indexados el formato de esta sentencia es el siguiente:

Elaborado por Sergio Oswaldo Rojas Bernal Página 73


MANUAL DE COBOL

Formato 1: (acceso secuencial)

NEXT
READ fichero RECORD [INTO nombre dato-1]
PREVIOUS

KEPT
[WITH LOCK]
NO

[AT END sentencia-1]


[NOT AT END sentencia-2]
[END-READ]

EJEMPLO:

Formato 2: (Acceso aleatorio)


READ fichero RECORD [INTO nombre dato-1]

KEPT
[WITH LOCK]
NO

nombre-de-dato-2
KEY IS
clave-m
[INVALID KEY sentencia-3]
[NOT INVALID KEY sentencia-4]
[END-READ]

Cuando el modo de acceso es secuencial, el acceso a los registros del


fichero indexado se hace en orden ascendente de la clave, la cual viene dada por
el campo descrito a continuación de la cláusula RECORD KEY.

Cuando se utiliza el formato 2, antes de que se ejecute la sentencia READ,


es necesario haber cargado el campo descrito a continuación de la cláusula

Elaborado por Sergio Oswaldo Rojas Bernal Página 74


MANUAL DE COBOL

RECORD KEY, el valor de la clave del registro que se quiere leer.

La opción NEXT o PREVIOUS debe especificarse cuando en un fichero en


modo de acceso DYNAMIC los registros se leen secuencialmente.

Si la opción PREVIOUS se ha especificado, después de ejecutarse una


sentencia READ el puntero de lectura-escritura pasa a apuntar al registro anterior.
Si el puntero ya se encontraba en el primer registro. Si el puntero que se
encontraba en el primer registro, entonces se da una condición de fin de fichero
(AT END).

En un fichero abierto I-O con LOCK MODE MANUAL WITH LOCK ON


RECORD, una sentencia READ puede adquirir un registro en modo exclusivo
solamente si la frase WITH LOCK ha sido especificada.

En un fichero abierto I-O con LOCK MODE MANUAL WITH LOCK ON


MULTIPLE RECORDS, una sentencia READ puede adquirir un registro en modo
exclusivo solamente si la frase WITH KEPT LOCK ha sido especificada. Esto es,
KEPT debe ser incluido, cuando manualmente se desea hacer exclusivos
múltiples registros.

En un fichero abierto I-O con LOCK MODE AUTOMATIC, a menos que se


especifique la opción WITH NO LOCK, cada registro es en el momento de leerse
exclusivo, no compartido, siendo liberado cuando finaliza la lectura.

Si se especifica la opción KEY la clave utilizada para recuperar un registro


viene dada por nombre-dato-2 o por clave-m. Si esta opción no se especifica, para
recuperar un registro se utiliza la clave principal, que viene dada por el campo
descrito a continuación de la cláusula RECORD KEY.

Cuando se ejecuta una sentencia READ, descrita de acuerdo con formato-


2, el contenido del campo especificado como clave, es comparado con los valores
contenidos en los correspondientes campos de los registros del fichero, hasta que
se encuentre un valor igual, en cuyo caso se recupera el registro y se ejecuta la
sentencia-4 si la frase NOT INVALID KEY ha sido especificada. Si no se encuentra
el registro entonces se ejecuta sentencia-3 descrita a continuación de la frase
INVALID KEY, si esta opción ha sido especificada.

EJEMPLO:

Elaborado por Sergio Oswaldo Rojas Bernal Página 75


MANUAL DE COBOL

READ SALDOS NEXT AT END MOVE 1 TO FDA


NOT AT END PERFORM CALCULOS
END-READ

READ SALDOS INVALID KEY PERFORM NO-EXISTE


NOT INVALID KEY PERFORM CALCULOS
END-READ

Elaborado por Sergio Oswaldo Rojas Bernal Página 76


MANUAL DE COBOL

Sentencia WRITE:

Para ficheros indexados el formato de esta sentencia es el siguiente:

WRITE registro [FROM nombre-dato-1]


[INVALID KEY sentencia-1]
[NOT INVALID KEY sentencia-2]
[END-WRITE]

El valor de la clave principal debe ser único en el fichero.

El nombre de dato que especifica la clave principal, debe ser puesto por el
programa al valor deseado, antes de ejecutar la sentencia WRITE.

Si el modo de acceso es SEQUENTIAL, los registros deben ser emitidos al


sistema en orden ascendente de la clave principal.

Si el modo de acceso es RANDOM o DYNAMIC los registros pueden ser emitidos


al sistema en cualquier orden.

Si la opción INVALID KEY se ha especificado, sentencia-1 se ejecutará en los


siguientes casos:

a) Cuando se ha especificado modo de acceso secuencial para un fichero


abierto para escribir (OUTPUT) y la clave del registro no es mayor que la
del registro anterior.
b) Cuando el fichero se ha abierto en modo OUTPUT o I-O y la clave del
registro a escribir existe ya en el fichero.
c) Cuando el fichero se ha abierto en modo OUTPUT o I-O y la clave
alternativa del registro a escribir ya existe en el fichero.
d) Cuando el disco esta lleno.

EJEMPLO:

WRITE REG-SALDOS INVALID KEY PERFORM YA-EXISTE


NOT INVALID KEY ADD 1 TO CONTA-GRABADOS

Elaborado por Sergio Oswaldo Rojas Bernal Página 77


MANUAL DE COBOL

END-WRITE

Elaborado por Sergio Oswaldo Rojas Bernal Página 78


MANUAL DE COBOL

Sentencia REWRITE:

Para ficheros indexados el formato de esta sentencia es el siguiente:

REWRITE registro [FROM nombre-dato-1]


[INVALID KEY sentencia-1]
[NOT INVALID KEY sentencia-2]
[END-REWRITE]

El fichero asociado con registro debe ser un fichero residente en disco y abierto en
modo I-O.

Para ficheros en los que el modo de acceso es SEQUENTIAL, la ultima sentencia


ejecutada antes de la ejecución de la sentencia REWRITE debe ser una sentencia
READ, la cual localiza el registro a reemplazar por el valor contenido en le campo
que hace referencia a la clave principal.

Para ficheros en los que el modo de acceso es RANDOM o DYNAMIC, el registro


a reemplazar viene dado por el contenido del campo que hace referencia a la
clave principal. No es necesario ejecutar previamente una sentencia READ.

Si la opción INVALID KEY se ha especificado, la sentencia-1 se ejecutará en los


siguientes casos:

a) Cuando se ha especificado modo de acceso secuencial y el valor


contenido en el campo clave del registro que ha de ser reemplazado no es
igual al valor del campo clave del ultimo registro leído.

b) Cuando el valor del campo que referencia la clave principal no coincide


con el valor de la clave de alguno de los registros del fichero.

c) Cuando el valor del campo que referencia la clave alternativa existe ya en


el fichero.

EJEMPLO:

Elaborado por Sergio Oswaldo Rojas Bernal Página 79


MANUAL DE COBOL

REWRITE REG-SALDOS INVALID KEY PERFORM NO-EXISTE


NOT INVALID KEY ADD 1 TO CONTA-MODIFICADOS
END-REWRITE

Elaborado por Sergio Oswaldo Rojas Bernal Página 80


MANUAL DE COBOL

Sentencia START:

Esta sentencia permite iniciar el proceso de acceso a los registros de un fichero


con organización indexada o relativa a partir de una clave especificada y no a
partir del principio del fichero.

EQUAL TO
=
GREATER THAN
>
NOT LESS THAN
NOT <
START fichero [KEY IS GREATER THAN OR EQUAL TO nombre-dato]
>=
LESS THAN
<
NOT GREATER THAN
NOT >
LESS THAN OR EQUAL TO
<=
[WITH SIZE entero]
[INVALID KEY sentencia-1]
[NOT INVALID KEY sentencia-2]
[END-START]

Fichero es el nombre de un fichero indexado abierto en modo INPUT o I-O, con


modo de acceso SEQUENTIAL o DYNAMIC.

Nombre-dato es un campo alfanumérico que debe ser declarado en una cláusula


RECORD KEY asociada con el fichero.

Nombre-dato puede ser también un campo subordinado al campo especificado en


la cláusula RECORD KEY. Este campo subordinado debe ser la posición del
carácter mas a la izquierda, se corresponda con la posición del carácter mas a la
izquierda del campo especificado en la cláusula RECORD KEY, esto es, el primer
campo subordinado.

Previamente a la ejecución de una sentencia START el programa debe cargar en


nombre-dato el valor de la clave correspondiente al registro en el que nos
queremos posicionar.

Elaborado por Sergio Oswaldo Rojas Bernal Página 81


MANUAL DE COBOL

La comparación indicada por la operación de relación especificada a continuación


de KEY, ocurre entre el valor del campo clave de los registros del fichero y el valor
del contenido en el campo-dato. Si la longitud de los campos comparados no son
iguales, el campo mas largo se trunca a la longitud del mas corto.

Si la frase KEY no se especifica, la operación de relación que se asume es


EQUAL TO (=) y la comparación anterior se hace con respecto al campo
declarado en la cláusula RECORD KEY.

Si el operador de relación especifica que la clave debe ser mayor que, o mayor o
igual que nombre-dato, entonces el puntero de lectura escritura del fichero se
posiciona en el primer registro lógico cuya clave satisfaga la condición.

Si el operador de relación especifica que la clave debe ser menor que, o menor o
igual que nombre-dato, entonces el puntero de lectura escritura se posiciona en el
ultimo registro lógico del fichero cuya clave satisfaga la condición.

Si la condición no es satisfecha por alguno de los registros del fichero, entonces


se da la condición INVALID KEY y se ejecuta la sentencia 1, si la frase ha sido
especificada.

Si se especifica la opción WITH SIZE, entonces se ignora el operador de relación


especificado a continuación de KEY. Esta opción especifica el numero de
caracteres de la clave que se van a utilizar en la comparación (EQUAL TO).

EJEMPLO:

START SALDOS KEY IS = COD-PRODUCTO


INVALID KEY PERFORM NO-EXISTE
NOT INVALID KEY PERFORM LEER-ARCHIVO
END-START

Elaborado por Sergio Oswaldo Rojas Bernal Página 82


MANUAL DE COBOL

Sentencia DELETE:

Esta sentencia permite borrar un determinado registro de un fichero con


organización indexada o relativa.

FORMATO 1:

DELETE fichero RECORD [INVALID KEY sentencia-1]


[NOT INVALID KEY sentencia-2]
[END-DELETE]

Fichero es el nombre de un fichero indexado abierto en modo I-O.

Antes de que se ejecute una sentencia DELETE, es necesario haber cargado en el


campo descrito a continuación de la cláusula RECORD KEY, el valor de la clave
del registro al que se quiere acceder.

Para ficheros en los que el modo de acceso es SEQUENTIAL la ultima sentencia


ejecutada antes de la ejecución de la sentencia DELETE debe ser la sentencia
READ, la cual localiza el registro a borrar por el valor contenido en el campo que
hace referencia a la clave principal.

Para ficheros en los que el modo de acceso es RANDOM o DYNAMIC, el registro


a borrar viene dado por el contenido del campo que hace referencia a la clave
principal. No es necesario ejecutar previamente una sentencia READ.

Cuando se ejecuta la sentencia DELETE, el contenido del campo especificado


como clave, es comparado con los valores contenidos en los correspondientes
campos de los registros del fichero, hasta que se encuentre un valor igual, en cuyo
caso se borra el registro y se ejecuta la sentencia-2 si la frase NOT INVALID KEY
ha sido especificada. Si no se encuentra un valor igual a la clave dada, entonces
se ejecuta la sentencia-1 descrita a continuación de la frase INVALID KEY, si esta
ha sido especificada.

La frase INVALID KEY no puede ser especificada con una sentencia DELETE que
haga referencia a un fichero con modo de acceso secuencial.

EJEMPLO:

Elaborado por Sergio Oswaldo Rojas Bernal Página 83


MANUAL DE COBOL

DELETE SALDOS INVALID KEY PERFORM NO-EXISTE


NOT INVALID KEY ADD 1 TO CONTA-BORRADOS
END-DELETE

FORMATO 2:

DELETE FILE { fichero } ...

Esta sentencia borra los ficheros especificados, los cuales deben ser cerrados
previamente.

EJEMPLO:

DELETE FILE SALDOS

Elaborado por Sergio Oswaldo Rojas Bernal Página 84


MANUAL DE COBOL

CAPITULO XI SUBPROGRAMACION

SUBPROGRAMACION

Es un método de programación que se basa en la utilización de un programa


principal comunicado con uno o más subprogramas.
Los objetivos de la subprogramación son:
1) Evitar programas demasiado largos
Cuanto mas dividimos las funciones de un programa, mejor podremos
manejarlo, y en modificaciones futuras tendremos muchas más felicidades.
2) Evitar redundancias
Existen tareas comunes a varios programas para lo que se creará un
subprograma que realice esta tarea y que pueda ser llamado por todos
aquellos programas que lo necesiten.
En la subprogramación existe un programa principal que será el "llamador" y l os
subprogramas los "llamados".
Tanto el programa principal como los subprogramas son programas individuales y
compilados a parte unos de otros.
Sin embargo, los subprogramas dependen del programa principal, ya que es el
único ejecutable.
El programa principal se ejecuta, y cuando en su PROCEDURE se encuentra con
un CALL ‘nombre-programa', transferirá el control al subprograma en cuestión.
Cuando este termine su ejecución, devolverá el control al programa principal
mediante la instrucción EXIT-PROGRAM.
En subprogramación hay que tener en cuenta que se sigue una especie de
jerarquía:
El programa principal se puede comunicar con todos los subprogramas.

Elaborado por Sergio Oswaldo Rojas Bernal Página 85


MANUAL DE COBOL

Un subprograma puede ser llamado por un subprograma de nivel superior, pero


nunca al contrario.

En este formato sí se intercambian datos.


Su uso más común es la de transmitir datos del programa principal al
subprograma, donde son tratados y posteriormente le es devuelto el resultado.
El funcionamiento de la instrucción es la siguiente:

BY REFERENCE
CALL nombre-programa USING nombre-
variable-1
BY CONTENT

Elaborado por Sergio Oswaldo Rojas Bernal Página 86


MANUAL DE COBOL

Llamamos (CALL) al subprograma (nombre-programa) y le mandamos datos,


usando (USING) las variables (nombre-variable-1, nombre-variable-2 ...), que
anteriormente ya han sido definidos en la DATA DIVISION.
La diferencia entre BY REFERENCE y BY CONTENT es que con la 1ª opción los
datos pasados al subprograma podían ser modificados, sin embargo en el BY
CONTENT únicamente puede ser consultados pero no permite su modificación.
El subprograma además de tener en la WORKING sus propias variables de
trabajo, debe definir unas variables en la LINKAGE SECTION para recibir los
datos de las variables que se transfieren desde el programa principal.
El nombre de estas variables podrá ser el mismo, o distinto, ya que ello no supone
ningún condicionante en el buen desarrollo del subprograma:
Lo que si es importante son las siguientes consideraciones:
Si no queremos tener problemas en la transmisión, definir las variables en la
LINKAGE con la misma PICTURE que sus homólogas.
La relación entre las variables de un programa y otro se efectúa de la siguiente
forma:
Programa Principal:

CALL PROGRAMA USING CAMPO-A, CAMPO-CAMPO-B,


CAMPO-C
Subprograma:
PROCEDURE DIVISION USING CAMPO-D, CAMPO-E, CAMPO-
F.

CAPITULO XII BUSQUEDAS EN ARCHIVOS

BUSQUEDAS EN ARCHIVOS

BUSQUEDAS SIMPLE

Elaborado por Sergio Oswaldo Rojas Bernal Página 87


MANUAL DE COBOL

En el proceso de búsqueda de datos intervienen dos archivos de entrada los


cuales deben estar ordenados por la misma llave. El proceso que se describe a
continuación se ajusta para estructuras de búsqueda 1 1 y N 1.

RUTINA:

PROCEDURE DIVISION.
PERFORM 1-INICIO-PROCESO
PERFORM 2-PROCESO UNTIL SI-FIN-ARCHIVO1
PERFORM 3-FIN-PROCESO
STOP RUN.

1-INICIO-PROCESO.
INITIALIZE VARIABLES
* (CARGAR TABLAS EN MEMORIA SI ES NECESARIO)
OPEN INPUT ARCHIVO1 (ENTRADA)
INPUT ARCHIVO2 (ENTRADA)
OUTPUT ARCHIVO3 (SALIDA O SALIDAS DE IMPRESION)
PERFORM LEER-ARCHIVO1
PERFORM LEER-ARCHIVO2.

2-PROCESO.
PERFORM LEER-ARCHIVO2 UNTIL SI-FIN-ARCHIVO2 OR
LLAVE-1 >= LLAVE-2
IF LLAVE-2 = LLAVE-1 AND NOT SI-FIN-ARCHIVO2
PERFORM ( ENCONTRO DATO)
ELSE
PERFORM ( NO ENCONTRO DATO)
END-IF
PERFORM LEER-ARCHIVO1.
*********************************************************

Elaborado por Sergio Oswaldo Rojas Bernal Página 88


MANUAL DE COBOL

Recordar los contadores para registros encontrados y registros no


encontrados, que se mostraran al final del proceso.

Que hay que mirar si esta estructura no arroja los resultados esperados:

1. Revisar que los archivos se encuentren ordenados por la supuesta llave.


2. Revisar que las llaves de los archivos tengan la misma estructura.
3. Que las condiciones de comparación de las llaves se encuentren invertidas
4. Que el final de alguno de los archivos no este bien controlado

Elaborado por Sergio Oswaldo Rojas Bernal Página 89


MANUAL DE COBOL

LINEAS DE BALANCE

El funcionamiento básico de una línea de balance consiste evaluar el


contenido de la llave primaria de cada archivo de entrada así: (SE MANEJA
LLAVE UNICA)

Si Llave-1 < Llave-2 el dato que se busca no esta en archivo-2


y debe leer el siguiente registro de archivo-1.
Si Llave-1 > Llave-2 se debe leer el siguiente registro de
archivi-2.
Si Llave-1 = Llave-2 se encontró el dato que se buscaba y
debe leer el siguiente registro de archivo-1 y archivo-2.

RUTINA:

PROCEDURE DIVISION.
PERFORM 1-INICIO-PROCESO
PERFORM 2-PROCESO UNTIL SI-FIN-ARCHIVO1 OR
SI-FIN-ARCHIVO2
IF SI-FIN-ARCHIVO1
PROCESA-2 UNTIL SI-FIN-ARCHIVO2
ELSE
PROCESA-1 UNTIL SI-FIN-ARCHIVO1
END-IF
PERFORM 3-FIN-PROCESO
STOP RUN.

1-INICIO-PROCESO.
INITIALIZE VARIABLES
OPEN INPUT ARCHIVO1 (ENTRADA)
INPUT ARCHIVO2 (ENTRADA)

Elaborado por Sergio Oswaldo Rojas Bernal Página 90


MANUAL DE COBOL

OUTPUT ARCHIVO3 (SALIDA)


PERFORM LEER-ARCHIVO1
PERFORM LEER-ARCHIVO2.

2-PROCESO.
IF LLAVE-1 > LLAVE-2
PROCESA-2
ELSE
IF LLAVE-1 < LLAVE-2
PROCESA-1
ELSE
PROCESA-IGUAL.
END-IF.

PROCESA-1.
PROCESO-NO-ESTA-EN-2
LEER-ARCHIVO1.

PROCESA-2.
PROCESO-NO-ESTA-EN-1
LEER-ARCHIVO2.

PROCESA-IGUAL.
PROCESO-IGUALES
LEER-ARCHIVO1
LEER-ARCHIVO2.
*********************************************************

NOTA: No hay que hacer rutinas especiales para final de archivos.

Elaborado por Sergio Oswaldo Rojas Bernal Página 91

También podría gustarte