
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 SPECIAL-NAMES 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 KEY-CLIENTE.
r 03
CLICOD rPIC 9(4) COMP-6.
02 CLINOM PIC X(30).
02 CLIDIR PIC X(30).
02 CLIPOB PIC X(20).
02 CLIPRO PIC X(20).
02 CLINIF PIC X(9).
02 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 ...
|
|