Hay que tener en cuenta que en los ficheros de longitud variable las 4 primeras posiciones contienen la longitud de cada registro.
Así como a la hora de contar posiciones para posicionarnos en un campo empezamos por la 5, al hacer el outrec la información de las 4 primeras posiciones también hay que llevársela al fichero de salida.
Por otro lado, en un fichero VB habrá registros que no lleguen a ocupar la longitud máxima, por lo que si no indicamos qué hacer, el SORT dará error al no saber cómo rellenar o ignorar esas posiciones.
En el manual de DFSORT de IBM nos indican como solucionar los casos en que tenemos registros con diferentes longitudes (es decir, no todos los registros del fichero tienen la longitud máxima):
"If a variable-length record was too short to contain all INREC, OUTREC, or OUTFIL fields, use an INREC or OUTREC statement with operands OVERLAY or IFTHEN as appropriate, or an OUTFIL statement with operands OVERLAY, IFTHEN, or BUILD and VLFILL=C 'x' or VLFILL=X 'yy' as appropriate, to prevent DFSORT from terminating"
En nuestro ejemplo vamos a usar un OUTREC con OVERLAY.
FICHERO DE ENTRADA, LONGITUD MÁXIMA 55 (4+51):
----+----1----+----2----+----3----+----4----+----5-
***************************** Top of Data *********
2015-01-01DATOS VARIABLES
FFFF6FF6FFCCEDE4ECDCCCDCE44444444444444444444444444
201500100141362051991235200000000000000000000000000
---------------------------------------------------
2015-01-01DATOS VARIABLES LARGO 40 FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCD444FF444444444444444
201500100141362051991235203197600040000000000000000
---------------------------------------------------
2015-01-01DATOS VARIABLES MAS LARGO 45
FFFF6FF6FFCCEDE4ECDCCCDCE4DCE4DCDCD4444FF4444444444
201500100141362051991235204120319760000450000000000
---------------------------------------------------
2015-01-01DATOS VARIABLES LARGO MAXIMO 51
FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCD4DCECDD44444444444FF
201500100141362051991235203197604179460000000000051
---------------------------------------------------
Supongamos que queremos cambiar todas las fechas a 9999-12-31, manteniendo idéntico el resto del fichero.
En un OUTREC de un fichero FB pondríamos:
//PASO040 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=fichero_de_entradaFB,DISP=SHR
//SORTOUT DD DSN=fichero_de_salidaFB,
// DISP=(,CATLG),
// SPACE=(CYL,(150,75),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(C'9999-12-31',11,41)
Si intentásemos usarlo para ficheros VB:
//PASO040 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=fichero_de_entradaVB,DISP=SHR
//SORTOUT DD DSN=fichero_de_salidaVB,
// DISP=(,CATLG),
// SPACE=(CYL,(150,75),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(C'9999-12-31',15,41)
Obtendremos un error SORT01 - ABEND=S000 U0251:
Pues nos hemos dejado por el camino las posiciones que llevan la información de la longitud.
Si sobre el mismo outrec añadimos las 4 primeras posiciones:
//PASO040 EXEC PGM=SORT//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=fichero_de_entradaVB,DISP=SHR
//SORTOUT DD DSN=fichero_de_salidaVB,
// DISP=(,CATLG),
// SPACE=(CYL,(150,75),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(1,4,C'9999-12-31',15,41)
Obtendremos el error SORT01 - ABEND=S000 U0218:
Que nos dice que hay registros con longitud menor al máximo del fichero.
La solución para un OUTREC de un fichero VB sería:
//PASO040 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=fichero_de_entradaVB,DISP=SHR
//SORTOUT DD DSN=fichero_de_salidaVB,
// DISP=(,CATLG),
// SPACE=(CYL,(150,75),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTREC OVERLAY=(5:C'9999-12-31')
De esta forma indicamos el cambio que queremos hacer y que el resto de posiciones de cada registro se copien tal cual estén en el fichero de entarda.
OJO! En el fichero de salida no se está indicando la longitud porque es la misma que la del fichero de entrada. Si en un outrec el fichero de salida tiene diferente longitud que el fichero de entrada, hay que indicarlo en el DCB:
DCB=(RECFM=VB,LRECL=55,BLKSIZE=0)
Y de regalo os dejo como pasar de FB a VB y viceversa:
//**********************************************
//* FICHERO FB A VB
//* LA SALIDA MEDIRÁ 4 POSICIONES MÁS
//**********************************************
//SORT01 EXEC PGM=SORT
//SORTIN DD DSN=fichero_de_entradaFB,DISP=SHR
//VBOUT DD DSN=fichero_de_salidaVB,
// DISP=(,CATLG,DELETE),
// SPACE=(CYL,(200,50),RLSE)
//SYSOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
OUTFIL FNAMES=VBOUT,FTOV
/*
//***********************************************
//* FICHERO VB A FB
//* INDICAMOS LAS POSICIONES A COPIAR
//* PODEMOS COPIAR LAS POSICIONES QUE LLEVAN LA
//* INFORMACION DE LA LONGITUD DEL REGISTRO, O NO
//***********************************************
//SORT01 EXEC PGM=SORT
//SORTIN DD DSN=fichero_de_entradaVB,DISP=SHR
//FBOUT DD DSN=fichero_de_salidaFB,
// DISP=(,CATLG,DELETE),
// SPACE=(CYL,(200,50),RLSE)
//SYSOUT DD SYSOUT=*
//SYSIN DD *
OPTION COPY
OUTFIL FNAMES=FBOUT,VTOF,OUTREC(5,51)
/*
No hay comentarios: