Alters

COBOL: archivos + ejemplo

Hola de nuevo!

Ya que esta será la última entrega "teórica", he decidido poner el ejemplo en esta misma.

Ahora veremos el tema de ficheros. En COBOL hay varios tipos de ficheros, cada uno con sus ventajas y desventajas. Vamos allá

Ficheros:

Como decía, hay varios tipos de ficheros. Esto no significa diversas extensiones (COBOL no mira extensiones), sino organizaciones internas, modos de acceso...

En concreto, hay tres tipos de ficheros:

 * Secuenciales
 * Indexados
 * Relativos

Explicaré un poco las características de cada tipo:

Los secuenciales son accedidos de manera secuencial (obviamente), es decir, de principio a fin. Si quieres acceder al tercer registro tienes que hacer tres lecturas, no hay más.

Los indexados pueden ser accedidos de manera secuencial o bien de manera directa (mediante clave, ya lo veremos)

Los relativos se basan en "registros", pudiendo ser accedidos de manera secuencial o directa (usando clave).

A continuación, una lista de ventajas / inconvenientes de los tipos de archivo:

 * Secuencial

Ventajas:
   - Tamaño mínimo
   - Fácilmente editable (a mano)

Inconvenientes
   - A tamaño grande, la lectura se ralentiza.
   - Acceso puramente secuencial

* Indexado

 Ventajas
   - Rápidamente accesible
   - Sistema de claves

 Inconvenientes
   - Mayor tamaño
   - Apenas editable (a mano)

* Relativo

 Ventajas
   - Claves "invisibles"
   - Acceso rápido

Inconvenientes
   - No se puede ordenar
   - Apenas editable (a mano)


Aparte de los tipos de archivo, hay lo que se denomina modo de acceso: SEQUENTIAL, RANDOM, DYNAMIC. El primero establece un acceso secuencial, el segundo aleatorio (por clave) y el tercero ambos.

Si el fichero es secuencial solo se puede acceder mediante SEQUENTIAL; en cualquier otro caso vale cualquiera.


El uso de las claves funciona de manera similar a las bases de datos; en el caso de los indexados la clave puede ser cualquier cosa (un dni, teléfono...); en los archivos relativos se usa un índice numérico, de manera transparente al usuario y al programador.


Para declarar un fichero, tenemos que extender dos DIVISION: la ENVIRONMENT y la DATA.

La declaración básica se da en la ENVIRONMENT, y en la DATA definimos simplemente la estructura. En la primera parte, la declaración tiene variaciones dependiendo del tipo de fichero; en la segunda no.

  - ENVIRONMENT SECTION:

   Para un archivo SECUENCIAL, debemos poner algo tal que:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS SEQUENTIAL
                   ACCESS MODE IS SEQUENTIAL.


Veamos: Se declara la division, una nueva section (Input-Output), y se declara un fichero mediante FILE CONTROL. Finalmente se especifica el fichero:
   * SELECT var -> asigna una variable de "volcado" para el 'archivo' (hasta 8 caracteres!), que está asignado en el disco (otra opción es, por ejemplo PRINTER).
  * ORGANIZATION IS SEQUENTIAL -> le decimos que es secuencial. Podemos no poner esta sentencia, ya que si no está, por defecto COBOL lo tomará como secuencial.

  * ACCESS MODE IS SEQUENTIAL -> le decimos el modo de acceso, en este caso el único disponible: secuencial.

Para un archivo indexado, debemos poner algo similar a esto:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS INDEXED
                   ACCESS MODE IS [SEQUENTIAL | RANDOM | DYNAMIC]
                   RECORD KEY IS var1
                   [ALTERNATE KEY IS var2 [WITH DUPLICATES]].


Revisemos el tema:

  * ORGANIZATION IS INDEXED -> le decimos que es un archivo indexado
  * ACCES MODE IS ... -> aquí especificamos el modo de acceso (explicado más arriba)
  * RECORD KEY IS var1 -> le decimos cuál es la clave (como una PK de una tabla) del archivo
  * ALTERNATE KEY IS ... -> podemos especificar una clave alternativa (como un índice). Es opcional. Si ponemos "with duplicates" (también opcional) le decimos a COBOL que aceptamos que haya duplicados en esta clave. Por defecto COBOL no acepta duplicados en ningún tipo de clave.

Finalmente, para un archivo relativo:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS RELATIVE
                   ACCESS MODE IS  [SEQUENTIAL | RANDOM | DYNAMIC] .

Como veis, este último no hace falta explicarlo...

Ahora falta el siguiente punto, la data division:


       DATA DIVISION.
       FILE SECTION.

       FD var LABEL RECORD STANDARD.

       01    var1.
          02 var2 PIC X.

Esto es un poco lioso, así que vamos a explicarlo bien...

Primero abrimos la file section, y a partir de ahí describimos los archivos:

 * FD var LABEL RECORD STANDARD: Es la abreviatura de "File Descriptor". var es el nombre de variable usado en la ENVIRONMENT. La label record es una cláusula que especifica una variable de control interna para los ficheros. Yo recomiendo ponerla siempre como STANDARD (la otra opción es OMITTED).

* 01 var1... -> Declaramos la estructura para var. Tal cual, como cualquier otra estructura. Si el fichero es INDEXED, en esta estructura estarán las RECORD KEY y ALTERNATE KEY.




Ahora ya podemos delcarar ficheros; pero falta usarlos.

Para usar un archivo COBOL, debemos seguir la rutina básica de toda la vida, es decir

 - Abrir archivo
 - Manipular archivo
 - Cerrar archivo

Para abrir el archivo, tenemos la siguiente cláusula:

OPEN [INPUT | OUTPUT | EXTEND | IO] var.

Se tiene que especificar una de las 4 opciones, a saber:

 * INPUT: abre el archivo solo para lectura
 * OUTPUT: abre el archivo solo para escritura (lo crea si no existe, si existe lo borra y empieza de nuevo)
 * EXTEND : abre el archivo solo para escritura (si no existe da error, si existe escribe sin borrarlo)
 * I-O: abre el archivo para lectura/escritura (el archivo tiene que existir)

Hay varias operaciones para manipular el archivo. El tema es que COBOL tiene una "tabla" de operaciones disponibles para cada modo de acceso y modo de apertura:

 - ACCESO secuencial
   * INPUT
       · READ: lee un registro
       · START: se posiciona sobre un registro
  * OUTPUT (o EXTEND)
       · WRITE: escribe un registro
  * I-O
       · READ
       · REWRITE: sobreescribe el registro almacenado
       · DELETE: borra el registro almacenado
       · START

- ACCESO aleatorio

   * INPUT
       · READ
  * OUTPUT (o EXTEND)
       · WRITE
  * I-O
       · READ
       · WRITE
       · REWRITE
       · DELETE

 - ACCESO dinamico

   * INPUT
       · READ
       · START
  * OUTPUT (o EXTEND)
       · WRITE
  * I-O
       · READ
       · WRITE
       · REWRITE
       · DELETE
       · START

Finalmente aclarar: las operaciones se hacen sobre var, y las modificaciones sobre la estructura creada.




Para terminar el tema de COBOL, dejo el SRC de mi trabajo final de COBOL. Recordad leer el README, y si vais a compartir el archivo, citad la fuente y/o la autoría, por favor :-)

http://www.mediafire.com/?4algy7xluud6ay4


Para las próximas entradas tengo varios temas pensados, dejo aquí unas posibles opciones
 - Optimización para PHP
 - Uso de .htaccess para mejorar nuestra web
 - Tutorial HPL2: creando escenarios

Siento haber tardado tanto en hacer esta entrega; he estado liado y enfermo...


Saludos, y ¡Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!



6 comentarios:

Unknown dijo...

Buenos días. Estoy con un programa COBOL que escribe de 1 a 5 ficheros dinámicamente (según los tenga definidos en el JCL), a través de un programa en ensamblador. Quería saber si es posible hacer lo mismo en COBOL, dado que COBOL requiere de la definición del fichero en compilación. Quizá exista alguna manera alternativa al uso de ensamblador. Muchas gracias de antemano. Un saludo.

David O. Solé González dijo...

Hola!
Por supuesto... Define los cinco ficheros en tu JCL, y define también en el FILE SECTION.

Luego, puedes ir abriendo solo los ficheros que te interese... Al final, declarar los ficheros no implica que los vayas a usar.

Anónimo dijo...

Por favor estoy atascado en un programa cobol donde en la select aparte de la clave principal utilizo 4 claves alternativas mas, pero no se por que no me lee ninguna clave alternativa ( las cuales las como posible claves duplicadas ).
Quisiera saber si las claves alternativas hay que crearlas antes o simplemente reseñarlas en la select.
Estoy utilizando OPEN COBOL IDE.
Saludos y gracias anticipadas por todo.

David O. Solé González dijo...

Hola!
Sí, influye cómo lo hayas creado. Si lo creaste solo con una clave, al almacenar los datos (WRITE) solo tiene en cuenta el índice que hayas definido.

Por tanto tendrías que definir el fichero con los índices que necesites en el momento/programa que va a escribir este fichero, de lo contrario no podrás usar esos índices.

Otra alternativa es crear un programa intermedio que lea ese fichero y escriba en otro fichero con las claves que tú necesitas.

Saludos,

DARIO LOPEZ RODRIGUEZ dijo...

Hola buenas tardes.
Me gustaría si es posible que me ayudarais por que estoy atascado en un programa que estoy haciendo en COBOL, ( soy un aficionado ) y me encuentro que quiero utilizar las teclas de función ( F1 F2 F3 F4 .... ) por tanto quiero conocer el valor de estas teclas al pulsarlas y ejecutar la sentencia en una dirección ú otra.
He visto que hay en ACCEPT una codificación,

ACCEPT NOMBRE LINE 10 COL 20 , ON EXCEPTION ESCA MOVE 1 TO QW.

ACCEPT PANTALLA-INICIAL ON EXCEPTION ESCA MOVE 1 TO QW. - ESTA ES LA MIA, PERO ME DA ERROR AL COMPILAR.

PREGUNTO : HAY QUE DEFINIR EN ALGUN LUGAR LAS VARIABLES F1 F2 ... ETC

Gracias anticipadas por vuestro tiempo.

SAludos cordiales

DARIO LOPEZ RODRIGUEZ.

David O. Solé González dijo...

Hola Dario
No recuerdo los valores exactos de las teclas F, pero podrías hacer lo siguiente

ACCEPT TECLA.
DISPLAY 'HAS PULSADO:' TECLA '*'.

De esta manera podrías ver el valor de cada tecla pulsada, y podrías guardarlo en alguna variable para comparar, o hacer lo que necesites con ella.

Perdón por no contestar antes, el sistema de comentarios de Google no suele avisar... Siempre puedes encontrarnos en Twitter (@ESC_ILU).

Saludos

Publicar un comentario