Alters

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

COBOL: archivos + ejemplo

Hola de nuevo!

Ya que esta será la última entrega "teórica", he decidido poner el ejemplo en esta misma.

Ahora veremos el tema de ficheros. En COBOL hay varios tipos de ficheros, cada uno con sus ventajas y desventajas. Vamos allá

Ficheros:

Como decía, hay varios tipos de ficheros. Esto no significa diversas extensiones (COBOL no mira extensiones), sino organizaciones internas, modos de acceso...

En concreto, hay tres tipos de ficheros:

 * Secuenciales
 * Indexados
 * Relativos

Explicaré un poco las características de cada tipo:

Los secuenciales son accedidos de manera secuencial (obviamente), es decir, de principio a fin. Si quieres acceder al tercer registro tienes que hacer tres lecturas, no hay más.

Los indexados pueden ser accedidos de manera secuencial o bien de manera directa (mediante clave, ya lo veremos)

Los relativos se basan en "registros", pudiendo ser accedidos de manera secuencial o directa (usando clave).

A continuación, una lista de ventajas / inconvenientes de los tipos de archivo:

 * Secuencial

Ventajas:
   - Tamaño mínimo
   - Fácilmente editable (a mano)

Inconvenientes
   - A tamaño grande, la lectura se ralentiza.
   - Acceso puramente secuencial

* Indexado

 Ventajas
   - Rápidamente accesible
   - Sistema de claves

 Inconvenientes
   - Mayor tamaño
   - Apenas editable (a mano)

* Relativo

 Ventajas
   - Claves "invisibles"
   - Acceso rápido

Inconvenientes
   - No se puede ordenar
   - Apenas editable (a mano)


Aparte de los tipos de archivo, hay lo que se denomina modo de acceso: SEQUENTIAL, RANDOM, DYNAMIC. El primero establece un acceso secuencial, el segundo aleatorio (por clave) y el tercero ambos.

Si el fichero es secuencial solo se puede acceder mediante SEQUENTIAL; en cualquier otro caso vale cualquiera.


El uso de las claves funciona de manera similar a las bases de datos; en el caso de los indexados la clave puede ser cualquier cosa (un dni, teléfono...); en los archivos relativos se usa un índice numérico, de manera transparente al usuario y al programador.


Para declarar un fichero, tenemos que extender dos DIVISION: la ENVIRONMENT y la DATA.

La declaración básica se da en la ENVIRONMENT, y en la DATA definimos simplemente la estructura. En la primera parte, la declaración tiene variaciones dependiendo del tipo de fichero; en la segunda no.

  - ENVIRONMENT SECTION:

   Para un archivo SECUENCIAL, debemos poner algo tal que:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS SEQUENTIAL
                   ACCESS MODE IS SEQUENTIAL.


Veamos: Se declara la division, una nueva section (Input-Output), y se declara un fichero mediante FILE CONTROL. Finalmente se especifica el fichero:
   * SELECT var -> asigna una variable de "volcado" para el 'archivo' (hasta 8 caracteres!), que está asignado en el disco (otra opción es, por ejemplo PRINTER).
  * ORGANIZATION IS SEQUENTIAL -> le decimos que es secuencial. Podemos no poner esta sentencia, ya que si no está, por defecto COBOL lo tomará como secuencial.

  * ACCESS MODE IS SEQUENTIAL -> le decimos el modo de acceso, en este caso el único disponible: secuencial.

Para un archivo indexado, debemos poner algo similar a esto:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS INDEXED
                   ACCESS MODE IS [SEQUENTIAL | RANDOM | DYNAMIC]
                   RECORD KEY IS var1
                   [ALTERNATE KEY IS var2 [WITH DUPLICATES]].


Revisemos el tema:

  * ORGANIZATION IS INDEXED -> le decimos que es un archivo indexado
  * ACCES MODE IS ... -> aquí especificamos el modo de acceso (explicado más arriba)
  * RECORD KEY IS var1 -> le decimos cuál es la clave (como una PK de una tabla) del archivo
  * ALTERNATE KEY IS ... -> podemos especificar una clave alternativa (como un índice). Es opcional. Si ponemos "with duplicates" (también opcional) le decimos a COBOL que aceptamos que haya duplicados en esta clave. Por defecto COBOL no acepta duplicados en ningún tipo de clave.

Finalmente, para un archivo relativo:


       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
            SELECT var ASSIGN TO DISK 'archivo'
                   ORGANIZATION IS RELATIVE
                   ACCESS MODE IS  [SEQUENTIAL | RANDOM | DYNAMIC] .

Como veis, este último no hace falta explicarlo...

Ahora falta el siguiente punto, la data division:


       DATA DIVISION.
       FILE SECTION.

       FD var LABEL RECORD STANDARD.

       01    var1.
          02 var2 PIC X.

Esto es un poco lioso, así que vamos a explicarlo bien...

Primero abrimos la file section, y a partir de ahí describimos los archivos:

 * FD var LABEL RECORD STANDARD: Es la abreviatura de "File Descriptor". var es el nombre de variable usado en la ENVIRONMENT. La label record es una cláusula que especifica una variable de control interna para los ficheros. Yo recomiendo ponerla siempre como STANDARD (la otra opción es OMITTED).

* 01 var1... -> Declaramos la estructura para var. Tal cual, como cualquier otra estructura. Si el fichero es INDEXED, en esta estructura estarán las RECORD KEY y ALTERNATE KEY.




Ahora ya podemos delcarar ficheros; pero falta usarlos.

Para usar un archivo COBOL, debemos seguir la rutina básica de toda la vida, es decir

 - Abrir archivo
 - Manipular archivo
 - Cerrar archivo

Para abrir el archivo, tenemos la siguiente cláusula:

OPEN [INPUT | OUTPUT | EXTEND | IO] var.

Se tiene que especificar una de las 4 opciones, a saber:

 * INPUT: abre el archivo solo para lectura
 * OUTPUT: abre el archivo solo para escritura (lo crea si no existe, si existe lo borra y empieza de nuevo)
 * EXTEND : abre el archivo solo para escritura (si no existe da error, si existe escribe sin borrarlo)
 * I-O: abre el archivo para lectura/escritura (el archivo tiene que existir)

Hay varias operaciones para manipular el archivo. El tema es que COBOL tiene una "tabla" de operaciones disponibles para cada modo de acceso y modo de apertura:

 - ACCESO secuencial
   * INPUT
       · READ: lee un registro
       · START: se posiciona sobre un registro
  * OUTPUT (o EXTEND)
       · WRITE: escribe un registro
  * I-O
       · READ
       · REWRITE: sobreescribe el registro almacenado
       · DELETE: borra el registro almacenado
       · START

- ACCESO aleatorio

   * INPUT
       · READ
  * OUTPUT (o EXTEND)
       · WRITE
  * I-O
       · READ
       · WRITE
       · REWRITE
       · DELETE

 - ACCESO dinamico

   * INPUT
       · READ
       · START
  * OUTPUT (o EXTEND)
       · WRITE
  * I-O
       · READ
       · WRITE
       · REWRITE
       · DELETE
       · START

Finalmente aclarar: las operaciones se hacen sobre var, y las modificaciones sobre la estructura creada.




Para terminar el tema de COBOL, dejo el SRC de mi trabajo final de COBOL. Recordad leer el README, y si vais a compartir el archivo, citad la fuente y/o la autoría, por favor :-)

http://www.mediafire.com/?4algy7xluud6ay4


Para las próximas entradas tengo varios temas pensados, dejo aquí unas posibles opciones
 - Optimización para PHP
 - Uso de .htaccess para mejorar nuestra web
 - Tutorial HPL2: creando escenarios

Siento haber tardado tanto en hacer esta entrega; he estado liado y enfermo...


Saludos, y ¡Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!



COBOL: flujo externo


Hacía días que no escribía nada aquí... he estado algo liado...

Sin contar esta entrada, quedan solamente dos más para completar este mini - curso. Al final del mismo, siendo un poco audaces y haciendo buen uso de la lógica pragmática seréis capaces de programar en COBOL. Obviamente las técnicas avanzadas no las trataremos en este apartado; quizás más adelante hago un mini - curso de COBOL avanzado...

En fin, esta entrada será relativamente corta, vamos allá

 - Flujo externo

Flujo externo

Como flujo externo se entiende todo aquello que ocurre fuera del código que estamos editando; es decir, está fuera del alcance de la aplicación.

En java, llamar a un objeto es "usar" el flujo externo (normalmente decimos que "llamamos al método X de la Clase Y", o "delegamos en X"...). En COBOL no hay objetos en sí (aunque se pueden simular con tiempo y algo de código), pero un programa externo es algo similar a llamar a un objeto, si lo planteamos bien.

Por supuesto, el flujo externo no se basa solamente en llamar a otro archivo COBOL; podemos llamar a cualquier fichero ejecutable externo, ya veremos.

Para llamar a un archivo COBOL externo, necesitamos usar la sentencia CALL.

CALL "PROGRAMA" USING var.

Analicemos rápidamente: "PROGRAMA" es el ID (PROGRAM-ID, generalmente el mismo nombre que el archivo, por convención siempre se hace) del COBOL al que llamamos.

La parte de "USING var" es opcional. Si la usamos, estamos pasando "var" por referencia, es decir, pasamos el puntero de var (que puede ser una variable compleja) y "PROGRAMA" la recibirá.

Esto debe nos debe resultar muy familiar: FUNCIONES. Sí, pero funciones EXTERNAS, no hay que olvidarlo.

Recalco esto porque las funciones externas consumen un poco más de recursos, ya que se tienen que apliar datos, desapliar, llamar al fichero COBOL, modificar el runtime...

Volviendo al tema; para cuando usamos la cláusula "USING", la variable "var" debe estar declarada en la WSS, sino dará error.

Por otra parte, el programa "PROGRAMA" debe incluir una sección especial en la DATA SECTION:

es la llamada LINKAGE SECTION.

En ella declaramos una variable con la misma PIC que la variable que pasamos.

Finalmente, en "PROGRAMA" debemos incluir otra cláusula en la PROCEDURE, de manera que quedaría algo así:

IDENTIFICATION DIVISION.
    PROGRAM-ID. PROGRA.
    REMARKS. PRUEBA DE FLUJO

ENVIRONMENT DIVISION.

DATA DIVISION.
WORKIN-STORAGE SECTION.

LINKAGE SECTION.
01 PASO.
    02 PA1 PIC X.
    02 PA2 PIC 9.

PROCEDURE DIVISION USING PASO.

El "USING var" indica que debe meter la variable pasada en la variable indicada (PASO, en este caso). Después, podremos acceder a PASO sin problemas.

Si queremos hacer algo similar a un valor de retorno, solo tenemos que ampliar la variable a pasar, y añadir una variable que dependa de ella, coincidente al valor a retornar. Luego, en la procedure, se rellena ese campo y al salir del programa, como se pasa por parámetro, el programa principal lo recibirá.

Para llamar a otro archivo ejectuable (un exe, por ejemplo), debemos hacerlo mediante un "bridge". COBOL permite hacer un call al sistema, del siguiente método:

CALL "SYSTEM.EXE" USING str.

En este caso, USING es obligatorio (en teoría no), y le pasamos como argumento el comando a ejecutar (por ejemplo, "DIR"). De este modo, en str podemos poner una llamada a un exe, y se ejecutará sin problemas.

Como última aclaración, decir que en todo programa que llamemos (programa de COBOL), si no queremos que termine el programa, debemos cambiar el STOP RUN típico por el EXIT PROGRAM. Esto hace que COBOL retorne el flujo de ejecución una posición atrás en la pila, y por tanto, el programa anterior recobra el control.

Tal y como había dicho, esta será una entrada corta, así que aquí acaba el tema del flujo externo. Solo nos queda aprender a usar ficheros, y después haré un ejemplo completo (haré dos versiones, una compacta y la otra diversificada en varios archivos).

Así pues,
Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!



COBOL: flujo

Hola de nuevo!

Como veis, he actualizado el diseño del blog, ahora es algo más actual...

Siguiendo con el mini - curso de COBOL, en la entrada de hoy toca ver el flujo: es decir, sentencias que cambian el rumbo normal del un programa.

- Flujo en COBOL
* IF
* PERFORM
* GO TO
* Salir y continuar


IF

Un IF en COBOL es como cualquier otro if, es decir

IF condicion
sentencias
ELSE IF condicion
sentencias
ELSE
sentencias


Los operadores lógicos son escritos (es decir, NOT, AND, OR...). Los operadores aritméticos son los típicos (<, >, = - solo un "="). Este tema lo miramos después.

Un ejemplo de if:

IF opcion = 'A'
DISPLAY 'HOLA'
END-IF.

Hay una cosa a tener en cuenta: dentro de un bloque (un bloque es un conjunto de sentencias que va entre un token de apertura y uno de cierre - END -) no hay ningún punto. También fijaros que los IF acaban en END-IF. Si son de una línea se puede abrevias con IF con THEN sen., pero yo soy más de poner siempre el END-IF (evita confusiones).


PERFORM

Un PERFORM es una "llamada a función", pero recordad que va entre comillas porque realmente llamamos a un párrafo.

PERFORM también permite crear bloques, ya que, en realidad, PERFORM es un token polimórfico. Sirve para:

- Llamar párrafos
- Llamar conjunto de párrafos
- Llamar a bloques
- Llamar a sección
- Repetir párrafo / conjunto / bloque X veces (for)
- Repetir hasta condición (do/while, do/until).

Podemos hacer

PERFORM 5 TIMES
DISPLAY 'HOLA'
END-PERFORM.

Así como:

PERFORM SALUDO 5 TIMES.

SALUDO.
DISPLAY 'HOLA'.


Hemos visto que con "X TIMES" hace un for. Para hacer un "while/until", la cosa es algo más complicada. La sintaxis básica es:

PERFORM parrafo/seccion VARYING variable FROM inicio BY paso UNTIL condicion.

Para llamar a una serie de párrafos, añadimos la cláusula THRU. Esto hará que ejecute desde el primer al último párrafo indicado, por ejemplo:

PERFORM uno THRU cinco. , en el ejemplo que sigue, ejecutaría todo el código.

uno.
DISPLAY 'uno'.

dos.
DISPLAY 'dos'.

tres.
DISPLAY 'tres'.

cuatro.
DISPLAY 'cuatro'.

cinco.
DISPLAY 'cinco'.

Condicionales:

Se me había olvidado poner en el índice cómo usar las condiciones, así que las explico antes del GO TO:

Condiciones hay básicamente de dos tipos: aritmética y lógica.

- Lógica: Se usan unas tablas para verificar la veracidad de la sentencia. Son usados AND, OR, NOT... en este tipo de sentencias.

- Aritmética: Se calculan valores y comparan entre ellos, para decidir el resultado. Son usados símbolos aritméticos (=, <, >...) para comparar, así como operaciones aritméticas.

Un inciso: las operaciones aritméticas en COBOL son algo diferentes. Normalmente podemos hacer algo así como

COMPUTE var1 = expr.

Siendo expr una operación matemática, por ejemplo: "var1 - 5". En este tipo de sentencias se usan los signos típicos: *, /. +, -.

Se pueden hacer cálculos de otros tipos, como ADD, SUBSTRACT, MULTIPLY y DIVIDE.

En estas sentencias se sigue el siguiente formato:

ADD val TO var -> es como "var+=val"
ADD val TO var GIVING var2 -> es como "var2 = val+var"
SUBSTRACT val TO var (GIVING var2)
MULTIPLY val TO var (GIVING var2)
DIVIDE val TO var (GIVING var2) (REMAINDER var3) -> el resto va a var3

Adicionalmente, se pueden añadir las cláusulas ROUNDED y ON SIZE ERROR.

ROUNDED: va antes de "val", sirve para obtener un valor redondeado. Si no se pone ROUNDED y la precisión de nuestra variable es menor, se trunca.

ON SIZE ERROR: si no redondeamos, podemos poner esta cláusula al final de la sentencia, y esto añade un "handler" a la operación, por ejemplo

ADD 1 TO var ON SIZE ERROR MOVE 0 TO var2.

IF var2 = 0
...


Por ahora esto es lo básico de operaciones aritméticas.

GO TO


Sin duda, ésta es la sentencia más odiada por todos, y realmente no se porqué.
GO TO hace un salto incondicional hacia un párrafo. Es útil cuando tenemos que ir a un párrafo desde más de un sitio a la vez, independientemente del contexto en el que estemos.

Es cierto que el uso excesivo del GO TO puede confundir, pero si sabéis lo que hacéis no hay problemas.

Su uso es: GO TO parrafo.

Salir y continuar

Hay dos sentencias, similares a "continue" y "exit/break" que se pueden usar en bloques. Los equivalentes en COBOL son CONTINUE y NEXT SENTENCE.

CONTINUE hace que ejecute un "salto", es el típico continue
NEXT SENTENCE lleva la ejecución a la próxima sentencia (es decir, después del siguiente ".").


Como colofón, añadir que estas sentencias pueden ir anidadas, sin olvidar que sólo el último cierre de bloque ha de tener el punto.

Como os digo siempre, acepto sugerencias en los comentarios.

Saludos y hasta la próxima


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!



COBOL: pantallas

Hola de nuevo!

En esta entrada hablaré sobre las pantallas en COBOL. Con esto, nuestras SECTION se ampliarán, pero por contra, ganaremos en diseño y usabilidad.

Esto todavía no lo he probado (se me acaba de ocurrir mientras escribía), pero estoy casi seguro que se puede hacer una biblioteca de pantallas, para llamarlas desde donde sea...


Bueno, vamos allá!

Pantallas:

Como he escrito, las pantallas amplían las section, específicamente la DATA DIVISION - SCREEN SECTION.

¿Y que es una screen (pantalla)? Pues un conjunto de datos previamente cargados que podemos mostrar y pedir datos sobre esos mismos datos.

Aquí dejo un ejemplo:


       SCREEN SECTION.
      *  Pantalla inicial
       01 PRINCIPAL.
          03 LINE 05 COL 10 VALUE "MENU PRINCIPAL".
          03 LINE 07 COL 10 VALUE "ELIGA OPCION: ".
          03 LINE 09 COL 10 VALUE "TRATAMIENTO (A)UTO. DE CLIENTES".
          03 LINE 11 COL 10 VALUE "TRATAMIENTO (M)ANUAL DE CLIENTES".
          03 LINE 13 COL 10 VALUE "OBTENCION DE (L)ISTADOS".
          03 LINE 15 COL 10 VALUE "(S)ALIR".
          03 LINE 17 COL 10 VALUE "> ".
          03 PIC X USING OPCION.

Esta pantalla es del trabajo final que hice para obtener el título de Experto en COBOL. Como se ve, están los parámetros LINE y COL (COL hace lo mismo que POSITION). También tenemos VALUE, PIC...

USING es un token que aún no habíamos visto; en este caso le dice a COBOL en qué variable tiene que meter los datos. Anotar que esta variable tiene que estar definida en la WSS (en esta screen, por así decirlo, le pasamos un "puntero" a la variable).

Os explico un poco el transfondo de esta pantalla: se supone que el usuario puede introducir tres opciones: A, M, y L (en mayúscula o minúscula, da igual). Este valor se guarda en OPCION, y luego se usa para dirigir a uno u otro sitio.

En este caso, siendo un ejemplo, haremos un programa que muestre la opción.

Para hacer bien el ejemplo, voy primeo a explicar un poco lo que haré.

- En la WSS crearé unas variables de hardcode, la variable de opción, y una variable "tonta" (dummy).
- En la Screen Section crearemos varias pantallas, incluyendo una pantalla vacía.
- En la procedure mostraremos la pantalla, y actuaremos en consecuencia.


       IDENTIFICATION DIVISION.
       PROGRAM-ID. MENU.
       REMARKS. MENÚ PRINCIPAL

       ENVIRONMENT DIVISION.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
      * Opción de menú
       77   OPCION PIC X VALUE SPACE.

      *  Variables de hardcode
       01    HARDCO.
          02 M-MAY PIC X VALUE 'M'.
          02 M-MIN PIC X VALUE 'm'.
          02 A-MAY PIC X VALUE 'A'.
          02 A-MIN PIC X VALUE 'a'.
          02 L-MAY PIC X VALUE 'L'.
          02 L-MIN PIC X VALUE 'l'.
          02 S-MAY PIC X VALUE 'S'.
          02 S-MIN PIC X VALUE 's'.

      * Variable vacía
       77    DUMMY PIC X VALUE SPACE.

       SCREEN SECTION.
      *  Pantalla inicial
       01 PRINCIPAL.
          03 LINE 05 COL 10 VALUE "MENU PRINCIPAL".
          03 LINE 07 COL 10 VALUE "ELIGA OPCION: ".
          03 LINE 09 COL 10 VALUE "TRATAMIENTO (A)UTO. DE CLIENTES".
          03 LINE 11 COL 10 VALUE "TRATAMIENTO (M)ANUAL DE CLIENTES".
          03 LINE 13 COL 10 VALUE "OBTENCION DE (L)ISTADOS".
          03 LINE 15 COL 10 VALUE "(S)ALIR".
          03 LINE 17 COL 10 VALUE "> ".
          03 PIC X USING OPCION.

      * Pantalla de error
       01 ERROR-SCR.
          03 LINE 05 COL 10 VALUE "ERROR".
          03 LINE 07 COL 10 VALUE "NO EXISTE LA OPCION".
          03 LINE 09 COL 10 VALUE "ELIGA ENTRE LAS OPCIONES:".
          03 LINE 11 COL 10 VALUE "A, M, o L".
          03 PIC X USING DUMMY.

      *  Pantalla vacía
       01 VACIO.
          03 BLANK SCREEN.

       PROCEDURE DIVISION.
       INICIO.
      *    Mostramos la pantalla inicial
           DISPLAY PRINCIPAL.
           ACCEPT  PRINCIPAL.

      *    Limpiamos la pantalla
           DISPLAY VACIO.

      *   Hacemos cosas...

           DISPLAY 'HAS USADO LA OPCION' OPCION.
           DISPLAY 'PULSA CUALQUIER TECLA PARA SALIR.'.
           ACCEPT DUMMY.


           EXIT PROGRAM.


Como se puede ver, hay cosas que no usamos, como las variables de HC o la pantalla de error. Estas cosas las dejaré por ahora, ya las usaré cuando hable del flujo, en la siguiente entrada.


No es muy difícil de entender el funcionamiento de este programa... ahora podéis experimentar con las pantallas, usando las opciones que vimos ayer, por ejemplo.

Saludos, y,

Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!




COBOL: lo básico de COBOL

Hola de nuevo, en esta entrega trataremos el segundo punto del índice expuesto en la primera entrada del mini-curso de COBOL.

- Lo básico de COBOL
   * PIC
   * Display
   * Accept

PIC

PIC es la instrucción clave para declarar variables en COBOL. Esta cláusula establece una máscara de entrada de datos.

Esto significa que nos podemos ir olvidando de "int", "float", "char", "String"... en cobol no hay de esto. Que suceda así tiene sus ventajas e inconvenientes:

Ventajas:
   - Comprobación automática de valores: si pedimos una entrada de 10 caracteres y nos introducen un número, automáticamente cancela la entrada y la vuelve a pedir, con todo lo que ello comporta

   - Adecuación a ficheros: siempre sabremos la longitud de cada variable, ya que siempre son de longitud fija

Inconvenientes:
  - Tenemos que tener siempre en cuenta los desbordamientos
  - Perdemos algunas mejoras con los tipos (esto se puede salvar con un extra de código)

Antes de aprender a declarar con PIC, vamos a ver qué máscaras hay:

X -> caracter alfanumérico
9 -> caracter numérico
A -> caracter alfabético
S -> caracter de signo
V -> caracter de decimal

Para aclarar un poco, veamos unas conversiones mySQL a COBOL:

varchar(5) -> PIC XXXXX
                 -> PIC X(5)

float(8, 2) -> PIC 999999V99
                -> PIC 9(6)V99
                -> PIC 9(6)V9(2)
                -> PIC S9(6)V9(2)

Como se ve, las máscaras se pueden abreviar, haciendo que el caracter escrito se repita n veces, escribiendo (n).

Bien, el tema de PIC está explicado; ahora falta un tema fundamental para las variables: el NIVEL

en COBOL, toda variable ha de tener un nivel. Pero ¿de qué sirve? pues es fácil: una variable de nivel alto depende de una de nivel bajo. Esto nos sirve para crear estructuras de una manera muy rápida.

Aquí unos ejemplos para ver cómo funcionan los niveles:



       01    CLI.
          02 CODCLI PIC X(5).
          02 NOMCLI PIC X(25).
          02 DIRCLI PIC X(25).
          02 POBCLI PIC X(25).
          02 POSCLI PIC 9(5).
          02 ALTCLI PIC X(8).
          02 IMPCLI PIC 9(6)V9(2).

Aquí creamos una variable global "CLI" (de cliente). Como se ve, tiene nivel 1 (01, siempre tienen 2 dígitos).
Inmediatamente debajo tenemos varias declaraciones de nivel 2 (02), que corresponden a un código, nombre, dirección, población, código postal, fecha de alta e importe, respectivamente.

Todas estas variables dependen de CLI. Esto significa, que realmente CLI sería (no realmente) algo como

77 CLI PIC X(80)9(5)X(8)9(6)V9(2).

¿Y eso? Pues bien, a la hora de pedir datos a variables (accept, ahora lo vemos), podemos pedir la variable CLI, o, por ejemplo, CODCLI. Tenemos que tener cuidado con eso.

Un par de apuntes más:

Las variables de nivel 77 son siempre independientes. No pueden tener "hijos" ni formar parte de un nivel superior.



Los niveles se pueden otorgar arbitrariamente, siempre que se incremente el nivel en los hijos. Dejo un ejemplo de cómo se hace mal y cómo se hace bien:

 05 CLI.
    06 CODCLI PIC XXXXX.
    06 POSCLI.
         10 PRO PIC 99.
         10 RES PIC 999.
    06 NOMCLI.

Esto estaría bien, pero lo siguiente NO


 05 CLI.
    06 CODCLI PIC XXXXX.
    06 POSCLI.
         77 PRO PIC 99.
         77 RES PIC 999.
    06 NOMCLI.

ya que tiene una variable de nivel 77.


Siguiendo con PIC y las variables, hay ciertos valores preestablecidos que se pueden usar como constantes. Estos son, entre otros:

 - ZERO (también ZEROES, ZEROS): Rellena todo con 0, útil para iniciar numéricos
 - SPACE (también SPACES): Rellena todo con espacio (' '), útil para iniciar alfanuméricos
 - QUOTE (también QUOTES): Representa el caracter ', es como el \' de php o c.
 - ALL "texto": Rellena con el valor establecido (por ejemplo ALL "_" crearía un efecto línea)
 - HIGH-VALUE: inserta el valor más grande
 - LOW-VALUE: inserta el valor más pequeño.

Nótese que estas expresiones van sin encomillar.

Para usar estas expresiones, así como otras, podemos mover el valor en la PROCEDURE, o "settear" el valor de la variable a la par que la creamos.

Para settear variables, se añade la cláusula "VALUE" en la declaración, es decir, algo así:

77 SALUDO PIC X(4) VALUE 'HOLA'.
01 YO.
   02 FNAM PIC X(25) VALUE 'DAVID'.
   02 LNAM PIC X(25) VALUE 'SOLÉ'.
77 HR PIC X(80) VALUE SPACES.


Por otra parte, para mover valores en la PROCEDURE, se usa la instrucción MOVE.

MOVE ALL '_' TO HR.

Rellenaría la variable HR con 80 "_" (como un <hr> en HTML, por ejemplo).



Display


Esta instrucción se usa para mostrar cosas por pantalla.

¿Cosas? Si. Desde pantallas hasta registros completos. Por ahora lo dejamos ahí, y mostraré el funcionamiento básico de cómo usar DISPLAY:

DISPLAY SALUDO.
DISPLAY HR.
DISPLAY YO.

La instrucción DISPLAY tiene varias opciones, a saber:

- NO ADVANCING: evita un retorno de carro tras el display.
- LINE: en qué línea se mostrará
- POSITION: en qué columna se mostrará
- BEEP: emite un pitido tras el display
- ERASE (ERASE EOS, ERASE EOL): sirve para borrar zonas: ERASE borra toda la pantalla, ERASE EOS borra desde la posición del cursor hasta el final; ERASE EOL borra la línea en la que está el cursor.

Como se ve, se puede hacer un "print" indicando fila y columna... esto es realmente útil para las pantallas (ya lo veremos).

Accept

Sirve para recoger datos (de pantalla o no). Se suele usar así:

ACCEPT SALUDO.
ACCEPT LNAME.

También tiene opciones, las cuales son:

 - LINE, POSITION, NO BEEP, ERASE

Que hacen lo mismo que en DISPLAY.


Os dejo un pequeño ejemplo de display y accept:


77 SALUDO PIC X(4) VALUE 'HOLA'.
01 YO.
   02 FNAM PIC X(25) VALUE 'DAVID'.
   02 LNAM PIC X(25) VALUE 'SOLÉ'.
77 HR PIC X(80) VALUE SPACES.
01 DT PIC
     02 ANIO PIC X(2).
     02 MES PIC X(2).
     02 DIA PICX(2).

DISPLAY SALUDO LINE 3 POSITION 5.
DISPLAY 'COMO TE LLAMAS?' LINE 5 POSITION 5.
ACCEPT FNAM LINE 5 POSITION 22.
DISPLAY 'BIENVENIDO' FNAM ERASE LINE 3 POSITION 5.
ACCEPT DT FROM DATE.
DISPLAY 'HOY ES ' DIA ' DE ' MES ' DE '  ANIO LINE 5 POSITION 5.

Espero que podáis comprenderlo mejor con este pequeño ejemplo. Destacar que la sentencia "ACCEPT VAR FROM DATE/TIME" se usar para insertar la fecha (formato AAMMDD) o la hora (formato HHMMSSCC) en la variable.

En la siguiente entrega mejoraremos la presentación de este ejemplo, con pantallas.

Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!



COBOL: primeros pasos


Hola de nuevo,
Como comenté en entradas anteriores, voy a dar un pequeño paseo por el mundo Cobol. El hecho de que sea en Cobol es porque, ya que poseo el título de "Técnico Superior en Desarrollo de Aplicaciones Informáticas y Experto en COBOL", me gustaría transmitiros un poco de mi conocimiento en este buen lenguaje de programación.

Como las entradas anteriores, voy a dividir cada punto del curso en una entrada, para que sea más legible.

Sin más, empecemos

 - Primeros pasos
   * Algo de historia
   * ¿Por qué COBOL?
   * Aspectos a tener en cuenta
   * Visión global
      · Division
      · Section
      · Párrafo
      · Línea
      · Plantilla básica

Algo de historia:

COBOL fue un lenguaje de programación creado por "CODASYL", una comisión de varias entidades, entre la cual se encontraba el Departamento de Defensa de los Estados Unidos.
Vio la luz en el año 59, y ha sido sometido a diversas remodelaciones y adaptaciones. Actualmente hay versiones que incluyen soporte para "emular" OOP (programación orientada a objetos), incluso aspectos visuales. Se puede incluso programar webs con cobol.

Como anotación, decir que los conocimientos que tengo son de RM/COBOL-85. Éste fue el penúltimo estándar, aunque en el nuevo estándar (ANSI-COBOL) añadieron funciones matemáticas, por lo que con el 85 en realidad basta, ya que estas funciones matemáticas son relativamente avanzadas, y las podemos crear con código.

No me gusta aburrir mucho con la historia, así que este punto lo doy por zanjado con la siguiente conclusión: no se puede decir que COBOL es un lenguaje en desuso, y mucho menos que no es actual; ya que continuamente evoluciona. Es por eso que la historia de cobol todavía no está terminada.

¿Por qué COBOL?

Sencillo. Para explicar esto a grandes rasgos, usaré un fragmento de la wikipedia:

"Pese a que muchas personas creen que el lenguaje COBOL está en desuso, la realidad es que casi todos los sistemas que requieren gran capacidad de procesamiento por lotes (Batch), tanto las entidades bancarias como otras grandes empresas con sistemas mainframes utilizan COBOL. Esto permite garantizar la compatibilidad de los sistemas antiguos con los más modernos, así como tener la seguridad de que el lenguaje es perfectamente estable y probado. Según un informe de Gartner Group de 2005, el 75% de los datos generados por negocios son procesados por programas creados en COBOL, y en otro informe de 1997 estima que el 80% de los 300.000 millones de líneas de código existentes están creados en COBOL, escribiéndose 5.000 millones de líneas nuevas de COBOL cada año. Con todo eso, hoy por hoy, la programación en COBOL es uno de los negocios más rentables del mundo de la informática. En el resto de aplicaciones el COBOL ha caído en desuso, reemplazado por lenguajes más modernos o versátiles.

Pero no todo es así. Hoy (2012) siguen existiendo decenas de miles de usuarios Cobol e instituciones que siguen instruyendo este lenguaje dados los números informados. Cobol sigue estando soportado y sigue evolucionando permanentemente; esto principalmente por la cantidad de aplicaciones que hoy sigue funcionando y que superan en número a los demás lenguajes gracias a tanta difusión en el pasado. Esto sigue propiciando su continua evolución y, palabras del propio Bill Gates: "No sé qué lenguajes habrá en el futuro, pero seguro que Cobol estará todavía allí".

Si lo leéis completo, veréis que al año, 5.000 millones (sí, sí, 5.000.000.000, 5*10^9) de líneas se escriben cada año.


Otra razón es el conocimiento que tengo de este lenguaje. No todo el mundo sabe cobol, y me parecería algo egoísta no pasar mis conocimientos... es difícil encontrar alguien dispuesto a eso, a pasar conocimiento gratuito...


Más razones: velocidad de procesamiento, compatibilidad con casi cualquier sistema, curiosidad, gran capacidad de gestión de ficheros...

Aspectos a tener en cuenta:

Lo dicho anteriormente, uso estándar rm/cobol-85, y un consejo que quiero que os grabéis a fuego, si de verdad vais a seguir el cursillo.

COBOL está diseñado para trabajar sobre tarjetas perforadas, y esto da ciertas restricciones a la hora de programar:

  - Toda línea que no sea comentario debe empezar, por norma general, en el octavo espacio. Es decir, cada línea nueva, tendréis que pulsar siete espacios antes de escribir nada.
Luego veremos que hay más, entrando en la A-Zone y B-Zone.

 - Toda línea no puede pasar los 80 caracteres de ancho. Esto incluye ancho de variables (es decir, por ejemplo, una cadena de texto de más de 80 caracteres.

 - Se ha de tener siempre en cuenta las zonas de código.

 - El fin de sentencia no es el habitual (";"), sino el punto (".").

 - El sistema de codificación, al tratarse de un lenguaje tan viejo, cambia radicalmente.

Visión global:

Al igual que cualquier lenguaje (de programación o no), cobol se divide en vario elementos, de manera que los elementos grandes contienen los pequeños, y diversos pequeños pueden formar uno grande.

      · Division
      · Section
      · Párrafo
      · Línea
      · Plantilla básica

Division:

Una division (es inglés, por aquello del acento...) está formado por un conjunto de instrucciones, que empieza por una declaración.

En COBOL hay 4 division:

IDENTIFICATION DIVISION
ENVIRONMENT DIVISION
DATA DIVISION
PROCEDURE DIVISION

La primera se encarga de la identificación del programa (una de las instrucciones sirve para crear un nombre interno para cobol). También se puede añadir algún otro tipo de información, como algún comentario de documentación. La única instrucción obligatoria que requiere es la primera (la de identificación

La environment division trata los datos relacionados con el programa: I/O, tipo de caracteres... en esta sección podemos decirle qué tipo de caracteres usaremos, y especificar los archivos a los que accederá. Normalmente esta sección estará vacía, menos cuando accedamos a archivos.

La data division se usa para declarar variables y constantes. COBOL no trabaja con variables locales, solo con globales. Sin embargo esto se puede "apañar" con el flujo externo. En esta division estarán todas las variables y constantes que vayamos a usar en nuestro programa.

Finalmente, la procedure division es aquella en la que va el código puro.

Section:

Una section (sección, en castellano) es una parte de una division.
Una division puede no tener sections, o puede tener varias; de manera opuesta, una section no puede existir si no es dentro de una division.

Las section agrupan los datos de las division en grupos más concretos, como la SCREEN SECTION dentro de DATA DIVISON.

Párrafo:

Un párrafo es un grupo de instrucciones, siempre dentro de la PROCEDURE DIVISION, que se diferencia del resto de párrafos por un identificador.

Es posible (aunque no recomendable) crear una procedure sin párrafos, pero un párrafo siempre estará dentro de la procedure.

Usar párrafos sirve como método de estructuración. Llamar a un párrafo es como llamar a una función.

Línea:

Una línea es un conjunto de palabras finalizadas por punto. Todo está formado por líneas. Sin líneas no hay ni párrafo, ni section, ni division.

Las líneas están en todos los ámbitos.

Plantilla básica:

Como plantilla básica, entendiendo por ello una plantilla de texto que sirva para crear un programa básico (sin ficheros, ni flujo externo, ni pantallas) puede ser algo así:



       IDENTIFICATION DIVISION.
       PROGRAM-ID. ID.
       REMARKS. Comentarios varios.

       ENVIRONMENT DIVISION.
     
       DATA DIVISION.
       WORKING-STORAGE SECTION.
      *   Varialbes y constantes...

       PROCEDURE DIVISION .
      *    Sentencias...
           EXIT PROGRAM.

Revisemos rápidamente, por líneas:

1. Declara la IDENTIFICATION DIVISION
2. Creamos un id. el "ID" lo cambiamos por el que queramos (sin pasar de 8 caracteres)
3. Podemos añadir, opcionalmente, algún comentario. Esta línea es omisible.
4. Declaramos una ENVIRONMENT vacía.
5. Declaramos la DATA.
6. Iniciamos la WSS (Working-storage Section), donde van los datos dedicados a memoria
7. Declaramos la PROCEDURE
8. Salimos del programa

Finalmente, comentar que el EXIT PROGRAM hace que salga por completo del programa. Cuando veamos el flujo externo veremos otras sentencias que son diferentes. También remarcar el tema de los espacios: 7 par una línea, 6 y "*" para un comentario.

Los comentarios son todos de línea entera.

Añadir que he marcado los tokens (palabras reservadas) en negrita.

Por ahora, este es el fin de la primera parte del curso.

Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!





Mini - Curso: COBOL

Ayer fue la última entrada acerca del tema de la pseudo-capa. Quedo abierto a mejoras, dudas, sugerencias...

En las siguientes entradas voy a tratar de hacer un pequeño "curso" de COBOL.

Lo haré partiendo de la base que aquellos que leen estas entradas conocen, por lo menos, como funciona un IF y un FOR, por lo menos (ya que no explicaré cómo funcionan este tipo de sentencias, a no ser que alguien lo pida).

Dejo un pequeño índice:

 - Primeros pasos
   * Algo de historia
   * ¿Por qué COBOL?
   * Aspectos a tener en cuenta
   * Visión global
      · Division
      · Section
      · Párrafo
      · Línea
      · Plantilla básica

 - Lo básico de COBOL
    * PIC
    * Display
    * Accept

 - Pantallas

 - Flujo en COBOL
   * IF
   * PERFORM
   * GO TO
   * Salir y continuar

 - Flujo externo
 - Ficheros
    * Tipos
    * Declarar
    * Usar

 - Ejemplo completo

En la próxima entrega empezaré con el primer punto.

Por ahora, y para abrir boca, comentar que COBOL, por muy obsoleto que parezca, es uno de los lenguajes de programación más antiguos que se mantienen. Según la wiki, el 80% del código fuente mundial es COBOL...

Si estáis acostumbrados a hacer proyectos en los que os exigen una codificación óptima para obtener un resultado lo más rápido con un mínimo de consumo, os dejo una anotación: en una tarea tan simple como contar del 0 al 99999 (esto es, 1.000.000 de números), poniendo un número en cada fila, COBOL tarda aproximadamente 7 veces menos en hacerlo que C.

Por último, decir que COBOL tiene una sentencia para ejecutar archivos externos (es decir, un .bat, o incluso un comando de consola). Si reflexionáis sobre esta última frase, y lo ligáis a la velocidad que tiene, podréis encontrar una gran utilidad al anterior proyecto que comenté (el bridge). Si bien COBOL, con su sistema de fichero, podría emular perfectamente una base de datos, no se encuentran muchos sistemas que funcionen con sistemas de ficheros, por lo que conectar a una base de datos desde un JAR externo suena bien, ¿no?

Hasta la próxima!


¿Te han resultado útiles mis conocimientos de COBOL?
¡Llévatelos donde quieras!