Ficheros (III)
Que Cobol tiene muchas cosas buenas, no hace falta decirlo, pero su facilidad para trabajar con datos y por lo tanto con ficheros, es sencillamente increible.
Increible hasta el punto que podemos trabajar con un fichero, antes incluso de saber como se llama y donde se encuentra.

Lo mas lógico y mas utilizado es asignar previamente una localización y nombre para nuestro fichero en la SELECT, por ejemplo:
    SELECT VENTAS ASSIGN TO RANDOM "VENTAS.DAT"
    ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY CLA-VENTAS
    FILE STATUS STA-VENTAS.

    SELECT COMPRAS ASSIGN TO RANDOM "C:DATOSCOMPRAS.DAT"
    ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY CLA-VENTAS
    FILE STATUS STA-VENTAS.
Ya sabéis que la extensión de nuestros ficheros es indiferente para Cobol, pero siempre nos ayudará a nosotros mismos a distinguir los archivos de datos de otro tipo de archivos.
Por eso generalmente se les suele poner la extensión .DAT.

Bien, ambas formas son correctas para designar los ficheros con los que vamos a trabajar en nuestra aplicación. Pero, ¿ que pasa si el nombre dependiera de alguna condición o debiera cumplir alguna regla ?.

En estos casos solo tendremos que asignar el fichero a una variable que definiremos en la WORKING-STORAGE SECTION. A esa variable le podremos dar los varlores que queramos para conformar nuestro nombre. Por supuesto, antes de abrir el fichero, esa variable debe de contener alguna información, de lo contrario nos daría error, simplemente porque no podría abrir un fichero sin nombre.

Para ver un ejemplo, os voy a explicar como trabajo yo personalmente. En mi empresa cada cambio de campaña (año de trabajo) los datos se copian y se empieza todo desde 0. A los ficheros les cambio el nombre, de tal forma que para las ventas, por ejemplo, tengo varios archivos que se llaman:
  • ventas.dat (actual)
  • vent0102.dat (campaña 2001/2002)
  • vent0001.dat (campaña 2000/2001)
  • vent9900.dat (campaña 1999/2000)
  • ... y asi sucesivamente, todos los años que tenga.
Por lo tanto el programa que utilizo es el mismo al igual que la SELECT y la FD, porque en realidad solo utilizo un fichero lógico, pero con varios ficheros físicos. Os explico una tarea común en cualquier programa que trabaje con varios ficheros.
Primero defino la SELECT para dicho fichero:
    SELECT VENTAS ASSIGN TO RANDOM FILVEN
    ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY KEYVEN
    ALTERNATE RECORD KEYVEN1 FILE STATUS STAVEN.
Como veis ahora no hay un nombre fijo asignado, sino que la referencia se hace a una variable llamada FILVEN. Para guardar los nombres de los distintos ficheros utilizo una tabla. Lo siguiente es definirlo todo en la WORKING:
    ...
    WORKING-STORAGE SECTION.
    01 FILVEN PIC X(20).
    01 CUAL PIC 9 VALUE 1.
    ...
    01 TABLAVENTAS.
      02 FILLER PIC X(20) VALUE "ventas.dat"
      02 FILLER PIC X(20) VALUE "vent0102.dat"
      02 FILLER PIC X(20) VALUE "vent0001.dat"
      02 FILLER PIC X(20) VALUE "vent9900.dat"
    01 RETABLAVENTAS REDEFINES TABLAVENTAS.
      02 ELFICHERO PIC X(20) OCCURS 4 TIMES.
    ...
Siempre, cuando empiezo directamente asigno el primer elemento de la tabla, que se supone que es el fichero actual con el que estoy trabajando, por lo tanto hago lo siguiente:

    ...
    PROCEDURE DIVISION.
    INICIO.
      MOVE ELFICHERO (CUAL) TO FILVEN.
      OPEN INPUT VENTAS.
      ...
A partir de aqui realizo el programa normalmente, pero tengo una opción para seleccionar campaña, en la cual llamo a una rutina que me muestra los elementos de la tabla, cuando el usuario seleccione alguna yo cambio el valor de la variable CUAL y vuelvo el control del programa al párrafo INICIO, con lo cual, me tomará el valor que le haya asignado en la elección.
Es una manera de hacerlo, a mi me va muy bien.

Pero la idea era que comprendiérais como se pueden asignar diferentes nombres de fichero dentro de un programa.

A continuación veremos como pasar los datos de un fichero indexado a uno secuencial y generar un fichero de texto para exportarlo a Excel. Es una tarea muy común con la que cualquier programador se va a encontrar en algún momento, ya sea para paso a Excel o Access o a cualquier otra aplicación externa a nuestros programas, que tenga alguna opción de importación de datos.

Voy a aprovechar también para asignar el nombre del fichero dentro del programa dependiendo de la fecha.

Empecemos ... por el principio.
    IDENTIFICATION DIVISION.
    PROGRAM-ID. TRASPASO.
    ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
    SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
    INPUT-OUTPUT SECTION.
    FILE-CONTROL.
      SELECT CLIENTES ASSIGN TO RANDOM "CLIENTES.DAT"
      ORGANIZATION INDEXED ACCESS DYNAMIC RECORD CLA-CLI
      FILE STATUS STA-CLI.

      SELECT TRASPASO ASSIGN TO RANDOM ELNOMBRE
      ORGANIZATION LINE SEQUENTIAL.

    DATA DIVISION.
    FILE SECTION.
    FD CLIENTES LABER RECORD STANDARD.
    01 REG-CLIENTES.
      02 CLI-CODIGO PIC 9(6).
      02 CLI-NOMBRE PIC X(30).
      02 CLI-DOMICILIO PIC X(30).
      02 CLI-CPOSTAL PIC 9(5).
      02 CLI-POBLACION PIC X(30).
      02 CLI-PROVINCIA PIC X(20).

    FD TRASPASO LABEL RECORD STANDARD.
    01 REG-TRASPASO.
      02 TRA-CODIGO PIC 9(6).
      02 TRA-SEP1 PIC X.
      02 TRA-NOMBRE PIC X(30).
      02 TRA-SEP2 PIC X.
      02 TRA-DOMICILIO PIC X(30).
      02 TRA-SEP3 PIC X.
      02 TRA-CPOSTAL PIC 9(5).
      02 TRA-SEP4 PIC X.
      02 TRA-POBLACION PIC X(30).
      02 TRA-SEP5 PIC X.
      02 TRA-PROVINCIA PIC X(20).

    WORKING-STORAGE SECTION.
    01 TABLAMES.
      02 FILLER PIC X(30) VALUE 'ENEFEBMARABRMAYJUNJULAGOSEPOCT'.
      02 FILLER PIC X(6) VALUE 'NOVDIC'.
    01 TABLIMES REDEFINES TABLAMES.
      02 ELEMES PIC XXX OCCURS 12 TIMES.

    01 FECHA PIC 9(6).
    01 FECHO REDEFINES FECHA.
      02 FANIO PIC 99.
      02 FMES PIC 99.
      02 FDIA PIC 99.
    01 NOMBREAR.
      02 NOM-MES PIC XXX.
      02 NOM-ANIO PIC 99.
      02 NOM-SEP PIC X.
      02 NOM-DIA PIC 99.
      02 NOM-EXT PIC XXXX.

    01 FINFIC PIC X.
    PROCEDURE DIVISION.
    INICIO.
      ACCEPT FECHA FROM DATE
      MOVE ELEMES (FMES) TO NOM-MES
      MOVE FANIO TO NOM-ANIO
      MOVE FDIA TO NOM-DIA
      MOVE '-' TO NOM-SEP MOVE '.TXT' TO NOM-EXT
      MOVE NOMBREAR TO ELNOMBRE

      OPEN INPUT CLIENTES OUTPUT TRASPASO
      MOVE ' ' TO FINFIC
      PERFORM UNTIL FINFIC = 'S'
        READ CLIENTES NEXT RECORD AT END MOVE 'S' TO FINFIC
          NOT AT END
          MOVE CLI-CODIGO TO TRA-CODIGO
          MOVE CLI-NOMBRE TO TRA-NOMBRE
          MOVE CLI-DOMICILIO TO TRA-DOMICILIO
          MOVE CLI-CPOSTAL TO TRA-CPOSTAL
          MOVE CLI-POBLACION TO TRA-POBLACION
          MOVE CLI-PROVINCIA TO TRA-PROVINCIA
          MOVE '|' TO TRA-SEP1 TRA-SEP2 TRA-SEP3 TRA-SEP4 TRA-SEP5
          WRITE REG-TRASPASO
        END-READ
      END-PERFORM
      CLOSE TRASPASO CLIENTES
      STOP RUN.

El separador entre campos ha sido el carácter 124, que se obtiene pulsando AltGr+1, pero también podemos definirlo como hexadecimal como PIC X VALUE '7C'.
Si lo que deseamos es mandar le enviamos el valor hexadecimal 9, para ello definimos una variable en la WORKING, por ejemplo:
    01 TABU PIC X VALUE H"09".
Y luego le enviamos esa variable a los campos de separación. Como véis el nombre del fichero de traspaso se ha formado a partir de la fecha del sistema, con lo que si lo hubieramos ejecutado hoy, el nombre del fichero resultante, hubiera sido: MAR03-28.TXT.

Con éste capítulo doy por terminada la sección dedicada a los ficheros, espero que como siempre os digo, os sirva y os ayude a comprender mejor el funcionamiento de los ficheros en Cobol.



Este artículo proviene de Cobol en español
http://www.escobol.com

La dirección de esta noticia es:
http://www.escobol.com/modules.php?name=Sections&op=viewarticle&artid=96