5. Data Division
A organização de um programa COBOL em divisões, seções e parágrafos tem por objetivo manter cada coisa em seu lugar. Talvez essa percepção fique mais evidente a partir de agora. O COBOL faz uma clara distinção entre a descrição do processamento, que acontecerá na PROCEDURE DIVISION, e os dados que esse processamento utilizará. O lugar onde declaramos esses dados é justamente na DATA DIVISION.
A DATA DIVISION descreve de uma forma estruturada todos os dados que serão acessados pelo programa. Todas as variáveis devem ser declaradas nesta divisão, sejam elas campos de arquivos convencionais, atributos de banco de dados, parâmetros fornecidos pelo usuário ou pelo programa chamador, arrays, telas, relatórios ou simples variáveis de trabalho.
Dados estruturados
Os dados utilizados por um programa COBOL são organizados numa hierarquia. Basicamente essa hierarquia é formada por itens de grupo e itens elementares. Em termos bem simples, um item elementar é uma variável. Um item de grupo é um conjunto de itens elementares.
Vamos detalhar esse conceito através de um exemplo prático. A figura abaixo mostra um registro de dados. Você pode pensar num registro como se fosse uma linha num arquivo texto.
O registro Conta a Receber é formado pelos campos chave, código do cliente, data de emissão, data de vencimento, valor da duplicata, categoria e situação. O campo chave, por sua vez, é formado pelo número da fatura e pelo número da duplicata.
Podemos visualizar essa estrutura como uma hierarquia de dados:
Conta a Receber Chave Número da Fatura Número da Duplicata Código do Cliente Data de Emissão Data de Vencimento Valor da Duplicata Categoria Situação
Para representar essa hierarquia no COBOL precisamos estabelecer níveis para cada “camada” de informação. Esses níveis são números que vão de 1 a 49, onde 01 é o nível mais alto e 49 o nível mais baixo possível. Assim, usando a notação do COBOL, nossa hierarquia de dados ficaria assim:
01 Conta a Receber 03 Chave 05 Número da Fatura 05 Número da Duplicata 03 Código do Cliente 03 Data de Emissão 03 Data de Vencimento 03 Valor da Duplicata 03 Categoria 03 Situação
Repare que o registro Conta a Receber recebe o nível mais alto (01). As informações que compõem esse registro estão num nível mais baixo (03). O campo chave, por sua vez, é formado por itens elementares que estão num nível ainda mais baixo (05).
Número da Fatura e Número da Duplicata são chamados de itens elementares, pois eles não se subdividem. Conta a Receber e Chave são chamados de itens de grupos, pois são formados por itens elementares.
Alguns detalhes são importantes sobre a numeração de hierarquias:
- O nível mais alto sempre deve receber o número 01. Abaixo dele, você pode escolher qualquer número entre 02 e 49.
- Nesse exemplo, usamos os números 01, 03 e 05, mas poderíamos ter escolhido 01, 02 e 03; ou 01, 05, 10; ou 01, 10, 20… Desde que o nível de baixo tenha um número maior que o nível de cima, quaisquer números entre 02 e 49 seria válido. No entanto, é uma boa prática de programação numerar os níveis de dois em dois, ou cinco em cinco, deixando “espaço” para a criação de itens de grupo intermediários no futuro.
- Não é obrigatório, mas é uma prática altamente recomendável, que todos os itens de um mesmo nível tenham a mesma numeração. No nosso exemplo, chave, código do cliente, data de emissão, data de vencimento, valor da duplicata, categoria e situação estão no mesmo nível hierárquico (imediatamente abaixo do registro conta a receber). Por esse motivo esses itens receberam o mesmo número de nível (03).
- Quem determina a hierarquia entre os itens é o número de nível. A edentação procura apenas facilitar a leitura dos programadores.
Dando nomes às variáveis
A maioria dos compiladores exige que os nomes das variáveis na DATA DIVISION sejam formados por letras, números, alguns caracteres especiais (como hífen e underscore). O primeiro caracter desses nomes deve necessariamente ser alfabético.
Muitos compiladores atualmente permitem o uso de letras maiúsculas e minúsculas na formação dos nomes, mas na grande maioria das vezes você verá apenas nomes formados por letras maiúsculas e hífens.
Supondo que quiséssemos definir em nosso programa o registro conta a receber, do exemplo anterior, poderíamos adotar os seguintes nomes para os itens de grupo e itens elementares:
01 CONTA-RECEBER 03 CHAVE 05 NUMERO-FATURA 05 NUMERO-DUPLICATA 03 CODIGO-CLIENTE 03 DATA-EMISSAO 03 DATA-VENCIMENTO 03 VALOR-DUPLICATA 03 CODIGO-CATEGORIA 03 SITUACAO-DUPLICATA
Cada empresa estabelece suas próprias convenções de nomenclatura para definição de variáveis. É comum, por exemplo, que alguns nomes mais frequentes sejam abreviados seguindo sempre um mesmo padrão. Por exemplo:
NUMERO: NR CODIGO: CD DATA: DT VALOR: VL SITUACAO: ST NOME: NM MATRICULA: MT DESCRICAO: DS TIPO: TP
Seguindo essa norma, nosso exemplo ficaria assim:
01 CONTA-RECEBER 03 CHAVE 05 NR-FATURA 05 NR-DUPLICATA 03 CD-CLIENTE 03 DT-EMISSAO 03 DT-VENCIMENTO 03 VL-DUPLICATA 03 CD-CATEGORIA 03 ST-DUPLICATA
Tipos de dados
O COBOL trabalha basicamente com dois tipos de dados: numérico e alfanumérico. Existe um terceiro tipo, chamado de alfabético, que só aceita letras e espaços. Por ser mais limitado, esse tipo raramente é utilizado, sendo quase sempre substituído pelo tipo alfanumérico.
O que define o tipo de uma variável, seu tamanho e seu formato é a cláusula picture (PIC) codificada após o nome de cada variável. Seu formato mais simples é:
- PIC 9(n), para variáveis numéricas, onde “n” deve ser substituído pelo tamanho da variável
- PIC X(n), para variáveis alfanuméricas, onde “n” também deve ser substituído pelo tamanho da variável.
Exemplos:
Os dois últimos exemplos mostrados na figura anterior mostram algumas variações do tipo numérico. Usar um S na frente da picture indica que a variável pode ser sinalizada. Um V no meio da picture separa a parte inteira da parte decimal. Vale a pena salientar que o ponto ou vírgula decimal é apenas posicional: ele não ocupa espaço na variável.
Voltemos ao exemplo do registro de conta a receber. Vamos supor que as variáveis tivessem as seguintes características:
Itens de grupo não possuem cláusula picture, uma vez que seu tipo, tamanho e formato será determinado pelo tipo, tamanho e formato dos seus itens elementares.
A variável NR-FATURA só receberá valores numéricos, de 000001 a 999999. Seis dígitos, portanto. Sua picture será 9(006). Já a variável NR-DUPLICATA também é numérica, mas receber valores que só vão de 00 a 99. Sua picture será 9(002). Costuma-se dizer que a primeira é uma variável “9 de 6”, e a segunda é uma variável “9 de 2”.
A variável CD-CLIENTE receberá letras e/ou números, e pode ter no máximo 6 caracteres. Sua picture, portanto, será X(006). Costuma-se dizer que ela é uma variável “X de 6”.
A variável VL-FATURA parece ser diferente, mas já vimos sua picture em um exemplo anterior. Como ela receberá valores com 13 dígitos na parte inteira e 2 dígitos na parte decimal, sua picture será 9(013)V9(002), ou S9(013)V9(002). O S, como já vimos, informa que a variável também poderá receber valores negativos. Não faz muito sentido um valor de duplicata ser menor que zeros, mas existe uma convenção de se usar variáveis sinalizadas para valores monetários. Declarado dessa forma, o sinal não ocupa espaço na variável; esta variável ocupa, na prática, 15 posições.
Com a cláusula picture, nosso exemplo ficaria assim:
01 CONTA-RECEBER. 03 CHAVE. 05 NR-FATURA PIC 9(006). 05 NR-DUPLICATA PIC 9(002). 03 CD-CLIENTE PIC X(006). 03 DT-EMISSAO PIC 9(008). 03 DT-VENCIMENTO PIC 9(008). 03 VL-DUPLICATA PIC S9(013)V9(002). 03 CD-CATEGORIA PIC X(003). 03 ST-DUPLICATA PIC X(003).
O alinhamento das pictures não é exigido pela linguagem, mas facilita a leitura do programador. Como não vamos colocar nada depois da picture, temos que encerrar cada sentença com um ponto.
As variáveis DT-EMISSAO e DT-VENCIMENTO merecem um comentário adicional. Não existem variáveis do tipo date no COBOL; todas as variáveis ou são numéricas ou alfanuméricas. O formato AAAAMMDD, citado no exemplo, implica em quatro dígitos numéricos para ano, dois dígitos numéricos para mês e dois dígitos numéricos para dia, totalizando oito dígitos numéricos. Por esse motivo, nossas datas foram codificadas com picture 9(008). Se precisássemos fazer referencias específicas a dia, mês e/ou ano, poderíamos transformar essas datas em itens de grupo e incluir itens elementares sob elas, como no exemplo abaixo:
01 CONTA-RECEBER. 03 CHAVE. 05 NR-FATURA PIC 9(006). 05 NR-DUPLICATA PIC 9(002). 03 CD-CLIENTE PIC X(006). 03 DT-EMISSAO. 05 AA-EMISSAO PIC 9(004). 05 MM-EMISSAO PIC 9(002). 05 DD-EMISSAO PIC 9(002). 03 DT-VENCIMENTO. 05 AA-VENCIMENTO PIC 9(004). 05 MM-VENCIMENTO PIC 9(002). 05 DD-VENCIMENTO PIC 9(002). 03 VL-DUPLICATA PIC S9(013)V9(002). 03 CD-CATEGORIA PIC X(003). 03 ST-DUPLICATA PIC X(003).
Um item de grupo se comporta como uma variável alfanumérica (PIC X) cujo tamanho é igual à soma dos tamanhos de seus itens elementares. No exemplo acima, CONTA-RECEBER tem tamanho 51, CHAVE tem tamanho 8, DT-EMISSAO e DT-VENCIMENTO também.
Por se comportar como uma variável PIC X, é possível mover conteúdo para um item de grupo e recuperar parte desse seu conteúdo usando as variáveis elementares. Para dar um exemplo, considere o seguinte item de grupo
01 ENDERECO. 03 LOGRADOURO PIC X(020). 03 BAIRRO PIC X(010). 03 CIDADE PIC X(010). 03 ESTADO PIC X(002). 03 CEP PIC X(008).
Se preenchermos ENDERECO com algum conteúdo, digamos…
MOVE “RUA DO IMPERADOR 101 CENTRO PETROPOLISRJ24340000” TO ENDERECO
…o valor da variável ESTADO será RJ.
Detalhamento de arquivos convencionais
Já vimos que a ENVIRONMENT DIVISION é a divisão onde declaramos todos os arquivos convencionais que serão acessados pelo programa. A ENVIRONMENT, no entanto, não informa quais são os registros de cada arquivo, nem que campos eles possuem. Esta é uma das funções da DATA DIVISION.
Todos os arquivos declarados na ENVIRONMENT DIVISION precisam ser detalhados na DATA DIVISION, numa seção específica chamada FILE SECTION. A FILE SECTION deve ser declarada na coluna 8, logo depois do nome da divisão:
*======================================================================* DATA DIVISION. *----------------------------------------------------------------------* FILE SECTION.
Para mostrar como os arquivos são detalhados, partiremos da ENVIRONMENT DIVISION que codificamos no capítulo anterior:
*======================================================================* ENVIRONMENT DIVISION. *----------------------------------------------------------------------* CONFIGURATION SECTION. SPECIAL-NAMES. DECIMAL-POINT IS COMMA. INPUT-OUTPUT SECTION. FILE-CONTROL. *----------------------------------------------------------------------* * UNLOAD DA TABELA DE DUPLICATAS *----------------------------------------------------------------------* SELECT CRA0205 ASSIGN TO “../dat/cra0205.dat” ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WT-ST-CRA0205. *----------------------------------------------------------------------* * DUPLICATAS ATIVAS EMITIDAS NO PERIODO *----------------------------------------------------------------------* SELECT CRA0206 ASSIGN TO “../dat/cra0206.dat” ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WT-ST-CRA0206.
Vamos detalhar primeiro o arquivo CRA0205. Ele é um arquivo sequencial linear (um arquivo texto), cujos registros (linhas) possuem o seguinte layout:
Para detalhar esse arquivo, incluiremos um parágrafo de file description (FD) na FILE SECTION. Dentro desse parágrafo colocaremos a definição do registro (um item de grupo com nível 01) e dentro do registro colocaremos as variáveis correspondentes a cada campo mostrado na figura anterior.
O detalhamento do arquivo ficaria assim:
*======================================================================* DATA DIVISION. *----------------------------------------------------------------------* FILE SECTION. *----------------------------------------------------------------------* * UNLOAD DA TABELA DE DUPLICATAS *----------------------------------------------------------------------* FD CRA0205. 01 CRA0205-REGISTRO. 03 CRA0205-NR-FATURA PIC 9(006). 03 CRA0205-NR-DUPLICATA PIC 9(002). 03 CRA0205-CD-CLIENTE PIC X(006). 03 CRA0205-DT-EMISSAO PIC 9(008). 03 CRA0205-DT-VENCIMENTO PIC 9(008). 03 CRA0205-VL-FATURA PIC S9(013)V9(002). 03 CRA0205-CD-CATEGORIA PIC X(003). 03 CRA0205-ST-FATURA PIC X(003).
Repare alguns detalhes sobre essa codificação:
- É uma boa prática inserir comentários que descrevam o arquivo. Basicamente copiamos os mesmos comentários que já havíamos inserido na ENVIRONMENT DIVISION.
- O parágrafo FD possui uma grande quantidade de opções e cláusulas adicionais que permitem ao programador descrever o tamanho do registro (em bytes), o tamanho de blocos (em quantidades de registros), o formato dos registros (se fixos ou variáveis), e assim por diante. No nosso exemplo, não usamos nada disso. O programa assumirá que os registros têm todos o mesmo tamanho (formato fixo) e que o tamanho dos registros será igual ao somatório dos tamanhos de cada campo.
- Abaixo da declaração do arquivo (FD) temos um único item de grupo (nível 01). Isso acontece porque todas as linhas (registros) do nosso arquivo têm o mesmo layout. Se o arquivo tivesse linhas com layouts diferentes, teríamos um nível 01 para cada layout;
- O COBOL exige que todas as declarações de variáveis, inclusive a declaração do registro, terminem com um ponto;
- Todos os campos do registro são itens elementares (possuem pictures). Nada impediria que o layout tivesse itens de grupo agrupado alguns itens elementares, mas isso não foi necessário nesse exemplo;
- Usar o nome do arquivo como prefixo dos campos (CRA0205-…) não é obrigatório; é apenas um dos muitos padrões de nomenclatura que as empresas adotam e é uma boa prática de programação. Mais adiante, quando estivermos codificando o algoritmo na PROCEDURE DIVISION, será importante identificar rapidamente se estamos trabalhando com uma variável de trabalho, com um campo de arquivo, com um parâmetro externo etc.
- O detalhamento do arquivo na FILE SECTION não diz se o programa vai ler, gravar, atualizar ou excluir registros. Isso será feito na PROCEDURE DIVISION.
Vamos seguir o mesmo princípio para detalhar o segundo arquivo, CRA0206. Apenas para facilitar o exemplo, usaremos o mesmo layout do primeiro. Logo, as declarações serão praticamente iguais. Copiaremos as linhas anteriores e alteraremos apenas o comentário, o nome do arquivo e o prefixo das variáveis.
Nossa FILE SECTION ficaria assim:
*======================================================================* DATA DIVISION. *----------------------------------------------------------------------* FILE SECTION. *----------------------------------------------------------------------* * UNLOAD DA TABELA DE DUPLICATAS *----------------------------------------------------------------------* FD CRA0205. 01 CRA0205-REGISTRO. 03 CRA0205-NR-FATURA PIC 9(006). 03 CRA0205-NR-DUPLICATA PIC 9(002). 03 CRA0205-CD-CLIENTE PIC X(006). 03 CRA0205-DT-EMISSAO PIC 9(008). 03 CRA0205-DT-VENCIMENTO PIC 9(008). 03 CRA0205-VL-FATURA PIC S9(013)V9(002). 03 CRA0205-CD-CATEGORIA PIC X(003). 03 CRA0205-ST-FATURA PIC X(003). *----------------------------------------------------------------------* * DUPLICATAS ATIVAS EMITIDAS NO PERIODO *----------------------------------------------------------------------* FD CRA0206. 01 CRA0206-REGISTRO. 03 CRA0206-NR-FATURA PIC 9(006). 03 CRA0206-NR-DUPLICATA PIC 9(002). 03 CRA0206-CD-CLIENTE PIC X(006). 03 CRA0206-DT-EMISSAO PIC 9(008). 03 CRA0206-DT-VENCIMENTO PIC 9(008). 03 CRA0206-VL-FATURA PIC S9(013)V9(002). 03 CRA0206-CD-CATEGORIA PIC X(003). 03 CRA0206-ST-FATURA PIC X(003).
Variáveis e constantes de trabalho
Dificilmente você codificará (ou modificará) um programa que não precise de algumas variáveis de trabalho. Normalmente elas são utilizadas para armazenar informações temporárias (contadores, acumuladores, resultados intermediários…), sinalizar estados do programa (flags), ou formatar saídas para telas e relatórios.
Todas as variáveis de trabalho do COBOL são declaradas na segunda seção da DATA DIVISION, que se chama WORKING-STORAGE SECTION. Essa seção também precisa ser codificada na coluna 8:
*======================================================================*
WORKING-STORAGE SECTION.
*----------------------------------------------------------------------*
As regras para formação de nomes, a estrutura hierárquica em níveis, e as pictures que vimos até aqui são as mesmas que utilizaremos na criação de variáveis de trabalho, com alguns poucos recursos adicionais.
Vamos supor que precisemos de dois contadores em nosso programa. Um para contar a quantidade de registros lidos e outro para contar a quantidade de registros gravados. Para isso, criaremos duas variáveis numéricas de trabalho, que comportem até seis dígitos (valor máximo 999.999) e que poderemos chamar de WT-CT-LIDOS e WT-CT-GRAVADOS.
Uma das muitas opções possíveis para declarar essas variáveis é:
*======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 01 WT-CT-LIDOS PIC 9(006). 01 WT-CT-GRAVADOS PIC 9(006).
No entanto, não é comum criar itens elementares no nível 01. O COBOL permite a criação de itens elementares isolados (que não fazem parte de nenhum item de grupo) com um nível especial, de número 77.
*======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 77 WT-CT-LIDOS PIC 9(006). 77 WT-CT-GRAVADOS PIC 9(006).
Frequentemente encontramos programas com variáveis de trabalho criadas no nível 77. Mas essa não é uma boa prática de programação. Um programa grande tende a ter muitas variáveis, e colocá-las indistintamente, uma embaixo da outra, pode dificultar a leitura do programa no futuro.
Por esse motivo, é recomendável agrupar nossos itens elementares em itens de grupo que destaquem a finalidade de suas variáveis:
*======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 01 WT-CONTADORES. 03 WT-CT-LIDOS PIC 9(006). 03 WT-CT-GRAVADOS PIC 9(006).
Quando um programa COBOL é carregado, suas variáveis de trabalho não têm valores iniciais; normalmente seu conteúdo está preenchido com o que chamamos de “lixo de memória”. Isso pode ser um problema principalmente para variáveis numéricas, pois um lixo alfanumérico numa variável numérica certamente fará o programa encerrar imediatamente, de forma anormal.
Para evitar que isso aconteça é altamente recomendável que todas as variáveis de trabalho da WORKING-STORAGE SECTION sejam iniciadas com algum valor, compatível com seus tipos. Na declaração de nossos contadores devemos colocar uma cláusula VALUE após a picture:
*======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 01 WT-CONTADORES. 03 WT-CT-LIDOS PIC 9(006) VALUE ZEROS. 03 WT-CT-GRAVADOS PIC 9(006) VALUE ZEROS.
A constante figurativa ZEROS é autoexplicativa: indica que queremos que as variáveis sejam iniciadas com valor zero. Para variáveis alfanuméricas normalmente usamos a constante figurativa SPACES, que preenche a variável com espaços em branco.
Quando declaramos nossos arquivos na ENVIRONMENT DIVISION dissemos que os códigos de retorno (file status) dos arquivos CRA0205 e CRA0206 ficariam nas variáveis WT-ST-CRA0205 e WT-ST-CRA0206, respectivamente.
Variáveis para file status são alfanuméricas com dois caracteres. Vamos criar um item de grupo específico essas variáveis:
*======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 01 WT-CONTADORES. 03 WT-CT-LIDOS PIC 9(006) VALUE ZEROS. 03 WT-CT-GRAVADOS PIC 9(006) VALUE ZEROS. 01 WT-FILE-STATUS. 03 WT-ST-CRA0205 PIC X(002) VALUE SPACES. 03 WT-ST-CRA0206 PIC X(002) VALUE SPACES.
Aqui, estamos colocando um prefixo WT- antes do nome das variável. Quando encontrarmos uma delas em nossa PROCEDURE DIVISION, ficará óbvio que se trata de uma variável de trabalho definida na WORKING-STORAGE.
Diversos outros prefixos do tipo W?- são recomendáveis para a declaração de variáveis. Podemos usar, por exemplo, WS- para variáveis que serão usadas em telas, WR- para variáveis que serão usadas em relatórios, e assim por diante. Cada empresa estabelece seu próprio padrão de nomenclatura e é importante que ele seja sempre respeitado para garantir a coesão semântica de todos os sistemas.
Exemplo completo
Neste capítulo, pouco a pouco, codificamos a DATA DIVISION de um programa que contém arquivos convencionais e seus campos (na FILE SECTION) e variáveis de trabalho (na WORKING-STORAGE SECTION).
A versão completa da DATA DIVISION ficou assim:
*======================================================================* DATA DIVISION. *----------------------------------------------------------------------* FILE SECTION. *----------------------------------------------------------------------* * UNLOAD DA TABELA DE DUPLICATAS *----------------------------------------------------------------------* FD CRA0205. 01 CRA0205-REGISTRO. 03 CRA0205-NR-FATURA PIC 9(006). 03 CRA0205-NR-DUPLICATA PIC 9(002). 03 CRA0205-CD-CLIENTE PIC X(006). 03 CRA0205-DT-EMISSAO PIC 9(008). 03 CRA0205-DT-VENCIMENTO PIC 9(008). 03 CRA0205-VL-FATURA PIC S9(013)V9(002). 03 CRA0205-CD-CATEGORIA PIC X(003). 03 CRA0205-ST-FATURA PIC X(003). *----------------------------------------------------------------------* * DUPLICATAS ATIVAS EMITIDAS NO PERIODO *----------------------------------------------------------------------* FD CRA0206. 01 CRA0206-REGISTRO. 03 CRA0206-NR-FATURA PIC 9(006). 03 CRA0206-NR-DUPLICATA PIC 9(002). 03 CRA0206-CD-CLIENTE PIC X(006). 03 CRA0206-DT-EMISSAO PIC 9(008). 03 CRA0206-DT-VENCIMENTO PIC 9(008). 03 CRA0206-VL-FATURA PIC S9(013)V9(002). 03 CRA0206-CD-CATEGORIA PIC X(003). 03 CRA0206-ST-FATURA PIC X(003). *======================================================================* WORKING-STORAGE SECTION. *----------------------------------------------------------------------* 01 WT-CONTADORES. 03 WT-CT-LIDOS PIC 9(006) VALUE ZEROS. 03 WT-CT-GRAVADOS PIC 9(006) VALUE ZEROS. 01 WT-FILE-STATUS. 03 WT-ST-CRA0205 PIC X(002) VALUE SPACES. 03 WT-ST-CRA0206 PIC X(002) VALUE SPACES.
No próximo capítulo, veremos como esses dados serão efetivamente processados pelo programa.
Anterior | Conteúdo | Próxima |