Hoy os traigo un ejemplo de cómo generar dinámicamente ficheros de salida a través de un programa cobol.
El BPXWDYN es una rutina del sistema, capaz de alocar/liberar/concatenar ficheros en una ejecución batch.
En este ejemplo, el programa lee de un fichero de entrada con N registros, y genera N ficheros de salida.
Para la nomenclatura, hemos utilizado un contador en uno de los delimitadores.
La utilidad? Imagina que tienes un fichero de entrada con 1 millón de registros, y tienes que generar un fichero de salida por cada uno de ellos (osea, 1 millón de ficheros). Vas a picarte el nombre de los ficheros a mano en el JCL? Además de que puede que no sepas el número exacto de registros que va a tener ese fichero, pues varíe cada día.
En fin, por si algún día os veis en la situación, aquí lo tenéis :-)
JCL:
//PASO01 EXEC PGM=PRUEBDYN
//ENTRADA DD DSN=FICHERO.DE.ENTRADA,DISP=SHR
//SYSOUT DD SYSOUT=*
//SYSTSPRT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
donde EXEC PGM= indica el programa SIN DB2 que vamos a ejecutar
SYSOUT DD SYSOUT=* indica que la información "displayada" se quedará en la cola del SYSOUT (no lo vamos a guardar en un fichero)
Para definir el fichero de entrada "ENTRADA" indicaremos que es un fichero ya existente y compartida al indicar DISP=SHR.
Fichero de entrada:
----+----1----+
REGISTRO1
REGISTRO2
REGISTRO3
REGISTRO4
PROGRAMA:
IDENTIFICATION DIVISION.
PROGRAM-ID. PRUEBDYN.
*==========================================================*
* PROGRAMA QUE LEE DE FICHERO Y GENERA DINAMICAMENTE
* VARIOS FICHEROS DE SALIDA
*==========================================================*
ENVIRONMENT DIVISION.
*
CONFIGURATION SECTION.
*
SPECIAL-NAMES.
DECIMAL-POINT IS COMMA.
*
INPUT-OUTPUT SECTION.
*
FILE-CONTROL.
*ENTRADA
SELECT ENTRADA
ASSIGN TO ENTRADA
FILE STATUS IS FS-ENTRADA.
*SALIDA
SELECT OTFILE ASSIGN TO OTFILE
FILE STATUS FS.
*
DATA DIVISION.
*
FILE SECTION.
*ENTRADA
FD ENTRADA
LABEL RECORD STANDARD
BLOCK CONTAINS 0 RECORDS
RECORDING MODE IS F.
01 REG-ENTRADA PIC X(80).
*SALIDA
FD OTFILE.
01 OT-REC PIC X(80).
*******************************************************
WORKING-STORAGE SECTION.
01 FS PIC X(02).
01 FN PIC X(20).
01 WS-ALLOC-STRING PIC X(100).
01 PGM PIC X(08) VALUE 'BPXWDYN'.
01 WS-VARIABLES.
05 SW-FIN-ENTRADA PIC X(01) VALUE 'N'.
88 FIN-ENTRADA VALUE 'S'.
88 NO-FIN-ENTRADA VALUE 'N'.
05 FS-ENTRADA PIC X(02).
05 WS-ENTRADA PIC X(80).
05 WS-NOMBRE-SALIDA.
10 WS-PARTE-FIJA PIC X(13) VALUE
'PARTE.COMUN.F'.
10 WS-VARIABLE PIC 9(7).
05 WS-LIBERAR PIC X(15) VALUE 'FREE FI(OTFILE)'.
******************************************************
PROCEDURE DIVISION.
******************************************************
PERFORM 100000-INICIO
PERFORM 200000-PROCESO
UNTIL FIN-ENTRADA
PERFORM 300000-FIN
.
*TRATO FICHERO DE ENTRADA
100000-INICIO.
OPEN INPUT ENTRADA
IF FS-ENTRADA NOT EQUAL '00'
DISPLAY 'ERROR AL LEER'
PERFORM 300000-FIN
END-IF
PERFORM 110000-LEER
.
*LEER FICHERO
110000-LEER.
READ ENTRADA INTO WS-ENTRADA
EVALUATE FS-ENTRADA
WHEN CTA-FS-CORRECTO
*Añadimos 1 a WS-VARIABLE para generar los diferentes
*nombres del fichero de salida
ADD 1 TO WS-VARIABLE
WHEN CTA-FS-FIN-FICHERO
SET FIN-ENTRADA TO TRUE
WHEN OTHER
DISPLAY 'ERROR AL LEER'
PERFORM 300000-FIN
END-EVALUATE
.
********************************************************
* PROCESO DEL PROGRAMA
* 1-MONTAMOS EL NOMBRE DEL FICHERO DE SALIDA
* 2-LLAMAMOS A BPXWDYN PARA ALOCAR
* 3-ESCRIBIMOS EN EL FICHERO DE SALIDA Y LO CERRAMOS
* 4-LLAMAMOS A BPXWDYN PARA LIBERAR EL FICHERO DE SALIDA
********************************************************
200000-PROCESO.
MOVE WS-NOMBRE-SALIDA TO FN
STRING 'ALLOC DD(OTFILE) DSN(' FN ') NEW '
'CATALOG ' 'LRECL(80) RECFM(FB)'
DELIMITED BY SIZE
INTO WS-ALLOC-STRING
*LLAMO AL PROGRAMA RARO
CALL PGM USING WS-ALLOC-STRING
DISPLAY 'SALIDA PGM:' RETURN-CODE
*ABRO FICHERO SALIDA
OPEN OUTPUT OTFILE
IF FS NOT EQUAL '00'
DISPLAY 'ERROR AL ABRIR SALIDA:' FS
END-IF
*ESCRIBO EN EL FICHERO
MOVE WS-ENTRADA TO OT-REC
WRITE OT-REC
IF FS NOT EQUAL '00'
DISPLAY 'ERROR AL ESCRIBIR SALIDA:' FS
END-IF
*CIERRO EL FICHERO DE SALIDA
CLOSE OTFILE
IF FS NOT EQUAL '00'
DISPLAY 'ERROR AL CERRAR SALIDA:' FS
END-IF
CALL PGM USING WS-LIBERAR
PERFORM 110000-LEER
.
*FIN
300000-FIN.
CLOSE ENTRADA
IF FS-ENTRADA NOT EQUAL '00'
DISPLAY 'ERROR AL CERRAR'
END-IF
STOP RUN
.
La primera vez que llamamos al programa BPXWDYN, lo hacemos con la opción "alocar", ALLOC.
Le indicamos el nombre del fichero, lo que iría en la DSN, con una variable "FN" que contiene el nombre PARTE.COMUN.F0000001.
Además le indicamos las opciones que irían en el DISP: NEW, CATALOG. La longitud LRECL(80) y que es un fichero de longitud fija RECFM(FB).
Estas opciones podemos modificarlas en función de nuestras necesidades.
La segunda vez que llamamos al programa BPXWDYN es necesaria para que OTFILE coja el siguiente nombre que le asignemos. Si no lo hiciésemos, el primer nombre (PARTE.COMUN.F0000001) se quedaría alocado y no se generaría ningún otro.
El resultado son 4 ficheros de salida:
PARTE.COMUN.F0000001 --> contiene REGISTRO1
PARTE.COMUN.F0000002 --> contiene REGISTRO2
PARTE.COMUN.F0000003 --> contiene REGISTRO3
PARTE.COMUN.F0000004 --> contiene REGISTRO4
1 comentario:
excelente!