Bueno, en el tocho de hoy, vamos a centrarnos en como crear un programa COBOL que mediante una transacción CICS, se ejecute y nos saque por pantalla un "Hola Mamones". Pero antes de meternos en el rollo de programar, primero hay que aclarar una serie de conceptos de CICS.
Para empezar, una transacción CICS puede ser de muy diversa índole y puede ser lanzada de muchas maneras: La puedes teclear en tu terminal, la puedes lanzar por un socket, o incluso puedes hacer un FTP y lanzar un JCL que a su vez lance una transacción, siempre y cuando se cumplan los requisitos de seguridad, y demás que obviaremos porque me eternizaría (aun mas). En nuestro caso, vamos a centrarnos en la parte más tradicional del CICS, es decir, que un usuario teclee una transacción y le salga por pantalla un mensaje.
Ni que decir tiene que CICS es un sistema muy robusto, tanto, que se queja por todo. Pero por TO-DO. Esa es una de las razones por las que es muy difícil que se cuelgue un programa, porque tienes que tener en cuenta todas las variables posibles de error y codificarlas, porque de lo contrario, CICS cancela la transacción así por las buenas, y con un bonito ABEND de regalo. Así que hay que tener cuidado a la hora de programar, pero no os preocupéis, el programa que vamos a codificar es tan sencillo que no hará falta realizar ningún tipo de control de errores. De hecho, ni siquiera lo haremos pseudo-conversacional, porque solo haremos que se muestre un mensaje y saldremos del programa, con lo que el CICS finalizará la transacción. No obstante, si os animáis, en una entrega posterior, podemos complicar un poco el programa para que veáis más conceptos de CICS.
Así que vamos al meollo de la cuestión: Hemos hablado de Transacciones, de Programas y de Pantallas de usuario. Pues en CICS hay que crear las 3 cosas: Hay que crear un programa, hay que crear la transacción que llamará al programa, y hay que crear la pantalla del usuario. Empezaremos por este último paso.
Creación de la Pantalla
Una Pantalla de usuario, o, en la jerga CICSera, mapa BMS (Basic Mapping Support), es una plantilla de lo que queremos que aparezca por la pantalla del terminal cuando invoques a la transacción: Puede ser un título, o unos campos a rellenar, o cualquier cosa que se te ocurra en 24 lineas por 80 columnas. En nuestro caso, pondremos un cuadrado mas o menos centrado y su interior, el texto Hola Mamones, y podemos utilizar alguna característica 3270, como poner un color, por ejemplo. Todo esto lo voy a hacer a mano, pero existen muchas herramientas como VisualAge por ejemplo que te hacen las pantallas automáticamente. Pero a mi me gusta mas hacerlo a mano, porque se optimiza mucho mas el código (si, también me gusta escribir HTML en el Notepad, ¿pasa algo? xDDD).
Un MAPSET es un conjunto de mapas, que, al igual que los <div>
de las
webs, pueden definir regiones dentro de la pantalla que cada una tenga
características distintas, pero en nuestro caso, vamos a crear un mapset
y un mapa que ocupe toda la pantalla, para hacerlo mas fácil. El código que
yo he hecho ha sido este:
HOLAMP DFHMSD TYPE=DSECT,MODE=INOUT,TERM=ALL,STORAGE=AUTO,LANG=COBOL HOLAMP DFHMDI SIZE=(24,80),LINE=1,COLUMN=1,COLOR=GREEN,HILIGHT=OFF, X MAPATTS=(COLOR,HILIGHT),DSATTS=HILIGHT,CTRL=FREEKB DFHMDF POS=(10,10),LENGTH=20,INITIAL='********************', X COLOR=BLUE,ATTRB=(ASKIP,NORM) DFHMDF POS=(11,10),LENGTH=20,INITIAL='* *', X COLOR=BLUE,ATTRB=(ASKIP,NORM) DFHMDF POS=(12,10),LENGTH=20,INITIAL='* HOLA, MAMONES! *', X COLOR=BLUE,ATTRB=(ASKIP,NORM) DFHMDF POS=(13,10),LENGTH=20,INITIAL='* *', X COLOR=BLUE,ATTRB=(ASKIP,NORM) DFHMDF POS=(14,10),LENGTH=20,INITIAL='********************', X COLOR=BLUE,ATTRB=(ASKIP,NORM) DFHMSD TYPE=FINAL END
Tanto al mapset como al mapa, lo he llamado HOLAMP. También guardaremos el fichero con el mismo nombre, ya que el CICS va a ir a buscar ese fichero y debe coincidir con el nombre del mapa. Como podréis ver, hay 3 tipos de “instrucciones”:
-
DFHMSD, hace referencia al MAPSET. Tiene una serie de variables que no comentaré aquí porque me alargaría todavía más, pero ya veis que el subtipo TYPE da la referencia de donde empieza y donde acaba.
-
DFHMDI, hace referencia al MAPA en cuestión, y como podréis ver entre otros parámetros, muestra el tamaño de dicho mapa.
-
DFHMDF, hace referencia a los CAMPOS de ese mapa. Cada campo puede ser editable o no, y podría cada uno tener colores distintos, etc. También se le indica la posición de ese campo dentro del mapa con el parámetro POS. En nuestro caso, este mapa solo va a mostrar datos, nada mas, por lo que en el campo INITIAL pondremos el contenido que queramos poner, en nuestro caso, el banner, y queremos que sea de color azul.
Con esto, ya tenemos los datos que saldrán por pantalla. Lo siguiente que haríamos, será compilar dicho mapa con el compilador de COBOL, con un JCL, finalizado el cual dejará dos ficheros: Uno, el mapa compilado y linkeditado que usará el CICS para mostrarlo por pantalla, y el otro, la COPY del mapa. Este último fichero sirve para que, añadiéndolo al programa en la WORKING-STORAGE SECTION, el programa tenga la referencia de a que llamar para que el CICS lo llame.
Generalmente, este fichero si tuviera campos editables y para rellenar, sería muy larga, porque todo mapa tiene un campo que se trata como entrada (I) que es cuando el usuario ha introducido algo, y otro que se trata como Salida(O) que es cuando el CICS le debe responder en un campo. Por ejemplo, si tuviéramos un campo llamado DNI para rellenar, el compilador haría 2 Redefines de ese campo: DNII cuando el usuario Introduzca el DNI, y DNIO cuando el programa quiera escribir ahí un DNI de una base de datos, por ejemplo. El caso es que nos ha salido un churro como este:
01 HOLAMP PIC X(100). 01 HOLAMPI REDEFINES HOLAMP. 02 FILLER PIC X(12). 01 HOLAMPO REDEFINES HOLAMPI. 02 FILLER PIC X(12).
Traduciendo, el mapa ocupará 100 bytes, y luego deja 12 bytes (no me digáis para que, que no tengo ni idea), y como no tiene campos editables de entrada ni de salida, el mapa de entrada HOLAMPI es redefinido con el de salida (HOLAMPO). Pues esas 5 líneas las pegaremos en nuestro programa COBOL cuando lo escribamos, en la zona WORKING-STORAGE SECTION.
Creación del programa
Lo malo del COBOL, es que es estricto de narices en su escritura y su estructura, y un espacio de más o de menos en ciertas columnas puede hacer que el programa (por ejemplo, los comentarios empiezan con asterisco en la columna 8, y solo en la 8) dé mil quebraderos de cabeza. Lo bueno, es que una vez superada esa tocada de narices, programas líneas una detrás de otra como si estuvieras manteniendo una conversación en ingles, y es tremendamente fácil y potente. Para mí, mucho más fácil que JAVA o C. Sin mas, el programa sería algo tan sencillo como esto:
************************************************* * * PROGRAMA HOLA MAMONES DE CICS-COBOL * ************************************************* IDENTIFICATION DIVISION. PROGRAM-ID. HOLA. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 HOLAMP PIC X(1000). 01 HOLAMPI REDEFINES HOLAMP. 02 FILLER PIC X(12). 01 HOLAMPO REDEFINES HOLAMPI. 02 FILLER PIC X(12). * PROCEDURE DIVISION. * MOSTRAR-MAPA. EXEC CICS SEND MAP('HOLAMP') MAPONLY ERASE NOHANDLE END-EXEC. FIN-PGM. EXEC CICS RETURN END-EXEC. GOBACK.
Lo cojonudo del caso es que casi hay más líneas de código de la "estructura" obligatoria a seguir de COBOL, que lo que realmente hace el programa. Pero vamos, lo que hemos puesto es lo siguiente:
-
En la Working, hemos pegado la copy del mapa que hemos hecho antes.
-
Hemos escrito un procedimiento llamado MOSTRAR-MAPA que no hace más que un EXEC CICS enviando el mapa. Con la opción MAPONLY, te curas en salud y te pasas por el forro la gestión de errores porque con esto le dices al CICS que solo va a mostrar un mapa, y que el usuario no va a teclear nada más.
-
Y hemos escrito otro procedimiento llamado FIN-PGM que lo que hace es devolver el control al CICS. Como van seguidos, una vez ejecutado el MOSTRAR-MAPA, ejecutará este y por lo tanto, saldrá del CICS.
Con otro JCL, compilaremos dicho programa y su programa "linkeditado" se quedará en una librería que el CICS tenga configurada como de carga de programas (al igual que el mapa), y deberá llamarse igual que el PROGRAM-ID que hemos puesto (en nuestro caso, el fichero se llamará HOLA).
Creación de la Transacción y definición en el CICS
Bueno, estamos en la recta final del tocho. Ahora que tenemos el programa y el mapa compilados, hay que molestar al CICS para decirle que tiene disponibles un programa y un mapa para que vía una transacción, muestre todo. Para ello, la herramienta que utilizaremos para molestar al CICS es la transacción CEDA.
Usando la CEDA (no tiene nada que ver con ceder el paso xDDD), definiremos la transacción, el programa y el mapa. CICS, para poder administrarse mejor, esta dividido en Grupos de aplicaciones, ya que si no, nos volveríamos locos si tenemos miles de programas y hay que buscar alguno en concreto. Es por ello, que crearemos un grupo llamado HOLA, en el que definiremos el programa, la transacción y el mapa. Decir también que el grupo se crea cuando creemos el primer miembro del grupo, por ejemplo, si empezamos definiendo el programa, y siempre que tengamos los permisos adecuados para ejecutar la transacción CEDA, haremos lo siguiente:
CEDA DEF PROG (HOLA) GROUP (HOLA)
Ahora, definiremos el mapa con el comando siguiente:
CEDA DEF MAP (HOLAMP) GROUP (HOLA)
Y por último, definiremos la transacción, la llamaremos HOLA (como tiene 4 caracteres, va que ni pintado) y le pondremos como parámetro cual es el programa que tiene que llamar en primer lugar, que, como en nuestro caso es HOLA, pues lo pondremos así:
CEDA DEF TRANS(HOLA) PROG(HOLA) GROUP(HOLA)
Bien, hasta aquí tenemos todo definido. Si hacemos un CEDA DI GROUP (HOLA), aparecerá una lista tal que esta:
DI GROUP(HOLA) ENTER COMMANDS NAME TYPE GROUP DATE TIME HOLAMP MAPSET HOLA 07.137 13.00.01 HOLA PROGRAM HOLA 07.137 12.59.45 HOLA TRANSACTION HOLA 07.137 12.59.32
Pero faltan dos pasos todavía: Hay que INSTALAR lo definido para que el CICS lo recuerde siempre a partir de ahora, y eso con poner una I a continuación del grupo en las tres líneas, y damos al enter, se instalará todo, y debería quedarse la pantalla algo como esto:
DI GROUP(HOLA) ENTER COMMANDS NAME TYPE GROUP DATE TIME HOLAMP MAPSET HOLA i INSTALL SUCCESSFUL HOLA PROGRAM HOLA i INSTALL SUCCESSFUL HOLA TRANSACTION HOLA i INSTALL SUCCESSFUL
¿Ya estamos listos? No. Falta un último paso: Cargar el programa. Con la CEDA, hemos definido el programa y lo hemos instalado, pero con eso no basta, el código binario del programa se debe cargar en la región del CICS, para así poder ser ejecutado. Con el mapa no es necesario, porque es el programa quien llama al mapa, pero el programa debe estar siempre cargado. Así que haremos uso de la transacción CEMT para cargarlo.
Si hacemos un CEMT S PROG(HOLA), tendría que salir algo similar a esto:
S PROG(HOLA) STATUS: RESULTS - OVERTYPE TO MODIFY Prog(HOLA ) Leng(0000000000) Cob Pro Ena Pri Ced Res(000) Use(0000000000) Bel Uex Ful Qua
Como podréis observar, el campo Leng está a ceros, es decir, el CICS sabe que tiene algo reservado, pero no está ocupado. Así que si ponemos el cursor entre el campo Pri y el campo Ced, y tecleamos una N (Newcopy), al pulsar Enter el valor de Leng debe cambiar y mostrar el tamaño en bytes del programa, quedando algo así como esto:
S PROG(HOLA) STATUS: RESULTS - OVERTYPE TO MODIFY Prog(HOLA ) Leng(0000004736) Cob Pro Ena Pri N Ced NORMAL Res(000) Use(0000000000) Bel Uex Ful Qua
Pues bien, ya está todo preparado. Si tecleamos en nuestra pantalla, la transacción HOLA, veremos lo siguiente:
******************** * * * HOLA, MAMONES! * * * ********************
Y con esto, se acaba la transacción, y evidentemente ha sido instantánea.
Si lo pedís y estáis interesados, podría escribir en otra entrega la manera de complicar un poquito el programa y hacer que interactúe el usuario, de tal forma, que según la opción que teclee, le salga un mensaje u otro, y todo de manera conversacional.
Comentarios