
Instr. de Archivos
Sin duda son las instrucciones mas importantes con las que cuenta el lenguaje Cobol, con ellas
tendremos la oportunidad de manipular toda la información contenida en nuestros archivos,
es decir, podremos abrir archivos, cerrarlos, leerlos, guardar información nueva o
modificar datos existentes. Todo ésto lo haremos con las instrucciones que voy a explicar
a continuación.
Antes de empezar a explicar éstas
instrucciones me gustaría que entendiéseis bien algunos conceptos como fichero, registro
y campo, para que podais comprender mas claramente, la explicación de todas las
instrucciones que se verán en ésta sección.
- ¿Que es un fichero? Podríamos
definir un fichero como un conjunto de registros, pero estaríamos mas o menos igual. Si
comparásemos un fichero de cobol con nuestra vieja agenda de teléfonos, para cada amigo
tendríamos los mismos datos, es decir, nombre, teléfono, dirección, etc ... cada uno de
esos datos es lo que llamamos campo y el conjunto de todos esos campos para cada amigo
sería un registro. Ahora podemos comprender mejor que un fichero o archivo es un conjunto
de registros, como una agenda es un conjunto de datos de amigos.
- ¿Que es una clave? Una clave, es
un campo de nuestra agenda que nos sirve para identificar a cada amigo, en la agenda
normal la clave podría ser la lengüeta con la letra del abecedario correspondiente a los
apellidos del amigo. Informáticamente es mas completa y con ella podremos identificar a
cada uno de ellos, por ejemplo con su nombre o su teléfono o un código que le asignemos
nosotros personalmente.
En Temáticos trataremos el tema de los ficheros en mas profundidad.
OPEN, ésta es la instrucción que utilizaremos para
abrir un archivo, o lo que es lo mismo hacerlo disponible para operar sobre el, obviamente
éste archivo debe de haberse descrito en la Environment y la Data según se explicó, su
formato es el siguiente:
OPEN (EXCLUSIVE
) modo nombre de archivo (
WITH LOCK) (WITH
NO REWIND)
Donde modo, indica como se abrirá el
archivo y puede tener los siguientes valores según su utilización:
- INPUT, el archivo se abrirá solo para lectura, es decir no podremos grabar ni
modificar datos del mismo.
- I-O, el archivo se abrirá como lectura y escritura, con lo cual tendremos
acceso a toda la información de dicho archivo para leerla, escirbirla, reescribirla o
borrarla.
- OUTPUT, el archico se abre solo para escritura, es el formato que se utiliza en
los achivos de impresión y secuenciales. Tiene la particularidad que crea el fichero
nuevo cada vez que se utiliza, por lo tanto hay que tener cuidado con archivos Indexados.
- EXTEND, igual que el anterior pero no crea el archivo, sino que la información
se va añadiendo a la ya existente. Se utiliza para archivos secuenciales.
Las opciones EXCLUSIVE y WITH LOCK, nos indica cuando trabajamos en multipuesto que éste archivo estará
bloqueado, es decir que no estará disponible para otros usuarios. El hecho de que existan
dos opciones para lo mismo es por compatibilidad con versiones anteriores.
La opción WITH NO REWIND, se utiliza cuando utilizamos archivos de cinta, para que no la rebobine al abrirla.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
OPEN I-O CLIENTES
OPEN EXTEND IMPRE.
CREAR-ARCHIVO.
OPEN OUTPUT TRABAJO CLOSE TRABAJO.
... |
|
Nota: Con éstas tres instrucciones estamos abriendo tres archivos, cada uno de
una forma diferente. Tambien podriamos haberlos puesto en una sola linea de la siguiente
forma:
OPEN INPUT ARTICULOS
I-O CLIENTES
EXTEND IMPRE.
En el caso del archivo TRABAJO, se consigue crearlo como
nuevo, exista antes o no.
|
CLOSE, ésta es la instrucción contraria a OPEN, es
decir termina la conexión establecida con el archivo, a partir del momento que aparezca
ésta instrucción el archivo no estará disponible para operar con él, hasta la próxima
vez que se abra. Obviamente antes de cerrarlo debe de estar abierto.
CLOSE nombre de archivo (
WITH LOCK) (WITH NO REWIND
)
El nombre de archivo corresponderá a algún archivo abierto anteriormente.
Las opciones WITH LOCK y WITH NO REWIND
, tienen la misma explicación que la vista en la orden OPEN.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
OPEN I-O CLIENTES
OPEN EXTEND IMPRE.
...
...
...
CERRAR.
CLOSE ARTICULOS CLIENTES IMPRE.
... |
|
Nota: Apuntaré que si finalizamos el programa con la sentencia
STOP RUN, que luego veremos, los archivos que estuvieran abiertos
se cierran automáticamente aunque no se haya especificado la orden CLOSE.
Anque siempre es preferible utilizarla, ya que puede haber algunos compiladores mas
antiguos que no los cierren.
Me gustraría destacar
de éstas dos instrucciones vistas que lo mas normal es no utilizar ninguna de las
opciones, es decir solo abrir de una manera el archivo para su uso y una vez hayamos
acabado con él, cerrarlo.
|
READ, es la instrucción que utilizamos para leer
registros de un archivo, debe de estar abierto. Con ella conseguimos que los datos
referentes al registro accedido queden en la descripción de dicho fichero, es decir,
conseguimos que los campos declarados en la FD, tengan el valor correspondiente al
registro leido.
La sentencia READ, se utiliza para leer
ficheros secuanciales o indexados, o para leer indexados de manera secuencial, por lo que
su sintaxis tiene dos formatos principales.
Formato para leer ficheros de
manera secuncial. (Indexados o secuenciales)
READ nombre de archivo (
NEXT/PREVIOUS RECORD) (
INTO descripción)
(AT END / NO AT END sentencia)
END-READ
nombre de archivo
corresponderá a algún archivo abierto anteriormente.
La opción NEXT RECORD,
indica que se va a leer el siguiente registro y es la que se toma por defecto, ya que,
cuando estamos leyendo un archivo de forma secuencial, éste leerá registros uno tras
otro, hasta llegar al final.
La opción PREVIOUS RECORD leería el registro anterior. Esta opción es la única que no es válida
para ficheros secuenciales de éste formato.
La opción INTO, indica cual de las descripciones de registro que hayamos podido declarar será la que almacene
los datos del registro leido. Tenemos que tener en cuenta que Cobol nos permite mantener
mas de una descripción de registro para un mismo archivo. Si tuvieramos mas de una, ésta
sería la opción para indicarle cual es la que queremos utilizar en ésta lectura.
La sentencia que va después de AT END
, indica que debe de hacer el programa al llegar al final del fichero.
Puede ser cualquier orden de cobol, pero es evidente que si volvemos a leer una vez
llegado al final, producirá un error.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
LECTURA.
READ ARTICULOS NEXT RECORD AT END GO CERRAR.
...
...
...
GO LECTURA.
CERRAR.
CLOSE ARTICULOS.
... |
|
Nota: Si bien este formato nos sirve para leer cualquier tipo de archivo de
manera secuencial, en el caso de que el archivo fuera secuencial, éste solo se podría
leer así.
Existen muchas ocasiones en que un
archivo indexado nos interesa leerlo de manera secuencial. Si lo hicieramos éste sería
su formato, además en éste caso podriamos leerlo tanto del principio al final con la
opción NEXT, como del final al principio con la opción PREVIOUS.
Para poder leer un fichero indexado de manera secuencial,
deberemos de haber especificado en la SELECT, que su acceso
va a ser DYNAMIC o SEQUENTIAL.
|
Formato para leer ficheros
indexados con acceso aleatorio.
READ
nombre de archivo (INTO
descripción) (KEY
nombre de clave) (
INVALID KEY / NOT INVALID KEY
sentencia) END-READ
Las opciones que se repiten con con el
formato anterior tienen el mismo formtato y producen el mismo resultado.
La opción KEY, indica
por que clave se va a leer el fichero, siempre que éste tenga mas de una.
La sentencia después de INVALID KEY
se utiliza para ejecutar una acción cuando se intenta acceder a un
registro que no existe. En el caso de utilizar NOT INVALID KEY
sería al contrario, es decir cuando el registro existe.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
LECTURA.
MOVE 100 TO CLAVE-ARTICULO.
READ ARTICULOS INVALID KEY GO ERROR.
...
...
...
GO LECTURA.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
... |
|
Nota: Sin duda la forma mas usual de acceder a un registro será por su clave.
Asi por ejemplo para acceder a un fichero de poblaciones cuya clave fuera su código
postal, dando cualquier código accederiamos a ese registro en concreto.
La acción que hagamos después de un INVALID
KEY, dependerá del contexto en que se encuentre, podremos volver a solicitar otra
clave, permitir crear un registro, etc .. |
WRITE, con ésta instrucción se consigue grabar la
información contenida en ese momento en los campos del registro de un fichero. Es decir,
si introducimos una ficha nueva en la agenda con los datos de un nuevo amigo, ésta
instrucción será la que nos sirva para almacenar en el fichero los datos. A partir de
ese momento estarán disponibles tantas veces como queramos para leerla. Y por supuesto el
fichero debe de estar abierto como OUTPUT o I-O.
WRITE nombre de registro (
FROM descripción) (
INVALID KEY / NOT INVALID KEY sentencia)
END-WRITE
La opción FROM, indica
con cual de las descripciones de registro que hayamos podido declarar se graben los datos
en el fichero. Hay que señalar que ésta descripción puede estar definida en la
WORKING, y lo que nos ahorra en realidad es mover los datos de esa descripción
que hemos usado como "temporal" a la auténtica descripción del registro.
Las cláusulas de INVALID KEY y NOT INVALID KEY, tienen la misma función dada en la instrucción
READ. Solo que aqui, INVALID KEY
, se produciría cuando al grabar el registro, éste ya existiese o hubiera algún error por el cual no se pudieran grabar los datos.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN I-O ARTICULOS.
LECTURA.
MOVE 100 TO CLAVE-ARTICULO.
MOVE "ANDRES MONTES" TO NOMBRE.
WRITE REGISTRO-ARTICULO INVALID KEY GO ERROR.
...
...
GO CERRAR.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
... |
|
Nota: Aunque se puedan utilizar varias descripciones, lo mas lógico es utilizar
siempre la misma para cada fichero. El error mas
probable siempre que sea una INVALID KEY, suele ser que
existe un registro ya con esa clave, a parte de ese, falta de espacio en disco, archivo
mal abierto o sin abrir.
|
Además de éste formato, existe para ésta instrucción
otro muy común. Y es el que utilizamos para enviar datos a la impresora, es decir para
listar, para imprimir.
Es en éste caso, donde se hace indispensable el uso de
mas de una descripción por registro. ¿Porque? Sencillo, definiremos nuestro fichero con
un registro de tamaño igual al ancho de nuestro listado, y luego en la
WORKING, describiremos el formato de cada una de las lineas que
utilizaremos en la impresión. Quiero hacer un ejemplo mas extenso para éste caso, que
será muy utilizado y distinto en su filosofía al resto.
WRITE nombre de registro (
FROM descripción) (
AFTER número de lineas)(PAGE)
END-WRITE
Además para éste formato tendremos la cláusula
AFTER, en la cual indicamos el número de lineas que debe de
avanzar la impresora antes de escribir, o bien que lo haga directamente al principio de la
siguiente página, poniendo AFTER PAGE. Existen algunas otras
cláusulas, pero no las vamos a ver aquí por ser poco usadas.
|
IDENTIFICATION
DIVISION.
PROGRAM-ID. LISTADO.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IMPRESORA ASSIGN TO PRINT
"LPT1".
DATA DIVISION.
FILE SECTION.
FD IMPRESORA LABEL RECORD OMITTED.
01 REG-IMPRE PIC X(80).
WORKING-STORAGE SECTION.
01 LINEA1.
02 FILLER PIC X(30) VALUE SPACES.
02 FILLER PIC X(20) VALUE "ESTA ES LA
LINEA 1".
01 LINEA2.
02 FILLER PIC X(30) VALUE SPACES.
02 FILLER PIC X(20) VALUE "ESTA ES LA
LINEA 2".
...
...
PROCEDURE DIVISION.
INICIO.
OPEN OUTPUT IMPRESORA
ESCRIBIR.
WRITE REG-IMPRE FROM LINEA1 AFTER PAGE.
WRITE REG-IMPRE FROM LINEA2 AFTER 2.
...
...
CERRAR.
CLOSE IMPRESORA.
... |
|
Nota: Como podeis ver, hemos definido el registro como REG-IMPRE,
pero al escribir sobre el fichero impresora utilizamos las descripciones de
LINEA1 y LINEA2, de ésta manera conseguimos que se impriman las dos lineas
en una impresora conectado al puerto LPT1 y que antes de escribir la primera
linea, salte a una página en blanco. |
REWRITE, ésta instrucción se utiliza para regrabar
datos de un registro ya existente. Toda la sintaxis es exactamente igual que la explicada
en WRITE.
REWRITE nombre de registro (
FROM descripción) (
INVALID KEY / NOT INVALID KEY
sentencia) END-REWRITE
Todas las opciones igual que en WRITE.
Por lo que en el ejemplo vamos a ver ambos casos juntos.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN I-O ARTICULOS.
LECTURA.
MOVE 100 TO CLAVE-ARTICULO.
MOVE "ANDRES MONTES" TO NOMBRE.
WRITE REGISTRO-ARTICULO INVALID KEY GO ERROR.
MOVE "OTRO NOMBRE" TO NOMBRE.
REWRITE REGISTRO-ARTICULO INVALID KEY GO ERROR.
...
...
GO CERRAR.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
... |
|
Nota: Podemos decir que ésta sentencia es la que utilizaremos para modificar el
contenido de cualquier registro, pero eso si, nunca podremos alterar la clave, solo los
campos que no formen parte de la clave principal.
Si quisieramos modificar cualquiera de los campos clave de un registro, deberíamos crear uno
nuevo con el mismo contenido pero con la clave que ahora queramos y luego borrar el que
teníamos. |
DELETE, instrucción para borrar un registro de un
fichero. La explicación es corta, pero tiene pocos mas matices, lo que conseguimos es
borrar todos los datos de un registro. Su sintaxix es la siguiente:
DELETE nombre de fichero (
INVALID KEY / NOT INVALID KEY sentencia)
END-DELETE
Las únicas cláusulas INVALID y NOT INVALID KEY, se usan exactamente igual que en las demás relativas a ficheros, es decir
ejecutará la sentencia que pongamos a continuación cuando una de las condiciones se
cumpla, que la clave exista o que no exista.
Si nos fijamos vemos que la gran diferencia está en que aquí la orden hace referencia al nombre del fichero y no al del
registro, como en las instrucciones anteriores.
|
...
PROCEDURE DIVISION.
INICIO.
OPEN I-O ARTICULOS.
LECTURA.
MOVE 100 TO CLAVE-ARTICULO.
READ ARTICULOS INVALID KEY GO ERROR.
DELETE ARTICULOS INVALID KEY GO ERROR.
...
...
GO CERRAR.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
...
...
|
|
Nota: Obviamente para borrar un registro,
primero hemos de tenerlo en memoria, por eso en el ejemplo lo he leido primero.
|
START, ésta instrucción es de suma importancia en el
tratamiento de ficheros, y nos sirve para posicionarnos en cualquier parte del mismo, para
una lectura mas rápida. Si imaginamos un fichero con 10.000 clientes, clasificados por
código, para ver todos los que cuyo código es mayor a 9.000, tendríamos que
leernos el fichero secuencialmente hasta llegar al sitio correcto, en cambio con ésta
orden, podremos colocarnos en la posición del fichero que queramos dentro de unas normas,
que veremos a continuación.
START nombre de fichero
KEY (expresión) nombre de clave (
INVALID KEY / NOT INVALID KEY
sentencia) END-START
Las únicas cláusulas INVALID y NOT INVALID KEY, se usan exactamente igual que en las demás relativas a ficheros, es decir
ejecutará la sentencia que pongamos a continuación cuando una de las condiciones se
cumpla, que la clave exista o que no exista.
Si nos fijamos vemos que la gran diferencia está en que aquí la orden hace referencia al nombre del fichero y no al del
registro, como en las instrucciones anteriores.
La expresión a la que se hace referencia en la sintaxis, pueden ser las siguientes:
- LESS (<) menor que.
- NOT LESS (NOT <) no menor que.
- EQUAL (=) igual a.
- GREATER (>) mayor que.
- NOT GREATER (NOT >) no mayor que.
- GREATER OR EQUAL (>=) mayor o igual que.
- LESS OR EQUAL (<=) menor o igual que.
- FIRST principio de fichero (RM/COBOL).
- LAST final del fichero (RM/COBOL).
|
...
PROCEDURE DIVISION.
INICIO.
OPEN I-O ARTICULOS.
COLOCAR.
MOVE 100 TO CLAVE-ARTICULO.
START ARTICULOS KEY NOT LESS KEY CLAVE-ARTICULOS
INVALID KEY GO ERROR.
LECTURA.
READ ARTICULOS NEXT RECORD AT END GO CERRAR.
...
GO LECTURA.
ERROR.
...
...
GO CERRAR.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
...
...
|
|
Nota: Aqui empezariamos a leer el ficher
artículos desde la clave que no sea menor que 100, es decir de 100 en adelante. Fijaros
como luego la lectura se hace en otro párrafo diferente, ya que sino, siempre estariamos
haciendo el START. Recordad que con ésta instrucción SOLO
nos situamos en un sitio determinado del fichero, a partir de ahí podremos operar como
queramos.
|
RESUMIENDO
En la programación estructurada es conveniente sustituir el punto como final de una
instrucción por la cláusula END-....... para cada instrucción.
De esta manera conservamos la estructura y no obligamos con el punto a finalizar ninguna
instrucción o bucle en el que estemos metidos.
Una vez vistas todas las intrucciones relativas a ficheros, quiero dejar bien claro su utilización.
Tendremos siempre en cuenta que cuando leemos, realmente le damos el valor del registro que hemos leido a los campos o variables que lo componen.
Que cuando grabamos o regrabamos, le estamos dando el valor de las variables en ese momento al
registro para que se grabe en disco y cuando borramos, estamos quitando fisicamente del
disco esa información.
He realizado un temático dedicado integramente al uso de ficheros, podéis echarle
un vistazo por si os han quedado dudas.
Temáticos
|
|