Mostrando entradas con la etiqueta OUTREC. Mostrar todas las entradas
Mostrando entradas con la etiqueta OUTREC. Mostrar todas las entradas

lunes, 24 de octubre de 2016

Sort vol 2.4: OUTREC. Rellenar con espacios.

Hace unas semanas un compi me comentó que le daba error al rellenar 18000 espacios al final de un registro escribiendo 18000X. Nunca me había planteado si había un límite, pues nunca había tenido que rellenar semejante cantidad de posiciones. Descubrimos que efectivamente no se puede xd

La verdad es que si leemos el manual de OUTREC de IBM lo dice claramente, pero son esas cosas que solo lees cuando tienes un error (mal!).

Aquí tenéis lo que dice IBM al respecto:

Es decir, que como mucho podemos decirle que incluya 4095 espacios. Y que si necesitamos más, hagamos repeticiones hasta el número deseado :D

Os dejo el ejemplo de OUTREC completo:
//SORT01   EXEC PGM=SORT                                    
//SORTIN   DD DSN=FICHERO.DE.ENTRADA,DISP=SHR
//SORTOUT  DD DSN=FICHERO.DE.SALIDA,                     
//            DISP=(,CATLG,DELETE),                         
//            SPACE=(CYL,(200,50),RLSE),                    
//            DCB=(RECFM=FB,LRECL=8395,BLKSIZE=0)           
//SYSOUT   DD SYSOUT=*                                      
//SYSIN    DD *                                             

   SORT FIELDS=COPY
   OUTREC FIELDS=(1:C'TEXTO',6:1,200,206:4095X,4095X)

Y os lo cuento para que no se me olvide :-)

lunes, 8 de agosto de 2016

JFY: alinear campos en JCL

Una opción que podemos utilizar tanto con OUTREC como con INREC es la de "justificar" a izquierda o derecha con JFY.

Os dejo a continuación un ejemplo de OUTREC para fichero de longitud fija FB y de longitud variable VB.

FICHERO DE ENTRADA:

+----1----+----2----+----3----+----4----+----5-
***************************** Top of Data *****

2015-01-01DATOS VARIABLES     T 20
FFFF6FF6FFCCEDE4ECDCCCDCE44444E4FF4444444444444 20150010014136205199123520000030200000000000000 -----------------------------------------------

2015-01-01DATOS VARIABLES LARGO   40 FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCD444FF44444444444 20150010014136205199123520319760004000000000000 -----------------------------------------------
2015-01-01DATOS VARIABLES MAS L        45              
FFFF6FF6FFCCEDE4ECDCCCDCE4DCE4D44444444FF444444 20150010014136205199123520412030000000045000000 -----------------------------------------------

2015-01-01DATOS VARIABLES LARGO              51
FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCD44444444444444FF
20150010014136205199123520319760000000000000051
-----------------------------------------------
 


Si os fijáis, de la posición 36 a la 51 tenemos un campo con diferente número de espacios a la izquierda del dato que nos interesa.

Para un fichero 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 OVERLAY=(40:40,16,JFY=(SHIFT=LEFT))


Le estamos indicando que en la posición 40 (36+4 porque es un VB) escriba el campo que está en la posición 40 ocupando 16, pero alineándolo a la izquierda. Y que deje el resto del registro igual (podéis ver más detalle en Sort vol.2.3: OUTREC. Ficheros VB).

El resultado:

+----1----+----2----+----3----+----4----+----5-
************************* Top of Data *********
2015-01-01DATOS VARIABLES     T20             
FFFF6FF6FFCCEDE4ECDCCCDCE44444EFF44444444444444
20150010014136205199123520000032000000000000000
-----------------------------------------------
2015-01-01DATOS VARIABLES LARGO40             
FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCDFF44444444444444
20150010014136205199123520319764000000000000000
-----------------------------------------------
2015-01-01DATOS VARIABLES MAS L45             
FFFF6FF6FFCCEDE4ECDCCCDCE4DCE4DFF44444444444444
20150010014136205199123520412034500000000000000
-----------------------------------------------
2015-01-01DATOS VARIABLES LARGO51             
FFFF6FF6FFCCEDE4ECDCCCDCE4DCDCDFF44444444444444
20150010014136205199123520319765100000000000000


Para un fichero de longitud fija:
//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 *
     OPTION COPY                                   
     OUTREC FIELDS=(1:1,35,36:36,16,JFY=(SHIFT=LEFT))


Obteniendo el mismo resultado.
Si quisiésemos alinear a la derecha escribríamos SHIFT=RIGHT.

miércoles, 22 de junio de 2016

Sort vol.2.3: OUTREC. Ficheros VB

Para aquellos que trabajéis con ficheros de longitud variable VB os traigo un ejemplo de como hacer un OUTREC.

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)
/*

miércoles, 9 de mayo de 2012

JCL Avanzado II. Operaciones aritméticas con OUTREC.

Este es un ejemplo de como podemos operar con la información de un fichero usando la opción OUTREC del programa SORT.

//SORT001 EXEC PGM=SORT
//SORTIN DD DSN=nombre.fichero.entrada1,DISP=SHR
//SORTOUT DD DSN=nombre.fichero.salida1,
// DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SYSOUT DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(I,L,Ti,O,D,TO=Tf,LENGTH=L)

I  – Inicio. Posición donde empieza el campo.
L  – Longitud máxima del campo.
Ti - Tipo de dato inicial:
     CH - Alfanumérico
     ZD - Numérico
     BI - Hexadecimal (campos COMP)
     PD - Empaquetado con o sin signo(campos COMP-3)
O  - Operador:
     ADD - Suma
     SUB - Resta
     MUL - Multiplicación
     DIV - División
D  – Dato de la operación
Tf - Tipo de dato final
L  - Longitud del campo convertido


La razón por la que incluimos el tipo de dato inicial y final es que, si no lo hacemos, perderemos el formato del campo.
En lugar de indicar SORT FIELDS=COPY podríamos indicar cualquier tipo de ordenación.


Ejemplo 1: Añadir uno al saldo del fichero de empresas.

----+----1----+----2----+----3----+----4----+
000000002EMPRESA CAFETERIA NOVELTY 00110000
000000001EMPRESA LANAS MARUJA      00220000
000000004EMPRESA ASESORIA ASOCIA   00100000

Fórmula:
SORT FIELDS=COPY
 OUTREC FIELDS=(1,35,36,8,ZD,ADD,+1,TO=ZD,LENGTH=8)


Resultado 1:

----+----1----+----2----+----3----+----4----+
000000002EMPRESA CAFETERIA NOVELTY 00110001
000000001EMPRESA LANAS MARUJA      00220001
000000004EMPRESA ASESORIA ASOCIA   00100001


Como podéis ver en el último campo todas las cantidades se ven incrementadas en 1.

Si quisiésemos cambiar el formato hay que tener en cuenta que la longitud del fichero de salida cambiaría.

Ejemplo 2:Añadir 5 al saldo del fichero de empresas y convertirlo a COMP-3.

----+----1----+----2----+----3----+----4----+
000000002EMPRESA CAFETERIA NOVELTY 00110000
000000001EMPRESA LANAS MARUJA      00220000
000000004EMPRESA ASESORIA ASOCIA   00100000

Fórmula:
SORT FIELDS=COPY
 OUTREC FIELDS=(1,35,36,8,ZD,ADD,+5,TO=PD,LENGTH=5)


Resultado 2:

----+----1----+----2----+----3----+----4----+
000000002EMPRESA CAFETERIA NOVELTY
FFFFFFFFFCDDDCEC4CCCCECDCC4DDECDEE40010544444
000000002547952103165359910565533800100C00000
---------------------------------------------
000000001EMPRESA LANAS MARUJA
FFFFFFFFFCDDDCEC4DCDCE4DCDEDC4444440020544444
000000001547952103151204194110000000200C00000
---------------------------------------------
000000004EMPRESA ASESORIA ASOCIA
FFFFFFFFFCDDDCEC4CECEDDCC4CEDCCC4440000544444
000000004547952101252699101263910000100C00000


La operación se aplica al campo inmediatamente anterior indicado en el OUTREC. En ambos ejemplos veis que por un lado hemos indicado que queremos sacar en salida la información de la posición 1 ocupando 35, y después de la 36 ocupando 8, para la cual se aplica la operación "sumar 1".

Podéis probar con todas las operaciones : )

Aportes de los lectores:
Se pueden sumar dos campos del mismo archivo asi:
OUTREC FIELDS=((01,10,ZD),ADD,(11,10,ZD),TO=ZD,LENGTH=10)

Convertir un campo 9(3)v9(6) comp-3 a un 99v999 comp-3:
OUTREC FIELDS=(57,5,PD,DIV,+1000,TO=PD,LENGTH=3) 

lunes, 5 de septiembre de 2011

Sort vol.2.2: OUTREC. Máscaras de edición

FICHERO DE ENTRADA

Supongamos que tenemos este fichero, en el que tenemos los siguientes campos sin formatear:

- una fecha (posiciones del 5 al 10)
- una hora (del 20 al 25)
- importe 1 comprimido (del 26 al 31)
- importe 2 (del 32 al 35)
- importe 3 (del 36 al 45)
- importe 4 (del 46 al final)


----+----1----+----2----+----3----+----4----+----5----+
***************************** Top of Data *************
0001100811MARIA    143010      011100001111110000111111
FFFFFFFFFFDCDCC4444FFFFFF000001FFFFFFFFFFFFFFFFFFFFFFFF
000110081141991000014301000000C011100001111110000111111
-------------------------------------------------------
0002230411VICTOR   153523      022200002222220000222222
FFFFFFFFFFECCEDD444FFFFFF000002FFFFFFFFFFFFFFFFFFFFFFFF
000223041159336900015352300000C022200002222220000222222
-------------------------------------------------------
0003150811MARIANO  164022      033300003333330000333333
FFFFFFFFFFDCDCCDD44FFFFFF000003FFFFFFFFFFFFFFFFFFFFFFFF
000315081141991560016402200000C033300003333330000333333
-------------------------------------------------------
0004251211LUCIA    174515     <044400004444440000444444
FFFFFFFFFFDECCC4444FFFFFF000004FFFFFFFFFFFFFFFFFFFFFFFF
000425121134391000017451500000C044400004444440000444444



Con este ejemplo vamos a aprender a dar el formato que queramos a cada uno de estos campos. Para ello utilizaremos un OUTREC, en donde vamos a tener este fichero de entrada y otro de salida donde saldrán los campos formateados. En este OUTREC vamos a aplicar las MASCARAS. Las máscaras simplemente son herramientas que nos van a permitir modificar el formato de los campos seleccionados con el OUTREC:


//PASO040 EXEC SORTD,OUT=*
//SYSOUT  DD SYSOUT=*
//SORTIN  DD DSN=fichero_de_entrada,DISP=SHR
//SORTOUT DD DSN=fichero_de_salida,
//           DISP=(,CATLG),
//           SPACE=(CYL,(150,75),RLSE)
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(01,04,
               05,06,ZD,M9,LENGTH=8,
               11,09,
               20,06,ZD,M8,LENGTH=8,
               26,06,PD,
               32,04,ZD,M18,LENGTH=4,
               36,10,ZD,M4,LENGTH=11,
               46,10,ZD,M26,LENGTH=11)



En el fichero_de_salida obtendremos como RESULTADO:

----+----1----+----2----+----3----+----4----+----5----+----6----+--
***************************** Top of Data *************************
000110/08/11MARIA    14:30:10     11.11  +1,111.11+0000111111
000223/04/11VICTOR   15:35:23     22.22  +2,222.22+0000222222
000315/08/11MARIANO  16:40:22     33.33  +3,333.33+0000333333
000425/12/11LUCIA    17:45:15     44.44  +4,444.44+0000444444


Por ejemplo, en el primer caso (01,04), simplemente hemos seleccionado el campo pero no hemos aplicado ninguna máscara.
Sin embargo, en el segundo (05,06,ZD,M9,LENGTH=8), hemos seleccionado el campo 'fecha' que ocupa 6 posiciones(DDMMAA) y la hemos aplicado el código de máscara M9 que lo que hace es meter una '/' entre medias formateando el campo a DD/MM/AA.

Para el campo 'hora' hemos hecho lo mismo pero aplicando el código M8, que convierte un formato HHMMSS en HH:MM:SS.
Para los importes también hemos aplicado otros códigos, por ejemplo el M4 que pone a una cantidad un signo(+ o -), una coma para separar los miles y un punto para separar los decimales.

Existe una tabla donde están reflajados los códigos de conversión de las máscaras. Os dejo la que tengo para descargar, si encontráis más códigos de conversión por favor indicarlos.

Lista de códigos de conversión de las máscaras

Tengo entendido que puedes formar tus propias máscaras a partir de estos valores, y así no utilizar los códigos de conversión. De ese modo es más libre y cada uno puede formatear según le interese. Cuando sepa como se hace lo indico, estoy en ello...


MÁS UTILIDADES DE LAS MÁSCARAS.

El ejemplo anterior nos permite dar un formato más leíble a nuestros ficheros, pero además si tu host lo permite, podemos exportar este fichero fuera del host, y visualizarlo en una hoja de cálculo. Para ello, podemos preparar el fichero para abrirlo por ejemplo con el Excel. Solo tenemos que poner un ';' entre cada campo del siguiente modo:

//PASO040 EXEC SORTD,OUT=*
//SYSOUT DD SYSOUT=*
//SORTIN DD DSN=LAET.LAEHISTA.CCOBOL,DISP=SHR
//SORTOUT DD DSN=LAET.MASCARA.SALIDA,
// DISP=(,CATLG),
// SPACE=(CYL,(150,75),RLSE)
//SYSIN DD * 

SORT FIELDS=COPY
OUTREC FIELDS=(01,04,C';',
               05,06,ZD,M9,LENGTH=8,C';',
               11,09,C';',
               20,06,ZD,M8,LENGTH=8,C';',
               26,06,PD,C';',
               32,04,ZD,M18,LENGTH=4,C';',
               36,10,ZD,M4,LENGTH=11,C';',
               46,10,ZD,M26,LENGTH=11)



RESULTADO:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7----
***************************** Top of Data ********************************
0001;10/08/11;MARIA    ;14:30:10;    1;1.11;  +1,111.11;+0000111111
0002;23/04/11;VICTOR   ;15:35:23;    2;2.22;  +2,222.22;+0000222222
0003;15/08/11;MARIANO  ;16:40:22;    3;3.33;  +3,333.33;+0000333333
0004;25/12/11;LUCIA    ;17:45:15;    4;4.44;  +4,444.44;+0000444444


Ahora solo hay que exportar el fichero host a un archivo excel poniendo al archivo la extensión .CSV (por ejemplo: "ejemplo_mascaras.csv").
De este modo el excel utiliza los ';' para separar los campos en celdas y que cada campo quede organizado en su correspondiente columna. Si has seguido el ejemplo te ha de quedar de este modo:


lunes, 23 de mayo de 2011

Sort vol.2.1: OUTREC. IFTHEN

Ampliando un poco las funciones del OUTREC os voy a explicar como incluir condiciones. Es muy sencillo y puede evitar tener que crear programas en un momento dado.

Pongamos el caso de que tenemos el siguiente fichero con los datos de unos clientes:

----+----1----+----2----+----3----+----4----+----5----+----
***************************** Top of Data *****************
000000001JOSE      LOPEZ     PITA     AUTONOMO        47001
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      47001
000000003CARLOS    PEREZ     FANO     AUTONOMO        47001
000000004CARLOS    POLO      DEL BARROAUTONOMO        47001
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        47001
000000006ANTONIO   VILLA     SUSO     AUTONOMO        47001
000000007FULANITO  VILLA     SUSO     AUTONOMO        47001


Un buen día nos dicen que quieren añadir al final de cada registro un indicador que nos marque lo siquiente:

Si es un AUTONOMO añadir el indicador 'A'
Si es un ASALARIADO añadir el indicador 'S'

Utlizaremos el siguiente paso de jcl donde aplicamos la condición:

//OUTREC   EXEC SORTD
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=Nombre_Fichero_De_Entrada,DISP=SHR
//SORTOUT  DD DSN=Nombre_Fichero_De_Salida,
//            DISP=(,CATLG),
//            SPACE=(CYL,(100,100),RLSE)
//SYSIN    DD *
 SORT FIELDS=COPY
 OUTREC IFTHEN=(WHEN=(39,11,CH,EQ,C'AUTONOMO   '),
          OVERLAY=(1,59,C'A')),
        IFTHEN=(WHEN=NONE,
          OVERLAY=(1,59,C'S'))


El resultado obtenido será el siguiente:

----+----1----+----2----+----3----+----4----+----5----+----6
***************************** Top of Data ******************
000000001JOSE      LOPEZ     PITA     AUTONOMO        47001A
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      47001S
000000003CARLOS    PEREZ     FANO     AUTONOMO        47001A
000000004CARLOS    POLO      DEL BARROAUTONOMO        47001A
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        47001A
000000006ANTONIO   VILLA     SUSO     AUTONOMO        47001A
000000007FULANITO  VILLA     SUSO     AUTONOMO        47001A


Vemos como a los AUTONOMOS les marca con una A y a los ASALARIADOS con una S.

Notas:
- Para añadir más condiciones se deben añadir más IFTHEN al OUTREC.
- Esto es válido también para el INREC.

lunes, 16 de mayo de 2011

Sort vol.5.1: SUM. Averiguar registros duplicados

Hola. Os dejo un jcl que os puede sacar de un apuro en más de una ocasión (a mí me salvó más de una vez).
Se trata de un procesito fácil, barato y para toda la familia, que nos permite averiguar que registros de un fichero están duplicados, cuales no y cuantos son.

Como siempre, para que quede más claro seguiré un ejemplo práctico, válido para cualquier caso:

Supongamos que tenemos el siguiente fichero con los duplicados:


----+----1----+----2----+----3----+----4----+----5----
***************************** Top of Data ************
000000001JOSE      LOPEZ     PITA     AUTONOMO        
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      
000000003CARLOS    PEREZ     FANO     AUTONOMO        
000000004CARLOS    POLO      DEL BARROAUTONOMO        
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        
000000006ANTONIO   VILLA     SUSO     AUTONOMO        
000000007FULANITO  VILLA     SUSO     AUTONOMO 
...


Vemos que Javier y Yolanda salen repetidos, Yolanda icluso viene 3 veces. A simple vista los vemos porque el ejemplo está preparado para ello, pero imaginate que el fichero tuviera 100.000 registros y solo 2 duplicados, se complica la búsqueda no? continuamos:

PASO1 - Lo primero que haremos será ordenar el fichero por la clave (en este caso son las primeras 9 posiciones) y después poner un 1 al final de cada uno de los registros del fichero, para ello:


//PASO001  EXEC SORTD
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=nombre_fichero_con_diplicados1,DISP=SHR
//SORTOUT  DD DSN=nombre_fichero_salida1_paso001,
//            DISP=(,CATLG),
//            SPACE=(CYL,(100,100),RLSE)
//SYSIN    DD *
 SORT FIELDS=(1,9,ZD,A)
 OUTREC FIELDS=(1,54,C'1')


El fichero quedará del siguiente modo:


----+----1----+----2----+----3----+----4----+----5----+
***************************** Top of Data *************
000000001JOSE      LOPEZ     PITA     AUTONOMO        1
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      1
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      1
000000003CARLOS    PEREZ     FANO     AUTONOMO        1
000000004CARLOS    POLO      DEL BARROAUTONOMO        1
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        1
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        1
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        1
000000006ANTONIO   VILLA     SUSO     AUTONOMO        1
000000007FULANITO  VILLA     SUSO     AUTONOMO        1
...


PASO2 - Ahora lo que haremos será agrupar los registros por clave y utilizar el numeríto (1) que hemos introducido para sumar los registros que agrupemos:


//PASO002  EXEC SORTD
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=nombre_fichero_salida1_paso001,DISP=SHR
//SORTOUT  DD DSN=nombre_fichero_salida,
//            DISP=(,CATLG),
//            SPACE=(CYL,(100,100),RLSE)
//SYSIN    DD *
 SORT FIELDS=(1,9,ZD,A)
 SUM FIELDS=(55,1,ZD)


Obtendremos el resultado siguiente:


----+----1----+----2----+----3----+----4----+----5----+
***************************** Top of Data *************
000000001JOSE      LOPEZ     PITA     AUTONOMO        1
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      2
000000003CARLOS    PEREZ     FANO     AUTONOMO        1
000000004CARLOS    POLO      DEL BARROAUTONOMO        1
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        3
000000006ANTONIO   VILLA     SUSO     AUTONOMO        1
000000007FULANITO  VILLA     SUSO     AUTONOMO        1
...


Bien, ahora simplemente hacemos busquedas en el fichero teniendo en cuenta lo siguiente:
- Si el numerito introducido al final de cada registro no ha variado (si vale 1), quiere decir que el registro no está duplicado
- Si ha variado el valor querra decir que el registro estaba duplicado y nos dirá el número de veces que está duplicado.

Según el ejemplo vemos como Javier tiene un 2 porque está repetido dos veces, Yolanda tiene un 3 porque está repetida 3 veces, y el resto tienen un 1 porque no están repetidos.

Así de facil!

Otros casos útiles:

En algunas ocasiones queremos camparar dos ficheros para encontrar las direfencias, por ejemplo, suponte que deberían de ser iguales pero uno de ellos tiene 3 registros más que el otro, y que esto pueda ser debido algún registro duplicado.
Para resolverlo, podéis aplicar este mismo método, aplicando el PASO1 a los dos ficheros y luego metiendo los dos ficheros en el PASO2. Te dirá que registros son únicos(tanto de un fichero como del otro), cuales no lo són y el número de los que estén repetidos.

Espero que os haya servido, no obstante cualquier duda comentarla.

viernes, 7 de enero de 2011

SORT vol.2: OUTREC.

La estructura general de un SORT es la siguiente:

//SORT001  EXEC PGM=SORT,PARM=('DYNALLOC=(SYSALLDA,32)')
//SORTIN   DD DSN=nombre.fichero.entrada1,DISP=SHR
//         DD DSN=nombre.fichero.entrada2(opcional),DISP=SHR
//SORTOUT  DD DSN=nombre.fichero.salida1,
//            DISP=(,CATLG,DELETE),SPACE=CYL,500,100))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *




PGM=SORT --> Indica el programa a utilizar, en este caso el SORT.
PARM=('DYNALLOC=(SYSALLDA,32)') --> Cantidad de memoria que se da a la ejecución del paso. Si se queda corto, aumentarla en valores de 8,12,32,64,128, 256 (como las memorias RAM)
SORTIN --> Ficheros de entrada
SORTOUT --> Ficheros de salida
SYSIN --> Indica el tipo de sort a realizar, las opciones disponibles son muchas y muy variadas, pudiendo utilizarse varias juntas en un mismo paso. Algunas de ellas son SORT, SUM, OMIT, INCLUDE, INREC, OUTREC, OUTFIL, OPTION … .

En este documento se explica en detalle algunas de estas funciones:

OUTREC

OUTREC FIELDS. --> Toma los registros del fichero de entrada y los guarda formateados en el fichero de salida:

//SORT001  EXEC PGM=SORT,PARM=('DYNALLOC=(SYSALLDA,32)')
//SORTIN   DD DSN=nombre.fichero.entrada1,DISP=SHR
//         DD DSN=nombre.fichero.entrada2,DISP=SHR
//SORTOUT  DD DSN=nombre.fichero.salida1,
//            DISP=(,CATLG,DELETE),SPACE=CYL,500,100))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
SORT FIELDS=COPY
OUTREC FIELDS=(I,L,D(opcional))

I – Inicio. Posición donde empieza el campo.
L – Longitud máxima del campo.
D – Dato a incluir (opcional).


¡OJO! En este ejemplo hemos utilizado el SORT FIELDS=COPY, para indicar que no queremos ordenar el fichero, sino sólo copiarlo, pero podría indicarse cualquier tipo de ordenación. Podéis ver el uso del SORT en el artículo Sort vol.1: SORT, INCLUDE.

Hay diferentes formas de utilizar el OUTREC, voy a intentar señalar unas cuantas:

OUTREC – FORMATEO DE FICHEROS

Situación 1. Tenemos un fichero de entrada con los siguientes datos: Número de cliente, Nombre, Apellido1, Apellido2 y Situación Laboral(AUTONOMO ó ASALARIADO).
Supongamos que queremos obtener un fichero que contenga sólo el Nombre seguido de una coma, y a continuación la Situación Laboral:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006ANTONIO   VILLA     SUSO     AUTONOMO  
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO  
000000001JOSE      LOPEZ     PITA     AUTONOMO  
000000004CARLOS    POLO      DEL BARROAUTONOMO  
000000003CARLOS    PEREZ     FANO     AUTONOMO  

La fórmula sería:

OUTREC FIELDS=(10,10,C’,’,39,10)

La salida quedará del siguiente modo:

----+----1----+----2-
JAVIER    ,ASALARIADO
ANTONIO   ,AUTONOMO  
YOLANDA   ,AUTONOMO  
JOSE      ,AUTONOMO  
CARLOS    ,AUTONOMO  
CARLOS    ,AUTONOMO  

Situación 2. Sobre el fichero inicial supongamos que queremos poner primero los Apellidos y luego el Nombre.

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006ANTONIO   VILLA     SUSO     AUTONOMO  
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO  
000000001JOSE      LOPEZ     PITA     AUTONOMO  
000000004CARLOS    POLO      DEL BARROAUTONOMO  
000000003CARLOS    PEREZ     FANO     AUTONOMO  

La fórmula sería:

OUTREC FIELDS=(1,9,20,19,10,10,39,34)

La salida quedará del siguiente modo:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002MARTINEZ  CARRETEROJAVIER    ASALARIADO
000000006VILLA     SUSO     ANTONIO   AUTONOMO  
000000005LOPEZ     ALONSO   YOLANDA   AUTONOMO  
000000001LOPEZ     PITA     JOSE      AUTONOMO  
000000004POLO      DEL BARROCARLOS    AUTONOMO  
000000003PEREZ     FANO     CARLOS    AUTONOMO  

Situación 3. Supongamos que entre el número de cliente y el nombre queramos meter 10 espacios en blanco:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006ANTONIO   VILLA     SUSO     AUTONOMO  
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO  
000000001JOSE      LOPEZ     PITA     AUTONOMO  
000000004CARLOS    POLO      DEL BARROAUTONOMO
000000003CARLOS    PEREZ     FANO     AUTONOMO  

La fórmula sería:

OUTREC FIELDS=(1,9,C'          ',10,53)

Otra opción:
OUTREC FIELDS=(1,9,10X,10,53)

Y otra:
OUTREC FIELDS=(1,9,10C'         ',10,53)


La salida quedará del siguiente modo:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002          JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006          ANTONIO   VILLA     SUSO     AUTONOMO
000000005          YOLANDA   LOPEZ     ALONSO   AUTONOMO  
000000001          JOSE      LOPEZ     PITA     AUTONOMO  
000000004          CARLOS    POLO      DEL BARROAUTONOMO  
000000003          CARLOS    PEREZ     FANO     AUTONOMO


OUTREC – CONVERSIÓN DE DATOS

El outrec nos permite cambiar el formato de los campos. Se realiza del siguiente modo:

OUTREC FIELDS=(inicio_campo1,
               longitud_campo1,
               tipo_dato_inicial,
               TO=tipo_dato_de_destino,
               LENGTH=longitud_final_del_campo_convertido,
               …)

Los tipos de formato son los siguientes:

CH --> Alfanumérico
ZD --> Numérico normal
BI --> Hexadecimal (campos COMP)
PD --> Empaquetado con o sin signo(campos COMP-3)

Para saber la longitud del LENGTH, se debe seguir la norma siguiente:
- Campos COMP --> Dividimos la longitud entre 2 y nos quedamos con la parte entera:
   S9(9) COMP --> LENGTH=4
   9(9)  COMP --> LENGTH=4
   S9(8) COMP --> LENGTH=4
   9(8)  COMP --> LENGTH=4


- Campos COMP-3 --> Dividimos la longitud + 1 entre 2, si el resultado da decimales se redondea al mayor:
   S9(9) COMP-3 --> LENGTH=5
   9(9)  COMP-3 --> LENGTH=5
   S9(8) COMP-3 --> LENGTH=5
   9(8)  COMP-3 --> LENGTH=5


- Si el campo tiene decimales, ya sea COMP o COMP-3, se suman primero los enteros + los decimales, y a partir de ahí se aplica la fórmula anterior:
   S9(9)V99 COMP   --> LENGTH=5
   9(9)V99  COMP   --> LENGTH=5
   S9(9)V99 COMP-3 --> LENGTH=6
   9(9)V99  COMP-3 --> LENGTH=6


Ejemplos prácticos suponiendo que el campo comience en la primera posición:

- Convertir 9(8) a S9(9) COMP-3 y viceversa:

OUTREC FIELDS=(1,8,ZD,TO=PD,LENGTH=5)
OUTREC FIELDS=(1,5,PD,TO=ZD,LENGTH=8)

- Convertir 9(8) COMP a 9(8) y viceversa:

OUTREC FIELDS=(1,4,BI,TO=ZD,LENGTH=8)
OUTREC FIELDS=(1,8,ZD,TO=BI,LENGTH=4)


Cosas a tener en cuenta:
- La longitud del fichero de salida puede no ser la misma de entrada, porque si convertimos tipos de datos, por ejemplo, un numérico normal a un empaquetado la longitud se reduce al comprimir el campo.
- Se pueden realizar varias conversiones dentro de un mismo OUTREC.
- No se puede convertir un campo alfanumérico(que tenga letras) a un campo numérico.


OUTREC CHANGE – Cambiar datos

Una utilidad curiosa del outrec es la de sustituir datos del fichero por otros.
Por ejemplo, en el ejemplo anterior hemos incluido un campo con 10 espacios, imaginemos que nos hemos confundido, y lo que queríamos hacer era crear un campo con 10 ceros en vez de espacios. El outrec sería del siguiente modo:

Fichero de entrada:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002          JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006          ANTONIO   VILLA     SUSO     AUTONOMO
000000005          YOLANDA   LOPEZ     ALONSO   AUTONOMO
000000001          JOSE      LOPEZ     PITA     AUTONOMO
000000004          CARLOS    POLO      DEL BARROAUTONOMO
000000003          CARLOS    PEREZ     FANO     AUTONOMO

OUTREC FIELDS=(1,9,10,10,CHANGE=(10,C'          ',
C’0000000000’),NOMATCH=(10,10))

Otra forma:

OUTREC FIELDS=(1,9,10,10,CHANGE=(10,X'40404040404040404040',
X'00000000000000000000'),NOMATCH=(10,10))


Fichero de salida:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
0000000020000000000JAVIER    MARTINEZ  CARRETEROASALARIADO
0000000060000000000ANTONIO   VILLA     SUSO     AUTONOMO
0000000050000000000YOLANDA   LOPEZ     ALONSO   AUTONOMO
0000000010000000000JOSE      LOPEZ     PITA     AUTONOMO
0000000040000000000CARLOS    POLO      DEL BARROAUTONOMO
0000000030000000000CARLOS    PEREZ     FANO     AUTONOMO


OUTREC – Máscaras de edición

Las máscaras de edición son una utilidad muy potente del outrec que nos permite manipular el formado de cualquier campo del fichero. Dado que es bastante amplio, reservamos esta parte para otro artículo exclusivo para ello.

Otras opciones del OUTREC:
Ver Sort vol.2.1.: OUTREC. IFTHEN