Académique Documents
Professionnel Documents
Culture Documents
IDENTIFICATION DIVISION.
IDENTIFICATION DIVISION. Esta es la primera linea de todo programa Cobol e
identifica a la primera divisin donde se especifica el nombre del programa, el del autor
y dems datos, su sintaxis sera la siguiente:
IDENTIFICATION DIVISION.
PROGRAM-ID. Nombre del programa.
AUTHOR. Nombre del autor.
INSTALLATION. Lugar donde est instalado.
DATE-WRITTEN. Fecha de creacin.
DATE-COMPILED. Fecha de compilacin.
REMARKS. Comentarios.
Vemos que el nico prrafo obligatorio adems del nombre de divisin es el que hace
referencia al nombre del programa, los dems nombre de autor, lugar de instalacin,
fechas de creacin y compilacin y comentarios son opcionales, eso si, si se incluyen
se deben de poner cumpliendo las normas.
Podemos incluir adems 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 continuacin, por ejemplo.
* /////// Este programa es para hacer algo ///////
* // atencin a la seccin 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 dems no son
tan pequeas, sin embargo posee dos de las lineas mas importantes de
cualquier programa cobol.
ENVIRONMENT DIVISION.
ENVIRONMENT DIVISION. Es la segunda division por orden de aparicin, 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
comunicacin con dicho fichero.
Diremos antes de continuar que en los primeros cobol haba muchas partes que eran
obligatorias en cada programa, pero hoy en dia, por ejemplo, sta divisin ya no es
obligatoria, asi como ninguna de sus partes. Su sintaxis sera 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 asignacin de valores a ciertas constantes
utilizadas por el compilador, estos valores se introducen en sus
respectivas lineas como se ve arriba.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT 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 clusulas que encontramos dentro de la Input-Output
Section.
Clusula SELECT es aqu donde especificamos el nombre lgico 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.
Clusula ASSIGN aqu 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
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:\DATOS\CLIENTES.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 KEYCLIENTE1 y hemos asignado una variable para guardar los
posibles cdigos de error para cuando operemos con ste
fichero STACLI. Al indicarle el acceso dinmico le decimos que
una vez dentro del programa podremos acceder al fichero
secuencialmente o bien directamente al registro que queramos
por cualquiera de las claves.
Como el fichero IMPRESORA es secuencial no es necesario
ninguna aclaracin, al darle el nombre PRINTER coger la
impresora que tengamos por defecto, si le damos cualquier otro
nombre que no identificara a ninguna impresora, el resultado
sera grabar todo lo que debera salir por la impresora en un
archivo con ese nombre.
Nota final:
Creo que es una de las partes ms interesantes de la programacin
cobol y que cuando he utilizado alguno de stos nuevos lenguajes
DATA DIVISION.
DATA DIVISION. Es la tercera divisin por orden de aparicin, 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.
En esta seccin describiremos los campos que van a componer el
registro de cada uno de los archivos con los que vamos a trabajar, sta
sera su sintaxis:
123456789012
A
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.
Nmero de Nivel ...... Nombre de campo ...... PIC, VALUE, REDEFINES,
OCCURS, JUST, SIGN, SYNC.
Cada campo declarado debe de llevar un nmero 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 ningn registro.
El nivel 88, identifica los posibles valores condicionales de una variable
previamente definida.
Los niveles 02 al 49 indicarn las distintas subdivisiones de un campo
cuya primera entrada ha sido definida a nivel 01. Los niveles 01 y 77
debern de ir siempre en el Area A (Col 8) el resto es independiente.
WORKING-STORAGE SECTION.
01 DOMICILIO.
02 TIPO PIC XX.
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 representara: 01/11/1998.
Si IMPORTE es 12815V37 en negativo e IMPORTE-EDIT el mismo, ste
se representara: 12.815,37-.
VALUE esta palabra a continuacin del PIC indica el valor inicial que
contendr la variable hasta que ste sea modificado. Por ejemplo
podemos definir una variable:
123456789012
A
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
clusula convertimos cualquier variable en una constante. En cualquier
momento del programa podremos cambiar ese valor. Para las variables
numricas es conveniente ponerlas siempre con VALUE 0 para que al
empezar cada programa estemos seguros de que no nos arrastra ningn
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.
WORKING-STORAGE SECTION.
01 DIAS PIC X(21) VALUE "LUNMARMIEJUEVIESABDOM".
01 TADIA REDEFINES DIAS.
02 DIA PIC XXX OCCURS 7 TIMES.
He incluido la clusula OCCURS para que sea vea un ejemplo prctico,
aunque todava no lo he explicado, pero como veis a partir de ste
momento DIAS y TADIA tendrn siempre el mismo valor pero con
diferente nombre y formato de datos.
WORKING-STORAGE SECTION.
01 NUMERO-DIAS PIC 99.
01 TABLA.
02 DIA PIC XXX OCCURS 7 TIMES.
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(10).
01 NOMBRE1 PIC X(10) JUST RIGHT.
Si le diramos el mismo valor a las dos variables "ANDRES", la primera
nos dara "ANDRES " y la segunda " ANDRES", la diferencia, su
justificacin.
123456789012
A
WORKING-STORAGE SECTION.
01 IMPORTE PIC 9(8). Ocupa 8 bytes uno por cada dgito.
01 FECHA PIC 9(8) COMP-6. Ocupa 4 bytes, uno cada 2 dgitos.
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 tamao es impar el signo no ocupa ya que comparte byte con
el ltimo dgito, el punto decimal tampoco ocupa espacio, ya que solo
indica su posicin. 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 compactacin es decir no utilizo la clusula USAGE (que
por cierto y como habreis visto se puede omitir) y por defecto toma
DISPLAY (un byte por caracter), en cambio cuando trabajo con campos
de registro de ficheros si me gusta compactar lo mximo para que el
tamao de los archivos no se dispare.
Ejemplo:
DATA DIVISION.
FILE SECTION.
FD
01
02
02
02
CLIPRO
CLINIF
FILLER
PIC X(20).
PIC X(9).
PIC X(17).
Nota final:
La DATA DIVISION nos sirve para tener todas nuestras variables bien
definidas, ya sean independientes o que formen parte de algn 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 declaracin de variables previamente y en cambio ahora en la mayora
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
PROCEDURE DIVISION.
PROCEDURE DIVISION. Bien, hemos llegado a la ltima divisin 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..), como
explicaremos a continuacin. Cada uno de ellos con un formato y una solucin que
resolver.
Como son muchos los verbos de que se compone el lenguaje, vamos a ver stos
divididos por grupos: De clculo, De archivos, De pantalla, Resto.
Este sera a groso modo el formato general de una Procedure, pero incluso se puede
omitir si en un programa no vamos a realizar ningn proceso (es obvio que siempre lo
realizaremos, pero se podra omitir). Vamos a explicar un poco su formato:
PROCEDURE DIVISION (USING Variable Variable ...).
Cuando especificamos USING en la linea de PROCEDURE DIVISION,
despus 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 traern un valor procedente del programa llamador, que a su
vez utiliz la instruccin CALL con las mismas variables.
DECLARATIVES, es una seccin 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 continuacin de la linea de PROCEDURE DIVISION. Despues
de subdivira 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 continuacin iran los prrafos con sus
respectivas instrucciones a realizar en caso de error.
Se pondran tantos prrafos y secciones como quisieramos controlar,
siempre teniendo en cuenta que sta se acaba cuando se indique END
DECLARATIVES.
Si no quisieramos utilizar sta seccin, 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 aqu incluiremos todas las
instucciones necesarias para la correcta ejecucin del programa.
[ (NOT) GREATER
[ (NOT) >
MENOR QUE
[ (NOT) LESS
[ (NOT) <
]
]
IGUAL QUE
Literal
Variable
[ (NOT) EQUAL
[ (NOT) =
]
]
Literal
Variable
[ GREATER OR EQUAL
[ >=
]
]
[ LESS OR EQUAL
[ <=
]
]
Tambien podemos utilizar para las condiciones complejas los operandos lgicos, AND,
OR y NOT segn se requieran, todas las condicionea que incluyan AND han de ser
correctas para que pase la condicin, si se utiliza OR solo alguna de ellas ha de ser
correcta, cuando se utilice NOT no podr ser correcta para que la condicin sea vlida.
PROCEDURE DIVISION
INSTRUCCIONES DE CALCULO. Debido a que el lenguaje Cobol fue concebido para
la gestin de grandes cantidades de datos y a resolver problemas de tipo comercial y
de administracin, no se incluyeron dentro de sus especificaciones verbos que nos
puedieran ayudar a resolver clculos complejos como integrales, trigonometra, raices
cuadradas, etc..., sino simplemente las orientadas a los clculos bsicos, suma, resta,
multiplicacin y divisin que son las que vamos a ver a continuacin:
add, subtract, multiply, divide, compute.
ADD, sta es la instruccin que utilizaremos para realizar sumas y tiene los siguientes
formatos:
1.- ADD variable literal variable literal ... TO variable (ROUNDED)
(ON SIZE ERROR) instruccin
2.- ADD variable literal variable literal ... GIVING variable
(ROUNDED) (ON SIZE ERROR) instruccin
Formato 2:
ADD UNO TRES 5 GIVING RESULTADO.
En ste caso la variable RESULTADO tendr el valor de la suma de
las variables anteriores, sin tener en cuenta su valor inicial, es decir,
ser de: 10 (de la variable UNO) + 540 (de la variable TRES) + 5 =
555.
Formato 3:
ADD CORR VALORES TO OTROS.
SUBTRACT, sta es la instruccin que utilizaremos para realizar restas y tiene los
siguientes formatos:
1.- SUBTRACT variable literal variable literal ... FROM variable
(ROUNDED) (ON SIZE ERROR) instruccin
2.- SUBTRACT variable literal variable literal ... FROM variable
literal GIVING variable (ROUNDED) (ON SIZE ERROR) instruccin
3.- SUBTRACT CORR variable FROM variable (ROUNDED) (ON SIZE
ERROR) instruccin
Para ver las explicaciones de cada uno de los formatos partiremos de la misma
WORKING que hemos utilizado con la instruccin ADD, poniendo a continuacin un
ejemplo y su explicacin.
Formato 1:
SUBTRACT UNO TRES 5 FROM RESULTADO.
Se restarn todas las variables o literales numricos (cifras) del valor
de la variable que se de a continuacin del FROM, guardandose el
resultado tambin en sta ltima.
Por tanto al realizar sta operacin el valor de la variable
RESULTADO, ser de: -10 (de la variable UNO) - 540 (de la variable
TRES) - 5 + 10 (de Resultado) = -545.
Como veis se le han restado los valores de UNO, TRES y 5 que
suman -555 pero como RESULTADO vala +10, ste se suma y da un
valor de -545.
Formato 2:
SUBTRACT UNO 5 FROM TRES GIVING RESULTADO.
Aqu lo que conseguiremos ser restar el valor de la variable UNO y 5
del valor de la variable TRES y el resultado guardarlo en la variable
RESULTADO, sin tener en cuenta su valor inicial, es decir, ser de:
540 (de la variable TRES) - 10 (de la variable UNO) - 5 = 525.
Formato 3:
SUBTRACT CORR VALORES FROM OTROS.
Al igual que con la instruccin ADD, con ste formato conseguimos
que las variables del campo compuesto VALORES se resten al valor
de las variables con el mismo nombre del campo compuesto OTROS,
obteniendo como resultado: 280 (de la variable DOS del campo
VALORES) - 110 (de la variable DOS del campo OTROS) = 170.
Si hubiera coincidido alguna variable mas con el mismo nombre en
ambos campos tambin se hubiese restado.
Formato 1:
MULTIPLY 5 FROM RESULTADO.
Multiplica el nmero 5 por el valor de la variable RESULTADO,
Formato 2:
MULTIPLY 5 BY TRES GIVING RESULTADO.
Aqu multiplicaremos el nmero 5 por el valor de la variable TRES
guardando el resultado en la variable RESULTADO, sin tener en
cuenta su valor inicial, es decir, ser de: 5 x 540 (de la variable
TRES) = 2700.
DIVIDE, sta es la instruccin que utilizaremos para realizar divisiones y tiene los
siguientes formatos:
1.- DIVIDE variable literal INTO variable (ROUNDED) (ON SIZE
ERROR) instruccin
2.- DIVIDE variable literal (BY INTO) variable literal GIVING
variable (ROUNDED) (REMAINDER) variable (ON SIZE ERROR)
instruccin
Utilizando la misma WORKING que hemos utilizado con las instrucciones ADD y
SUBTRACT, veremos a continuacin unos ejemplos y su explicacin.
Formato 1:
DIVIDE 10 INTO TRES.
Divide el valor de la variable TRES entre el nmero 10, guardando el
resultado en la variable TRES: 540 (de la variable TRES) / 10 = 54.
Formato 2:
DIVIDE 7 INTO TRES GIVING RESULTADO REMAINDER RESTO.
Aqu dividiremos el valor del la variable TRES entre 7 guardando el
resultado en la variable RESULTADO, sin tener en cuenta su valor
inicial, y adems el resto de la operacin lo guardar en la variable
RESTO, quedando as: 540 / 7 = 77, pero como 7 x 77 son 539 el
resto es 1 que ser el valor de RESTO.
Si en vez de utilizar INTO utilizamos BY cambia el orden de los
operandos, es decir en vez de dividir TRES entre 7 dividiramos 7
entre TRES.
La opcin REMAINDER no es obligatoria, todo depender del uso que
queramos hacer de la instruccin.
COMPUTE, con sta orden podemos realizar todos los clculos aritmticos posibles en
una sola instruccin, utilizando los operadores +(suma) -(resta) *(multiplicacin) /
(divisin) **(potenciacin), adems de utilizar parntesis para especificar mejor la
operacin a realizar.
1.- COMPUTE variable (ROUNDED) = expresin aritmtica (ON SIZE
ERROR) instruccin
Utilizando la misma WORKING que hemos utilizado anteriormente vamos a ver un
ejemplo:
Formato 1:
COMPUTE RESULTADO = DOS OF VALORES * 16 / 100.
El valor de la variable RESULTADO ser de 44, obtenido despus de
multiplicar 280 (de la variable DOS del grupo VALORES) x 16 y lo
que de dividido entre 100.
En realidad si hacemos el clculo en una calculadora nos daremos
cuenta que el resultado exacto es 44,80 pero como la variable
RESULTADO no la hemos definido con decimales stos son
depreciados por el compilador.
Puesto que la variable DOS pertenece a dos grupos de variables
deberemos especificar a que grupo pertenece (OF VALORES).
Debemos de tener en cuenta que siempre tienen preferencia los
operadores que vayan entre parntesis, a continuacin los de
multiplicacin y divisin (*) y (/) y por ltimo los de suma y resta
(+) y (-) y el orden en que va a ir realizando las operaciones ser de
izquierda a derecha, por lo tanto:
COMPUTE RESULTADO = 2 + 3 * 5.
Esta operacin dara como resultado 3*5=15+2=17.
COMPUTE RESULTADO = (2 + 3) * 5.
En cambio sta otra dara: 2+3=5*5=25.
Espero que hayais notado la diferencia y la podais aplicar a vuestros
casos en concreto.
Para todas stas instrucciones de clculo que hemos visto la opcion ROUNDED significa
lo mismo y quiere decir que fuerza al redondeo del resultado para cada operacin y
Igual ocurre con la frase ON SIZE ERROR instruccin, que propiciar que se ejecute la
instruccin que pongamos a continuacin cuando se produzca un desbordamiento del
campo que va a acoger el resultado, por ejemplo si el resultado de una operacin es
8.976.400 y la variable la hemos definido con PIC 9(6) y hemos especificado dicha
opcin se ejecutar la instruccin especificada.
PROCEDURE DIVISION
INSTRUCCIONES DE ARCHIVOS. Sin duda son las instrucciones mas importantes
con las que cuenta el lenguaje Cobol, con ellas tendremos la oportunidad de manipular
toda la informacin contenida en nuestros archivos, es decir, podremos abrir archivos,
cerrarlos, leerlos, guardar informacin nueva o modificar datos existentes. Todo sto lo
haremos con las instrucciones que voy a explicar a continuacin:
open, close, read, write, rewrite, delete, start.
Antes de empezar a explicar stas instrucciones me gustara que entendiseis bien
algunos conceptos como fichero, registro y campo, para que podais comprender mas
claramente, la explicacin de todas las instrucciones que se vern en sta seccin.
Ahora quizs entendais mejor el resto, si veo alguna aclaracin necesaria, ampliar
este prrafo.
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
OPEN I-O CLIENTES
OPEN EXTEND IMPRE.
CREAR-ARCHIVO.
OPEN OUTPUT TRABAJO CLOSE TRABAJO.
...
Nota: Con stas tres instrucciones estamos abriendo tres archivos,
cada uno de una forma diferente. Tambien podriamos haberlos
puesto en una sola linea de la siguiente forma:
OPEN INPUT ARTICULOS I-O CLIENTES EXTEND IMPRE.
En el caso del archivo TRABAJO, se consigue crearlo como nuevo,
...
PROCEDURE DIVISION.
INICIO.
OPEN INPUT ARTICULOS.
OPEN I-O CLIENTES
OPEN EXTEND IMPRE.
...
...
...
CERRAR.
CLOSE ARTICULOS CLIENTES IMPRE.
...
Nota: Apuntar que si finalizamos el programa con la sentencia
STOP RUN, que luego veremos, los archivos que esttuvieran abiertos
se cierran automticamente aunque no se haya especificado la orden
CLOSE. Anque siempre es preferible utilizarla, ya que puede haber
algunos compiladores mas antiguos que no los cierren.
Me gustrara destacar de stas dos instrucciones vistas que lo mas
normal es no utilizar ninguna de las opciones, es decir solo abrir de
una manera el archivo para su uso y una vez hayamos acabado con
l, cerrarlo.
READ, es la instruccin que utilizamos para leer registros de un archivo, debe de estar
abierto. Con ella conseguimos que los datos referentes al registro accedido queden en
la descripcin de dicho fichero, es decir, conseguimos que los campos declarados en la
FD, tengan el valor correspondiente al registro leido.
La sentencia READ, se utiliza para leer ficheros secuanciales o indexados, o para leer
indexados de manera secuencial, por lo que su sintaxis tiene dos formatos principales.
Adems de ste formato, existe para sta instruccin otro muy comn. Y es el que
utilizamos para enviar datos a la impresora, es decir para listar, para imprimir.
Es en ste caso, donde se hace indispensable el uso de mas de una descripcin por
registro. Porque? Sencillo, definiremos nuestro fichero con un registro de tamao
igual al ancho de nuestro listado, y luego en la WORKING, describiremos el formato de
cada una de las lineas que utilizaremos en la impresin. Quiero hacer un ejemplo mas
extenso para ste caso, que ser muy utilizado y distinto en su filosofa al resto.
WRITE nombre de registro (FROM descripcin) (AFTER nmero de
lineas)(PAGE) END-WRITE
Adems para ste formato tendremos la clusula AFTER, en la cual
indicamos el nmero de lineas que debe de avanzar la impresora antes
de escribir, o bien que lo haga directamente al principio de la siguiente
pgina, poniendo AFTER PAGE. Existen algunas otras clusulas, pero no
las vamos a ver aqu por ser poco usadas.
IDENTIFICATION DIVISION.
PROGRAM-ID. LISTADO.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IMPRESORA ASSIGN TO PRINT "LPT1".
DATA DIVISION.
FILE SECTION.
FD IMPRESORA LABEL RECORD OMITTED.
01 REG-IMPRE PIC X(80).
WORKING-STORAGE SECTION.
01 LINEA1.
02 FILLER PIC X(30) VALUE SPACES.
02 FILLER PIC X(20) VALUE "ESTA ES LA LINEA 1".
01 LINEA2.
02 FILLER PIC X(30) VALUE SPACES.
02 FILLER PIC X(20) VALUE "ESTA ES LA LINEA 2".
...
...
PROCEDURE DIVISION.
INICIO.
OPEN OUTPUT IMPRESORA
ESCRIBIR.
WRITE REG-IMPRE FROM LINEA1 AFTER PAGE.
WRITE REG-IMPRE FROM LINEA2 AFTER 2.
...
...
CERRAR.
CLOSE IMPRESORA.
...
Nota: Como podeis ver, hemos definido el registro como REG-IMPRE,
pero al escribir sobre el fichero impresora utilizamos las
descripciones de LINEA1 y LINEA2, de sta manera conseguimos que
se impriman las dos lineas en una impresora conectado al puerto
...
PROCEDURE DIVISION.
INICIO.
OPEN I-O ARTICULOS.
COLOCAR.
MOVE 100 TO CLAVE-ARTICULO.
START ARTICULOS KEY NOT LESS KEY CLAVE-ARTICULOS
INVALID KEY GO ERROR.
LECTURA.
READ ARTICULOS NEXT RECORD AT END GO CERRAR.
...
GO LECTURA.
ERROR.
...
...
GO CERRAR.
ERROR.
...
...
CERRAR.
CLOSE ARTICULOS.
...
...
Nota: Aqui empezariamos a leer el ficher artculos desde la clave
que no sea menor que 100, es decir de 100 en adelante. Fijaros
como luego la lectura se hace en otro prrafo diferente, ya que sino,
siempre estariamos haciendo el START. Recordad que con sta
instruccin SOLO nos situamos en un sitio determinado del fichero, a
partir de ah podremos operar como queramos.
RESUMIENDO
En la programacin estructurada es conveniente sustituir el punto como final de una
instruccin por la clusula END-....... para cada instruccin. De esta manera
conservamos la estructura y no obligamos con el punto a finalizar ninguna instruccin
o bucle en el que estemos metidos.
Una vez vistas todas las intrucciones relativas a ficheros, quiero dejar bien claro su
utilizacin.
Tendremos siempre en cuenta que cuando leemos, realmente le damos el valor del
registro que hemos leido a los campos o variables que lo componen. Que cuando
grabamos o regrabamos, le estamos dando el valor de las variables en ese momento al
registro para que se grabe en disco y cuando borramos, estamos quitando fisicamente
del disco esa informacin.
He realizado un temtico dedicado integramente al uso de ficheros, podis echarle un
vistazo por si os han quedado dudas. Ficheros
PROCEDURE DIVISION
INSTRUCCIONES DE PANTALLA Y MOVIMIENTO. Sin duda alguna e
independientemente del lenguaje de programacin escogido, las instrucciones que mas
se suelen utilizar, sern las que hagan uso de la pantalla, ya sea como salida o entrada
de informacin.
Para la programacin en Windows, pondr la informacin en la seccin Programando
en Windows, en cuanto tenga todo preparado, la podris consultar.
Vamos a utilizar sta seccin para hacer un anlisis profundo de dichas instrucciones.
accept, display.
Letra Fondo
Negro
32
Azul
64
Verde
96
Celeste
128
Rojo
160
Morado
192
Marrn
224
Blanco
256
Observaciones
Para conseguir los colores, debemos
de sumar las dos cantidades
correspondientes a la letra y al
fondo, por ejemplo si queremos el
fondo blanco y la letra azul, el valor
que se le debera de asigna a la
clusula COLOR ser de 258 (256
fondo blanco + 2 letra azul).
PROCEDURE DIVISION.
INICIO.
ACCEPT NOMBRE LINE 10 COL 20 PROMPT LOW REVERSE ECHO CONTROL
"FCOLOR=BLUE, BCOLOR=WHITE" ON EXCEPTION ESCA MOVE 1 TO QW.
ACCEPT CODIGO LINE 12 COL 20 CONVERT.
...
Nota: Con el primer ACCEPT conseguiriamos introducir un valor en la variable
NOMBRE, lo aceptaremos en brillo suave con video reverso y una vez
introducido el campo, este se volver a mostrar tal y como va a quedar, gracias
a ECHO. Adems se aceptar en color azul con fondo blanco y si pulsamos una
de las teclas que causan excepcion segn los valores permitidos, esta se
guardara en la variable ESCA y luego podramos preguntar por su valor. Por
ejemplo si pulsamos F1, F2, F3 tomar el valor 1, 2, 3. Si pulsamos ENTER (13)
ESCAPE (27), Tabular (9), etc ...
La siguiente orden nos permitir aceptar la variable CODIGO en la cual los
carcteres no numricos no se admitirn al llevar la clsusula CONVERT.
Os aconsejo que hagis todo tipo de pruebas con las opciones disponibles hasta
que el resultado sea el que deseis.
Muchas veces cuando se muestra un mensaje, se acepta una
variable a continuacin solo para dar tiempo al usuario. Algunos
compiladores como Acucobol han implementado la siguiente
opcin:
ACCEPT OMITTED, y as no tenemos que definir ninguna variable.
Teneis que tener en cuenta que algunas de las clusulas que
explico es posible que no funcionen en todos los compiladores,
as como es posible que existan otras que yo desconozca debido
a que son usadas por otros compiladores.
DISPLAY, es la instruccin que usaremos como salida de datos en pantalla. Con ella
mostraremos cualquier texto, cualquier variable, cualquier constante o cualquier valor,
en resumidas es la instruccin para que aparezca lo que sea en pantalla. Las clusulas
asociadas a esta instruccin son practicamente las mismas que hemos visto para
ACCEPT, con lo que solo las indicar, su explicacin la obtendris arriba. De todas
maneras sta instruccin est siendo implementada en muchos mas campos, por
determinados compiladores y no sera justo pensar que su nica funcin es la que voy
a explicar aqu, lo que si es cierto es que sta es la comn a todos los compiladores.
Mas abajo hablar un poco de todo esto que os digo y de su futuro.
DISPLAY variable, literal CLAUSULAS ...
...
WORKING-STORAGE SECTION.
77 NOMBRE PIC X(30).
...
PROCEDURE DIVISION.
INICIO.
DISPLAY " " LINE 1 ERASE CONTROL "FCOLOR=BLUE,
BCOLOR=WHITE".
DISPLAY "INTRODUZCA EL NOMBRE" LINE 10 COL 10
REVERSE.
ACCEPT NOMBRE LINE 10 COL 34 PROMPT LOW ECHO.
...
Nota: Una cosa a tener en cuenta tanto con FCOLOR, como con
BCOLOR, es que los colores que tomen seguirn activos hasta
encontrar otra orden que los cambie, por eso al comenzar con esa
primera linea conseguimos que toda la pantalla se muestre blanca y
el texto en azul para todo el programa, hasta que se encuentre el
compilador con otra linea que lo cambie. O sea que no ser
necesario seguir incluyendo la clusula CONTROL, en todos los
ACCEPT y DISPLAY que vayamos a utilizar mientras queramos
mantener ste formato.
Otros formatos de DISPLAY:
DISPLAY nombre de pantalla CLAUSULAS ..., podemos mostrar una
pantalla completa que previamente hayamos definido en la SCREEN
SECTION.
DISPLAY WINDOW CLAUSULAS ..., en Acucobol se utiliza para crear
las ventanas virtuales con las que Cobol puede trabajar, pero para ver su
uso, os podeis ir a la seccin que existe especfica para ello aqu.
PROCEDURE DIVISION
INSTRUCCIONES DE MOVIMIENTO DE VARIABLES.
Dar cabida en esta seccin a la explicacin de todas las instrucciones que hacen
referencia a las variables y sus valores. Como todas, este grupo de instrucciones tiene
su vital importancia en la programacin y son usadas habitualmente.
Instrucciones incluidas en esta seccin:
move, initialize, inspect, string, unstring
MOVE, es la instruccin que usaremos para enviar datos de una variable a otra u
otras.
Lo que en realidad hace es que la una variable adquiera un valor determinado, ya sea
procedente de otra variable o bien desde un valor fijo o constante.
Estos son los dos formatos que posee:
Formato 1:
MOVE variable, valor TO variable, variable, variable, ....
Con el primer formato las variables que siguen al TO tomarn el dato de la
variable o del valor que le preceden. De todo se ver al final una serie de
ejemplos bien detallados.
Siempre tendremos una serie de normas o restricciones para asegurarnos de
que los valores han pasado correctamente.
NUMERO1=001536
NUMERO2=0000153600 (La coma decimal es virtual)
NUMERO3= 1.536,00
TEXTO1=LENGUAJE COBOL
TEXTO2=LENGUAJE C
TEXTO3=
LENGUAJE COBOL
Formato 2:
MOVE CORR Identificador1 TO Identificador2
Agregando CORR a la instruccin conseguimos mover de una sola vez un
valor entre identificadores siempre que los campos que contengan
tengan el mismo nombre. Estos identificadores no pueden ir en niveles
66, 77 ni 88. El efecto es el mismo que si hicieramos tantos MOVE
normales como campos iguales tuviera el identificador. No es muy usual,
pero si hay casos en los que puede ser razonable su uso.
No es necesario que tengan el mismo PIC, ni que estn en el mismo
orden, solo que coincidan en su nombre.
...
WORKING-STORAGE SECTION.
01 DATOS1.
02 NOMBRE PIC X(30).
02 REGION PIC X(20).
02 PAIS
PIC X(15).
01 DATOS2.
02 PAIS
PIC X(10).
02 REGION PIC X(10).
02 NOMBRE PIC X(10).
...
PROCEDURE DIVISION.
INICIO.
MOVE "ANDRES MONTES" TO NOMBRE IN DATOS1.
MOVE "ANDALUCIA" TO REGION IN DATOS1.
MOVE "ESPAA" TO PAIS IN DATOS1.
MOVE CORR DATOS1 TO DATOS2.
...
Nota: Para partir con unos valores, primero los he movido a las variables del
primer grupo (DATOS1). Despus de aplicar el MOVE CORR, el valor de las
variables de DATOS2 sera:
DATOS2:
PAIS=ESPAA
REGION=ANDALUCIA
NOMBRE=ANDRES MON
Fijaros que aunque el orden ni el tamao era el mismo, el resultado es el que
queramos.
Veamos unos ejemplos para salir de dudas. Primero vamos a definir una
WORKING-STORAGE.
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8).
...
PROCEDURE DIVISION.
INICIO.
INSPECT TEXTO TALLYING CONTA FOR CHARACTERS.
...
El valor de conta ser de 15 que son los caracteres que tiene la
variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR ALL "A".
...
El valor de conta ser de 2 que son las veces que aparece la letra A
en la variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR LEADING "A".
...
El valor de conta ser de 0 porque no aparece ninguna A en el
primer carcter de la variable TEXTO.
INSPECT TEXTO TALLYING CONTA FOR ALL "A"
BEFORE INITIAL "N".
...
El valor de conta ser de 1 que son las veces que aparece la letra A
en la variable TEXTO hasta la aparicin del caracter N.
INSPECT TEXTO TALLYING CONTA FOR ALL "A"
Formato 2:
INSPECT campo1
REPLACING variable1 CHARACTERS BY Cambio1
((BEFORE/AFTER) INITIAL) Cadena1
(ALL)(LEADING)(FIRST) Cadena2 ...
(Se puede repetir de nuevo)
Con este formato podemos cambiar caracteres de Campo1, su
funcionamiento es igual que el anterior formato solo que en vez de
contar reemplaza. Se ha incluido solo FIRST, que indicara que solo se
reemplazara la primera vez que coincidieran las condiciones. El tamao
de la sustitucin debe de ser igual al tamao sustituido, ya que la
variable campo1 no puede cambiar su tamao.
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
77 CONTA PIC 9(8).
...
PROCEDURE DIVISION.
INICIO.
INSPECT TEXTO REPLACING CHARACTERS BY "H".
...
El valor de TEXTO ser "HHHHHHHHHHHHHHH", es decir cambia
todos los caracteres por el caracter H.
INSPECT TEXTO REPLACING ALL "A" BY "I".
...
El valor de TEXTO ser "PIGINI DE COBOL", es decir ha cambiado
todas las A por I.
INSPECT TEXTO REPLACING FIRST "A" BY "O".
...
El valor de TEXTO ser "POGINA DE COBOL", solo cambia la primera
A por una O.
...
Complicando un poco mas, el valor de TEXTO despues de la
sentencia INSPECT ser PAGI--TOPETOPA, es decir se cambia todas
...
Aqu hemos mezclado ambos formatos y el resultado es el siguiente.
El valor de CONTA es 3 que son las veces que aparece la cadena PA
en TEXTO y despus se ejecuta el REPLACING y el resultado da que
TEXTO vale PAGIPATOPEPOPA, ya que ha cambiado todos los TO por
PO pero despus de la cadena OP.
Formato 3:
INSPECT campo1
CONVERTING Identificador1 TO Identificador2
((BEFORE/AFTER) INITIAL) Cadena1 ...
(Se puede repetir de nuevo)
Con este formato convertimos los caracteres que se especifiquen en
identificador1 por los que pongamos en identificador2, respetando el
orden.
Veamos algunos ejemplos, se suele utilizar mucho para que al aceptar
un campo nos de igual se ha sido introducido en maysculas o en
minsculas ya que lo convertiriamos a alguno de los formatos.
...
WORKING-STORAGE SECTION.
77 TEXTO PIC X(15) VALUE "PAGINA DE COBOL".
...
PROCEDURE DIVISION.
INICIO.
INSPECT TEXTO CONVERTING "AO" TO "12".
...
El valor de TEXTO ser "P1GIN1 DE C2B2L", convertir todas las A
por 1 y todas las O por 2.
INSPECT TEXTO CONVERTING
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" TO
"abcdefghijklmnopqrstuvwxyz".
...
El valor de TEXTO ser "pagina de cobol" ya que ha convertido todas
las letras maysculas por minsculas.
Para finalizar con el comando INSPECT, decir que es un comando muy particular y cada
uno deber decidir en cada momento y con que situaciones utilizarlo.
DELIMITED BY, indica hasta donde vamos a "coger" del campo para concatenar
sin contar ese caracter o cadena que se especifique en campo2 o literal2, es
decir si tenemos un campo con un valor = "HOLA" y especificamos DELIMITED
BY "L" a la hora de la concatenacin nos hubiera cogido solo el HO, ya que al
encontrarse la primera L hubiera parado.
SIZE, indica que se pasar todo el contenido del campo1 o literal1 sin
limitaciones.
INTO, con esto indicamos en que variable se guardar el resultado, campo3.
WITH POINTER, si incluimos esta clusula el valor de identificador1 ser en la
posicin en que empezar a contener datos la variable que recibe el STRING.
Ese identificador1 debe estar definido como binario. Por defecto el valor es 1.
ON OVERFLOW, se ejecutara Sentencia1 si hubiera habido un error al hacer la
concatenacin, por ejemplo si se especifica Identificador1 con un valor superior
al tamao del Campo3.
NOT ON OVERFLOW, se ejecutar Sentencia2 si no existe error en la operacin.
Vamos a ver unos ejemplos y adems vamos a comparar como se hubiera hecho
utilizando la Working si no existiera el STRING.
...
WORKING-STORAGE SECTION.
01 LAFECHA.
02 FILLER PIC X(7) VALUE "HOY ES ".
02 LDIA PIC Z9.
02 FILLER PIC X(4) VALUE " DE ".
02 LMES PIC X(10).
02 FILLER PIC X(4) VALUE " DE ".
02 LANIO PIC 9999.
01 FECHA.
02 DIA PIC 99 VALUE 22.
02 MES PIC 99 VALUE 06.
02 ANIO PIC 9999 VALUE 2001.
01 CONSTRING PIC X(40).
01 TABLAMES.
02 FILLER PIC X(30) VALUE "ENERO
FEBRERO MARZO
".
02 FILLER PIC X(30) VALUE "ABRIL
MAYO
JUNIO
".
02 FILLER PIC X(30) VALUE "JULIO
AGOSTO SEPTIEMBRE".
02 FILLER PIC X(30) VALUE "OCTUBRE NOVIEMBREDICIEMBRE
".
01 LATABLA REDEFINES TABLAMES.
02 TMES PIC X(10) OCCURS 12 TIMES.
01 PUNTO PIC 9(4) BINARY.
...
PROCEDURE DIVISION.
INICIO.
MOVE DIA TO LDIA.
MOVE TMES (MES) TO LMES.
MOVE ANIO TO LANIO.
STRING "HOY ES " DIA " DE " TMES (MES) " DE " ANIO
DELIMITED BY SIZE INTO CONSTRING.
...
El valor de LAFECHA sera: HOY ES 22 DE JUNIO
DE 2001.
DE 2001.
MOVE 4 TO PUNTO.
STRING "HOY ES " DIA " DE " DELIMITED BY SIZE
TMES (MES) DELIMITED BY " "
" DE " ANIO DELIMITED BY SIZE INTO CONSTRING
WITH POINTER PUNTO.
El valor que tendr ahora CONSTRING ser el siguiente:
HOY ES 22 DE JUNIO DE 2001.
UNSTRING, hace exactamente lo contrario de que hemos visto que haca STRING, es
decir divide el contenido de un campo en otros.
UNSTRING campo1, literal1
DELIMITED BY (campo2, literal2)(ALL)
OR (campo2, literal2)(ALL)
(Se puede repetir de nuevo)
INTO Campo3, Campo4, ....
(DELIMITER Identificador1)
(COUNT Identificador2)
(Se puede repetir de nuevo)
(WITH POINTER Identificador3)
(TALLYING Identificador4)
(ON OVERFLOW Sentencia1)
(NOT ON OVERFLOW Sentencia2)
DELIMITED BY, indica el lmite hasta donde vamos cogiendo el campo1 para
partirlo. Igual que en STRING, solo que con la funcin a la inversa.
OR es igual que DELIMITED y se utiliza si hay varios delimitadores sobre los que
buscar.
INTO indica en que campo o campos se guardar la informacin que vaya
fragmentando.
DELIMITER va a contener en cada caso el elemento separador, si hemos incluido
en DELIMITED varios, Identificador1 guardar el carcter que de los elegidos ha
sido el causante de la fragmentacin.
COUNT cuenta el nmero de caracteres incluidos en la fragmentacin.
DELIMITER y COUNT se podrn usar si se ha especificado DELIMITED. Podemos
usar tantos DELIMITER y COUNT como campos se vayan a crear en la
fragmentacin.
TALLYING si especificamos esta opcin la instruccin nos guardar en
Identificador4 el nmero de campos que se han utilizado en la fragmentacin.
POINTER indica desde que posicin va a ser examinado el campo que desea
desfragmentar, por defecto su valor es 1, es decir desde el primer caracter.
ON OVERFLOW, se ejecutara Sentencia1 si hubiera habido un error al hacer la
operacin.
NOT ON OVERFLOW, se ejecutar Sentencia2 si no existe error en la operacin.
Vamos a hacer lo contrario de antes y conseguir una fecha numrica de una frase con
la fecha:
...
WORKING-STORAGE SECTION.
01 LAFECHA PIC X(30) VALUE "HOY ES 22 DE JUNIO DE 2001".
01 FECHA.
...
TEXTO1 = HOY
TEXTO2 = ES
TEXTO3 = DE
TEXTO4 = DE
ELMES = JUNIO
DIA = 22
ANIO = 2001
FECHA = 22062001
LETRAS = 5
PALABRAS = 7
...
PROCEDURE DIVISION
PERFORM. Creo que por mritos propios esta instruccin se merece un apartado para
ella sola. Es una instruccin que nos permite tranferir el control a otro u otros
procedimientos o bien realizar una serie de sentencias dentro de ella misma mientras
se cumplan las condiciones que le hayamos indicado. Es la instruccin mas importante
tanto por su variedad de formatos, como por el nmero de veces que se suele usar
dentro de un programa, adems nos puede hacer mucho mas sencillo el realizar una
programacin estructurada.
Cuando decimos que un programa est estructurado, no cabe duda que es debido al
uso de sta instruccin. Pero creo que lo importante no es tanto hablar de ella, sino
comenzar a explicarla.
Empecemos a ver sus formatos desde el mas simple al mas complicado: Siempre
debis de tener en cuenta que los ejemplos son solo para aclarar la explicacin, nunca
los tomis como programas completos y con una lgica aplastante.
Formato 2: Una extensin del anterior es indicarle que ejecute mas de un prrafo,
especificando el inicio y el fin.
PERFORM nombre_parrafo THRU nombre_parrafo
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 OP PIC X.
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE.
PERFORM PIDENOMBRE THRU PIDEAPELLIDO.
...
Formato 4: Igual que el antrior formato solo que el nmero de veces que se ejecute
depender de una condicin y no de un nmero fijo.
PERFORM nombre_parrafo THRU nombre_parrafo UNTIL condicin
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 OP
PIC X.
01 LI
PIC 99 VALUE 10.
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE.
PERFORM PIDENOMBRE THRU PIDEAPELLIDO.
PERFORM SALUDAR UNTIL LI = 15.
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.
SALUDAR.
ADD 1 TO LI.
DISPLAY 'HOLA ' LINE LI.
DISPLAY NOMBRE LINE LI COL 6.
DISPLAY APELLIDO LINE LI COL 20.
ACCEPT OP LINE 20.
...
Nota: En este caso el compilador comprueba antes de iniciar el
PERFORM que la condicin no se cumple para ejecutarla, en el
momento que se cumpla salta a la siguiente instruccin. En el
ejemplo ejecutar el PERFORM hasta que la variable LI alcance el
valor 15.
PRIMERA CONCLUSION
En los dos primeros formatos, como podris comprobar a menos que sean
instrucciones que se vayan a llamar desde nuestro programa en mas de una ocasin,
stas podan haber ido en el lugar del PERFORM, es decir las instrucciones una detrs
de otra y evitar el PERFORM.
Hasta ahora se ha explicado una manera de utilizar la sentencia PERFORM en la que el
control pasa a otro lugar del programa. Como vis el STOP RUN est antes de los
prrafos que han sido llamados con los PERFORM lo cual indica que stos no se
ejecutarn sino es precisamente por los PERFORM.
Si bien con esto conseguimos una estructuracin para nuestro programa la instruccin
PERFORM nos permite un mayor grado de estructura incluyendo las sentencias de los
prrafos llamados dentro de la propia sentencia PERFORM.
Para ello hay que tener en cuenta que la utilizacin del punto en las instrucciones dara
lugar al fin de la instruccin y nos dara errores, por ello, para finalizar la instruccin
nos basamos en END-PERFORM. Veamos un ejemplo de ello con los dos ltimos
formatos explicados anteriormente.
PERFORM nmero-variable TIMES
sentencias
END-PERFORM
PERFORM UNTIL condicin
sentencias
END-PERFORM
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 OP
PIC X.
01 LI
PIC 99 VALUE 10.
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE.
PERFORM PIDENOMBRE THRU PIDEAPELLIDO.
PERFORM 3 TIMES
ADD 1 TO LI
DISPLAY 'HOLA ' LINE LI
DISPLAY NOMBRE LINE LI COL 6
DISPLAY APELLIDO LINE LI COL 20
ACCEPT OP LINE 20
END-PERFORM
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.
...
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 OP
PIC X.
01 LI
PIC 99 VALUE 10.
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE.
PERFORM PIDENOMBRE THRU PIDEAPELLIDO.
PERFORM UNTIL LI = 15
ADD 1 TO LI
DISPLAY 'HOLA ' LINE LI
DISPLAY NOMBRE LINE LI COL 6
DISPLAY APELLIDO LINE LI COL 20
ACCEPT OP LINE 20
END-PERFORM
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: Esta es una manera mas lgica de utilizar el PERFORM en
estos formatos, como ves se consigue una visin muy clara de lo
que estamos haciendo y no hay saltos de secuencia innecesarios.
Por supuesto el COBOL permite cualquier modalidad de uso y
siempre funcionara igual. Como veis no puede haber puntos entre el
PERFORM y en END-PERFORM puesto que eso hara terminar con
error la sentencia.
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 OP
PIC X.
01 LI
PIC 99.
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE.
PERFORM PIDENOMBRE THRU PIDEAPELLIDO.
PERFORM VARYING LI FROM 10 BY 1 UNTIL LI = 15
DISPLAY 'HOLA ' LINE LI
DISPLAY NOMBRE LINE LI COL 6
DISPLAY APELLIDO LINE LI COL 20
ACCEPT OP LINE 20
END-PERFORM
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.
...
La instruccin realiza los siguientes pasos:
Inicializa la variable LI con el valor que sigue al FROM, es decir 10, a continuacin va
incrementado el valor de LI en 1 que es lo que va despus del BY y ejecuta las
sentencias que van a continuacin hasta que se cumple la condicin de LI = 15.
Es decir las sentencias se ejecutaran para el valor 10, 11, 12, 13 y 14.
La instruccin PERFORM se puede anidar tantas veces como se quiera, teniendo en
cuenta que el PERFORM contenido debe de ejecutarse completamente interno o
completamente externo al que lo contiene.
Si necesitamos que por alguna circunstancia finalice la ejecucin de un PERFORM an
cuando la secuencia no corresponde, podemos utilizar la sentencia EXIT, que
precisamente lo que propicia es eso, que se interrumpa la sentencia PERFORM.
Para finalizar vamos a ver un ejemplo con varios PERFORM anidados:
...
WORKING-STORAGE SECTION.
01 NOMBRE PIC X(12).
01 APELLIDO PIC X(12).
01 SALUDO PIC X(30).
01 OP
PIC X.
01 LI
PIC 99.
01 CONTA1 PIC 99.
01 CONTA2 PIC 9(6).
PROCEDURE DIVISION.
INICIO.
DISPLAY 'PROGRAMA DE SALUDO' LINE 1 ERASE
PERFORM PIDENOMBRE THRU PIDEAPELLIDO
STRING 'HOLA ' DELIMITED BY SIZE NOMBRE DELIMITED BY ' '
' ' DELIMITED BY SIZE APELLIDO DELIMITED BY ' ' INTO SALUDO
PERFORM VARYING LI FROM 10 BY 1 UNTIL LI = 15
PERFORM VARYING CONTA1 FROM 1 BY 1 UNTIL CONTA1 > 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 vis, despus de aceptar el nombre y el apellido
construimos una frase y la guardamos en la variablen SALUDO utilizando el
comando STRING. A continuacin y para mantener los mismos ejemplos de
toda la seccin hacemos que aparezca en pantalla el SALUDO 5 veces,
(dependiendo del valor de LI, que como dijimos antes sera 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 escribiramos el SALUDO con una mquina de
escribir.
Como pdeis observar el nico punto de toda la secuencia se haya en el STOP
RUN. El hecho de mantener los mrgenes izquierdos, es para dar mas
claridad a la programacin y conseguir que sta sea lo mas estructurada
posible.
En primer lugar, por defecto el contenido del PERFORM se ejecuta despus de hacer la
comprobacin de la condicin que precede a UNTIL, pero podemos hacer que sta se
realice antes.
PERFORM WITH TEST [AFTER - BEFORE ] VARYING
variable FROM nmero, variable BY nmero, valor UNTIL condicin
sentencias
END-PERFORM
Con la opcin TEST BEFORE, que es la opcin por defecto se comprueba primero la
condicin 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 condicin.
Con la opcin TEST AFTER, se ejecutan las sentencias antes de comprobar la
condicin, con lo cual las sentencias se van a ejecutar al menos en una ocasin, incluso
aunque entremos en el PERFORM con la condicin rota.
AUMENTANDO LAS CONDICIONES
Efectivamente adems de la primera condicin podemos incrementar el nmero de
condiciones para que se cumplan los requisitos y as ejecutar las sentencias. Esto lo
conseguimos incluyendo mas clusulas precedidas de AFTER.
PERFORM WITH TEST [AFTER - BEFORE ] VARYING
variable FROM nmero, variable BY nmero, valor UNTIL condicin
AFTER variable FROM nmero, variable BY nmero, valor UNTIL
condicin
sentencias
AFTER .......
END-PERFORM
Al aplicar este formato cuando se cumpla la primera condicin pasar el control al
AFTER y comprobar de nuevo la condicin que precede al siguiente UNTIL segn los
valores especificados en la lnea que contiene AFTER. Adems podemos ir
incrementando el nmero 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 utilizacin de PERFORM sin duda traer un uso menor de la declaracin GO
y con ello conseguimos una programacin estructurada. Las ventajas de la
programacin estructurada las quiero explicar en un apartado dentro de sta misma
seccin de Manuales, una vez explique las sentenicas GO e IF, que sern la siguiente
aportacin al manual.
En esa nueva seccin se ver un caso mas prctico y real de utilizacin de PERFORM
con uso de lecturas de ficheros y dems experiencias cotidianas en el mundo de la
programacin en el mbito de la gestin.
CODIGOS DE ERROR
Son muchos los errores que se pueden producir en tiempo de ejecucin cuando
trabajamos con archivos, a continuacin dar una explicacin de los mas comunes.
Todos stos errores los podemos obtener si definimos FILE STATUS en la FILECONTROL, y actuar consecuentemente, por ejemplo yo siempre cuando abro los
ficheros al principio de cada programa compruebo que el error sea 00, es decir que
todo est bien para continuar, sino automaticamente saco una ventanita con el error
que se ha producido y el nombre del fichero para que mis usuarios me lo comuniquen
y poder solucionarlo, pero no dejo que se siga ejecutando el programa, con lo que se
evitarn problemas posteriores que podran resultar peores. De todas formas una vez
que est el programa verificado y comprobado, y que todos los archivos se
corresponden con su descripcin en la FD, los errores que nos puede dar son los
relativos a claves duplicadas o inexistentes, o a errores del sistema.
Los errores se representan como 2 digitos para el error que pueden ir seguidos de una
coma y otros 2 dgitos para indicar la naturaleza del error.
ERROR
EXPLICACION
00
10
22
23
24
30
34
35
39
41
42
43
47
48
49
90
91
92
93
94
98
99
A pesar de todos stos errores con algunos de ellos podriamos seguir trabajando, pero
siempre es mejor corregirlos antes de que pasen a mayores.
Para evitar bloqueos en los registros cuando trabajamos con varios usuarios
accediendo a los mismos registros, es convenientoe tener en cuenta los modos de
apertura de los ficheros, ya que abrindolos en INPUT nunca habr problema de
bloqueo.
VENTANAS EN COBOL
Que son y para que sirven las "ventanas" en cobol ?.
Este nombre del que estamos tan acostumbrados a oir y que parece que es propiedad
de Microsoft, tiene otras y muy diversas utilidades. Una ventana es en realidad una
porcin virtual de la pantalla, la cual podremos definir con unas caractersticas propias
de tamao, color, etc ...
Hasta que stas aparecieron, cada vez que queriamos sobreponer una informacin a la
que tenamos en pantalla, la construiamos encima y despus, debiamos de volver a
pintar la que estuviera debajo. Con el uso de las ventanas sto ya no es necesario. Os
pondr un ejemplo:
Supongamos que tenemos un mantenimiento de clientes, el cual nos
ocupa toda la pantalla, y vamos a introducir la provincia. Si en ste
momento quisieramos mostrarle una tabla con todas las opciones
VENTANAS EN RM/COBOL.
En RM/Cobol, todas las caractersticas se dan mediante unas variables definidas en la
WORKING, stas son las siguientes. Por supuesto le puedes poner el nombre que
quieras a las variables, ya que lo que al final vamos a conseguir es darle una variable
con longitud 80 y una sentencia para que la ventana se dibuje.
01 WCB.
03 WINCAB
03 WINLIN
03 WINCOL
03 WINLOC
*
(S-W)
03 WINBORST
*
(Y-N)
03 WINBORTI
03 WINBORCH
03 WINLLE
*
(Y-N)
03 WINLLECH
03 WINTITSI
*
(T-B)
PIC
PIC
PIC
PIC
03 WINTITPO
(C-L-R)
03 WINTITLO
03 WINTIT
...
MOVE 10 TO WINLIN.
MOVE 40 TO WINCOL.
MOVE " PROBANDO VENTANAS " TO WINTIT.
MOVE 19 TO WINTITLO.
MOVE WCB TO WIN (1).
DISPLAY WIN (1) LINE 3 COL 3 LOW ERASE
CONTROL "WINDOW-CREATE".
MOVE 1 TO WINLIN.
MOVE 30 TO WINCOL.
MOVE SPACES TO WINTIT MOVE 0 TO WINTITLO.
MOVE WCB TO WIN (2).
DISPLAY WIN (2) LINE 5 COL 10 LOW ERASE
CONTROL "WINDOW-CREATE".
* Cuando usamos mas de una ventana, deberemos de ir
* cerrndolas segn la ltima que se abri.
DISPLAY WIN (2) CONTROL "WINDOW-REMOVE".
DISPLAY WIN (1) CONTROL "WINDOW-REMOVE".
VENTANAS EN ACUCOBOL.
Para dibujar una ventana en Acucobol, todo se realizar desde la Procedure y solo ser
necesario incluir en la WORKING una variable de PIC X(10), que nos servir
principalmente para tener varias ventanas abiertas y saber sobre cual actuamos. Esto
se consigue con una implementacin de la sentencia DISPLAY, que vamos a explicar a
continuacin.
WORKING-STORAGE SECTION.
01 VENTANAS.
02 WIN PIC X(10) OCCURS 10 TIMES.
...
...
PROCEDURE DIVISION.
...
...
DISPLAY WINDOW LINE 3 COL 3 LOW ERASE
SIZE 40 LINES 10
BOXED SHADOW
TOP CENTERED TITLE " PROBANDO "
POP-UP AREA WIN (1).
* Para cerrarla, utilizaremos la siguiente instruccin.
CLOSE WINDOW WIN (1).
RESUMIENDO
Ya veis, que aunque cambie un poco la sintaxis, el fin es exactamente el mismo,
disponer de una parte de la pantalla con autonoma propia.
Solo espero que despus de stas explicaciones seais capaces de aprovechar todas las
ventajas que nos puede proporcionar el trabajar con ventanas. Yo siempre las he
utilizado, eso si, tampoco deberemos de hacer de un programa cobol, una serie de
ventanas, hay que utilizarlas cuando realmente las necesitemos. Recordad que:
El control solo ser sobre la ventana activa.
Una vez abierta una ventana, sta tendr el control, hasta que se cierre.
Por supuesto, todas la variables que utilicemos sern portables entre
ventanas, ya que en realidad estaremos en el mismo programa.
PALABRAS RESERVADAS
Las palabras reservadas del Cobol, son aquellas que el propio compilador utiliza y por
lo tanto no podemos utilizar como variables en nuestros programas. Estas han ido
avanzando con el paso de los tiempos y cada compilador incluso, incluyendo nuevas.
Aqu voy a poner una lista de la cantidad mayor que pueda.
SELECCIONA LA LETRA, PARA IR DIRECTAMENTE O AVANZA POR LA PAGINA
A B C D E F G H I J K L M N O P Q R S T U V W Z
Otras
ACCEPT
ADDRESS
ALL
ALPHABETIC-LOWER
ALPHANUMERIC-EDITED
ALTERNATE
APPLY
AREAS
AT
AUTO-SKIP
ACCESS
ADVANCING
ALPHABET
ALPHABETIC-UPPER
ALSO
AND
ARE
ASCENDING
AUTHOR
AUTOMATIC
ADD
AFTER
ALPHABETIC
APHANUMERIC
ALTER
ANY
AREA
ASSIGN
AUTO
AUTOTERMINATE
BACKGROUND
BACKGROUND-LOW
BEFORE
BINARY
BLINKING
BOTTOM
B
BACKGROUND-COLOR
BACKWARD
BELL
BLANK
BLOCK
BY
BACKGROUND-HIGH
BEEP
BIND
BLINK
BOLD
CALL
CF
CHARACTERS
COBOL
COL
COMMA
COMP-1
COMP-4
COMPUTATIONAL-1
COMPUTATIONAL-4
CONSOLE
CONTINUE
CONVERSION
COPY
COUNT
CURSOR
C
CANCEL
CH
CLASS
CODE
COLLATING
COMMUNICATION
COMP-2
COMP-6
COMPUTATIONAL-2
COMPUTE
CONTAINS
CONTROL
CONVERT
CORR
CRT
DATA
DATE-WRITTEN
DE
DECIMAL-POINT
DELETE
D
DATE
DAY
DEBUG
DECLARATIVES
DELIMITED
CD
CHARACTER
CLOSE
CODE-SET
COLUMN
COMP
COMP-3
COMPUTATIONAL
COMPUTATIONAL-3
CONFIGURATION
CONTENT
CONTROLS
CONVERTING
CORRESPONDING
CURRENCY
DATE-COMPILED
DAY-OF-WEEK
DEBUGGING
DEFAULT
DELIMITER
DEPENDING
DETAIL
DIVIDE
DUPLICATES
DESCENDING
DISABLE
DIVISION
DYNAMIC
ECHO
EMI
END
END-CALL
END-DIVIDE
END-MULTIPLY
END-READ
END-REWRITE
END-STRING
END-WRITE
EOL
EQUAL
ESCAPE
EVERY
EXIT
E
EGI
EMPTY-CHECK
END-ACCEPT
END-COMPUTE
END-EVALUATEQ
END-OF-PAGE
END-RECEIVE
END-SEARCH
END-SUBTRACT
ENTER
EOP
ERASE
ESI
EXCEPTION
EXTEND
DESTINATION
DISPLAY
DRAWN
FALSE
FILE-CONTROL
FILLER
FOOTING
FOREGROUND-COLOUR
F
FD
FILE-ID
FINAL
FOR
FROM
FILE
FILE-PREFIX
FIRST
FOREGROUND-COLOR
FULL
GENERATE
GO
GRID
G
GIVING
GOBACK
GROUP
ELSE
ENABLED
END-ADD
END-DELETE
END-IF
END-PERFORM
END-RETURN
END-START
END-UNSTRING
ENVIRONMENT
EOS
ERROR
EVALUATE
EXCLUSIVE
EXTERNAL
HEADING
HIGH-VALUES
H
HIGH
HIGHLIGHT
I-O
IF
I
I-O CONTROL
IN
GLOBAL
GREATER
HIGH-BALUE
IDENTIFICATION
INDEX
INDEXED
INITIALIZE
INSPECT
INVALID
JUST
INDICATE
INPUT
INSTALLATION
IS
INITIAL
INPUT-OUTPUT
INTO
J
JUSTIFIED
KEY
LABEL
LEFT
LENGTH-CHECK
LIMITS
LINES
LOCK-HOLDING
LOW-VALUES
L
LAST
LEFTLINE
LESS
LINAGE
LINKAGE
LOW
LOWLIGHT
MEMORY
MODULES
MULTIPLY
NATIVE
NO
NUMBER
OBJECT-COMPUTER
OFF
OPEN
ORDER
OTHERS
OVERLINE
M
MERGE
MOVE
N
NEGATIVE
NO-ECHO
NUMERIC
O
OCCURS
OMITTED
OPTIONAL
ORGANIZATION
OUTPUT
LEADING
LENGTH
LIMIT
LINGAKE-COUNTER
LOCK
LOW-VALUE
MODE
MULTIPLE
NEXT
NOT
NUMERIC-EDITED
OF
ON
OR
OTHER
OVERFLOW
PACKED-DECIMAL
PAGE-COUNTER
PICTURE
POS
PREVIOUS
PROCEDURE
PROGRAM
PROTECTED
P
PADDING
PERFORM
PLUS
POSITION
PRINT-CONTROL
PROCEDURES
PROGRAM-ID
PURGE
QUEUE
Q
QUOTE
RANDOM
READERS
RECORDING
REEL
RELATIVE
REMOVAL
REPLACING
REPORTING
RESERVE
RETURN-CODE
REVERSE-VIDEO
REWRITE
RIGHT
R
RD
RECEIVE
RECORDS
REFERENCE
RELEASE
RENAMES
REQUIRED
REPORTS
RETURN
RETURN-UNSIGNED
REVERSED
RF
ROLLBACK
SAME
SEARCH
SECURITY
SELECT
SEPARATE
SET
SORT
SOURCE-COMPUTER
SPECIAL-NAMES
STATUS
SUBTRACT
SYNC
S
SCREEN
SECTION
SEGMENT
SEND
SEQUENCE
SIGN
SORT-MERGE
SPACE
STANDARD
STOP
SUPPRESS
SYCHRONIZED
PGE
PIC
POINTER
POSITIVE
PRINTING
PROCEED
PROMPT
QUOTES
READ
RECORD
REDEFINES
REFERENCES
REMAINDER
REPLACE
REPORT
RERUN
RETUNRNIN
REVERSE
REWIND
RH
RUN
SD
SECURE
SEGMENT-LIMIT
SENTENCE
SEQUENTIAL
SIZE
SOURCE
SPACES
START
STRING
SYMBOLIC
TAB
TERMINAL
TEXT
THROUGH
TIMES
TRAILING
UNDERLINE
UNLOCK
UP
UPON
USING
T
TALLYNG
TERMINATE
THAN
THRU
TO
TRUE
U
UNDERLINED
UNSTRING
UPDATE
USAGE
VALUE
WHEN
WORKING-STORAGE
ZERO
TAPE
TEST
THEN
TIME
TOP
UNIT
UNTIL
UPDATES
USE
V
VALUES
VARYING
W
WITH
WRITE
WORDS
WRITERS
Z
ZEROS
ZEROES
AUTO-MINIMIZE
BOXED
CELLS
COLOUR
DESTROY
ENCRYPTION
FEXTERNAL-FORM
FLOATING
HANDLE
ICON
INQUIRE
MANUAL
AUTO-RESIZE
CCOL
CENTERED
CSIZE
DOUBLE
END-DISPLAY
FILE-PREFIX
FONT
HEIGHT
ID
LINK
MENU
MESSAGE
MODIFY
OBJECT
PARAGRAPH
PROPERTY
SHADOW
SYSTEM-INFO
THREAD
TOOL-BAR
VISIBLE
WINDOW
MODAL
NULL
ONLY
POP-UP
RESIZABLE
STYLE
TABLE
TITLE
TRANSACTION
WAIT
WRAP
MODELESS
NULL
OVERLAPPED
PRIORITY
SCROLL
SYSTEM
TERMINAL-INFO
TITLE-BAR
UPPER
WIDTH
02 KEYAGE.
03 AGECOD
02 AGENOM
02 AGEDOM
02 AGEPOS
02 AGEPOB
02 AGEPRO
02 AGETEL
02 AGEMOV
02 AGEMAI
02 AGEWEB
SD
01
ORDEN.
REGORD.
02 ORDNOM
02 ORDPOB
02 ORDPRO
PIC 9(4).
PIC X(30).
PIC X(30).
PIC 9(5).
PIC X(20).
PIC X(15).
PIC X(20).
PIC X(20).
PIC X(30).
PIC X(40).
PIC X(30).
PIC X(30).
PIC X(30).
Notad que hemos sustituido FD (File Descrition) por SD (Sort Description) para
nuestro fichero de clasificacin y que solo hemos incluido en ste fichero tres
campos, los que nosotros hemos escogido para hacer las clasificaciones. Este
archivo puede tener todos los campos que se desee, incluso otros que no estn
en el fichero a clasificar. Adems el orden en que figuren no tiene importancia ni
significa nada a la hora de clasificar. Con la SD solo indicamos los campos que
va a tener el fichero.
A partir de aqu, nuestro programa puede continuar normalmente hasta llegar al
momento en que deseemos clasificar y para ello vamos a ver un poco como es la
sintaxis de una sentencia SORT.
Formato 1: Este formato se utiliza para clasificar un archivo y guardar el
contenido del fichero clasificado en otro archivo. Esta opcin no se suele utilizar
ya que tiene pocas posibilidades. Tendramos un fichero en el que se basara
SORT para clasificar, un fichero maestro del que leeriamos para clasificar y el
resultado lo guardara en otro fichero.
SORT fichero_de_clasificacion
(ON ASCENDING KEY) campo
(ON DESCENDING KEY) campo
USING fichero a clasificar
GIVING fichero que quedar clasificado
Formato 2: Este formato es mas utilizado ya que el control de la clasificacin lo
hacemos nosotros tanto antes como despus.
SORT fichero_de_clasificacion
(ON ASCENDING KEY) campo
(ON DESCENDING KEY) campo
INPUT PROCEDURE que_hacemos antes
OUTPUT PROCEDURE que hacemos despues
que hacemos despues: indicaremos que hacer una vez el fichero est
clasificado. Igual que antes podremos indicar un prrafo o varios o
utilizar una SECTION.
TABLAS
El uso de tablas en Cobol es algo muy frecuente y por eso he decidido crear un
apartado especfico para hablar de ellas. En la seccin Data Division, dentro de
manuales, podris encontrar una explicacin de cada comando o clusula que veamos
de aqu en adelante.
En primer lugar daremos una definicin de ellas. 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 subndice. Todo lo que voy a explicar aqu, se har desde lo ms
bsico. Con un ejemplo lo vamos a ver mas claro:
Imaginaros que queremos tener la informacin de cuantas personas entran a un
museo cada da de la semana. Si como mximo entran al da mas o menos
1.000 personas deberamos declarar siete variables de la siguiente manera:
01
01
01
01
01
01
01
LUNES
MARTES
MIERCOLES
JUEVES
VIERNES
SABADO
DOMINGO
PIC
PIC
PIC
PIC
PIC
PIC
PIC
9(4).
9(4).
9(4).
9(4).
9(4).
9(4).
9(4).
200 TO LUNES.
430 TO MARTES.
136 TO MIERCOLES.
525 TO JUEVES.
380 TO VIERNES.
1910 TO SABADO.
2300 TO DOMINGO.
Fijaros que todas son del mismo tipo (numricas) y del mismo tamao (4), por
lo tanto cumplen el requisito para crear una tabla, as que vamos a sustituir
todo lo anterior haciendo uso de una tabla.
01 DIASEMANA.
02 VISITAS PIC 9(4) OCCURS 7 TIMES.
Ahora tendremos una nica variable donde guardar los datos y se llamar
VISITAS. Para introducir los datos lo haramos refirindonos con un subndice a
cada uno de sus elementos, siete en este caso, porque siete son los das de la
semana. Lo ms lgico ser respetar el orden de los das, es decir 1 para el
Lunes, 2 para el Martes, etc ...
MOVE
MOVE
MOVE
MOVE
MOVE
MOVE
MOVE
El resultado es el mismo, pero solo hemos tenido que declarar una variable. Por
supuesto el nmero que hace referencia al subndice puede ser a su vez una
variable, como veremos un poco mas abajo.
Cobol tambin posee la capacidad de crear una tabla y rellenarla a su vez
utilizando la WORKING-STORAGE SECTION. Para ello primero declaramos los
valores en una variable y gracias a la clusula REDEFINES, hacemos que su
valor se cargue en la tabla. Eso no quiere decir que su valor no se pueda
cambiar, pero al iniciar el programa, la tabla contendr esos valores. Para seguir
con el ejemplo crearemos una con los das de la semana.
01 TABLADIAS.
02 FILLER
02 FILLER
02 FILLER
02 FILLER
02 FILLER
02 FILLER
02 FILLER
01
TABLADEDIAS
02 ELDIA
WORKING-STORAGE SECTION.
01 DIA
PIC 9.
01 LVISITAS PIC Z.ZZ9.
...
PROCEDURE DIVISION.
...
PEDIR.
DISPLAY "INTRODUZCA DIA PARA VER SUS VISITAS"
LINE 4 COL 20.
ACCEPT DIA LINE 4 COL 50 PROMPT LOW.
IF DIA < 1 OR DIA > 7 GO PEDIR.
DISPLAY "EL " LINE 10 COL 20.
DISPLAY ELDIA (DIA) LINE 10 COL 23.
DISPLAY "HUBO " LINE 10 COL 33.
MOVE VISITAS (DIA) TO LVISITAS.
DISPLAY LVISITAS LINE 10 COL 38.
DISPLAY "VISITAS." LINE 10 COL 44.
Al introducir, por ejemplo el valor 3 el resultado hubiera sido:
EL MIERCOLES HUBO 136 VISITAS.
01 DIASEMANA.
02 GENERO
OCCURS 2 TIMES.
03 VISITAS PIC 9(4) OCCURS 7 TIMES.
Como veis nuestra tabla contiene dos clusulas OCCURS, con ello hemos
conseguido crear una matriz de 2 x 7, ahora la variable VISITAS tendr 14
elementos. Para dirigirnos a ellos utilizaremos dos subndices. En nuestro caso
al diferenciar el gnero, identificaremos con el valor 1 a los hombres y con el 2
a las mujeres. Veamos como rellenamos la tabla ahora:
MOVE
MOVE
MOVE
MOVE
MOVE
MOVE
MOVE
Por supuesto al igual que antes los subndices pueden ser sustituidos por
variables. Por ejemplo, sabiendo los datos anteriores vamos a sumar todas las
mujeres que entraron en la semana y todos los hombres y vamos a averiguar
cual fue el da de mayor visitas y el da de menor asistencia.
WORKING-STORAGE SECTION.
01 DIA
PIC 9.
01 LVISITAS PIC Z.ZZ9.
01 MAYOR PIC 9(4) VALUE 0.
01 MENOR PIC 9(4) VALUE 9999.
01 DIAMAYOR PIC 9.
01 DIAMENOR PIC 9.
01 TOTAL PIC 9(4).
01 HOMBRES PIC 9(4).
01 MUJERES PIC 9(4).
...
PROCEDURE DIVISION.
...
MOVE 0 TO DIA.
MIRAR.
ADD 1 TO DIA IF DIA > 7 GO FIN.
ADD VISITAS (1, DIA) TO HOMBRES.
ADD VISITAS (2, DIA) TO MUJERES.
COMPUTE TOTAL = VISITAS (1, DIA) + VISITAS (2, DIA).
IF TOTAL > MAYOR MOVE TOTAL TO MAYOR
MOVE DIA TO DIAMAYOR.
IF TOTAL < MENOR MOVE TOTAL TO MENOR
MOVE DIA TO DIAMENOR.
GO MIRAR.
FIN.
...
LLENANDO TABLAS
Ahora imaginamos que los datos de la tabla de visitas, en vez de asignarlos con
un MOVE como hemos hecho en los ejemplos anteriores, los vamos a pedir
mediante ACCEPT en un programa. Vamos a hacer un pequeo programa para
que veais como quedara:
WORKING-STORAGE SECTION.
01 DIASEMANA.
02 GENERO
OCCURS 2 TIMES.
03 VISITA PIC 9(4) OCCURS 7 TIMES.
01 SUB1
PIC 9.
01 SUB2
PIC 9.
01 OP
PIC X.
01 LGENERO PIC X(7).
...
PROCEDURE DIVISION.
INICIO.
DISPLAY "CAPTURA DE DATOS" LINE 2 COL 10 ERASE.
MOVE 0 TO SUB1 SUB2.
METER.
BUSCANDO EN TABLAS
Para buscar en las tablas existe un comando propio llamado SEARCH, que
veremos al final del captulo, pero ahora vamos a hacer una busqueda por
subndices normal para encontrar alguno o varios elementos que cumplan una
determinada condicin. Por ejemplo, siguiendo con nuestra tabla (es un poco
pequea, pero podra ser todo lo grande que quisieramos, siempre que no
desbordaramos la memoria del ordenador o la capacidad del compilador),
vamos a buscar los das en los que la afluencia es mayor de 1.000 personas,
para saber si es necesario contratar a mas personal para esos das.
Pero para complicar un poco mas el asunto, vamos a meter dichos das en otra
tabla y as aprendemos a trabajar con mas de una tabla a la vez.
WORKING-STORAGE SECTION.
01 DIASEMANA.
02 GENERO
OCCURS 2 TIMES.
03 VISITA PIC 9(4) OCCURS 7 TIMES.
01 TABLA1000.
02 ELEMENTOS1000 OCCURS 7 TIMES.
02 DIA1000
PIC 9.
02 VISITAS1000 PIC 9(4).
01 SUB1
PIC 9.
01 SUB2
PIC 9.
01 SUB3
PIC 9.
01 TOPE
PIC 9.
01 OP
PIC X.
01 LGENERO PIC X(7).
...
PROCEDURE DIVISION.
INICIO.
DISPLAY "BUSCANDO DIAS DE MAS DE 1000 VISITAS"
LINE 2 COL 10 ERASE.
MOVE 0 TO SUB1 SUB2.
BUSCAR.
ADD 1 TO SUB1 IF SUB1 > 7 GO MOSTRAR.
COMPUTE TOTAL = VISITAS (1, SUB1) + VISITAS (2,SUB1).
IF TOTAL > 1000
ADD 1 TO SUB2 MOVE SUB1 TO DIA1000 (SUB2)
MOVE TOTAL TO VISITAS1000 (SUB2).
GO BUSCAR.
MOSTRAR.
MOVE SUB2 TO TOPE MOVE 0 TO SUB2.
MOSTRAR1.
ADD 1 TO SUB2 IF SUB2 > TOPE GO FIN.
DISPLAY "EL " LINE 10 COL 29.
MOVE DIA1000 (SUB2) TO SUB3.
DISPLAY TSEM (SUB3) LINE 10 COL 37.
DISPLAY VISITAS1000 (SUB2) LINE 10 COL 50.
GO MOSTRAR1.
FIN.
DISPLAY "PROCESO DE BUSQUEDA FINALIZADO"
LINE 20 COL 20.
ACCEPT OP LINE 20 COL 1.
...
MAS TABLAS
Voy a poner algunos ejemplos de definicin de tablas mas complicados que los
expuestos en los ejemplos.
01 TABLA.
02 TRABAJADORES
03 NOMBRE
03 NIF
03 SALARIO
05 BRUTO
05 NETO
05 GASTOS
07 GASTO
Los valores para esta tabla sera:
Para saber el nombre del trabajador nmero 49: DISPLAY NOMBRE (49).
Para saber el Nif del trabajador 20: DISPLAY NIF (20).
Para saber el bruto de Mayo del trabajador 15: DISPLAY BRUTO (15, 5).
Para saber el neto del trabajador 90 del mes de Noviembre:
DISPLAY NETO (90, 11).
- Para saber el gasto nmero 3 del mes de Febrero del trabajador 10:
DISPLAY GASTO (10, 2, 3).
01 MES
PIC 99.
01 SEMANA.
02
PIC 9(4) OCCURS 28 TO 31 DEPENDING OF
VISTAS
MES.
INDEXACION.
Adems podemos asignar una variable por la cual nos referiremos a cada
elemento, esto se hace aadiendo a la lnea que contiene la clusula OCCURS,
la palabra INDEXED seguida del nombre de variable que deseemos. La ventaja
es que no hay que definirla en la WORKING. En nuestro ejemplo le pondremos
de nombre DIA y quedara asi:
01 DIASEMANA.
02 VISITAS PIC 9(4) OCCURS 7 TIMES INDEXED DIA.
La gran ventaja de utilizar este mtodo, es que no hay que definir esa variable,
no hay que controlar los rangos y adems el valor no se alterar ya que no
utilizaremos esa variable para nada mas.
Para dar valor a ste tipo de variables hay que utilizar la sentencia SET, ya que
no se pueden utilizar los comandos normales ni declaraciones aritmticas, con
el siguiente formato:
SET DIA TO 1. Da el valor 1 al ndice 1.
SET DIA UP 3. Suma 3 al valor del ndice.
SET DIA DOWN 2. Resta 1 al valor del ndice 2.
Adems tambin utilizamos la indexacin para hacer busquedas en las tablas
mediante la sentencia SEARCH.
Antes hemos visto como buscar utilizando un contador y unos IF para verificar
lo que buscamos. Pero Cobol tiene una sentencia especfica para buscar un
valor en una tabla. Esta sentencia se llama SEARCH.
Si imaginamos una tabla de trabajadores y queremos encontrar la posicin en
concreto que ocupa uno o saber si existe en la tabla haremos lo siguiente:
01 TABLA.
02 TRABAJADORES
03 NOMBRE
03 NIF
...
PROCEDURE DIVISION.
...
BUSCAR.
SET SUB1 TO 1.
SEARCH ELEMENTOS AT END GO NOEXIS
WHEN NOMBRE (SUB1) = "ANDRES MONTES"
GO EXISTE.
NOEXIS.
DISPLAY "TRABAJADOR INEXISTENTE" LINE 1.
GO FIN.
EXIS.
DISPLAY "EL NIF DEL TRABAJADOR ES ." LINE 2.
DISPLAY NIF (SUB1) LINE 2 COL 30.
...
Primero inicializamos la variable de indexacin para que empiece por el
elemento 1, pero podiamos haber escogido el valor que quisieramos, si le
hubiramos dado uno fuera de rango, simplemente la instruccin hubiera
saltado al prrafo NOEXIS indicado en el AT END.
La sentencia SEARCH a continuacin crea un bucle hasta que se cumpla la
condicin dada. Si no la encuentra realiza la instruccin que haya despues de AT
END. Podemos poner todas las condiciones con WHEN que queramos y se irn
ejecutanto en el orden en que se hayan puesto.
Tambin existe la posibilidad de hacer una busqueda total de la tabla con la
clusula ALL en la sentencia SEARCH, se denomina busqueda binaria.
Esta frmula es mas utilizada en tablas mas grandes. Aqu no hay que
preocuparse por el valor del subndice, el comando se encarga de todo. Pero
solo podremos poner una condicin WHEN y adems el elemento de la tabla por
el que se busque debe de estar clasificado y especificado en la WORKING con la
opcin ASCENDING o DESCENDING. Veamos un ejemplo:
01 TABLA.
02 TRABAJADORES
03 NOMBRE
03 NIF
...
PROCEDURE DIVISION.
...
BUSCAR.
SEARCH ALL ELEMENTOS AT END GO NOEXIS
WHEN NOMBRE (SUB1) = "ANDRES MONTES"
GO EXISTE.
NOEXIS.
DISPLAY "TRABAJADOR INEXISTENTE" LINE 1.
GO FIN.
EXIS.
DISPLAY "EL NIF DEL TRABAJADOR ES ." LINE 2.
DISPLAY NIF (SUB1) LINE 2 COL 30.
...
La diferencia en cuanto a programacin es mnima, pero el sistema tarda menos
en la busqueda y no tenemos que tener en cuenta el inicializar el contador. Por
el contrario es necesario tener ordenada nuestra tabla y esto a veces no sea tan
rentable.
Obviamente cada una de stas formas de buscar en Tablas son opciones que
ofrece el lenguaje Cobol. Supongo que como en todo lo que se buscaba al
principio era limitar los tiempos de respuesta, puesto que las mquinas eran
muy pequeas y tenan pocos rendimientos, de ah que sta orden se haya visto
inalterada desde el principio.
Cada uno puede utilizar la forma que mejor se le de, la que mejor entienda o la
que mejor haga su cometido.
Seguramente se podra haber hablado mucho mas de tablas, pero lo importante
y lo que pretenda con ste captulo, era que comprendirais el porque de una
tabla y su uso mas frecuente.