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

lunes, 28 de diciembre de 2020

SORT vol.1: SORT, INCLUDE.

ACTUALIZADO: comparando zonas de un mismo registro con INCLUDE.

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,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:

SORT

SORT FIELDS --> Ordena los registros a partir del fichero de entrada y los guarda ordenados 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=(I,L,T,O,I,L,T,O)

I – Inicio. Posición donde empieza el campo por el que se quiere ordenar
L – Longitud máxima del campo por el que se quiere ordenar
T – Tipo de dato del campo que se quiere ordenar:
       CH --> Alfanumérico o numérico normal(sin COMP)
       BI --> Hexadecimal (campos COMP)
       PD --> Empaquetado con o sin signo(campos COMP-3)
O – Orden. A-Ascendente, D- Descendente

Ejemplo:

Ordenar el siguiente fichero por Número y Nombre de cliente en orden ascendente:

----+----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

Fórmula:

SORT FIELDS=(1,9,CH,A,10,10,CH,A)

Resultado:

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

Otra opción que tiene el SORT es la siguiente:

SORT FIELDS=COPY

Con ella no indicamos ningún tipo de orden, por lo cual, el fichero de entrada se grabará en salida con el mismo orden.


INCLUDE

Filtra los registros deseados por la condición que se indique:

//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
 INCLUDE COND=(I,L,T,C,V)

I – Inicio. Posición donde empieza el campo por el que se quiere filtrar
L – Longitud máxima del campo por el que se quiere filtrar
T – Tipo de dato del campo que se quiere filtrar:
       CH - Carácter o numérico normal(sin COMP)
       BI - Hexadecimal (campos COMP)
C – Condición de la igualdad que se quiere realizar:
       EQ – Igual
       NE - Distinto
       GE – Mayor o igual
       GT - Mayor
       LE – Menor o igual
       LT - Menor
V – Valor del dato por el que se quiere filtrar
       X’001A‘ – Indica un valor hexadecimal o empaquetado
       C’AL12’ – Indica un valor alfanumérico

Ejemplos:

Ejemplo 1. Vamos a realizar un paso de SORT que realice un filtrado del fichero indicado, para quedarse con los clientes que cumplan lo siguiente: Sean AUTONOMOS y su número de teléfono sea un móvil (comience por 6):

Copy:

01 ENTRADA1.
   05 ENTRADA1-NUMCLI    PIC 9(9).
   05 ENTRADA1-NOMBRE    PIC X(10).
   05 ENTRADA1-APELLID1  PIC X(10).
   05 ENTRADA1-APELLID2  PIC X(10).
   05 ENTRADA1-TIPO      PIC X(11).
   05 ENTRADA1-CATEGORIA PIC 9(9) COMP-3.
   05 ENTRADA1-TLFNO     PIC 9(9).
   05 FILLER             PIC X(9) VALUE SPACES.

Fichero entrada:

=COLS>
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      983275586
FFFFFFFFFDCECCD4444DCDECDCE44CCDDCECDDCECDCDCCCD400001FFFFFFFFF444444444
00000000211595900004193955900319953596121319914600000C983275586000000000
------------------------------------------------------------------------
000000006ANTONIO   VILLA     SUSO     AUTONOMO        918514535
FFFFFFFFFCDEDDCD444ECDDC44444EEED44444CEEDDDDD44400003FFFFFFFFF444444444
00000000615365960005933100000242600000143656460000000C918514535000000000
------------------------------------------------------------------------
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        988453548
FFFFFFFFFEDDCDCC444DDDCE44444CDDDED444CEEDDDDD44400001FFFFFFFFF444444444
00000000586315410003675900000136526000143656460000000C988453548000000000
------------------------------------------------------------------------
000000001JOSE      LOPEZ     PITA     AUTONOMO        676757687
FFFFFFFFFDDEC444444DDDCE44444DCEC44444CEEDDDDD44400001FFFFFFFFF444444444
00000000116250000003675900000793100000143656460000000C676757687000000000
------------------------------------------------------------------------
000000004CARLOS    POLO      DEL BARROAUTONOMO        666415887
FFFFFFFFFCCDDDE4444DDDD444444CCD4CCDDDCEEDDDDD44400003FFFFFFFFF444444444
00000000431936200007636000000453021996143656460000000C666415887000000000
------------------------------------------------------------------------
000000003CARLOS    PEREZ     FANO     AUTONOMO        986115484
FFFFFFFFFCCDDDE4444DCDCE44444CCDD44444CEEDDDDD44400001FFFFFFFFF444444444
00000000331936200007595900000615600000143656460000000C986115484000000000
------------------------------------------------------------------------

Fórmula:

INCLUDE COND=(39,8,CH,EQ,C'AUTONOMO',AND,55,1,CH,EQ,C'6')


Fichero salida:

=COLS> ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000001JOSE      LOPEZ     PITA     AUTONOMO        676757687
FFFFFFFFFDDEC444444DDDCE44444DCEC44444CEEDDDDD44400001FFFFFFFFF444444444
00000000116250000003675900000793100000143656460000000C676757687000000000
-------------------------------------------------------------------------
000000004CARLOS    POLO      DEL BARROAUTONOMO        666415887
FFFFFFFFFCCDDDE4444DDDD444444CCD4CCDDDCEEDDDDD44400003FFFFFFFFF444444444
00000000431936200007636000000453021996143656460000000C666415887000000000
-------------------------------------------------------------------------


Ejemplo 2. Vamos a realizar un paso de SORT similar al anterior, que realice un filtrado del fichero indicado, para quedarse con los clientes que cumplan lo siguiente: Sean AUTONOMOS y su número de teléfono sea un móvil (comience por 6). Pero en este caso el número de teléfono vendrá empaquetado(COMP-3):

Copy:

01 ENTRADA1.
   05 ENTRADA1-NUMCLI    PIC 9(9).
   05 ENTRADA1-NOMBRE    PIC X(10).
   05 ENTRADA1-APELLID1  PIC X(10).
   05 ENTRADA1-APELLID2  PIC X(10).
   05 ENTRADA1-TIPO      PIC X(11).
   05 ENTRADA1-CATEGORIA PIC 9(9) COMP-3.
   05 ENTRADA1-TLFNO     PIC 9(9) COMP-3.
   05 FILLER             PIC X(13) VALUE SPACES.

Fichero entrada:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO      q Íì%
FFFFFFFFFDCECCD4444DCDECDCE44CCDDCECDDCECDCDCCCD400001937564444444444444
00000000211595900004193955900319953596121319914600000C8258C0000000000000
-----------------------------------------------------------------------
000000006ANTONIO   VILLA     SUSO     AUTONOMO        q Î %
FFFFFFFFFCDEDDCD444ECDDC44444EEED44444CEEDDDDD44400003937164444444444444
00000000615365960005933100000242600000143656460000000C8265C0000000000000
-----------------------------------------------------------------------
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO        o ÍÌ 
FFFFFFFFFEDDCDCC444DDDCE44444CDDDED444CEEDDDDD44400001937724444444444444
00000000586315410003675900000136526000143656460000000C6858C0000000000000
-----------------------------------------------------------------------
000000001JOSE      LOPEZ     PITA     AUTONOMO        #jéì%
FFFFFFFFFDDEC444444DDDCE44444DCEC44444CEEDDDDD44400001695564444444444444
00000000116250000003675900000793100000143656460000000C9118C0000000000000
-----------------------------------------------------------------------
000000004CARLOS    POLO      DEL BARROAUTONOMO        ÅÂÌì%
FFFFFFFFFCCDDDE4444DDDD444444CCD4CCDDDCEEDDDDD44400003667564444444444444
00000000431936200007636000000453021996143656460000000C7288C0000000000000
-----------------------------------------------------------------------
000000003CARLOS    PEREZ     FANO     AUTONOMO        m nç%
FFFFFFFFFCCDDDE4444DCDCE44444CCDD44444CEEDDDDD44400001939464444444444444
00000000331936200007595900000615600000143656460000000C4558C0000000000000
-----------------------------------------------------------------------

Fórmula:

 INCLUDE COND=(39,8,CH,EQ,C'AUTONOMO',AND,
    (55,5,BI,GE,X'600000000C',AND,55,5,BI,LT,X'700000000C'))

Resultado:

----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000001JOSE      LOPEZ     PITA     AUTONOMO        #jéì%
FFFFFFFFFDDEC444444DDDCE44444DCEC44444CEEDDDDD44400001695564444444444444
00000000116250000003675900000793100000143656460000000C9118C0000000000000
------------------------------------------------------------------------
000000004CARLOS    POLO      DEL BARROAUTONOMO        ÅÂÌì%
FFFFFFFFFCCDDDE4444DDDD444444CCD4CCDDDCEEDDDDD44400003667564444444444444
00000000431936200007636000000453021996143656460000000C7288C0000000000000
------------------------------------------------------------------------


NOTA: a la hora de comparar con valor (EQ, NE, GT...) podemos utilizar para la comparación otra zona del fichero:

Fichero entrada:
----+----1----+----2-
XXXXX111111XXXXX
YYYYY111111XXXXX
ZZZZZ111111ZZZZZ
WWWWW111111XXXXX

Fórmula:
INCLUDE COND =(1,5,CH,EQ,12,5,CH)

Resultado:
----+----1----+----2-
XXXXX111111XXXXX
ZZZZZ111111ZZZZZ

Hemos comparado las posiciones 1 a 5 con las posiciones 12 a 16 del mismo registro.

lunes, 14 de febrero de 2011

Sentencia SORT en un programa COBOL

Hemos visto en otros artículos como hacer un SORT en un JCL. En este artículo veremos como hacerlo en un programa cobol.
¿Utilidad? Depende. Lo cierto es que pudiendo hacerlo por JCL, no tiene caso hacerlo en un programa. Pero quién sabe! Tal vez alguno de los lectores puedan darnos una idea de su uso práctico : D

SORT:

La sentencia SORT en cobol sirve para ordenar registros por un campo clave que le indiquemos. Podremos elegir varias claves y definir si el orden será ascendente o descendente.
Para el ejemplo, hemos creado un fichero temporal en nuestro programa que utilizaremos para generar en él la información ordenada. Como registros a ordenar, utilizaremos una tabla interna, de tal forma que no necesitaremos utilizar ficheros en ningún momento.
La información ordenada se cargará desde el fichero temporal al registro de salida, que podría utilizarse a lo largo de la ejecución.
Nosotros nos pararemos cuando tengamos nuestra información ordenada, y la "displayaremos" mostrándola por SYSOUT.

 IDENTIFICATION DIVISION.
 PROGRAM-ID. PRGSORT.
*
 ENVIRONMENT DIVISION.
 CONFIGURATION SECTION.
 SPECIAL-NAMES.
 DECIMAL-POINT IS COMMA.
*
 INPUT-OUTPUT SECTION.
 FILE-CONTROL.
* Fichero temporal donde guardaremos la información ordenada
 SELECT TABLA-SORT ASSIGN TO DISK "SORTWORK".
*
 DATA DIVISION.
 FILE SECTION.
* Definición del fichero temporal
 SD TABLA-SORT
 DATA RECORD IS ELEMENTO-SORT.
 01 ELEMENTO-SORT.
    05 SORT-CLAVE1 PIC X.
    05 SORT-CLAVE2 PIC X(3).
    05 SORT-CAMPO PIC X(10).
    05 SORT-INDICADOR PIC X.
*
 WORKING-STORAGE SECTION.
* Formato del registro de salida
 01 VARIABLES.
    05 WA-REGISTRO.
       10 WA-SORT-CLAVE1 PIC X.
       10 WA-SORT-CLAVE2 PIC X(3).
       10 WA-SORT-CAMPO PIC X(10).
       10 WA-SORT-INDICADOR PIC X.
* Switches que utilizaremos en los bucles
 01 SWITCHES.
    05 SW-FIN-TABLA-SORT PIC X(1).
       88 SI-FIN-TABLA-SORT VALUE 'S'.
       88 NO-FIN-TABLA-SORT VALUE 'N'.
* Tabla interna con los datos a ordenar
 01 TABLA.
    05 WT-TBL-LISTA.
       10 PIC X(15) VALUE 'F216CAMPO02802S'.
       10 PIC X(15) VALUE 'M144CAMPO17114N'.
       10 PIC X(15) VALUE 'Q651CAMPO24536S'.
       10 PIC X(15) VALUE 'F217CAMPO03312N'.
       10 PIC X(15) VALUE 'T487CAMPO44914S'.
       10 PIC X(15) VALUE 'O372CAMPO52113N'.
       10 PIC X(15) VALUE 'F457CAMPO61224N'.
       10 PIC X(15) VALUE 'L547CAMPO73985N'.
       10 PIC X(15) VALUE 'L354CAMPO89173N'.
       10 PIC X(15) VALUE 'W516CAMPO92815N'.
    05 REDEFINES WT-TBL-LISTA.
       10 WT-TBL-ELEMENTO OCCURS 15
                           INDEXED BY WI-ELEM.
          15 WT-TBL-CLAVE1 PIC X.
          15 WT-TBL-CLAVE2 PIC X(3).
          15 WT-TBL-CAMPO PIC X(10).
          15 WT-TBL-INDICADOR PIC X.
* Formato del registro a ordenar
 01 WR-ELEMENTO-SORT.
   05 WR-SORT-CLAVE1 PIC X.
   05 WR-SORT-CLAVE2 PIC X(3).
   05 WR-SORT-CAMPO PIC X(10).
   05 WR-SORT-INDICADOR PIC X.
*
 PROCEDURE DIVISION.
*
    PERFORM 1000-INICIO
    PERFORM 2000-PROCESO
    PERFORM 9000-FINAL
    .
*
 1000-INICIO.
*
    INITIALIZE VARIABLES
    .
*
 2000-PROCESO.
* Proceso de SORT
* Indicamos las claves por las que ordenaremos ON ASCENDING ó 

* ON DESCENDING

    SORT TABLA-SORT
     ON ASCENDING KEY SORT-CLAVE1
     ON DESCENDING KEY SORT-CLAVE2
     INPUT PROCEDURE 2100-PROCESO-ENTRADA
     OUTPUT PROCEDURE 2200-PROCESO-SALIDA
* En la INPUT PROCEDURE cargamos los datos a ordenar
* En la OUTPUT PROCEDURE guardamos la información ordenada 

* en variables del programa

* Controlamos el retorno del SORT con SORT-RETURN
    IF SORT-RETURN NOT = ZEROS
       DISPLAY 'ERROR EN EL SORT:' SORT-RETURN
    END-IF
    .
*
 2100-PROCESO-ENTRADA.
* Cargamos los datos a ordenar(los de la tabla interna) en el

* fichero temporal donde se realizará la ordenación
* (ELEMENTO-SORT) con la sentencia RELEASE.
    PERFORM VARYING WI-ELEM
       FROM 1 BY 1
      UNTIL WT-TBL-CLAVE1(WI-ELEM) = LOW-VALUES
            OR WI-ELEM = 16
*
        MOVE WT-TBL-CLAVE1(WI-ELEM) TO WR-SORT-CLAVE1
        MOVE WT-TBL-CLAVE2(WI-ELEM) TO WR-SORT-CLAVE2
        MOVE WT-TBL-CAMPO(WI-ELEM) TO WR-SORT-CAMPO
        MOVE WT-TBL-INDICADOR(WI-ELEM) TO WR-SORT-INDICADOR
*
        RELEASE ELEMENTO-SORT FROM WR-ELEMENTO-SORT
        DISPLAY 'ELEMENTO-SORT:'WR-ELEMENTO-SORT
    END-PERFORM
    .
*
 2200-PROCESO-SALIDA.
* Recuperamos los datos ordenados del fichero temporal con la

* sentencia RETURN y los displayamos
    SET NO-FIN-TABLA-SORT TO TRUE
*
    PERFORM UNTIL SI-FIN-TABLA-SORT

     RETURN TABLA-SORT INTO WR-ELEMENTO-SORT
     AT END
            SET SI-FIN-TABLA-SORT TO TRUE
     NOT AT END
            MOVE WR-SORT-CLAVE1 TO WA-SORT-CLAVE1
            MOVE WR-SORT-CLAVE2 TO WA-SORT-CLAVE2
            MOVE WR-SORT-CAMPO TO WA-SORT-CAMPO
            MOVE WR-SORT-INDICADOR TO WA-SORT-INDICADOR
*
            DISPLAY 'REGISTRO->' WA-REGISTRO
*
     END-RETURN
    END-PERFORM
    .
*
 9000-FINAL.
*
    STOP RUN
    .
*


RESULTADO:

REGISTRO->F457CAMPO61224N
REGISTRO->F217CAMPO03312N
REGISTRO->F216CAMPO02802S
REGISTRO->L547CAMPO73985N
REGISTRO->L354CAMPO89173N
REGISTRO->M144CAMPO17114N
REGISTRO->O372CAMPO52113N
REGISTRO->Q651CAMPO24536S
REGISTRO->T487CAMPO44914S
REGISTRO->W516CAMPO92815N