Manual Detallado Cobol

MANUAL DE COBOL Introducción La orientación del curso / manual la enfocaré a mi entorno de trabajo, es decir RM bajo UNI

Views 103 Downloads 0 File size 243KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

MANUAL DE COBOL Introducción La orientación del curso / manual la enfocaré a mi entorno de trabajo, es decir RM bajo UNIX, pero como os he dicho antes, no hay muchas diferencias. Al pensar en Cobol como lenguaje de programación debemos de tener presente que nos referimos a un lenguaje dedicado a gestión de datos con una magnífica transportabilidad entre los distintos sistemas, yo he ejecutado el mismo programa en MS-DOS y UNIX sin modificar ni una linea de código y copiando solo el objeto. Si se le llaman lenguajes de programación, es porque realmente se consideran como cualquier idioma, es decir tiene su gramática, sus verbos, sus frases, sus párrafos y el cobol además tiene una gran similitud con el inglés, ya que todo su entorno está sacado de éste idioma. Cobol además es un lenguaje estructurado y sus partes se diferencias claramente en Divisiones. Estas son 4, son obligatorias y cada una de ellas tiene una misión diferente dentro de cada programa como veremos a continuación. El programa cobol se escribe secuencialmente en líneas de 80 caracteres o menos con la siguiente división:

La parte (1) comprende las columnas de la 1 a la 6 ambas inclusive y se utiliza para numerar las líneas, aunque hoy en día prácticamente no se utilizan. La parte (2) comprende la columna 7 y en ella podemos encontrar, un guión (-) que nos indica que esta línea es continuación de la anterior pero que por su tamaño ocupa mas de una línea, un asteristo (*) que nos indica que el texto que viene a continuación es un comentario y por lo tanto que el compilador lo ignore, o bien puede servir dependiendo de los compiladores para indicaciones del debug. La parte (3) se le llama Area A comprende las columnas 8 a 11 ambas inclusive y aquí es donde se escriben los nombre de las divisiones, de las secciones, de los párrafos, los indicadores de FD (File Description) y los niveles de variables 01 y 77. La parte (4) llamada Area B comprende desde la columna 12 a la 72 y en ellas se incluirán todas las instrucciones del programa, las lineas de las secciones y los niveles de variables mayores a 01. La parte (5) de la columna 73 a la 80 no se utiliza y por lo tanto es ignorada por el compilador. El punto es un signo de vital importancia en cobol ya que nos indica el final de una linea, en el han de terminar todas las secciones, divisiones y párrafos. Si al final de una linea el compilador no encuentra el punto, interpretará que la instrucción continúa hasta que aparezca el punto de fin de linea. Al igual que en otros lenguajes, el cobol dispone de palabras reservadas que no debemos de utilizar como nombres de variables o de párrafos, además éstos no deben de exceder de 30 caracteres (depende del compilador). Las variables y constantes que se pueden utilizar son numéricas, alfabéticas o alfanuméricas. Las numéricas al contrario de la mayoría de los lenguajes actuales o las bases de datos no

miden su tamaño por bytes sino por dígitos, es decir, que una variable de 6 dígitos podrá contener números desde 0 hasta 999999 si es de valor absoluto o incluyendo los negativos si lleva signo. Para las alfanuméricas en cambio no hay cambio alguna y su tamaño viene indicado por el número de caracteres que ocupa. Existen además en cobol unas variables que vienen con un valor propio y que se pueden utilizar libremente, también llamadas Constantes Figurativas, como ZERO, SPACE, LOW-VALUES, HIGHVALUES, etc... Quisiera respetar para todo el manual las mismas pautas, color Amarillo para las palabras reservadas cobol, subrayado para las obligatorias, en cursiva los comentarios y en normal el resto.

Identification Division Esta es la primera linea de todo programa Cobol e identifica a la primera división donde se especifica el nombre del programa, el del autor y demás datos, su sintaxis sería la siguiente: IDENTIFICATION DIVISION. PROGRAM-IDNombre del programa. AUTHOR Nombre del autor. INSTALLATION Lugar donde está instalado. DATE-WRITTEN Fecha de creación. DATE-COMPILED Fecha de compilación. REMARKSComentarios. Vemos que el único párrafo obligatorio además del nombre de división es el que hace referencia al nombre del programa, los demás nombre de autor, lugar de instalación, fechas de creación y compilación y comentarios son opcionales, eso si, si se incluyen se deben de poner cumpliendo las normas. Podemos incluir además todos los comentarios o explicaciones que creamos oportunas incluyendo en la columna 7 un asterisco (*) que nos indica que el compilador hará caso omiso de lo que venga a continuación, por ejemplo. * /////// Este programa es para hacer algo /////// * // atención a la sección de la fecha //// Ejemplo: IDENTIFICATION DIVISION. PROGRAM-ID. MANCLI. AUTHOR. ANDRES MONTES. INSTALLATION. WWW. REMARKS. Programa para mantenimiento de fichero de clientes. Nota final: Poco mas podemos decir de ésta division, obviamente las demás no son tan pequeñas, sin embargo posee dos de las lineas mas importantes de cualquier programa cobol. Nota final:

Poco mas podemos decir de ésta division, obviamente las demás no son tan pequeñas, sin embargo posee dos de las lineas mas importantes de cualquier programa cobol.

Environment Division Es la segunda division por orden de aparición, y en ella se especifican, el ordenador donde se escribió y se ejecutará el programa, asi como la relacion entre los ficheros a utilizar con sus correspondencias externas, es decir con los dispositivos a los que hará referencia el programa objeto cuando vaya a establecer comunicación con dicho fichero. Diremos antes de continuar que en los primeros cobol había muchas partes que eran obligatorias en cada programa, pero hoy en dia, por ejemplo, ésta división ya no es obligatoria, asi como ninguna de sus partes. Su sintaxis sería la siguiente: ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. Ordenador donde se escribió el fuente. OBJECT-COMPUTER. Ordenador donde se ejecuta el objeto. SPECIAL-NAMES. Cambiar valores para constantes del lenguaje, pueden variar en cada compilador. Como se aprecia en su sintaxis, ésta segunda division se divide a su vez en dos secciones, que se describen a continuacion: CONFIGURATION SECTION: Donde describimos los tipos de ordenadores en que se escribio y se ejecutará el programa, o bien el nombre del compilador y asignación de valores a ciertas constantes utilizadas por el compilador, estos valores se introducen en sus respectivas lineas como se ve arriba. Para la linea de SPECIAL-NAMES el uso mas habitual es el de cambiar el punto decimal usado por los ingleses por la coma y asi poder especificar los puntos para los miles, su formato sería el siguiente: SPECIAL-NAMES. DECIMAL-POINT IS COMMA. También podriamos cambiar el valor del símbolo de la moneda con: CURRENCY SIGN IS literal , suele ser un solo caracter y no puede coincidir con ninguno de los que usamos para definir las variables, es decir ni A,ni Z,ni 9,ni -,ni +,ni X, etc... O hacer que todas las letras introducidas sean mayúsculas o minúsculas o que no haya diferencias entre ambas con la clausula ALPHABET. INPUT-OUTPUT SECION: Es la siguiente sección dentro de la Environment, donde se especificarán todos los ficheros que vamos a utilizar, su tipo, su modo de acceso asi como el medio en que estarán, esta sección solo será obligatoria cuando vayamos a utilizar ficheros. Esta tiene dos párrafos FILE-CONTROL e I-O-CONTROL. 123456789012 AB INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT [OPTIONAL] Nombre-de-archivo ASSIGN TO Tipo-de-dispositivo ORGANIZATION IS Tipo de organizacion ACCESS MODE IS Mode de acceso al fichero RECORD KEY IS Clave del registro

ALTERNATE RECORD KEY IS Claves alternativas registro WITH DUPLICATES FILE STATUS IS Variable de estado del fichero. Vamos a explicar cada una de las cláusulas que encontramos dentro de la Input-Output Section. Cláusula SELECT es aqui donde especificamos el nombre lógico que va a tener el fichero dentro del programa, suele ser una palabra que identifique lo mas claro posible el contenido del fichero, por ejemplo ARTICULOS, PROVEEDORES, CLIENTES. Cláusula OPTIONAL si indicamos esta opción al hacer un OPEN I-O, si el archivo no existe, se crea. Con lo cual nos evitamos tener que abrirlo como OUTPUT y cerrarlo, antes de poder utilizarlo por primera vez. Cláusula ASSIGN aqui especificamos el tipo de dispositivo, si es una impresora PRINTER, si es un fichero sobre el que vamos a grabar RANDOM o DISC, se pueden utilizar otros como INPUT, INPUT-OUTPUT, CASSETTE, MAGNETIC-TAPE, pero sin duda los mas utilizados son los dos primeros para identificar si el fichero utilizará una salida impresa o se utilizará sobre disco. Para identificar ficheros utilizados para clasificar utilizaremos SORT. Cláusula ORGANIZATION aqui indicamos la organización de los registros de nuestro fichero, podrá ser SEQUENTIAL, RELATIVE o INDEXED, si nuestro archivo fuera secuencial se podrían omitir ésta clausula asi como las restantes. De ésta organización se deriva el formato del fichero, SEQUENTIAL si los registros se graban secuencialmente conforme se dan entrada sin importar si están o no repetidos, un ejemplo claro son los archivos de impresora, todos los listados son secuenciales. RELATIVE, si cada registro es identificado por un valor entero con su posición relativa (practicamente no se utiliza). INDEXED es la mas utilizada e identifica a ficheros que sus registros son accesibles mediante una clave unica e irrepetible o por varias que pueden estar duplicadas, cualquier fichero de mantenimiento, por ejemplo de ARTICULOS, podría ser INDEXED, y cada código será único para cada artículo y con el nos iremos a su posición y podremos ver todos los demas datos que hagan referencia al registro. Existe también para los archivos de texto, tipo AUTOEXEC.BAT la posibilidad de asignarlos directamente especificando LINE SEQUENTIAL en ésta clausula.

Cláusula ACCESS MODE indica el modo de acceso al fichero, puede ser SEQUENTIAL, RANDOM o DYNAMIC, si no se especifica ninguno o si el fichero es SEQUENTIAL entiende que el modo será SEQUENTIAL. RANDOM indica que accederemos a el aleatoriamente por su clave y DYNAMIC (la mas utilizada) con la que podremos acceder al fichero en el modo que queramos dentro del programa, unas veces secuencialmente, si nos interesa, otras veces por su clave. Cláusula RECORD KEY se utiliza solo si el fichero es indexado y en el decimos cual es el nombre de la clave por la cual accederemos a los registros. Esta deberá ser alfanúmerica y tendrá que estar especificada en la FD del fichero. Si el archivo fuera RELATIVE, esta clausula se sustituiría por RELATIVE KEY e indicará el número de registro del fichero, deberá estar declarado en la WORKING-STORAGE SECTION como una variable numérica sin signo. Cláusula ALTERNATE RECORD KEY solo para ficheros indexados e identifican una o mas claves alternadas para nuestros registros, por ejemplo en un fichero de clientes cuya clave principal sería el código, podríamos asignar como clave alternativa el NIF, y podríamos acceder a el por las dos claves, bien por código o bien por NIF, será también alfanumérico y deberá también estar declarado en la FD. Si aparece WITH DUPLICATES, indica que ésta clave alternativa pudiera estar duplicada, por ejemplo si hubieramos escogido como clave alternada además del NIF, el Nombre del cliente, podría darse el caso de que dos clientes tuvieran el mismo nombre. Cláusula FILE STATUS aqui damos un nombre de una variable que especificaremos en la WORKING como un campo alfanumérico de dos caracteres donde el programa depositará el

código de error que ocurra en el fichero, dependiendo del valor nosotros podremos operar o hacer alguna acción en concreto. El párrafo I-O CONTROL se utiliza par indicarle al programa cuantos archivos van a utilizar el mismo area de memoria para trabajar, os puedo decir poco mas de éste párrafo porque yo no lo he utilizado nunca (lo que no quiere decir que no sea útil). Ejemplo: ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. RMCOBOL. OBJECT-COMPUTER. RMCOBOL. SPECIAL-NAMES. DECIMAL-POINT IS COMMA. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT CLIENTES ASSIGN TO RANDOM "C:DATOSCLIENTES.DAT" ORGANIZATION INDEXED ACCESS DYNAMIC RECORD KEY KEY-CLIENTE ALTERNATE RECORD KEY-CLIENTE1 FILE STATUS STACLI. SELECT IMPRESORA ASSIGN TO PRINT "PRINTER". Hemos declarado el archivo CLIENTES como indexado con dos claves, una principal KEY-CLIENTE y otra alternativa KEY-CLIENTE1 y hemos asignado una variable para guardar los posibles códigos de error para cuando operemos con éste fichero STACLI. Al indicarle el acceso dinámico le decimos que una vez dentro del programa podremos acceder al fichero secuencialmente o bien directacmente al registro que queramos por cualquiera de las claves. Como el fichero IMPRESORA es secuencial no es necesario ninguna aclaración, al darle el nombre PRINTER cojerá la impresora que tengamos por defecto, si le damos cualquier otro nombre que no identificara a ninguna impresora, el resultado sería grabar todo lo que debería salir por la impresora en un archivo con ese nombre. Nota final: Creo que es una de las partes mas interesantes de la programación cobol y que cuando he utilizado alguno de éstos nuevos lenguajes orientados a objetos y que utilizan bases de datos, siempre he echado en falta. Para mi siempre es grato dirigirme a la Environment de cualquier programa y saber con exactitud todos los ficheros que se van a utilizar en ese programa. Apreciar que para cada especificación de fichero en la Select solo se pone el punto al final de todas las clausulas del párrafo. Al asignar la impresora, si asignamos el nombre PRINTER, éste hace referencia a la impresora por defecto pero tambien podríamos utilizar un nombre para especificar una impresora de red, por ejemplo, si en nuestra red existe una impresora que esta en PENTIUMHPLASER, podemos identificar un nombre en el Autoexec.bat para asignar ese valor a una variable de entorno como: IMPRE="PENTIUMHPLASER" y luego en el programa especificar como nombre de dispositivo de la impresora IMPRE, SELECT IMPRESORA ASSIGN TO PRINT IMPRE. En realidad haciendo ésto último podemos asignar cualquier archivo que esté en cualquier dirección de la red, ya que el nombre que damos es lógico y su asignación la podemos definir con una variable de entorno donde queramos.

Data Division

Es la tercera division por orden de aparición, y es donde se declaran absolutamente todos los nombres de campos, registros, variables, es decir donde nombramos cada dato que vayamos a utilizar en nuestro programa. Para almacenar todos estos nombres de datos, ésta DIVISION se divide en varias secciones, cada una de ellas orientada a un tipo de datos diferente.

• • • • •

FILE SECTION. Aqui describiremos todos los campos que componen los registros de todos los archivos que vayamos a utilizar, que previamente habremos declarado en la INPUT-OUTPUT SECTION dentro de la ENVIRONMENT DIVISION. WORKING-STORAGE SECTION. En ella declararemos todas las variables no referentes a archivos, pero que durante la ejecución del programa vayamos a utilizar. LINKAGE SECTION. Esta es la sección donde se registrarán las variables que nos servirán para enlazar el programa principal con el que llamemos mediante la orden CALL. COMMUNICATION SECTION. (No la he utilizado nunca). SCREEN SECTION. En ésta sección podremos describir los atributos y campos a utilizar en las pantallas.

Al igual que en la anterior DIVISION ninguna de sus partes es obligatoria, pero si vamos a utilizar alguna variable, aunque solo sea una, tendremos que incluirla en la WORKING-STORAGE SECTION y esto nos obligará tambien a definir la DATA DIVISION. Pasemos a continuación a explicar mas a fondo cada una de ellas. FILE SECTION. En esta sección describiremos los campos que van a componer el registro de cada uno de los archivos con los que vamos a trabajar, ésta sería su sintaxis:

FD Nombre del fichero. BLOCK CONTAINS Numero de registros por bloque RECORDS RECORD CONTAINS Número de caracteres por registro CHARACTERS LABEL RECORD Etiqueta de registro DATA RECORD Nombre del registro. Vamos a explicar un poco mas detalladamente cada cláusula de la FILE SECTION. Quiero dejar claro que ésta es mas amplia, pero que como en el resto del manual voy a explicar lo que creo que es mas importante y en definitiva lo que mas se utiliza. Cláusula FD nombre del fichero que previamente habiamos descrito en la cláusula SELECT de la INPUT-OUTPUT SECTION en la ENVIRONMENT DIVISION. Cláusula BLOCK CONTAINS cuando queremos que por cada bloque en disco se graben mas de un registro, aqui especificamos el número de ellos que va a contener cada bloque, (512, 1024), si no se especifica se supone que cada registro va a ocupar un bloque de memoria, o bien será el propio compilador el que haga el cálculo mas apropiado. Cláusula RECORD CONTAINS el número de caracteres que tiene el registro sumando todos sus campos, puede ser fija o variable. Si es fija utilizamos un valor y si es variable un rango desde hasta, si no se espicifica será el propio compilador quien la determine. Cláusula LABEL RECORD puede tener dos valores STANDARD u OMITTED , el primer caso indica que cada vez que se accede a un registro el compilador hará las comprobaciones estandares descritas por el propio compilador y en el segundo éstas serán omitidas. Para el caso de los

ficheros de datos en disco se suele poner STANDARD y cuando el fichero es de impresora se indica OMITTED. Cláusula DATA RECORD debido a que un mismo fichero puede tener varias descripciones de registro, aqui indicamos los nombre de éstas que deberán estar descritas a nivel 01. Normalmente no se utiliza y casi siempre se suele utilizar una sola descripción por fichero, por lo que no suele aparecer en casi ningún programa. A continuación vendría la descripción de todos los campos que comprenden el registro, pero antes de ver ésto es aconsejable tener claro como se define una variable con todas sus opciones ya que a fin de cuentas, los campos de un registro no son mas que eso, variables, con la única condición de que al formar parte de un registro la información que contiene nos identifica los datos que se guardarán en el medio en que esté el fichero (disco, impresora). Antes de seguir adelante quisiera decir que siendo el cobol un lenguaje orientado casi exclusivamente al manejo de ficheros de datos, es sin duda, ésta parte que hemos visto la mas importante. Un buen análisis de los ficheros a utilizar antes de empezar es fundamental y nos evitará muchos calentamientos de cabeza, tener claro cuales van a ser sus claves tanto la principal como las alternativas, definir bien todos sus campos y dejar espacio libre para un posible aumento de datos. Esto lo digo porque si creamos un fichero con 80 caracteres por registro y al cabo de un tiempo debemos de introducir un nuevo campo que no habiamos preveido, tendremos que modificar toda su estructura rehaciendo el fichero y recompilando todos los programas a los que afecte, si en cambio dejamos un poco de espacio nos evitaremos la reestructuración del archivo, ésto se consigue utilizando el nombre de variable FILLER como veremos un poco mas abajo. WORKING-STORAGE SECTION. LINKAGE SECTION. COMMUNICATION SECTION SCREEN SECTION Para la WORKING y la LINKAGE las normas son las mismas, asi que las veremos conjuntamente. Las otras dos secciones, COMMUNICATION y SCREEN no las veremos en el manual. Número de Nivel ...... Nombre de campo ...... PIC, VALUE, REDEFINES, OCCURS, JUST, SIGN, SYNC. Cada campo declarado debe de llevar un número de nivel que le informe al compilador del tipo de campo que es: El nivel 01, identifica la primera entrada de un registro o la primera entrada de un campo que se va a subdividir. El nivel 77, identifica a una variable que no se va a subdividir y que no forma parte de ningún registro. El nivel 88, identifica los posibles valores condicionales de una variable previamente definida. Los niveles 02 al 49 indicarán las distintas subdivisiones de un campo cuya primera entrada ha sido definida a nivel 01. Los niveles 01 y 77 deberán de ir siempre en el Area A (Col 8) el resto es independiente. A continuación pondremos el nombre del campo, que no podrá ser ninguna palabra cobol ni llevar ningún carácter extraño, principalmente se utilizarán letras y números o guiones. Es posible que algún campo que definamos nunca vaya a ser usado por el programa pero si en cambio es necesario que exista para que nos reserve el espacio, le llamaremos FILLER. Y finalmente podrán venir una serie de cláusulas como: PICTURE / PIC esta palabra es la que utilizamos para identificar el tipo de datos que va a contener la variable. Los posible valores son:

DE CAMPOS. 9 - Para campos numéricos. A - Para campos alfabéticos. X - Para campos alfanuméricos. S - Indica variable con signo. V - Indica punto decimal. DE EDICIÓN. $ - Representa la aparición del signo $ delante del campo numérico. . - Indica separación de miles. , - Indica punto decimal. (estas dos pueden variar según hayamos especificado en SPECIALNAMES DECIMAL-POINT IS COMMA). Z - Representa un espacio para el 0 a la izquierda en campos numéricos. * - Igual pero se cambia el 0 por *. B - Indica un espacio en blanco. - ó + - Indican la aparición del signo correspondiente. Puede haber mas pero los mas utilizados son los que se han comentado. Para indicar la longitud del campo se puede repetir el símbolo tantas veces como longitud tenga o expresarla entre paréntesis, es decir para definir una variable alfanumérica de 10 caracteres se pondría: PIC X(10) o PIC XXXXXXXXXX. Los valores S y V solo pueden aparecer una vez por cada variable. A continuacion vamos a ver un ejemplo de todo lo que hemos explicado para que se vaya quedando claro. WORKING-STORAGE SECTION. 01 DOMICILIO. 02 TIPO PIC XX. 02 NOMBRE PIC X(20). 02 NUMERO PIC 9(4). Fijaros que hemos definido 4 variables, la primera no tiene PIC, por que indica que está subdividida en las 3 restantes. La segunda "TIPO" nos dice que es una variable alfanúmerica y que puede contener 2 caracteres como máximo, la utilizariamos para guardar el tipo de calle, avenida, paseo, plaza, etc.. Para la tercera "NOMBRE" va a ser también alfanumérica pero con una longitud máxima de 20 caracteres y nos servirá para guardar el nombre de la calle, plaza, avenida, etc y la última "NUMERO" indica una variable numérica de 4 dígitos, que quiere decir que puede contener valores entre 0 y 9999. Observad que en Cobol no se guardan las varables numéricas por bytes como ocurre con todos los lenguajes actuales sino por número de dígitos, con ello quizás desaprovechamos mas la memoria pero en cambio tenemos un control mejor del dato que puede contener nuestra variable. Si TIPO fuera "AV", NOMBRE "DE LOS DESAMPARADOS " y NUMERO "15", si nos refiriéramos a la variable DOMICILIO ésta tendría el siguiente valor:"AVDE LOS DESAMPARADOS 0015".

Vamos a ver algunos ejemplos mas de variables posibles: WORKING-STORAGE SECTION. 77 FECHA PIC 9(8). 77 FECHA-EDIT PIC ZZ/ZZ/ZZZZ. 77 IMPORTE PIC S9(8)V99.

77 IMPORTE-EDIT PIC ZZ.ZZZ.ZZZ,ZZ-. 01 ESTADO PIC 9. 88 SOLTERO VALUE 1. 88 CASADO VALUE 2. 88 DIVORCIADO VALUE 3. Suponiendo que el valor de FECHA es 01111998 (1 Nov de 1998) y FECHA-EDIT es el mismo, éste último se representaría: 01/11/1998. Si IMPORTE es 12815V37 en negativo e IMPORTE-EDIT el mismo, éste se representaría: 12.815,37-. VALUE esta palabra a continuación del PIC indica el valor inicial que contendrá la variable hasta que éste sea modificado. Por ejemplo podemos definir una variable: WORKING-STORAGE SECTION. 01 RAYA PIC X(10) VALUE "----------". 01 MINOMBRE PIC X(30) VALUE "ANDRES MONTES". Asi tendremos una variable llamada RAYA que contiene 10 guiones y otra llamada MINOMBRE que contiene eso, mi nombre, si os fijais con ésta cláusula convertimos cualquier variable en una constante. En cualquier momento del programa podremos cambiar ese valor. Para las variables numéricas es conveniente ponerlas siempre con VALUE 0 para que al empezar cada programa estemos seguros de que no nos arrastra ningún valor. Normalmente al ejecutar un programa se ponen todas las variables a 0, pero si ese programa ha sido llamado desde otro no pasará eso, por eso no viene mal inicializarlas todas a 0. REDEFINES esta cláusula se utiliza para dar mas de un nombre y formato a un mismo campo. Este debe de ir a continuación del nombre de campo y antes del nombre del campo a que hace referencia, deben de estar en el mismo nivel y uno a continuación del otro en el orden de declaraciones. WORKING-STORAGE SECTION. 01 DIAS PIC X(21) VALUE "LUNMARMIEJUEVIESABDOM". 01 TADIA REDEFINES DIAS. 02 DIA PIC XXX OCCURS 7 TIMES. He incluido la cláusula OCCURS para que sea vea un ejemplo práctico, aunque todavía no lo he explicado, pero como veis a partir de éste momento DIAS y TADIA tendrán siempre el mismo valor pero con diferente nombre y formato de datos. OCCURS esta cláusula es la que se utiliza para declarar tablas. Una tabla es un conjunto de elementos con un mismo tipo y longitud que se denominan con el mismo nombre y se diferencian por un subíndice. No se puede especificar en niveles 01, 77 88. Puede tener varios formatos: WORKING-STORAGE SECTION. 01 NUMERO-DIAS PIC 99. 01 TABLA. 02 DIA PIC XXX OCCURS 7 TIMES. 02 MES PIC 99 OCCURS 28 TO 31 DEPENDING NUMERO-DIAS. 02 OTRA PIC X(5) OCCURS 5 INDEXED BY IN-OTRA. En la primera "DIA" indico que esa tabla va a tener 7 elementos que llamaremos DIA (nn) y entre paréntesis el orden dentro de la tabla. Si hubiéramos guardado en ésta tabla las 3 primeras letras de cada dia de la semana, para obtener el valor del lunes pediriamos DIA (1), para el del Jueves DIA (4) y para el del domingo DIA (7). En la segunda "MES" le indicamos que los elementos de la tabla pueden variar dependiendo del

valor de la variable "NUMERO-DIAS" que ha de estar definida antes de la tabla y siempre dentro de los márgenes de 28 y 31. En la tercera le indicamos además que la variable IN-OTRA va a ser la encargada de dirigirnos por los elementos de la tabla, ésta variable no puede estar definida antes. JUST la justificación de los valores de los campos suele ser a la izda. para los alfanuméricos y a la derecha para los numéricos, si en cambio queremos cambiar este orden tendremos que incluir ésta cláusula. WORKING-STORAGE SECTION. 01 NOMBRE PIC X(10). 01 NOMBRE1 PIC X(10) JUST RIGHT. Si le diéramos el mismo valor a las dos variables "ANDRES", la primera nos daría "ANDRES y la segunda " ANDRES", la diferencia, su justificación.

"

USAGE con ésta cláusula determinamos el formato en que se guarda el contenido de las variables (numéricas, ya que las alfanuméricas siempre ocuparán un byte por cada caracter). Con todos los campos se puede operar (obviamente) pero solo los que se definan como DISPLAY serán editables directamente. Tiene varias posibilidades:



DISPLAY, es la forma por defecto e indica que cada dígito ocupará un byte, es la que se toma por defecto y la que memoria ocupa. • BINARY, COMP-1, COMP-3, COMP-6, son diferentes formas de compactación de los datos. COMP-6 (la mas usual) guarda dos dígitos en cada byte, COMP-3 es igual pero admite signo el cual iría en los cuatro últimos bites del último byte. Las restantes formas se utilizan menos. WORKING-STORAGE SECTION. 01 IMPORTE PIC 9(8). Ocupa 8 bytes uno por cada dígito. 01 FECHA PIC 9(8) COMP-6. Ocupa 4 bytes, uno cada 2 dígitos. 01 PRECIO PIC S9(8)V99 COMP-3. Ocupa 6 bytes, uno para los dos decimales, cuatro para la parte entera y uno para el signo. Cuando el tamaño es impar el signo no ocupa ya que comparte byte con el último dígito, el punto decimal tampoco ocupa espacio, ya que solo indica su posición. Estas tres formas que he utilizado son las mas comunes, yo por ejemplo como las capacidades de los ordenadores son tan grandes ahora, cuando defino las variables en la WORKING nunca utilizo ninguna compactación es decir no utilizo la cláusula USAGE (que por cierto y como habreis visto se puede omitir) y por defecto toma DISPLAY (un byte por caracter).

LINKAGE SECTION. En ésta sección se declaran las variables de igual forma solo que las que aqui declaremos nos van a servir de enlace para pasar información a otro programa que será llamado por el principal. Ejemplo: DATA DIVISION. FILE SECTION. FD CLIENTES BLOCK CONTAINS 4 RECORDS RECORD CONTAINS 128 CHARACTERS LABEL RECORD STANDARD. 01 REG-CLIENTE.

02 r 02 02 02 02 02 02

KEY-CLIENTE. 03 CLICOD rPIC 9(4) COMP-6. CLINOM PIC X(30). CLIDIR PIC X(30). CLIPOB PIC X(20). CLIPRO PIC X(20). CLINIF PIC X(9). FILLER PIC X(17).

FD IMPRESORA LABEL RECORD OMITTED. 01 LINEA PIC X(132). WORKING-STORAGE SECTION. 01 TABLA. 02 FILLER PIC X(12) VALUE "LUNMARMIEJUE" . 02 FILLER PIC X(9) VALUE "VIESABDOM" . 01 TABLAIDA REDEFINES TABLA. 02 ELEDIA PIC XXX OCCURS 7 TIMES. 01 FECHA PIC 9(8). 01 IMPORTE PIC S9(8)V99. 01 VALORES. 02 UNO PIC 99 VALUE 0. 02 DOS PIC 9(6) 02 TRES PIC 9(4)V99. 01 LINPA. 02 LIMPOR PIC ZZ.ZZZ.ZZZ,ZZ-. Como veis he diseñado el fichero CLIENTES para que cada bloque de 512 Kb, ocupe 4 registros, dejando 17 caracteres (FILLER), para una posible ampliación del registro. En la descripción del archivo IMPRESORA se declara una variable a nivel 01 que hace referencia al total del registro para luego ir moviendo a éste campo el valor de lo que queramos imprimir. En la WORKING se han declarado algunos campos con distintos formatos, fijaros en la tabla que gracias al REDEFINES hemos llenado con las tres primeras iniciales de cada dia, asi al referirnos a la variable ELDIA (2) su contenido será "MAR". Nota final: La DATA DIVISION nos sirve para tener todas nuestras variables bien definidas, ya sean independientes o que formen parte de algún fichero para poder operar con ellas en la PROCEDURE DIVISION. Me acuerdo de cuando empezamos a estudiar que para otros lenguajes no era necesaria la declaración de variables previamente y en cambio ahora en la mayoría de los lenguajes se exige que se declaren, eso significa que el Cobol no iba mal encaminado. Tenemos que tener siempre muy claro que con cualquier campo podemos hacer lo que queramos, por ejemplo si en un registro de 120 caracteres nosotros en un programa solo vamos a utilizar los 40 primeros podemos definir todo lo restante como un campo FILLER y listo o viceversa si un campo de un registro lo tenemos definido como alfanumérico de 30 en un programa necesitamos los 10 primeros caracteres por un lado y los veinte restantes por otro, puese nada se subdivide para ese programa y no pasa nada. Espero que haya quedado por lo menos medio clara la explicación de ésta tercera DIVISION, evidentemente con la práctica es con lo que mas vamos a aprender siempre claro está que tengamos al menos unas nociones mínimas. Tenemos que tener en cuenta que como en todos los lenguajes, ya sean de programación o de

habla (español, inglés, frances) son muchas las opciones que nos ofrecen pero al final siempre utilizamos las que mas nos gustan o las que consideramos mas útiles. Una cosa que considero importante es dar a las variables un nombre un poco lógico que nos recuerde su contenido, por ejemplo si queremos guardar la fecha, pues llamarla FECHA, si queremos guardar el N.I.F. del gerente, NIFGEREN, etc ...

Procedure Division Bien, hemos llegado a la última división que existe un los programas Cobol, en ella encontramos todos los procesos necesarios para que el programa funcione, que haga para la que fue concebido. Todo ésto se realiza con instrucciones (ordenes, verbos, comandos, etc..), que se explican en otros capítulos del manual. Cada uno de ellos con un formato y una solución que resolver. A continuación vamos a explicar su formato y algunas consideraciones generales aparte de las propias instrucciones: PROCEDURE DIVISION (USING Variable, Variable ...). DECLARATIVES. Nombre-seccionSECTION. USE AFTER ERROR PROCEDURE ON tipo. Nombre-parrafo. Sentencias. ..... END DECLARATIVES. Nombre-seccion SECTION. Nombre-parrafo. Sentencias. ..... Este sería a groso modo el formato general de una Procedure, pero incluso se puede omitir si en un programa no vamos a realizar ningún proceso (es obvio que siempre lo realizaremos, pero se podría omitir). Vamos a explicar un poco su formato: PROCEDURE DIVISION (USING Variable, Variable ...). Cuando especificamos USING en la linea de PROCEDURE DIVISION , después deberemos de dar los nombres de variables que hayamos definido en la LINKAGE SECTION, para compartir en el programa, lo que nos indicará que éste ha sido llamado por otro programa y que esas variables traerán un valor procedente del programa llamador, que a su vez utilizó la instrucción CALL con las mismas variables. DECLARATIVES, es una sección dentro de la PROCEDURE que nos va a servir para controlar los posibles errores en cuanto al manejo de ficheros se refiere. La linea de DECLARATIVES, (si se va a utilizar) deberá de ir siempre a continuación de la linea de PROCEDURE DIVISION . Despues de subdiviría en tantas secciones como opciones de error tengamos, éstas pueden ser definidas por archivo o bien forma de apertura, es decir podremos controlar los errores que nos lleguen de un fichero en concreto o de todos aquellos que hayan sido abiertos de de igual forma, ésto se especifica en la linea USER AFTER ERROR PROCEDURE ON tipo, pudiendo ser tipo, el nombre del archivo o su modo de apertura (INPUT, OUTPUT, I-O , EXTEND. A continuación irían los párrafos con sus respectivas instrucciones a realizar en caso de error. Se pondrían tantos párrafos y secciones como quisieramos controlar, siempre teniendo en cuenta que ésta se acaba cuando se indique END DECLARATIVES. Si no quisieramos utilizar ésta sección, podriamos de igual manera controlar los errores en nuestro programa preguntando siempre por la variable de error de cada fichero que se definió como FILE STATUS en la FILE-CONTROL.

Nombre-seccion SECTION, a partir de aqui incluiremos todas las instucciones necesarias para la correcta ejecución del programa. Ya sabemos que Cobol es un lenguaje estructurado, pues bien no pensemos que la Procedure va a ser un caos de instrucciones escritas secuencialmente, no, en ella podremos definir tantas Secciones (SECTION) y Párrafos como queramos para organizar mejor las instrucciones y para delimitar acciones concretas, eso si siempre se ejecutarán secuencialmente, excepto cuando encuentre algún verbo de bifurcación como GO, PERFORM que haciendo referencia a esos nombres de párrafo harán que se rompa la secuencia lógica de ejecución. En las comparaciones que hagamos podremos utilizar los siguientes formatos:

Literal Variable

MAYOR QUE [ (NOT) GREATER [ (NOT) > MENOR QUE [ (NOT) LESS [ (NOT) < IGUAL QUE [ (NOT) EQUAL [ (NOT) = MAYOR O IGUAL QUE [ GREATER OR EQUAL [ = MENOR O IGUAL QUE [ LESS OR EQUAL [ =) mayor o igual que. LESS OR EQUAL ( 30 DISPLAY SALUDO(CONTA1:1) LINE LI COL CONTA1 LOW PERFORM VARYING CONTA2 FROM 1 BY 1 UNTIL CONTA2 > 400000 MOVE ' ' TO OP END-PERFORM END-PERFORM

END-PERFORM DISPLAY 'FINALIZADO' LINE 22 ACCEPT OP STOP RUN. PIDENOMBRE. DISPLAY 'INTRODUZCA EL NOMBRE ..' LINE 20 ACCEPT NOMBRE LINE 20 COL 30 PROMPT. PIDEAPELLIDO. DISPLAY 'INTRODUZCA EL APELLIDO ..' LINE 21 ACCEPT APELLIDO LINE 21 COL 30 PROMPT DISPLAY SPACES LINE 20 SIZE 70 DISPLAY SPACES LINE 21 SIZE 70. ... Nota: En el ejemplo como véis, después de aceptar el nombre y el apellido construimos una frase y la guardamos en la variablen SALUDO utilizando el comando STRING. A continuación y para mantener los mismos ejemplos de toda la sección hacemos que aparezca en pantalla el SALUDO 5 veces, (dependiendo del valor de LI, que como dijimos antes sería para 10, 11, 12, 13 y 14). Pero ahora hemos intercalado dos PERFORM dentro de éste, el primero para que nos muestre el mensaje letra a letra y el segundo para hacer de retardo y así conseguir un efecto como si escribiéramos el SALUDO con una máquina de escribir. Como pódeis observar el único punto de toda la secuencia se haya en el STOP RUN. El hecho de mantener los márgenes izquierdos, es para dar mas claridad a la programación y conseguir que ésta sea lo mas estructurada posible. AUN HAY MAS Pues sí, podemos desarrollar aún mas la instrucción incluyendo dos nuevos elementos. EJECUTANDO ANTES O DESPUES En primer lugar, por defecto el contenido del PERFORM se ejecuta después de hacer la comprobación de la condición que precede a UNTIL , pero podemos hacer que ésta se realice antes. PERFORM WITH TEST [AFTER - BEFORE ] VARYING variable FROM número, variableBY número, valorUNTIL condición sentencias END-PERFORM Con la opción TEST BEFORE, que es la opción por defecto se comprueba primero la condición y si se cumple se ejcuta el resto, con lo cual es posible que las sentencias no se ejecuten ninguna vez, si al comenzar ya está rota la condición. Con la opción TEST AFTER, se ejecutan las sentencias antes de comprobar la condición, con lo cual las sentencias se van a ejecutar al menos en una ocasión, incluso aunque entremos en el PERFORM con la condición rota. AUMENTANDO LAS CONDICIONES Efectivamente además de la primera condición podemos incrementar el número de condiciones para que se cumplan los requisitos y así ejecutar las sentencias. Esto lo conseguimos incluyendo mas cláusulas precedidas de AFTER. PERFORM WITH TEST [AFTER - BEFORE ] VARYING variable FROM número, variable BY número, valor UNTIL condición

AFTER variable FROM número, variable BY número, valor UNTIL condición sentencias AFTER ...... END-PERFORM Al aplicar este formato cuando se cumpla la primera condición pasará el control al AFTER y comprobará de nuevo la condición que precede al siguiente UNTIL según los valores especificados en la línea que contiene AFTER. Además podemos ir incrementando el número de condiciones a nuestro antojo, consiguiendo de éste modo hacer unos anidamientos y un desarrollo mas completo de la sentencia, obteniendo por consiguiente unos niveles de perfeccionamiento muy altos. RESUMIENDO Una mayor utilización de PERFORM sin duda traerá un uso menor de la declaración GO y con ello conseguimos una programación estructurada. Las ventajas de la programación estructurada las quiero explicar en un apartado dentro de ésta misma sección de Manuales, una vez explique las sentenicas GO e IF, que serán la siguiente aportación al manual. En esa nueva sección se verá un caso mas práctico y real de utilización de PERFORM con uso de lecturas de ficheros y demás experiencias cotidianas en el mundo de la programación en el ámbito de la gestión.