martes, 2 de noviembre de 2010

Mi primer programa de cruce. Cruce 1-1.

El programa de cruce de ficheros más sencillo es el denominado 1-1. Esto significa que el valor de los campos que vamos a comparar sólo estará una vez en cada fichero.

El campo de comparación se suele llamar "campo clave" o simplemente "clave". Este campo clave existirá en ambos ficheros y tendrá el mismo formato (PIC) en ambos. De no ser así tendríamos que formatear uno de ellos para que coincidan los formatos.

OJO! los ficheros de un programa de cruce siempre vendrán ordenados por el campo clave.

JCL:

//******************************************************
//******************** BORRADO *************************
//BORRADO EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEL FICHERO.ENTRADA1.ORDENADO

DEL FICHERO.ENTRADA2.ORDENADO
DEL FICHERO.SALIDA.CRUCE
SET MAXCC = 0
//******************************************************
//* ORDENAMOS EL FICHERO ENTRADA1 POR CLAVE *********
//SORT01 EXEC PGM=SORT
//SORTIN   DD DSN=FICHERO.ENTRADA1,DISP=SHR
//SORTOUT  DD DSN=FICHERO.ENTRADA1.ORDENADO,
//            DISP=(,CATLG),SPACE=(TRK,(50,10))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(1,1,CH,A)

//******************************************************
//* ORDENAMOS EL FICHERO ENTRADA2 POR CLAVE *********
//SORT01 EXEC PGM=SORT
//SORTIN   DD DSN=FICHERO.ENTRADA2,DISP=SHR
//SORTOUT  DD DSN=FICHERO.ENTRADA2.ORDENADO,
//            DISP=(,CATLG),SPACE=(TRK,(50,10))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=(1,1,CH,A)

//******************************************************
//*********** EJECUCION DEL PROGRAMA PRUEBA7 ***********
//PROG4 EXEC PGM=PRUEBA7
//SYSOUT  DD SYSOUT=*
//FICHERO1 DD DSN=FICHERO.ENTRADA1.ORDENADO,DISP=SHR
//FICHERO2 DD DSN=FICHERO.ENTRADA2.ORDENADO,DISP=SHR
//SALIDA   DD DSN=FICHERO.SALIDA.CRUCE,
//            DISP=(NEW, CATLG, DELETE),SPACE=(TRK,(50,10)),
//            DCB=(RECFM=FB,LRECL=1)
/*


Programa:
La base del proceso de un programa de cruce es la comparación de las claves:

3000-PROCESO.

EVALUATE TRUE
   WHEN CLAVE1 = CLAVE2

        (...)
   WHEN CLAVE1 < CLAVE2

        (...)
   WHEN CLAVE1 > CLAVE2

        (...)
END-EVALUATE
.


En cada WHEN pondremos el código de lo que queremos hacer. Por ejemplo, cuando las claves coincidan, escribiremos un registro en un fichero de salida.

EVALUATE TRUE
   WHEN CLAVE1 = CLAVE2

        PERFORM ESCRIBE-SALIDA-CRUCE
        PERFORM LEER-FICHERO1
        PERFORM LEER-FICHERO2
   WHEN CLAVE1 < CLAVE2

        DISPLAY 'CLAVE1 NO EXISTE EN FICHERO2'
        PERFORM LEER-FICHERO1
   WHEN CLAVE1 > CLAVE2

        DISPLAY 'CLAVE2 NO EXISTE EN FICHERO1'
        PERFORM LEER-FICHERO2
END-EVALUATE
.


Este proceso se repetirá X veces dependiendo del tratamiento que queramos hacer:
1.Proceso hasta final del fichero 1: cuando queremos tratar todos los registros del fichero 1, existan o no en el fichero 2.
2.Proceso hasta final del fichero 1 y final del fichero 2: cuando queremos tratar todos los registros de los 2 ficheros. Esto incluye los registros comunes a ambos ficheros, los registros del fichero 1 que no están en el fichero 2 y los registros del fichero 2 que no están el fichero 1.
3.Proceso hasta final del fichero 1 o final del fichero2: cuando sólo queremos tratar los registros coincidentes. En el momento en que uno de los ficheros se termine, no volveremos a tener claves coincidentes por lo que no tiene sentido continuar la ejecución.

Para verlo más claro pongamos un ejemplo:

En el INICIO del programa, leeremos el primer registro de cada fichero e informaremos los campos CLAVE1 y CLAVE2:

1000-INICIO.


    PERFORM LEER-FICHERO1
    PERFORM LEER-FICHERO2
    .


Donde:
LEER-FICHERO1.
    

    READ FICHERO1 INTO WX-ENTRADA1

    EVALUATE FS-FICHERO1
       WHEN ZEROES
            MOVE WX-ENTRADA1 TO CLAVE1
       WHEN 10
            SET FIN-FICHERO1 TO TRUE
       WHEN OTHER
            PERFORM 3000-FINAL
    END-EVALUATE
    .

LEER-FICHERO2.
Lo mismo que para Fichero1.


Después de la primera lectura:
CLAVE1 = 1; CLAVE2 = 1.

Repetiremos el proceso hasta llegar al final de alguno de los 2 ficheros.
PERFORM 3000-PROCESO
  UNTIL FIN-FICHERO1
     OR FIN-FICHERO2


a) CLAVE1 = CLAVE2:
Escribimos en el fichero de salida:
ESCRIBIR-SALIDA-CRUCE.
    MOVE CLAVE1 TO WX-SALIDA

    WRITE REG-SALIDA FROM WX-SALIDA

    IF FS-SALIDA-OK
       INITIALIZE WX-SALIDA
    ELSE
       DISPLAY 'ERROR EN WRITE DEL FICHERO:'FS-SALIDA
    END-IF 

    .

Leemos el siguiente registro del fichero 1: PERFORM LEER-FICHERO1
CLAVE1 = 2.
Leemos el siguiente registro del fichero 2: PERFORM LEER-FICHERO2
CLAVE2 = 3.

b) CLAVE1 < CLAVE2:
Esto significa que la CLAVE1 no existe en el fichero 2.
Leemos el siguiente registro del fichero 1: PERFORM LEER-FICHERO1
CLAVE1 = 5.

c) CLAVE1 > CLAVE2:
Esto significa que la CLAVE2 no existe en el fichero 1.
Leemos el siguiente registro del fichero 2: PERFORM LEER-FICHERO2
CLAVE2 = 5.

El tratamiento que hagamos en cada uno de los casos es indiferente para el proceso de cruce. Lo importante es el orden en el que leemos los ficheros.

Para terminar vamos a ver como serían las lecturas en caso de que el proceso se repita hasta final de los dos ficheros:
LEER-FICHERO1.
    READ FICHERO1 INTO WX-ENTRADA1

    EVALUATE FS-FICHERO1
       WHEN ZEROES
            MOVE WX-ENTRADA1 TO CLAVE1
       WHEN 10
            SET FIN-FICHERO1 TO TRUE
            

            MOVE HIGH-VALUES TO CLAVE1
       WHEN OTHER
            PERFORM 3000-FINAL
    END-EVALUATE
    .


LEER-FICHERO2.
Lo mismo que para Fichero1.


Como podéis ver hemos informado la clave con HIGH-VALUES. Esto significa que cuando finalize el fichero1, la CLAVE1 va a ser siempre mayor que la clave 2, y en el EVALUATE donde comparamos las claves, siempre entrará por el tercer WHEN.
Una vez leido todo el fichero1, el programa seguirá ejecutándose leyendo del fichero2, hasta que éste también finalice.

Y ya está, nuestro primer programa de cruce está listo : )

15 comentarios:

Álvaro dijo...

Hola. Por fin alguien crea un foro decente de cobol en este país. Otros no entran al detalle en los programas y solo se dedican a las sentencias básicas de cobol, y eso ayuda poco.
Chapó por el blog!!

carlos dijo...

muy interesante estudie esto hace 20 años, y la verdad es q no recuerdo nada, un refresco a la memoria siempre biene bien. pero creeis de la utilidad, y o aplicación del cobol al dia de hoy......?

Anónimo dijo...

JODEIS HERMANOS EN MEXICO SE OCUPA MUCHO EL COBOL GRACIAS TIOS POR ESTA AYUDA

Tallian dijo...

@Anónimo: de nada! Intentamos echar una mano a los compañeros de profesión : )

@carlos: hoy día se sigue utilizando en la mayoría de bancos/cajas. He pasado por unos cuantos y si no es COBOL, es PL/I. Y hay demanda de profesionales, no hay más que ver el artículo que publicamos sobre el mercado laboral en España en el mundillo de la programación (http://www.consultoriocobol.com/2011/04/estudio-del-mercado-laboral-espanol.html) : )
Y esperemos que aguante muchos años más! jaja

Anónimo dijo...

carlos tu as buscado trabajo alguna vez de cobol?jeje sobra

Anónimo dijo...

Hola el mapa epidemiologico de hambre - obesidad - 12423 enfermedades CIE-xx - control de inmunizacion y en total 19 observatorios esta construido en Cobol - wow vea imagenes
Imagenes de Software MapaSoft-Sisdinutri

http://www.mapadehambre.com/e-pantallas.HTM

Anónimo dijo...

necesito una ayuda tengo un archivo plano y necesito convertir los decimales a comp-3 se que debo hacerlo en cobol me prodrian ayudar

Anónimo dijo...

Ola, boa noite!
Parabens pelo seu site, estive olhando ele como um todo.
Tambem tenho um site de cobol e mais coisas:
www.cadcobol.com

Um grande abraço.

DORNELLES Carlos Alberto
Analista de Sistemas Senior
Indra Company
Brasilia - DF - Brasil

Loboc dijo...

Gracias Dornelles! Un saludo.

Tallian dijo...

Información muy interesante en www.cadcobol.com
Para los gallegos es bastante fácil de entender :P

Bo traballo!

Marcos Hernán García dijo...

Todo esto se puede hacer en un solo paso con un sort usando joinkeys. Y te admite full joins.

Anónimo dijo...

hace falta un compilador, cual recomiendas y si lo puedes proporcionar por favor.
basuracibernetic@gmail.com

Azael Gonzalez Martinez dijo...

muy buen aporte para este tipo de cruce!!

Unknown dijo...

Mil gracias! Muy fino escrito :)

arcoe dijo...

muy buena explicación, me ha sido de mucha ayuda