Você está na página 1de 426

José Augusto N. G.

Manzano
ORCID: 0000-0001-9248-7765

PROGRAMAÇÃO COBOL
PARA WINDOWS COM OpenCobol IDE 4.7.6
PRIMEIROS PASSOS COM FORMATO FIXO DIRETO AO PONTO
GnuCOBOL 3.1.2

1ª Edição

São Paulo
2021 - Propes Vivens
© Copyright 2021 by José Augusto N. G. Manzano / Propes Vivens.

Todos os direitos reservados. Proibida a reprodução total ou parcial, por qualquer meio ou processo, especialmente por sistemas gráficos, microfílmicos, fotográficos, reprográficos,
fonográficos, videográficos, internet, e-books. Vedada a memorização e/ou recuperação total ou parcial em qualquer sistema de processamento de dados e a inclusão de qualquer parte da
obra em qualquer programa jus cibernético existentes ou que a venham existir. Essas proibições aplicam-se também às características gráficas da obra e à sua editoração, exceto pelo
exporto no próximo parágrafo. A violação dos direitos autorais é punível como crime (art. 184 e parágrafos, do Código Penal, conforme Lei no 10.695, de 07.01.2003) com pena de reclusão,
de dois a quatro anos, e multa, conjuntamente com busca e apreensão e indenizações diversas (artigos 102 e 103 parágrafo único, 104, 105, 106 e 107 itens 1, 2 e 3 da Lei no 9.610, de
19.06.1998, Lei dos Direitos Autorais).

Esta obra é distribuída gratuitamente em formato digital (somente em PDF) apenas e tão somente no sítio do autor (www.manzano.pro.br) e na forma impressa comercialmente e disponi-
bilizada nas plataformas Clube de Autores e Agbook. Nenhum outro local da Internet ou fora dela está autorizado a distribuir, seja gratuitamente ou comercialmente este material. Não é
permitido o compartilhamento deste material em qualquer lugar ou por qualquer meio exceto o exposto neste parágrafo, bem como outro formato digital. Os infratores estão sujeitos a
processo judicial.

O Autor acredita que as informações aqui apresentadas estão corretas e podem ser utilizadas para qualquer fim legal. Entretanto, não existe qualquer garantia, explícita ou implícita, de que o uso de
tais procedimentos conduzirá sempre ao resultado desejado. O autor e a editora não poderão ser responsabilizados civilmente ou criminalmente. Os nomes de sítios e empresas, mencionados, foram
utilizados apenas como ilustração, não havendo nenhum vínculo com a obra, não garantindo a sua existência nem divulgação a posteriori.

Conteúdo de acordo com Acordo Ortográfico da Língua Portuguesa, desde 1 de janeiro de 2009.

Imagem de capa com foto de Jeremy Bishop, disponível em Unsplash (https://unsplash.com/).

Histórico de edições:
1ª. edição (set/2021) – versão 1.0

Produção, Capa e Editoração: José Augusto Navarro Garcia Manzano


Edição: Propes Vivens
FERRAMENTAS UTILIZADAS
Produto: OpenCobolIDE 4.7.6
Desenvolvedor: Python Software Foundation
Sítio: https://pypi.org/project/OpenCobolIDE/
Distribuidor: launchpad.net
Sítio: https://launchpad.net/cobcide
https://launchpad.net/cobcide/4.0/4.7.6

Produto: GnuCOBOL 3.1.2


Desenvolvedor: Bernard Giroud
Brian Tiffin
Keisuke Nishida
Simon Sobisch
Roger While
Sítio: https://www.gnu.org/software/gnucobol/
REQUISITOS DE HARDWARE E SOFTWARE
 Computador padrão IBM-PC (Intel / AMD) de 32 ou 64 bits;
 Sistema operacional Windows 8.1, 10 ou superior;
 Mínimo de 8 GB de memória RAM disponível;
 10 GB mínimo de espaço em disco rígido;
 Monitor padrão VGA (resolução mínima 1024 x 768 pontos);
 Dispositivo de apontamento (mouse);
 Acesso à Internet.
AGRADECIMENTOS
Primeiramente, e especialmente, à minha esposa Sandra e à minha filha Audrey, motivos de constante inspi-
ração e apoio ao meu trabalho. Pela paciência aos momentos de ausência que tenho mesmo próximo, quan-
do estou absorto em escrever, dedicando-me intensamente ao ensino e a você que me lê.

Um agradecimento mais do que especial a contra-almirante da Marinha dos Estados Unidos da América, Ana-
lista de Sistemas e Professora Grace Hopper (nascimento em 09/12/1906, falecimento em 01/01/1992) cria-
dora da linguagem FLOW-MATIC e por ter colaborado como mentora no desenvolvimento da linguagem de
programação COBOL que perdura em uso a décadas, sendo uma das linguagens de programação mais usa-
das e importantes no mundo.

Quero agradecer a Fabio Moraes de Carvalho pelas trocas de ideias e colaboração na realização deste traba-
lho iniciado como um rascunho, que avançou por vezes nas madrugadas do período do início da pandemia da
COVID-19 do início do ano de 2020 e seu efetivo desenvolvimento até meados do segundo semestre de 2021
quando no final de setembro foi concluído como livro. Não posso deixar de agradecer aos membros da comu-
nidade SourceForge relacionados ao projeto GnuCOBOL: Simon Sobisch, László Erdősn, Ralph Linkletter,
Eugenio Di Lorenzo e Vincent “Bryan” Coen pela solicitude e atenção no esclarecimento de dúvidas sobre o
funcionamento e características do compilador e outras orientações.

Quero agradecer a Rafael Ireno e ao expectador de meu canal no Youtube Claudiomar Ben Ysra'el que indi-
retamente são responsáveis pela decisão que tomei em publicar esta obra. O Claudiomar em uma postagem
no canal sugeriu que eu escrevesse um livro sobre COBOL e o Rafael esteve na escola e realizou uma pales-
tra sobre a plataforma de Mainframe IBM Z e divulgou o evento Master the Mainframe para nossos alunos.
Durante a palestra, lá pelas tantas um dos estudantes perguntou sobre a linguagem COBOL e se era usada?
O Ireno não só confirmou o uso, como disse que a IBM estava de "olho" em profissionais com conhecimentos
na linguagem. Alguns estudantes me olharam espantados, pois sempre disse em aula para darem-se a opor-
tunidade em aprender COBOL. Espantaram-se, pois muitos achavam que era apenas “papo gordo” do pro-
fessor. Atualmente não digo "aprendam COBOL", eu digo, "o que estão fazendo que não estão aprendendo
COBOL". Ao término da palestra e da reação provocada nos estudantes achei que era hora de empenhar
esforços em escrever um livro sobre a linguagem. Foi quando comecei a idealizar o trabalho que hoje é apre-
sentado a toda comunidade de estudantes brasileiros. Obrigado Rafael, por corroborar de forma muito natural
e indireta o que sempre digo em sala de aula, e assim dar-me a certeza de que eu não estava lutando contra
moinhos de vento, obrigado Claudiomar pela sugestão.

A todos os alunos que passaram e passam por minhas mãos, que acreditaram e acreditam na minha pessoa,
que seguiram e seguem as orientações que passo; por me incentivarem continuamente quando me questio-
nam, por me levarem a um patamar maior e por exigirem, assim, que eu pesquise mais.

Vida longa e próspera.


SUMÁRIO
Capítulo 1 - COBOL
1.1 - Linguagem ................................................................................................................................................................. 23
1.2 - Ferramentas de trabalho ........................................................................................................................................... 24
1.3 - OpenCobolIDE ........................................................................................................................................................... 27
1.4 - Estrutura sintática ..................................................................................................................................................... 33
1.4.1 - IDENTIFICATION DIVISION ............................................................................................................................. 44
1.4.2 - ENVIRONMENT DIVISION ............................................................................................................................... 46
1.4.3 - DATA DIVISION ............................................................................................................................................... 47
1.4.4 - PROCEDURE DIVISION.................................................................................................................................... 47
1.5 - Operações iniciais ...................................................................................................................................................... 50
1.6 - Windows Terminal e atualização ............................................................................................................................... 54

Capítulo 2 - Ação Sequencial


2.1 - Estruturação de programas ....................................................................................................................................... 57
2.2 - Dados operacionais.................................................................................................................................................... 58
2.2.1 - Layout de dados ............................................................................................................................................. 58
2.2.2 - Variáveis ......................................................................................................................................................... 62
2.2.3 - Espaço de memória......................................................................................................................................... 64
2.2.4 - Constantes...................................................................................................................................................... 67
2.2.5 - Reagrupamento de dados .............................................................................................................................. 69
2.3 - Processamento matemático ...................................................................................................................................... 70
2.3.1 - Estilo algébrico............................................................................................................................................... 70
2.3.2 - Estilo descritivo .............................................................................................................................................. 73
2.3.3 - Algébrico versus descritivo ............................................................................................................................. 79
2.3.4 - Funções intrínsecas ........................................................................................................................................ 79
2.4 - Entradas e saídas ....................................................................................................................................................... 80
2.5 - Hora de programar .................................................................................................................................................... 83
2.6 - Documentação: coluna 7............................................................................................................................................ 89

Capítulo 3 - Ação In/condicional


3.1 - Processamento lógico ................................................................................................................................................ 97
3.2 - Desvios condicionais .................................................................................................................................................. 99
3.2.1 - Desvio simples ................................................................................................................................................ 99
3.2.2 - Desvio composto .......................................................................................................................................... 101
3.2.3 - Desvio seletivo ............................................................................................................................................. 102
3.3 - Ações condicionais ................................................................................................................................................... 104
3.3.1 - Teste de classe .............................................................................................................................................. 104
3.3.2 - Teste de sinal ................................................................................................................................................ 104
3.3.3 - Nomes condicionais ...................................................................................................................................... 105
3.4 - Desvios incondicionais ............................................................................................................................................. 106
3.5 - Laços para repetições .............................................................................................................................................. 109
3.5.1 - Ciclo interativo ............................................................................................................................................. 109
3.5.2 - Ciclo iterativo ............................................................................................................................................... 111
3.5.3 - Ciclo seletivo ................................................................................................................................................ 112
3.6 - Divisibilidade ........................................................................................................................................................... 113
3.7 - Interrupção de laços ................................................................................................................................................ 115
3.8 - Hora de programar .................................................................................................................................................. 116
Capítulo 4 - Processamento com Coleções de Dados
4.1 - Coleção de dados...................................................................................................................................................... 133
4.2 – Estruturas de dados estáticas .................................................................................................................................. 134
4.2.1 - Manipulação de listas ................................................................................................................................... 134
4.2.2 - Manipulação de tabelas................................................................................................................................ 136
4.2.3 - Listas e tabelas internas ............................................................................................................................... 139
4.3 - Ações complementares ............................................................................................................................................ 144
4.3.1 - Inicialização de variáveis .............................................................................................................................. 145
4.3.2 - Classificação de dados .................................................................................................................................. 147
4.3.3 - Pesquisas de dados ....................................................................................................................................... 149
4.3.4 - Campos variáveis .......................................................................................................................................... 152
4.3.5 - Aleatoriedade variável ................................................................................................................................. 154
4.4 - Estruturas de dados dinâmicas ................................................................................................................................ 156
4.5 - Hora de programar .................................................................................................................................................. 157

Capítulo 5 - Modularização
5.1 - Programação estruturada ........................................................................................................................................ 169
5.2 - Seções customizadas ................................................................................................................................................ 170
5.3 - Sub-rotinas (módulos) .............................................................................................................................................. 173
5.4 - Passagens de parâmetro .......................................................................................................................................... 176
5.4.1 - Chamada por referência ............................................................................................................................... 177
5.4.2 - Chamada por conteúdo................................................................................................................................. 178
5.4.3 - Uso integrado de conteúdo e referência ...................................................................................................... 180
5.5 - Livro de cópia ........................................................................................................................................................... 181
5.6 - Escopo e comportamento de variáveis ..................................................................................................................... 183
5.7 - Sub-rotinas recursivas .............................................................................................................................................. 185
5.8 - Ações complementares ............................................................................................................................................ 187
5.8.1 - Dados renomeados ....................................................................................................................................... 187
5.8.2 - Acesso externo .............................................................................................................................................. 198
5.8.3 - Funções definidas ......................................................................................................................................... 191
5.8.4 - Funções recursivas ........................................................................................................................................ 192
5.9 - Hora de programar .................................................................................................................................................. 201

Capítulo 6 - Manipulação de Cadeias de Caracteres


6.1 - Concatenação de textos ........................................................................................................................................... 213
6.2 - Decomposição de textos .......................................................................................................................................... 217
6.3 - Inspeção de textos ................................................................................................................................................... 218
6.4 - Funções para caracteres ........................................................................................................................................... 220
6.5 - Dígito verificador ..................................................................................................................................................... 223
6.6 - Hora de programar .................................................................................................................................................. 228

Capítulo 7 - Utilização de Arquivos


7.1 - Arquivo, registro e campo ........................................................................................................................................ 237
7.2 - Preparação para uso de arquivos ............................................................................................................................. 239
7.3 - Modos de acesso e formas de organização............................................................................................................... 242
7.4 - Ações operacionais ................................................................................................................................................... 245
7.5 - Controle de acesso ................................................................................................................................................... 249
7.5.1 - Detecção de erro no acesso a arquivos ......................................................................................................... 249
7.5.2 - Tratamento das mensagens de erro ............................................................................................................. 253
7.6 - Manipulação básica de arquivos .............................................................................................................................. 257
7.6.1 - Arquivo sequencial linear para acesso sequencial ....................................................................................... 258
7.6.2 - Arquivo sequencial de registro para acesso sequencial ............................................................................... 268
7.6.3 - Arquivo relativo para acesso sequencial ...................................................................................................... 274
7.6.4 - Arquivo indexado para acesso sequencial .................................................................................................... 284
7.6.5 - Arquivo relativo para acesso randômico ...................................................................................................... 305
7.6.6 - Arquivo indexado para acesso randômico .................................................................................................... 311
7.6.7 - Arquivo relativo para acesso dinâmico ......................................................................................................... 317
7.6.8 - Arquivo indexado para acesso dinâmico ...................................................................................................... 324
7.7 - Classificação, agrupamento e junção de registros................................................................................................... 335
7.8 - Contagem de registros............................................................................................................................................. 346
7.9 - Melhoria no controle de acesso aos registros de um arquivo.................................................................................. 348

Capítulo 8 - Interfaces com o Usuário


8.1 - Utilização de relatórios............................................................................................................................................ 351
8.1.1 - Relatório com arquivo de impressão em disco ............................................................................................. 352
8.1.2 - Relatório com arquivo de impressão em papel ............................................................................................ 360
8.1.3 - Introdução ao escritor de relatórios............................................................................................................. 368
8.1.4 - Relatório simples no escritor de relatórios .................................................................................................. 371
8.1.5 - Relatório com quebra simples no escritor de relatórios .............................................................................. 375
8.1.6 - Relatório com totalização no escritor de relatórios ..................................................................................... 378
8.2 - Utilização de telas.................................................................................................................................................... 382
8.3 - Utilização de teclas de função e outros atalhos....................................................................................................... 393

Apêndices – Complementos Operacionais


Execução autonoma de programas (A) ............................................................................................................................ 399
Preparação de instalador (B)........................................................................................................................................... 405
Caracteres EBCDIC (C) ..................................................................................................................................................... 411
Caracteres ASCII (D) ........................................................................................................................................................ 413
Tabela de conversão EBCDIC para ASCII E) ...................................................................................................................... 415
Tabela de conversão ASCII para EBCDIC (F)..................................................................................................................... 417
Bibliografia (X) ................................................................................................................................................................ 419
PREFÁCIO
Este livro foi escrito para pessoas novatas na atividade de programação com a linguagem COBOL, desde que
possuam prévios conhecimentos de lógica de programação ou que já tenham domínio de alguma linguagem
de programação.
Este texto apresenta os primeiros passos na programação COBOL em um contexto extremamente simplifica-
do e introdutório, não há a menor pretensão em avançar além disto, sendo apenas este estudo um passapor-
te de entrada ao mundo da programação COBOL. O nível de detalhamento técnico apresentado neste livro é
básico. Nada intermediário ou avançado sobre COBOL é aqui apresentado.
Se você já é coboleiro ou coboleira experientes com certeza este livro não é para você. Caso você seja expe-
riente na linguagem é aconselhável realizar estudo de outras obras do assunto e neste sentido deixo como
indicação o livro:
Programação Estruturada em COBOL, 9a. Edição para o século XXI
Autores: Stern & Stern
LTC Editora

De forma geral, há outros livros que podem auxiliar o estudo da linguagem. Neste sentido, recomendo:
COBOL Sem Mistérios
Autor: Prof. Joel Saade
Editora: Novatec

Linguagem de programação COBOL para Mainframes, 2ª. Edição


Autor: Prof. Jaime Wojciechowski
Editora: Ciência Moderna

Mastering COBOL Programming, 2ª. Edição


Autores: Roger Hutty e Mary Space
Editora: Palgrave Master Series

Este livro apresenta a linguagem de maneira gradativa a partir de exemplos simplistas, despretensiosos e até
incomuns no mundo COBOL até chegar a exemplos contextualizados e com nível de complexidade maior. Os
exemplos utilizados ou desenvolvidos podem não ser as melhores soluções para determinados problemas,
mas são as soluções possíveis e estão dentro do contexto básico indicado na obra.
Este texto descreve detalhes básicos da linguagem, evitando-se apresentar informações que não são usadas
no contexto da obra, salvo raras exceções. Cada capítulo apresenta um tema que abrange recursos, expla-
nações, explicações e aplicações, partindo-se como base da escrita de códigos que sejam compatíveis com o
padrão 2014 para a linguagem. No entanto, algumas vezes são comentados e usados recursos dos padrões
normatizados em 1974 e 1985.
Cada capítulo, exceto o primeiro, mostra uma série de recursos da linguagem em trechos de código que de-
vem ser codificados para o desenvolvimento da aprendizagem. Ao final de cada capítulo, exceto o sétimo, é
definido um tópico chamado “hora de programar” que trás uma série de exemplos de códigos com o uso dos
recursos apresentados no próprio capítulo ou em capítulos anteriores, podendo conter detalhes não explana-
dos e que são então descritos de forma complementar. No sétimo capítulo devido à complexidade do tema
sobre o uso de arquivos nativos é apresentada uma série de programas de aplicação durante as explanações
dos detalhes conceituais não tendo o tópico “hora de programar”.
Os programas completos apresentados no livro são ofertados prontos para aquisição a partir da plataforma
GitHub em https://github.com/J-AugustoManzano/cobol.
Para a escrita deste livro não foram usados como referência, em excesso, outros livros da linguagem além
dos citados. Foram usados intensamente os manuais técnicos da linguagem publicados por empresas, como:
Apple, Computer Associates, Compaq, Bull, Digital, Envyr, Fujtsu, Hewlett Packard, Heirloom, IBM, Micro Fo-
cus, Unisys e VMS Software, além da documentação da FSF (Free Software Foundation) para o GnuCOBOL
tema deste trabalho.
Um registro que se faz necessário é que não respeitei os padrões oficiais de citação de normas bibliográficas.
Estou respeitando apenas as regras básicas de codificação de programas na linguagem. No entanto, há deta-
lhes usados no contexto de desenvolvimento no universo da alta plataforma que aqui não estão sendo respei-
tados.
Cabe destacar que este livro é distribuído gratuitamente em formato eletrônico PDF no site do autor ou dispo-
nibilizado comercialmente em sua forma impressa a partir das plataformas de publicação Clube de Autores e
Agbook para quem desejar ter o material no formato livro.
Este livro não passou por revisões de língua portuguesa e está em sua forma bruta em versão pré-alpha. Por
isso, poderão ser encontrados erros de escrita, concordância ou outros que passaram desapercebidos, exce-
to os códigos de programas os quais foram exaustivamente testados. Auxílios, neste sentido e mesmo na
estrutura dos programas, serão sempre bem vindos, desde que sejam realizados sem nenhum interesse fi-
nanceiro ou comercial e posicionados de forma repeitosa. Os colaboradores deste trabalho serão menciona-
dos sempre nas próximas edições da obra na seção colaboradores com seus nomes completos e por exten-
so, dispostos em ordem alfabética após a seção sobre o autor.
Ao final deste estudo o leitor estará capacitado a entender e aplicar as técnicas básicas de programação no
desenvolvimento de aplicações COBOL. São demonstrados mais de cem exemplos de programas escritos.
Este livro apresenta um total de oito capítulos mais alguns apêndices que cobrem diversos aspectos operaci-
onais da linguagem.
No capítulo 1 é mostrado de forma resumida o histórico de surgimento da linguagem COBOL, a motivação de
seu desenvolvimento e sua evolução até os dias atuais, acompanhando as definições e crescimento dos pa-
drões ANSI e ISO. Apresenta-se a ferramenta de desenvolvimento OpenCobolIDE, obtenção e instalação,
bem como, a definição de algumas configurações. Outro ponto de importante valor apresentado são as regras
de codificação da linguagem segundo sua estrutura sintática, os elementos componentes da linguagem e
exemplos de aplicação com alguns recursos essenciais. Um destaque deste capítulo é a apresentação de um
programa codificado em formulário, cartão perfurado e sua comparação com a forma dos dias atuais.
O capítulo 2 mostra de forma básica e inicial o processo de desenvolvimento de programas com estrutura
operacional sequencial com a efetivação das ações de entrada, processamento e saída. São estudados tipos
de dados e seus comportamentos em memória, variáveis, constantes, operadores aritméticos, expressões
aritméticas, uso de funções, tratamento das ações de entrada e saída, formatação de valores numéricos,
regras sobre documentação interna de código e estruturação da tabulação e quebra de linhas.
No capítulo 3 são apresentados os recursos de operação com ações condicionais e incondicionais, decisão,
operadores relacionais, operadores lógicos, ações com detecção se sinal, reconhecimento de formato de
caracteres, execução de laços condicional e incondicional, uso de desvio incondicional e divisibilidade, além
de fornecer outros detalhes relacionados as operações de controle da linguagem como validação da entrada
de dados.
O capítulo 4 apresenta o uso de agrupamento de valores na forma de coleções de dados em estilo lista e
tabelas a partir de estruturas de dados estáticas e dinâmicas (internas e externas). Este capítulo apresenta
um estilo de trabalho onde os dados são manipulados na memória principal do computador.
No capítulo 5 aborda-se o tratamento da organização interna do código, baseando-se o trabalho operacional
na filosofia da programação estruturada. São apresentados neste capítulo assuntos relacionados a divisões
em seções; uso de sub-rotinas internas e externas; reutilização de código; passagem de parâmetro por con-
teúdo e referência; copybook; recursividade simples e recursividade em cauda.
O capítulo 6 dá atenção a uso dos caracteres delimitados entre aspas simples ou aspas inglesas, chamados
de cadeias de caracteres (strings). São apresentados os recursos que possibilitam executar a manipulação de
concatenação, decomposição e inspeção de caracteres em variáveis alfabéticas e alfanuméricas. Apresenta-
se neste capítulo definições para geração de dígitos verificadores, manipulação de datas e melhora na ação
de validação de entrada de dados.
No capítulo 7, o mais longo de todo o trabalho, é dado ênfase ao tratamento e armazenamento de dados em
memória secundária: arquivos nativos. São apresentados o máximo de detalhamento possível sobre o tema,
normalmente passado de forma superficial em vários livros de programação para a linguagem COBOL. Neste
sentido são apresentados o uso de arquivos com organização sequencial, relativo e indexado com o uso dos
modos de acesso sequencial, randômico e dinâmico.
O último capítulo, número 8, aborda o tema relacionado a forma de comunicação que um programa tem com
seu usuário. São abordados os modos de uso de relatórios escritos manualmente e por meio do modo escri-
tor de relatórios criando-se relatórios simples, com quebras e com totalizações. O capítulo aborda os recursos
para tratamento da disposição de elementos em tela.
Antes de encerrar quero dizer que este foi um trabalho realizado desde o início, em seu rascunho, com a in-
tenção de ser distribuído gratuitamente e eletronicamente (a menos que se queira adquiri-lo na forma impres-
sa), diferentemente de outros livros que deixo a disposição no meu sítio pessoal (www.manzano.pro.br). Em-
penhei o mesmo esforço e carinho em seu desenvolvimento como se estivesse sendo escrito para ser distri-
buído comercialmente por qualquer editora especializada da área. Espero sinceramente ter conseguido for-
necer um livro que venha auxiliar adequadamente sua aprendizagem. Quero manifestar que foram grandes
os esforços empregados para escrever este material de forma independente. Foram muitas as horas de tra-
balho.
A todos um grande abraço e um excelente aprendizado!

Augusto Manzano

"Ignorar o COBOL é ignorar, entre outras coisas, a arte de programar computadores!" - Joel Saade (Maio de 1997)
SOBRE O AUTOR
José Augusto Navarro Garcia Manzano é brasileiro, nascido em São Paulo, capital em 26 de abril de 1965,
possui formação acadêmica em Análise e Desenvolvimento de Sistemas, Ciências Econômicas e Licenciatura
em Matemática. Atua na área de Tecnologia da Informação, Computação e Informática (desenvolvimento de
software, ensino e treinamento) desde 1986. Participou do desenvolvimento de aplicações computacionais
para áreas de telecomunicações e comércio. Na carreira de professor iniciou sua atividade docente primeira-
mente em cursos livres, trabalhando posteriormente em empresas de treinamento e atuando desde então nos
ensinos técnico e superior.
Atualmente é professor com dedicação exclusiva no IFSP (Instituto Federal de Educação, Ciência e Tecnolo-
gia de São Paulo, antiga Escola Técnica Federal). Em sua carreira desenvolveu competências e habilidades
para ministrar componentes curriculares de Lógica de Programação (Algoritmos), Estrutura de Dados, Mi-
croinformática, Informática, Linguagens de Programação Estruturada, Linguagens de Programação Orientada
a Objetos, Engenharia de Software, Sistemas de Informação, Engenharia da Informação, Arquitetura de
Computadores e Tecnologias Web. Possui conhecimento de uso de diversas linguagens de programação
imperativas, descritivas e de marcação, tais como: BASIC (clássico e estruturado), COBOL, COMAL, Logo,
Scratch, Assembly, Pascal, FORTRAN (77 e 90), C, C++, D, Java, F#, Modula-2, C#, Lua, HTML, XHTML,
CSS, Javascript, VBA, Ada, Rust, Python, LISP, Haskell, Standard ML, OCaml, Miranda, Hope, Groovy, Julia
e Elixir. Possui mais de cento e vinte obras publicadas, além de artigos no Brasil e exterior.
COLABORADORES
INTRODUÇÃO COM T-REX
CO BOL 23

COBOL

Neste capítulo é apresentado de forma resumida o histórico de surgimento da linguagem COBOL, a motiva-
ção de sua criação e evolução até os dias atuais, acompanhando as definições e crescimento dos padrões
ANSI e ISO. Apresenta-se a ferramenta de desenvolvimento OpenCobolIDE, obtenção e instalação, bem
como, a definição de algumas configurações mais importantes. Outro ponto importante é a apresentação das
regras básicas de codificação da linguagem segundo sua estrutura sintática, os elementos componentes da
linguagem e exemplos de aplicação com o uso de alguns recursos essenciais.

1.1 A LINGUAGEM
A linguagem de programação para computadores COBOL (COmmon Business-Oriented Language) é uma linguagem
de programação orientada a negócios comuns. Foi lançada no ano de 1961, tendo sido idealizada a partir de 1959 com
o objetivo de ser uma linguagem voltada ao desenvolvimento de aplicações comerciais, principalmente para o gerenci-
amento de aplicações financeiras. O principal objetivo de seu desenvolvimento foi ser uma linguagem única para ser
usada em qualquer tipo de computador, pois as poucas linguagens de programação existentes, na época, eram direcio-
nadas exclusivamente ao uso científico e matemático e muitas estavam associadas a um computador em específico.
A linguagem caracteriza-se por pertencer ao paradigma imperativo: inicialmente dando suporte apenas a programação
procedimental baseada no uso de sub-rotinas, mas desde o ano de 2002 dá suporte a programação orientada a obje-
tos. Muitos gurus da tecnologia computacional previram seu desaparecimento, mas contínua em pleno uso, principal-
mente em computadores de grande porte.
COBOL é parcialmente baseada na linguagem de programação FLOW-MATIC projetada pela cientista da computação,
professora do Vassar College e contra-almirante da Marinha dos Estados Unidos da América, Grace Hopper. A propósi-
to a professora Hopper teve grande influência no desenvolvimento da linguagem COBOL.
Durante a primavera de 1959 em uma conferência de dois dias chamada CODASYL (COnference on DAta Systems
Languages - conferência sobre linguagens de sistemas de dados), a qual teve a participação da professora Hopper foi
discutido o desenvolvimento de uma linguagem de programação que pudesse vir a ser utilizada como padrão em diver-
sos computadores: desse esforço surgiu a linguagem COBOL, chamada posteriormente de COBOL-60.
A professora Hopper sempre acreditou que as linguagens usadas na programação de computadores deveriam ser se-
melhantes e o mais próximo possível do idioma inglês, sendo COBOL o grande exemplar da crença de Hopper tendo-a
como grande influenciadora em seu desenvolvimento.
Desde seu lançamento a linguagem passou por diversas revisões e mudanças, buscando corrigir bugs ou ampliar fun-
cionalidades operacionais. Uma linguagem de programação não tem tanta atenção se não mostrar um mínimo de inte-
resse da comunidade computacional.
Entre os anos de 1961 e 1965 ocorreram três revisões da linguagem. A edição COBOL-60 foi substituída em 1961 pela
edição COBOL-61, em 1963 surge a edição COBOL-61 Extended, que posteriormente em 1965 é substituída pela edi-
ção COBOL-65. Nesse interim já existiam alguns dialetos da linguagem sendo utilizados, o que começou a dificultar seu
24 PRO G RA MA Ç ÃO CO B OL

uso e manutenção nas organizações, pois cada fabricante de computador colocava na linguagem o que julgava neces-
sário ela ter, descaracterizando por completo seu objetivo inicial.
No início de 1968 são iniciados os esforços de padronização da linguagem para mitigar os problemas de incompatibili-
dade entre as diversas versões COBOL que estavam em uso nos diferentes fabricantes de computadores. Foi neste
período que o instituto ANSI (American National Standards Institute - instituto nacional americano de padrões) produziu
a primeira norma da linguagem referenciada como USA COBOL X3.23 em agosto de 1968 (ANSI COBOL 68).
No ano de 1970 a linguagem COBOL tornou-se a linguagem de programação mais usada em todo o mundo o que levou
a ampliação de seus recursos culminando em 1974 no surgimento do padrão COBOL-74 - ANSI COBOL 74 X 3.23 (ou
COBOL ANSI-74). Em meados de 1978 são iniciados os trabalhos de revisão do padrão COBOL-74 que resultou na
definição do padrão COBOL-85 (ISO 1989:1985) publicado no final de 1985, posteriormente revisado e retificado em
1989 e 1993.
No início de 1990 foram iniciados os trabalhos de inclusão de orientação a objetos. Os recursos incluídos foram basea-
dos a partir dos recursos encontrados nas linguagens de programação C++, Eiffel e Smalltalk. Este trabalho foi concluí-
do em 20 de novembro de 2002 sendo referenciado como COBOL-2002 (ISO/IEC 1989:2002).
O padrão COBOL-2002 não foi muito bem sucedido passando por três revisões, sendo duas no ano de 2006 e outra no
ano de 2009. Nenhum dos compiladores existentes suportava completamente este padrão, o que culminou em outras
mudanças que levaram ao surgimento do padrão COBOL-2014 (ISO/IEC 1989:2014) lançado em 26 de abril de 2014
estando este atualmente em vigor.
COBOL foi desenvolvida para gerenciar operações em grandes computadores, mas com o surgimento dos microcompu-
tadores durante os anos 1970 acabou sendo portada para este tipo de máquina. Na ocasião esses pequenos computa-
dores de 8 bits rodavam alguma versão da linguagem COBOL implementada pela empresa Micro Focus e distribuída
pela empresa Microsoft sob o sistema operacional CP/M. Com o lançamento dos microcomputadores IBM, padrão PC
(Personal Computer – computador pessoal) de 16 bits em 1980 não demorou para que a linguagem COBOL fosse por-
tada para esta plataforma sob o sistema operacional MS-DOS.
Com a evolução dos microcomputadores para 32 bits e posteriormente para 64 bits surgiram diversos outros fornecedo-
res para a linguagem COBOL, pois a empresa Microsoft deixou de fornecer esta opção ao mercado em 1992. Um com-
pilador COBOL comercial, muito popular, é o Visual COBOL da empresa Micro Focus (https://www.microfocus.com). Já
no mundo open source há como opção o compilador GnuCOBOL que pode ser usado, por exemplo, a partir do ambien-
te integrado de desenvolvimento OpenColbolIDE (https://pypi.org/project/OpenCobolIDE).

1.2 FERRAMENTAS DE TRABALHO


O programa GnuCOBOL é uma implementação livre da linguagem COBOL com suporte seletivo aos padrões COBOL
85, COBOL 2002, COBOL 2014, IBM COBOL, MVS/VM COBOL, BS2000 COBOL, Micro Focus COBOL, ACULCOBOL-
GT, além de seu próprio modo padrão de operação, não dando suporte a POO até o momento de publicação deste
trabalho. Foi inicialmente escrito por Keisuke Nishida em linguagem de programação C e lançado em 20 de janeiro de
2002 com o nome de OpenCOBOL. É mantido, atualmente, por Bernard Giroud, Brian Tiffin e Simon Sobisch, tendo
tido a colaboração de Roger While (1950-2015).
O programa OpenCobolIDE é um ambiente de desenvolvimento integrado, escrito em Python com Qt totalmente direci-
onado ao uso do compilador GnuCOBOL, produzido por Céline Thiry, Colin Duquesnoy, Gatien Bovyn, Simon Sobisch e
Vlinhart e mantido pela Python Software Foundation.
Os programas GnuCOBOL e OpenCobolIDE podem ser executados nos sistemas operacionais Linux, Windows e mac
OS. A maneira mais fácil de obtê-los para o sistema operacional Windows é a partir de um único pacote instalável for-
necido na plataforma Launchpad. Acesse o endereço https://launchpad.net/cobcide e observe junto a figura 1.1 a
página apresentada. Para uso no sistema operacional mac OS há disponível a versão 4.7.4 a partir do endereço Web
https://launchpad.net/cobcide/4.0/4.7.6.
Ao lado direito da página indicada na figura 1.1, na seção Downloads junto a área Latest version is 4.7.6 há a indica-
ção de quatro pacotes de instalação, sendo um para o sistema operacional Windows, dois para o sistema operacional
Linux (em formato deb para Ubuntu e rpm para Fedora) e um pacote contendo o código fonte. Como o objetivo deste
livro é o uso do sistema operacional Windows, selecione o pacote: OpenCobolID...6_Setup.exe.
CO BOL 25

Assim que o programa de instalação for copiado. Vá até a pasta em que o programa está e selecione com um duplo
clique do ponteiro do mouse o arquivo OpenCobolIDE-4.7.6_Setup.exe para que o programa de instalação seja inicia-
do. A figura 1.2 mostra a imagem do modo de ação de segurança (se esta estiver configurada) solicitando autorização
de execução. Neste momento acione o botão Executar

Figura 1.1 – Plataforma Launchpad

Será apresentada a caixa de diálogo de controle de aces-


so a conta de usuário, acione o botão Sim. Na sequência
surge a caixa de diálogo Setup - OpenCobolIDE (Li-
cense Agreement) com os termos da licença de uso do
programa como indica a figura 1.3. Ao concordar com os
termos da licença acesse a opção I accept the agrément
e acione em seguida o botão Next.
A caixa de diálogo Setup - OpenCobolIDE (Select Des-
tination Location) apresenta o local onde a instalação
será realizada como mostra a figura 1.4. Não há necessi-
dade de alterar o local de instalação do programa, a me-
Figura 1.2 – Aviso de segurança nos que se queira. Assim sendo, acione o botão Next.
A caixa de diálogo Setup - OpenCobolIDE (Select Start Menu Folder) apresenta junto a figura 1.5 a referência de
acesso pela qual o programa será relacionado ao menu de seleção do ambiente operacional Windows. Não é necessá-
rio produzir alteração alguma. Basta então acionar o botão Next.
Ao ser apresentada a caixa de diálogo Setup - OpenCobolIDE (Select Additional Tasks) como mostra a figura 1.6,
marque a caixa de seleção Create a desktop shortcut para que um ícone de acionamento do programa seja criado na
área de trabalho do sistema operacional e na sequência acione o botão Next.
Será indicada a caixa de diálogo Setup - OpenCobolIDE (Ready to Install) como mostra a figura 1.7 contendo o resu-
mo das opções anteriormente ajustadas e selecionadas. Se desejar alterar alguma opção basta acionar o botão Back e
refazer as opções já selecionadas ou se estiverem em ordem basta acionar o botão Next para que o processo de insta-
lação seja iniciado.
26 PRO G RA MA Ç ÃO CO B OL

Figura 1.3 – Licence Agreement Figura 1.4 – Select Destination Location

Figura 1.5 – Select Start Menu Folder Figura 1.6 – Select Additional Tasks

Aguarde a conclusão do processo completo de instalação indicado junto a figura 1.8 a partir da apresentação da caixa
de diálogo Setup - OpenCobolIDE (Installing). Esta é uma operação que poderá, dependendo do computador em uso,
demorar um pouco, até ser concluída.

Figura 1.7 – Ready to Install Figura 1.8 – Installing


Terminada a instalação será apresenta a caixa de diálogo Setup - OpenCobolIDE (Completing the OpenCobolIDE
Setup Wizard) como mostra a figura 1.9.
Neste momento desmarque a seleção Launch OpenCobolIDE e em seguida acione o botão Finish.
CO BOL 27

Figura 1.9 – Completing the OpenCobolIDE Setup Wizard

A partir deste instante o programa OpenCobolIDE está instalado em seu sistema e pronto para uso. O uso do progra-
ma será efetuado com o acionamento do ícone definido junto a área de trabalho do ambiente operacional, mas antes de
proceder qualquer ação crie na pasta Documentos do seu usuário a pasta COBOL. Esta pasta será usada para arma-
zenar os códigos criados neste livro.

1.3 OPENCOBOLIDE
Como comentado, o programa OpenCobolIDE é um ambiente integrado de desenvolvimento básico para uso da lin-
guagem COBOL. Apesar de simples, este ambiente possui os recursos necessários para operar a linguagem a partir do
compilador GnuCOBOL com bastante comodidade tanto no modo formulário fixo como formulário livre. Neste trabalho
será considerado apenas o uso de códigos escritos no modo formulário fixo.
Para acessar e usar o ambiente, selecione na área de trabalho do sistema operacional Windows com um duplo clique
do ponteiro do mouse o ícone OpenCobolIDE. Será então apresentada a tela de splash do programa como mostra a
figura 1.10.

Figura 1.10 – Tela inicial do programa OpenCobolIDE

Para iniciar o uso do ambiente pode-se selecionar o botão New file para criar um novo programa ou usar o botão Open
file para carregar um programa já existente. A área Recent files mostra os últimos programas editados, o botão Pref-
erences abre a caixa de diálogo de configuração e o botão About apresenta a janela de créditos.
Inicialmente acione o botão New file e será apresentada a caixa de diálogo New file como indica a figura 1.11. Nesta
caixa de diálogo é possível definir o Template de uso de um programa (Program, Module ou Empty), o nome do pro-
grama definido junto ao campo Name e selecionar extensões válidas de identificação de programa COBOL (CBL, COB,
LST, PCO, SCB ou SQB). É possível definir no campo Directory a pasta onde os programas editados serão gravados.
28 PRO G RA MA Ç ÃO CO B OL

Para um teste operacional selecione no campo Template a opção Empty (vazio). No campo Name escreva a identifica-
ção c01ex01 (capítulo 1, exemplo 1) e selecione a extensão cob. No campo Directory selecione a pasta COBOL defi-
nida anteriormente dentro da pasta Documentos. Sua caixa de diálogo New file deverá ficar idêntica a figura 1.12. Ao
final acione o botão OK.

Figura 1.11 – Caixa de diálogo New file – modo padrão Figura 1.12 – Caixa de diálogo New file – modo editado
Assim que o botão OK da caixa de diálogo New file é acionado é apresentada a tela de operação e edição do progra-
ma como mostra a figura 1.13.

Figura 1.13 – Tela de edição do ambiente OpenCobolIDE.

A tela do programa é dividida em algumas áreas a serem conhecidas. No topo da janela encontra-se a barra de título
identificada com o texto c01ex01.cob [C:\Users\Manzano\Documents\COBOL\c01ex01.cob]- OpenCobolIDE 4.7.6.
Abaixo da barra de título encontra-se a barra de menu (File, Edit, View, COBOL e ?) e a barra de ferramentas com os
ícones de ação para oito botões dispostos da esquerda para a direita:
 New file (primeiro botão) – usado para criar um novo arquivo de programa a partir da caixa de diálogo New file.
Esta ação pode ser produzida com o comando de menu File/New (ou pelo atalho: CTRL + N);
 Open a file (segundo botão) – usado para carregar um arquivo de programa existente a partir da caixa de diálogo
Open a file. Esta ação pode ser produzida com o comando de menu File/Open (ou pelo atalho: CTRL + O);
 Save the current editor (terceiro botão) – usado para gravar o programa atual com o mesmo nome definido para a
edição. Esta ação pode ser produzida com o comando de menu File/Save (ou pelo atalho: CTRL + S);
 Save the current editor as (quarto botão) – usado para gravar o programa atual com um novo nome de identifica-
ção. Esta ação pode ser produzida com o comando de menu File/Save as (ou pelo atalho: CTRL + SHIFT + S);
 Compile the current editor (quinto botão) – usado para realizar a compilação de um programa permitindo a sele-
ção das opções Executable para compilar um programa executável ou Module para compilar um módulo de biblio-
teca. Esta ação pode ser produzida com o comando de menu COBOL/Program type para selecionar o modo de
compilação e produzida com o comando de menu COBOL/Compile (ou pelo atalho: F8);
CO BOL 29

 Clean (sexto botão) – usado para limpar o estado de compilação e reabilitar a operação do quinto botão. Esta ação
pode ser produzida com o comando de menu COBOL/Clean (ou pelo atalho: CTRL + ALT * C);
 Rebuid (sétimo botão) – usado para recompilar o programa em edição. Esta ação pode ser produzida com o co-
mando de menu COBOL/Rebuild (ou pelo atalho: SHIFT + F8);
 Run the current editor program (oitavo botão) – usado para executar um programa em edição que fora compila-
do. Esta ação pode ser produzida com o comando de menu COBOL/Run (ou pelo atalho: F5).
Abaixo da barra de ferramentas estão as áreas de operação do programa: à esquerda está a janela File system, ao
centro está a janela do formulário com as barras vermelhas e ao lado direito está a janela Navigation. As janelas File
system e Navigation podem ser removidas ou reapresentadas no programa com o acionamento do botão X em suas
respectivas barras de título ou a partir do uso da opção Windows do menu View.
Abaixo das áreas de operação do programa encontra-se a barra de status indicando ao lado esquerdo o local e pro-
grama em uso C:\Users\Manzano\Documents\COBOL\c01ex01.cob, do lado direito indicando o acionamento ou não
do botão Enable/disable linter (backgroud check) usado para fixar ou não o caminho de acesso ao compilador (dei-
xe-o ativado), o campo Free format que permite definir o modo de edição em estilo fixo ou estilo livre para a codificação
COBOL, a indicação 1:1 referente a linha e coluna em que o cursor esteja e o padrão de codificação de caracteres em
uso cp1252 para o modo Windows-1252 (Western) que pode ser alterado com Edit/Active Editor/Encodings.
A fim de conhecer a opção program na definição de um
programa execute o comando de menu File/New ou
acione o botão da barra de ferramentas New file. Man-
tenha o campo Template com a opção Program ativa-
da, no campo Name defina c01ex02, selecione a exten-
são cob e escolha em Directory a pasta COBOL da
pasta Documentos. Deixe essas opções idênticas a
imagem da figura 1.14 e acione o botão OK.
Assim que o botão OK é acionado o ambiente do pro-
grama mostra para o modo Program um programa que
tem por finalidade apresentar “Hello world”, codificado Figura 1.14 – Caixa de diálogo New file – template program
no modo formulário fixo, como mostra a figura 1.15.
Observe atentamente, neste momento, a janela File system contendo a indicação dos programas codificados e a jane-
la Navigation indicando os pontos de definição do programa, separando esses pontos em áreas de acesso.
O estilo de codificação fixa é a forma tradicional de se escrever códigos de programas COBOL. Neste estilo, as instru-
ções do programa são escritas a partir da oitava coluna e podem ser definidas até a septuagésima segunda coluna.
Nenhuma instrução COBOL poderá ser escrita após a septuagésima segunda coluna, pois o compilador simplesmente
as ignora.
Da primeira a sexta coluna o que for escrito é ignorado pelo compilador e servirá apenas para referência (mais adiante
esses detalhes são apresentados em maiores detalhes). A sétima coluna do formulário é usada para o estabelecimento
de alguns caracteres especiais, destacando-se o uso do asterisco para a definição de linha de comentários (detalhes
sobre estas características são apresentados mais adiante).
Não se preocupe em entender o código apresentado. Isso será providenciado durante todo o texto deste trabalho. Para
experimentar a ação de compilação do programa, acione a partir da barra de ferramentas o botão Compile de current
editor e será apresentada a janela Logs no meio da tela abaixo da janela de edição como mostra a figura 1.16.
Veja que na figura 1.16 a janela Logs possui três guias de informação. A guia ativa é a Issues contendo a apresenta-
ção do resultado da compilação que neste caso foi bem sucedida. Se nesta etapa ocorresse algum erro o código do
erro e local de ocorrência estaria indicado neste guia.
30 PRO G RA MA Ç ÃO CO B OL

Figura 1.15 – Programa Hello world gerado automaticamente

Figura 1.16 – Apresentação da janela Logs após compilação do programa

A guia Output da janela Logs é usada para a apresentação da saída do programa. Para ver seu uso acione na barra
de ferramentas o botão Run the current editor program e observe a ocorrência apresentada de acordo com a figura
1.17.

Figura 1.17 – Apresentação da janela Logs após execução do programa

A guia Compiler da janela Logs apresenta informações diferentes dependendo da ação executada quando da compila-
ção ou execução de um programa. A figura 1.18 mostra as mensagens apresentadas respectivamente após a realiza-
ção da compilação e da execução de um programa.

Figura 1.18 – Apresentação da janela Logs com mensagens de operação


CO BOL 31

Observe na parte superior da figura 1.18 que para compilar o programa COBOL é usada a instrução:

cobc.exe -x -o bin\c01ex02.exe -std=default -Wall -debug c01ex02.cob

Onde cobc.exe é a chamada do compilador COBOL, -x é a chave de criação do programa executável, -o é a chave
que direciona a saída da compilação para o local indicado a sua frente, bin\ a indicação do local dentro da pasta usada
para a criação da versão executável do programa, neste caso c01c02.exe, o indicador -std=default orienta o compila-
dor a usar o modo padrão de ação de compilação (podendo ser indicado outros dialetos de compilação), a chave -Wall
orienta o compilador a apresentar mensagens de advertência com a finalidade de orientar o programador a melhorar o
código escrito, a chave -debug é usada para ativar o modo de verificação de erros durante o tempo de compilação e
por fim o nome c01ex02.cob refere-se ao programa fonte COBOL a ser compilado.
A mensagem de compilação apresentada na guia Compiler da janela Logs pode ser escrita manualmente na janela de
console (modo terminal), desde que os caminhos da instalação do compilador estejam devidamente configurados juntos
as variáveis de ambiente. Essa ação, se desejada, deverá ser efetuada manualmente, pois a instalação do programa
OpenCobolIDE não as realiza.
Você deve ter notado que a aparência do ambiente de programação OpenCobolIDE pode ser melhorada. Assim sendo,
execute o comando de menu Edit/Preferences (figura 1.19) para que seja apresentada a caixa de diálogo Preferences
como indica a figura 1.20 (que poderá estar um pouco diferente em seu sistema, mas não se preocupe).

Figura 1.19 – Acesso a caixa de diálogo Preferences

Figura 1.20 – Caixa de diálogo Preferences

A caixa de diálogo Preferences é usada para definir e alterar diversas configurações junto ao ambiente de desenvolvi-
mento. Esta caixa possui as guias Editor, Style, Compiler, Run e SQL COBOL.
Na guia Style pode-se selecionar em Editor color scheme diversos esquemas de cores para formatação do ambiente,
pode-se estabelecer o tipo de fonte de texto usada em Editor font e mudar o tamanho da fonte em Font size. Assim
sendo, para melhorar a visualização selecione a partir da guia Style em Application style a opção Dark, depois em
Editor color scheme selecione a opção native e acione OK. Veja se esse visual atende. Caso não goste repita a ação
até encontrar o que melhor atende.
Depois na guia Editor da caixa de diálogo Preferences na área Margins pode-se mudar a cor das linhas verticais ver-
melhas. Por exemplo, alterar a cor vermelha para amarelo, e altera a posição da coluna 80 para 7. Deste modo a sétima
coluna ficara bem destacada.
32 PRO G RA MA Ç ÃO CO B OL

Outra alteração importante é desviar a saída do programa da


guia Output da janela Logs para a tela do modo console.
Para tanto, a partir da caixa de diálogo Preferences selecione
a guia Run e habilite com um clique do ponteiro do mouse a
opção Run in external terminal. O uso da guia Output na
janela Logs para a apresentação e indicação das saídas dos
programas não é muito conveniente. Observe os detalhes de
apontamento indicados junto a figura 1.21. Note os pontos de
seleção a serem configurados para a caixa de diálogo Prefer- Figura 1.21 – Habilitação Run in external terminal
ences.
A figura 1.22 apresenta a imagem do programa OpenCobolIDE após a execução das mudanças indicadas.

Figura 1.22 – Tela do programa OpenCobolIDE configurada

Para ver a saída produzida no modo console (janela do terminal) execute o programa a partir do botão Run the current
editor program e a saída será produzida em modo terminal como mostra a figura 1.23.

Figura 1.23 – Saída em modo terminal

O objetivo deste livro é apresentar a linguagem COBOL e não o ambiente OpenCobolIDE. Por esta razão são apenas
usados os recursos do ambiente que sejam necessários ao uso da linguagem em certo momento.
Outro ajuste importante para este estudo é a definição da versão da norma a ser usada no desenvolvimento dos pro-
gramas. Assim sendo, vá até o menu Edit e escolha a opção Preferences. Selecione a guia Compiler e na página
apresentada, em Standard escolha a opção cobol2014 e acione o botão OK. Pronto o compilador GnuCOBOL está
configurado para compilar os programas de acordo com a norma ISO/IEC 1989:2014.
CO BOL 33

1.4 ESTRUTURA SINTÁTICA


Os comandos e instruções da linguagem COBOL têm grande semelhança com a forma escrita do idioma inglês. A lin-
guagem foi projetada para ser auto documentada como se fosse a descrição textual de um algoritmo computacional
proporcionando alto grau de legibilidade. Das linguagens de programação existentes duas destacam-se nesses objeti-
vos COBOL e SQL. Mas, este grau de semelhança com o idioma inglês faz com que COBOL seja altamente detalhada
ao ponto de possuir mais de 300 palavras reservadas em contraste com outras linguagens de programação mais mo-
dernas e sucintas que possuem quantidades menores de comandos. Apesar desses detalhes COBOL é efetivamente
mais fácil de usar que outras linguagens de programação existentes. Um código escrito em linguagem COBOL é orga-
nizado em áreas chamadas divisões, as quais são formadas por seções. As seções, por sua vez, são formadas por
parágrafos e os parágrafos são formados por uma ou mais sentenças que expressam ações representadas a partir da
definição de instruções (comandos e cláusulas). As instruções por sua vez são a junção de um conjunto de verbos,
cláusulas e operadores que dão sentido a uma ou mais ações computacionais.
Há duas formas de se efetuar a codificação de programas em COBOL: uma com formulário fixo e outra com formulário
livre. Na forma fixa é necessário seguir uma estrutura rígida de escrita, diferentemente da forma livre onde essa rigidez
não é aplicada. Apesar da forma livre ser muito atraente é comum encontrar códigos COBOL escritos de forma fixa,
talvez devido a tradição da programação COBOL e a quantidade de código legado existente em uso. A forma fixa é tão
importante e popular que o próprio ambiente de programação OpenCobolIDE utiliza-o como forma padrão de codifica-
ção inicial. Os comandos da linguagem serão os mesmos entre as formas fixa e livre. No entanto, existirão detalhes
estéticos a serem considerados entre esses formatos. A título de ilustração despretensiosa considere a seguir um códi-
go escrito ao estilo COBOL-68 (mas não propriamente o padrão COBOL-68) que apresenta no monitor de vídeo a men-
sagem “ALO, MUNDO!”. O formato fixo está sendo definido a partir da forma mais rígida utilizada considerado elemen-
tos textuais que na atualidade não são mais usados. Já o formato livre utiliza uma forma de escrita mais despojada por
não fazer referência a nenhum outro elemento que não sejam apenas as instruções da linguagem. Observe, então, os
exemplos da codificação em formato fixo e livre como se estivesse impresso em papel zebrado.
Exemplo de codificação em formato fixo

001010*PROGRAMA EXEMPLO PROG_ALO


001020 PROG_ALO
001030 IDENTIFICATION DIVISION. PROG_ALO
001040 PROGRAM-ID. PROG_ALO. PROG_ALO
001050 AUTHOR. AUGUSTO MANZANO. PROG_ALO
001060 INSTALLATION. COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOWS. PROG_ALO
001070 DATE-WRITTEN. 10 DE MARCO DE 2020. PROG_ALO
001080 DATE-COMPILED. 10 DE MARCO DE 2020. PROG_ALO
001090 SECURITY. SEM RESTRICAO DE USO E ACESSO. PROG_ALO
001100 REMARKS. PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-68. PROG_ALO
001110 PROG_ALO
001120 ENVIRONMENT DIVISION. PROG_ALO
001130 CONFIGURATION SECTION. PROG_ALO
001140 SOURCE-COMPUTER. IBM-PC COMPATIVEL. PROG_ALO
001150 OBJECT-COMPUTER. IBM-PC COMPATIVEL. PROG_ALO
001160 SPECIAL-NAMES. CONSOLE IS MEU_TERMINAL. PROG_ALO
001170 PROG_ALO
001180 DATA DIVISION. PROG_ALO
001190 PROG_ALO
001200 PROCEDURE DIVISION. PROG_ALO
001210 DISPLAY "ALO, MUNDO!" UPON MEU_TERMINAL. PROG_ALO
001220 STOP RUN. PROG_ALO
001230 END PROGRAM PROG_ALO. PROG_ALO

Para a codificação de programas em formato fixo se utilizavam formulários padronizados que indicavam o local correto
e as posições de definição das partes do código. Note junto a figura 1.24 a imagem de um formulário padrão IBM pa-
dronizado para codificação COBOL disponível em http://aandds.com/blog/lang-cobol.html.
34 PRO G RA MA Ç ÃO CO B OL

Figura 1.24 – Formulário padronizado IBM para codificação COBOL

A primeira área do formulário é chamada SEQUENCE (colunas de 1 a 6). É usada para indicar o número de sequência
da página, subárea PAGE (colunas de 1 a 3) e o número de sequência da linha em edição, subárea SERIAL (colunas
de 4 a 6). Daí o código apresentado possuir linhas numeradas como 001010 (página 1 linha 10), 001020 (página 1 linha
20), etc. Nesta área pode-se usar caracteres alfabéticos pois a numeração é apenas referencial e o compilador não a
utiliza para a geração do programa. Normalmente as linhas são dispostas de 10 em 10 para se ter eventualmente espa-
ços disponíveis de inserção de alguma instrução caso esta fosse esquecida ou a ser colocada.
A segunda área do formulário é chamada CONT (coluna 7) disponível para indicar o uso de um caractere de continui-
dade, podendo ser: um caractere asterisco (*) para indicar linha de comentário ou linha em branco, um caractere hífen
(-) para indicar a continuação da escrita de uma linha literal anterior e o caractere barra (/) para gerar linha de comen-
tário iniciada em nova página no arquivo de listagem quando o código enviado a uma impressora.
A terceira área do formulário é chamada A (colunas de 8 a 11) sendo usada para a definição das divisões, seções e
parágrafos que formam a estrutura de um programa.
A quarta área do formulário é chamada B (colunas de 12 a 72) sendo usada para o estabelecimento das instruções a
serem executadas pelo programa. As instruções de um programa em formato fixo não podem ultrapassar a coluna 72.
Isso garante a codificação de instruções simples e de fácil manutenção.
Há ainda a quinta área do formulário chamada IDENTIFICATION (colunas 73 a 80) que poderá estar definida logo após
a coluna 72 ou definida junto ao cabeçalho do formulário ao lado direito. Esta área é usada para identificar o programa
com até oito caracteres. A informação desta área não é processada, podendo ser omitida.
O formulário padronizado é usado pelo programador na codificação de um programa escrito manualmente. Posterior-
mente este formulário era passado a um operador (ou mesmo um programador) que perfurava um conjunto de cartões
de cartolina em um equipamento de perfuração seguindo as orientações escritas no formulário, idênticos a imagem da
figura 1.25 gerada pelo programa The Virtual Keypunch (https://www.masswerk.at/keypunch).
CO BOL 35

Figura 1.25 – Cartão padrão para codificação COBOL

Após a perfuração, os cartões eram colocados em um equipamento de leitura que permitia passar as informações do
cartão para um computador que após a leitura de cada cartão, montava o programa na memória e podia ser compilado,
deixando-o pronto para o uso.
Observe que as marcações definidas junto ao cartão para codificação COBOL da figura 1.25 conjuminam com a estru-
tura do formulário padronizado indicado na figura 1.24.
Os computadores da época dos cartões perfurados operavam uma quantidade menor de caracteres que os atualmente
em uso. Cada um dos caracteres ocupava uma posição na coluna do carão. Para dar uma ideia de como isso ocorria,
observe a figura 1.26 com a indicação dos caracteres suportados nos computadores da época, gerados com o progra-
ma The Virtual Keypunch. Note que cada posição marcada com um ou mais furos determinam o caractere a ser consi-
derado.

Figura 1.26 – Cartão padrão para codificação COBOL

Cada cartão perfurado correspondia a uma única linha de instrução do código de um programa. Assim, se o programa
tivesse 1000 linhas seriam gerados 1000 cartões que deveriam sempre estar em ordem sequencial para serem proces-
sados adequadamente. Era aí que as informações da primeira e quarta áreas do formulário padronizado eram úteis,
pois a partir delas era mais fácil saber a que programa o cartão pertencia e qual sua posição na sequência de cartões
do programa.
A partir do código exemplo do programa PROG_ALO que tem por finalidade apresentar a mensagem “ALO, MUNDO!”,
considere a codificação de um programa muito simples em formulário padronizado como indicado na figura 1.27 e seu
código equivalente demostrado nas imagens de cartões perfurados das figuras de 1.28 até 1.50.
36 PRO G RA MA Ç ÃO CO B OL

Figura 1.27 – Exemplo de codificação COBOL em formulário padronizado

Figura 1.28 – Perfuração da instrução: PROGRAMA EXEMPLO

Figura 1.29 – Perfuração da instrução: LINHA EM BRANCO


CO BOL 37

Figura 1.30 – Perfuração da instrução: IDENTIFICATION DIVISION

Figura 1.31 – Perfuração da instrução: PROGRAM-ID. PROG_ALO

Figura 1.32 – Perfuração da instrução: AUTHOR. AUGUSTO MANZANO


38 PRO G RA MA Ç ÃO CO B OL

Figura 1.33 – Perfuração da instrução: INSTALLATION. COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOWS

Figura 1.34 – Perfuração da instrução: DATE-WRITTEN. 10 DE MARCO DE 2020

Figura 1.35 – Perfuração da instrução: DATE-COMPILED. 10 DE MARCO DE 2020


CO BOL 39

Figura 1.36 – Perfuração da instrução: SECURITY. SEM RESTRICAO DE USO E ACESSO

Figura 1.37 – Perfuração da instrução: REMARKS. PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-68

Figura 1.38 – Perfuração da instrução: LINHA EM BRANCO


40 PRO G RA MA Ç ÃO CO B OL

Figura 1.39 – Perfuração da instrução: ENVIRONMENT DIVISION

Figura 1.40 – Perfuração da instrução: CONFIGURATION SECTION

Figura 1.41 – Perfuração da instrução: SOURCE-COMPUTER. IBM-PC COMPATIVEL


CO BOL 41

Figura 1.42 – Perfuração da instrução: OBJECT-COMPUTER. IBM-PC COMPATIVEL

Figura 1.43 – Perfuração da instrução: SPECIAL-NAMES. CONSOLE IS MEU_TERMINAL

Figura 1.44 – Perfuração da instrução: LINHA EM BRANCO


42 PRO G RA MA Ç ÃO CO B OL

Figura 1.45 – Perfuração da instrução: DATA DIVISION

Figura 1.46 – Perfuração da instrução: LINHA EM BRANCO

Figura 1.47 – Perfuração da instrução: PROCEDURE DIVISION


CO BOL 43

Figura 1.48 – Perfuração da instrução: DISPLAY "ALO, MUNDO!" UPON MEU_TERMINAL

Figura 1.49 – Perfuração da instrução: STOP RUN

Figura 1.50 – Perfuração da instrução: END PROGRAM PROG_ALO

Veja que nas imagens dos cartões as colunas de 73 até 80 são mostradas a mesma informação definida. Como não se
usa mais cartões perfurados as colunas de 73 até 80 de um código COBOL em formato fixo são omitidas. Note também
a sequência de identificação de linhas entre as colunas 1 e 6 também omitidas devido ao fato de os ambientes de pro-
gramação modernos não necessitarem mais deste recurso e por esta razão não são usados.
44 PRO G RA MA Ç ÃO CO B OL

Exemplo de codificação em formato livre

*> programa exemplo prog_alo


prog_alo
identification division. prog_alo
program-id. prog_alo. prog_alo
author. Augusto Manzano. prog_alo
installation. Computador padrao IBM-PC, GnuCOBOL em Windows. prog_alo
date-written. 10 de marco de 2020. prog_alo
date-compiled. 10 de marco de 2020. prog_alo
security. Sem restricao de uso e acesso. prog_alo
remarks. Programa exemplo ao estilo ansi cobol-68. prog_alo
prog_alo
environment division. prog_alo
configuration section. prog_alo
source-computer. IBM-PC compativel. prog_alo
object-computer. IBM-PC compativel. prog_alo
special-names. console is meu_terminal. prog_alo
prog_alo
data division. prog_alo
prog_alo
procedure division. prog_alo
display "Alo, mundo!" upon meu_terminal. prog_alo
stop run. prog_alo
end program prog_alo. PROG_ALO

Ao olhar para os códigos do programa exemplo, tanto em formato fixo como livre, vê-se, praticamente, os mesmos
comandos: não há diferença na estrutura sintática, exceto o uso do símbolo de comentário (*) em formato fixo e (*>)
em formato livre. É claro que em formato livre os símbolos de continuidade (-) e (\) não são aplicados. Dentre os
exemplos apresentados é possível notar o uso de divisões, seções e parágrafos: são quatro as divisões padrão encon-
tradas em um programa COBOL (identificação, ambiente, dados e procedimento) definidas internamente, segundo a
ordem indicada de uso (não se coloca as divisões sob outra ordem), como:

IDENTIFICATION DIVISION
ENVIRONMENT DIVISION
DATA DIVISION
PROCEDURE DIVISION

O detalhamento dos recursos a seguir leva em consideração o fato de existirem códigos COBOL escritos a muito tempo
e que esses estão ainda em execução (código legado). Muito do que se escreve de forma moderna em COBOL não
seria possível de execução em computadores mais antigos e vice-versa. As descrições apresentadas de divisões a
seguir não são completas, sendo concentrado apenas o mínimo necessário para a produção de programa básicos na
linguagem, uma vez que este trabalho objetiva ser um material inicial de estudo da linguagem COBOL. Não há a pre-
tensão de tratar o assunto em sua totalidade ou profundidade.

1.4.1 IDENTIFICATION DIVISION


A divisão de identificação (IDENTIFICATION DIVISION) é a primeira estrutura a ser usada em um programa, tem por
objetivo fornecer informações documentais do código de um programa e identifica-lo junto ao computador. Esta divisão
pode basicamente fazer uso dos parágrafos: PROGRAM-ID, AUTHOR, INSTALLATION, DATE-WRITTEN, DATE-
COMPILED, SECURITY e REMARKS. Uma característica dessa divisão é que ela é formada apenas por parágrafos e
as informações nela contida não são implementadas pelo compilador no programa executável. Esses detalhes são
tratados pelo compilador apenas como comentários (elementos de referência documental).
O parágrafo PROGRAM-ID é obrigatório e tem por finalidade identificar na memória o nome de referência do programa
que poderá ter até trinta caracteres (letras, números e ou hífen), mas somente os oito primeiros caracteres são significa-
CO BOL 45

tivos para identificar o programa no computador. Opcionalmente pode ser acrescida com a cláusula AS com a referên-
cia de um nome de identificação grafado entre aspas inglesas.
O parágrafo AUTHOR é opcional e tem por finalidade identificar o nome do desenvolvedor do código.
O parágrafo INSTALLATION é opcional e tem por finalidade identificar a empresa ou local de desenvolvimento do pro-
grama.
O parágrafo DATE-WRITTEN é opcional e tem por finalidade identificar data de criação do programa.
O parágrafo DATE-COMPILED é opcional e tem por finalidade identificar data de compilação do programa.
O parágrafo SECURITY é opcional e tem por finalidade descrever informações sobre o nível de segurança utilizado no
programa.
O parágrafo REMARKS é opcional e tem por finalidade definir comentários adicionais sobre detalhes do programa.
As cláusulas AUTHOR, INSTALLATION, DATE-WRITTEN, DATE-COMPILED, SECURITY e REMARKS (não se apli-
cam mais). No compilador GnuCOBOL essas cláusulas são mantidas por questões de compatibilidade com o padrão
74. No padrão 85 são consideradas obsoletas e foram extinguidas a partir do padrão 2002, não sendo mais usadas.
Considerando os elementos apresentados uma IDENTIFICATION DIVISION pode ser referenciada como:

IDENTIFICATION DIVISION.
PROGRAM-ID.
AUTHOR.
INSTALLATION.
DATE-WRITTEN.
DATE-COMPILED.
SECURITY.
REMARKS.

A definição de parágrafos e sentenças na linguagem COBOL é finalizada com o uso de um ponto final como se estives-
se escrevendo um texto qualquer de forma normal, ressaltando que um parágrafo pode ser formado por mais de uma
sentença.
Considerando o que é aceito como válido para a IDENTIFICATION DIVISION ter-se-á no mínimo o formato de citação:

IDENTIFICATION DIVISION.
PROGRAM-ID.

Estrutura da definição válida para um programa exemplo apresentado a partir do padrão COBOL-85 (formato fixo):

IDENTIFICATION DIVISION.
PROGRAM-ID. PROG_ALO.
* AUTOR ................: AUGUSTO MANZANO
* INSTALACAO ...........: COMPUTADOR PADRAO IBM-PC, GNUCOBOL EM WINDOW
* DATA DE CODIFICACAO ..: 10 DE MARCO DE 2021
* DATA DE COMPILACAO ...: 10 DE ABRIL DE 2021
* SEGURANCA ............: SEM RESTRICAO DE USO E ACESSO
* OBS ..................: PROGRAMA EXEMPLO AO ESTILO ANSI COBOL-85

Estrutura da definição válida para um programa exemplo apresentado a partir do padrão COBOL-85 (formato livre):

Identification Division.
Program-Id. prog_alo.
*> Autor ................: Augusto Manzano
*> Instalacao ...........: Computador padrao IBM-PC, GnuCOBOL em Window
*> Data de Codificacao ..: 10 de marco de 2021
*> Data de Compilacao ...: 10 de abril de 2021
*> Seguranca ............: Sem restricao de uso e acesso
*> Obs ..................: Programa exemplo ao estilo ANSI COBOL-85
46 PRO G RA MA Ç ÃO CO B OL

No passado os comandos da linguagem COBOL eram escritos com os caracteres em formato maiúsculo. Os compila-
dores usados em microcomputadores (baixa plataforma) aceitam a definição em letras minúsculas, o que pode ocasio-
nar uma série de estilos desastrosos dentro do código. Desta forma, sugere-se usar sempre o estilo de escrita com
letras maiúsculas quando estiver em uso o formato fixo e usar o estilo de escrita com letras minúsculas quando estiver
em uso formato livre.
A cláusula PROGRAM-ID exige para a identificação de um programa o uso apenas de caracteres alfanuméricos e sub-
linhado (underline). Nenhum outro caractere poderá ser usado para a composição do nome de referência de um pro-
grama. O nome de referência deve possuir no máximo oito caracteres.

1.4.2 ENVIRONMENT DIVISION


A divisão de ambiente (ENVIRONMENT DIVISION) é a segunda estrutura a ser usada, tem como objetivo descrever a
configuração do computador usado na compilação e execução de um programa. Assim sendo, esta divisão apresenta
detalhes sobre a interface do programa com os periféricos usados e sua ligação com o ambiente operacional externo,
principalmente no que tange ao uso de arquivos lógicos mapeados a partir da definição de arquivos físicos e a relação
operacional com as unidades de entrada e saída. Esta divisão utiliza as seções: CONFIGURATION e INPUT-OUTPUT.
A seção CONFIGURATION SECTION destina-se a descrever a estrutura de configuração do ambiente, sendo compos-
ta pelos parágrafos:
 SOURCE-COMPUTER – componente obrigatório que descreve o padrão do computador usado na compilação do
código fonte. É o computador do programador;
 OBJECT-COMPUTER – componente obrigatório que descreve o padrão do computador usado na execução do
código compilado. É o computador do usuário;
 SPECIAL-NAMES – componente opcional usado para especificar ações de formatação de comportamento de certo
programa. Pode ser usado com cláusulas, como CONSOLE IS, CURRENCY SIGN IS ou DECIMAL-POINT IS. A
clausula CONSOLE IS permite especificar um nome de identificação para o direcionamento a um determinado ter-
minal de vídeo a ser usado com o comando DISPLAY, a clausula DECIMAL-POINT IS com a indicação COMMA
permite especificar a mudança de comportamento do símbolo de separação de decimais de ponto para vírgula e a
cláusula CURRENCY SIGN IS é usada quando há o desejo de se alterar a apresentação do símbolo monetário de
dólar por outro símbolo especificado. Além das cláusulas indicadas existem outras que estão sendo propositalmen-
te omitidas.
A seção INPUT-OUTPUT SECTION destina-se a descrever a configuração do ambiente de gravação e leitura, sendo
composta pelos parágrafos FILE-CONTROL e I-O-CONTROL, usados na definição de arquivos e de suas ligações com
arquivos físicos e periféricos de entrada e saída:
 FILE-CONTROL – componente opcional que especifica a ligação dos arquivos de dados com as unidades de en-
trada e saída que o programa fará uso;
 I-O-CONTROL – componente opcional que especifica as áreas de armazenamento dos arquivos compartilhados na
memória sendo utilizado para otimizar as operações de entrada e saída de dados.
Considerando os elementos apresentados uma ENVIRONMENT DIVISION pode ser estruturalmente referenciada co-
mo:

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER.
OBJECT-COMPUTER.
SPECIAL-NAMES.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
I-O-CONTROL.
CO BOL 47

1.4.3 DATA DIVISION


A divisão de dados (DATA DIVISION) é a terceira estrutura a ser usada, tem como objetivo definir uma área de aloca-
ção de memória para o processamento de dados de um programa controlando os layouts de uso de variáveis, registros,
constantes, tabelas, arquivos de entrada e saída, parâmetros de entrada de dados, parâmetros de retorno de dados,
áreas de tratamento de dados, locais de acessos a tabelas de dados, relatórios e telas exibidas. Esta divisão usa as
seções: FILE, WORKING-STORAGE, LOCAL-STORAGE, LINKAGE, REPORT e SCREEN.
A seção FILE SECTION destina-se a descrever os layouts e características dos registros usados nos arquivos de en-
trada e saída de um programa.
A seção WORKING-STORAGE SECTION destina-se a descrever as áreas temporárias globais de operação do pro-
grama usadas com a definição de variáveis, constantes e registros de dados no processamento de dados que não são
parte das ações de entrada e da saída de arquivos externos, mas que são necessários ao processamento interno do
programa em uso.
A seção LOCAL-STORAGE SECTION assemelhasse a seção WORKING-STORAGE tendo como diferencial o fato de
que os dados operacionalizados são inicializados toda vez que um programa é iniciado, ou seja, especifica dados locais. A
cada chamada, os itens de dados definidos na seção são realocados e inicializados.
A seção LINKAGE SECTION destina-se a descrever a área de memória a ser utilizada para compartilhamento de da-
dos entre programa principal e sub-rotinas, descreve os dados que são passados entre programas.
A seção REPORT SECTION destina-se a descrever o layout de relatórios a serem gerados e impressos a partir do uso
de um recurso chamado escritor de relatórios.
A seção SCREEN SECTION destina-se a descrever o layout a ser usado na apresentação de dados no terminal, sendo
um recurso encontrado nos compiladores COBOL de baixa plataforma. A linguagem COBOL na alta plataforma (compu-
tadores de grande porte) não possui esta seção.
Considerando os elementos comentados, uma DATA DIVISION pode ser estruturalmente referenciada como:

DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
LOCAL-STORAGE SECTION.
LINKAGE SECTION.
REPORT SECTION.
SCREEN SECTION.

1.4.4 PROCEDURE DIVISION


A divisão de procedimentos (PROCEDURE DIVISION) é a quarta estrutura a ser usada, tem como objetivo acomodar o
código que efetuará o processamento dos dados de um programa, sendo esta, a divisão mais importante entre todas as
usadas em um programa COBOL.
As divisões IDENTIFICATION, ENVIRONMENT e DATA operam com seções e/ou parágrafos predefinidos. No entanto,
a divisão de procedimento permite que o programador defina de maneira customizada suas próprias declarações, pará-
grafos e seções a fim de organizar a estrutura lógica de um programa.
A definição da área de declaração é realizada com o uso do comando DECLARATIVES seguido de um ponto final. Este
recurso é opcional, mas quando em uso deve ser definido imediatamente após PROCEDURE DIVISION, podendo ser
definido em qualquer uma das colunas do campo A para o formulário (tanto físico em papel, como virtual junto a tela da
IDE. O fechamento de uma área de declaração é realizado com o uso da instrução END DECLARATIVES seguida de
um ponto final.
A definição de uma área de declaração é usada para manipular e gerenciar ocorrências de erros de exceção em opera-
ções de E/S (entrada e saída) sob o uso de arquivos quando estes, por algum motivo, ocorrem na operação de certo
programa, ao invés de verificar isoladamente o código do status de erro após cada instrução de E/S.
48 PRO G RA MA Ç ÃO CO B OL

A estrutura de definição de área de declaração segue o esquema sintático:

PROCEDURE DIVISION.
DECLARATIVES.
[instruções para tratamento de exceção].
STOP RUN.
END DECLARATIVES.

A área declarada entre o comando DECLARATIVES e a instrução END DECLARATIVES pode conter sequencias de
instruções para realizar ações operacionais, bem como ser composta com o uso de seções e/ou parágrafos.
Para a criação de parágrafos basta que em PROCEDURE DIVISION ou após o comando DECLARATIVES seja defini-
da uma sequência de caracteres (letras, números ou hifens) encerradas por um ponto final. Normalmente usa-se na
definição do nome de parágrafo, antes do ponto final um hífen seguido da palavra PARA ou a definição inicial do termo
PARAGRAPH ou letra P com um hífen e o nome do parágrafo (há programadores que não utilizam essas estratégias
ou fazem uso de outras nomenclaturas). Apesar dos nomes de parágrafos aceitarem o uso do caractere linha baixa
(underline), mas este estilo não é comum e não deve ser utilizado.
Um parágrafo é encerrado quando outro parágrafo é iniciado, quando ocorre a definição de seções, quando chega-se
ao final de uma PROCEDURE DIVISION, quando se encontra o comando USE ou quando se encontra a instrução END
DECLARATIVES podendo-se defini-lo em qualquer uma das colunas do campo A para o formulário (tanto físico em
papel, como virtual junto a tela da IDE). Os nomes de parágrafos somente poderão se repetir se definidos em diferentes
seções. A estrutura básica de criação de parágrafos na PROCEDURE DIVISION deve seguir o esquema sintático:

PROCEDURE DIVISION.
PARAGRAPH-NOMES.
[instruções].
A001-FIRST-PARA.
[instruções].
0001-INICIO-PROGRAMA.
[instruções].
P-1000.
[instruções].
MAIN-PROGRAM.
[instruções].
STOP RUN.
A estrutura básica de criação parágrafos entre DECLARATIVES e END DECLARATIVES deve seguir o esquema sintá-
tico a seguir, observado abaixo da área de declaração o trecho de início principal do programa:

PROCEDURE DIVISION.
DECLARATIVES.
PARAGRAPH-ERRO.
[instruções para tratamento de exceção].
A001-FALHA-PARA.
[instruções para tratamento de exceção].
OUT-1000.
[instruções para tratamento de exceção].
END DECLARATIVES.
PROGRAMA-PRINCIPAL-INICIO.
[instruções]
STOP RUN.

Para a criação de seções deve-se definir um termo de identificação seguido do comando SECTION com a indicação
opcional de um valor numérico para identificação do segmento, normalmente definido a partir da quadragésima coluna
na área A do formulário fixo.
A definição de uma seção encerra-se quando outra seção é iniciada, no final da PROCEDURE DIVISION ou quando
encontrada a instrução END DECLARATIVES caso seja definida dentro de uma área de declaração, podendo uma
CO BOL 49

seção ser definida em qualquer uma das colunas do campo A para o formulário (tanto físico em papel, como virtual
junto a tela da IDE). O nome definido para uma seção não poderá ser repetido dentro do programa.
A estrutura básica de criação de seções na PROCEDURE DIVISION deve seguir o esquema sintático:

PROCEDURE DIVISION.
SECAO1 SECTION 10.
[instruções].
SECAO2 SECTION 20.
[instruções].
DECL-1 SECTION.
[instruções].
SECAO3 SECTION.
[instruções].
STOP RUN.

A estrutura básica de criação de seções com parágrafos na PROCEDURE DIVISION deve seguir o esquema sintático:

PROCEDURE DIVISION.
SECAO1 SECTION 10.
PARAGRAPH-NOMES.
[instruções].
SECAO2 SECTION 20.
[instruções].
DECL-1 SECTION.
[instruções].
A001-FIRST-PARA.
[instruções].
SECAO3 SECTION.
[instruções].
STOP RUN.

A estrutura básica de criação seções entre DECLARATIVES e END DECLARATIVES deve seguir o esquema sintático
a seguir:

PROCEDURE DIVISION.
DECLARATIVES.
SECAO1-ERROS SECTION 10.
PARAGRAPH-ERRO.
[instruções para tratamento de exceção].
A001-FALHA-PARA.
[instruções para tratamento de exceção].
SECAO2-ERROS SECTION.
OUT-1000.
[instruções para tratamento de exceção].
END DECLARATIVES.
PROGRAMA-PRINCIPAL-INICIO.
[instruções].
STOP RUN.

Como comentado a linguagem COBOL foi projetada para parecer-se ao máximo com o idioma inglês escrito e por con-
seguinte sua estrutura textual. A partir desta característica o código COBOL busca se parecer ao máximo com a estru-
tura escrita do idioma inglês. Desta forma declarações se parecem com capítulos, seções se parecem com tópicos e
sentenças são formados por um ou mais parágrafos.
O uso dos recursos relacionados a definição de seções e parágrafos são opcionais e podem ser omitidos sem prejuízo
direto de execução do programa. Usar ou não esses recursos pode ser uma questão pessoal ou de regras aplicadas a
partir do ambiente de trabalho da organização. Segundo, N. Bredin nos Estados Unidos da América há o hábito de se
usar seção em detrimento a parágrafo e na Europa ocorre o inverso (https://stackoverflow.com/questions/1675461).
50 PRO G RA MA Ç ÃO CO B OL

No entanto, usar estes recursos pode tornar o código de um programa melhor esquematizado apesar da aparente ver-
bosidade que possa existir.

1.5 OPERAÇÕES INICIAIS


A partir da visão geral dos detalhes da linguagem COBOL apresentados, torna-se interessante iniciar um estudo básico
com a estrutura do programa mais simples possível de ser codificada na linguagem: o famoso código “ALO, MUNDO!”
demonstrando especificamente a PROCEDURE DIVISION. Se perguntar a qualquer programador COBOL experiente
que trabalhe com alta plataforma (conhecidos como coboleiros) sobre escrever este tipo de programa, possivelmente
terá como resposta algo como: tínhamos coisas mais importantes para escrever na linguagem do que fazer isso. Consi-
dere então para a codificação apenas o trecho grafado em azul.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3 PROCEDURE DIVISION.
4 DISPLAY "ALO, MUNDO!".
5 STOP RUN.
------ ------------------------------------------------------------------------

Observe o código anterior escrito com o estilo de formatação na forma fixa e sua representação no editor COBOL usa-
do em um computador IBM System z, como demonstra a figura 1.51.

Figura 1.51 – Código “ALO, MUNDO!” em IBM System Z (imagem: Fabio Moraes de Carvalho)

Os programas apresentados nesta obra são escritos de acordo com o uso do formulário fixo (modo padrão do ambiente
OpenCobolIDE), com os comandos da linguagem grafados em formato maiúsculo, respeitando ao máximo a tradição de
codificação da linguagem.
CO BOL 51

Na sequência junto ao ambiente OpenCobolIDE abra uma nova instância vazia para edição, definindo para o arquivo de
programa fonte o nome c01ex03, selecionando a extensão COB e estabelecendo a pasta COBOL da pasta Documen-
tos. A figura 1.52 mostra o ambiente OpenCobolIDE com o programa indicado. Escreva então o programa, deixando a
última linha em branco (tradição na programação COBOL), salve o arquivo e efetue sua compilação e execução.

Figura 1.52 – Código exemplo no ambiente OpenCobolIDE

O código do programa c01ex03.cob na figura 1.49 mostra o menor programa possível de ser escrito em COBOL man-
tendo no código com os detalhes mínimos necessários, o qual executa as seguintes ações:
 A linha 1 define a divisão de identificação do programa a partir da instrução “IDENTIFICATION DIVISION.”;
 A linha 2 está define o nome de identificação do programa com a instrução “PROGRAM-ID. ALOMUNDO.”;
 A linha 3 define a divisão de procedimento do programa a partir da instrução “PROCEDURE DIVISION.”;
 A linha 4 efetua a partir do uso do comando DISPLAY a apresentação da mensagem “ALO, MUNDO!”;
 A linha 5 a partir dos comandos STOP e RUN efetua-se a parada da execução do programa.
As mensagens a serem apresentadas na linguagem com uso do comando DISPLAY na forma de cadeias, como mos-
trado na linha 4, devem ser delimitadas com o uso de aspas inglesas ou aspas simples. Fica a critério escolher o estilo.
A instrução STOP RUN tem por finalidade retornar o controle de execução de um programa para o recurso que fez a
chamada deste programa ao limite de controle mais próximo desta chamada, parando a execução do processamento.
Neste caso, em particular, o programa foi chamado a partir do sistema operacional, sendo então o retorno do programa
devolvido ao sistema operacional que é neste caso o limite mais próximo de controle da chamada anteriormente efetu-
ado.
Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex04,
selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa-
do em azul. Este programa demostra o uso de parágrafo indicando a instrução em tom laranja na linha 4. Há regras que
orientam que a PROCEDURE DIVISION tenha no mínimo um parágrafo.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3 PROCEDURE DIVISION.
------ ------------------------------------------------------------------------
52 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
4 PROG-PRINCIPAL-PARA.
5 DISPLAY "ALO, MUNDO!".
6 STOP RUN.
------ ------------------------------------------------------------------------

Observe na linha 4 do programa c01ex04.cob a definição do parágrafo PROG-PRINCIPAL-PARA identificando parte


do código como sendo um trecho principal de operação a partir de um parágrafo.
Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex05,
selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa-
do em azul. Este programa demostra o uso de seção em tom vermelho na linha 4.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3 PROCEDURE DIVISION.
4 PRINCIPAL SECTION.
5 DISPLAY "ALO, MUNDO!".
6 STOP RUN.
------ ------------------------------------------------------------------------

Observe na linha 4 do programa c01ex05.cob a definição da seção PRINCIPAL SECTION identificando o código com
uma seção principal.
Na sequência, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex06,
selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafa-
do em azul. Este programa demostra o uso de seção demarcada em tom vermelho na linha 4 com parágrafo demarcado
em tom laranja na linha 5.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3 PROCEDURE DIVISION.
4 PRINCIPAL SECTION.
5 PROG-PRINCIPAL-PARA.
6 DISPLAY "ALO, MUNDO!".
7 STOP RUN.
------ ------------------------------------------------------------------------

Observe nas linhas 4 e 5 do programa c01ex06.cob respectivamente as definições da seção PRINCIPAL SECTION e
do parágrafo PROG-PRINCIPAL-PARA identificando o código com uma seção principal com a definição de um pará-
grafo.
Os exemplos de codificação anteriores mostram de forma mínima as definições de seções e parágrafos. Na prática os
parágrafos são usados para separar o código em lotes de operação dentro de certa característica operacional que po-
dem estar definidos em seções. Esta é a forma estruturada que a linguagem COBOL possui para auxiliar a organização
do código baseado em certa temática dentro das colunas do campo A do formulário.
CO BOL 53

Desta forma, apesar de não comum, o código escrito no compilador GnuCOBOL poderá ser organizado de forma en-
dentada a fim de acomodar visualmente a estrutura das divisões, seções e parágrafos dentro do campo A. Assim sen-
do, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina para o nome c01ex07, selecione a
extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o programa a seguir grafado em azul
com as marcações de seção em vermelho e parágrafo em laranja.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3 PROCEDURE DIVISION.
4 PRINCIPAL SECTION.
5 PROG-PRINCIPAL-PARA.
6 DISPLAY "ALO, MUNDO!".
7 STOP RUN.
------ ------------------------------------------------------------------------

Veja que no código do programa c01ex07.cob a definição da IDENTIFICATION DIVISION é estabelecida na coluna 8,
a definição da seção na coluna 9 e a definição do parágrafo na coluna 10. Como comentado, apesar desta forma de
formatação não ser comum ela é válida uma vez que esses elementos devem ser declarados na área do campo A. A
regra determina usar o campo A mas não restringe o posicionamento de colunas dentro do campo.
Um recurso comum usado para melhorar a legibilidade do código é a definição de linhas em branco entre certos grupos
de ação do programa. Assim sendo, no ambiente OpenCobolIDE abra uma nova instância vazia para edição, defina
para o nome c01ex08, selecione a extensão COB e estabeleça a pasta COBOL da pasta Documentos e codifique o
programa a seguir grafado em azul com as marcações de seção em vermelho e parágrafo em laranja seguindo o estilo
mais tradicional ao manter a divisão, seção e parágrafo alinhados na coluna 8 do campo A.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ALOMUNDO.
3
4 PROCEDURE DIVISION.
5 PRINCIPAL SECTION.
6 PROG-PRINCIPAL-PARA.
7 DISPLAY "ALO, MUNDO!".
8 STOP RUN.
------ ------------------------------------------------------------------------

Mesmo utilizando-se a forma tradicional de codificação o ambiente OpenCobolIDE


mantem a apresentação de uma forma endentada da estrutura hierárquica do có-
digo. Veja na figura 1.53 a indicação de um trecho da janela Navigation.
A janela Navigation encontra-se, normalmente, posicionada a direita do ambiente
mostrando o alinhamento em cascata das divisões, seções e parágrafos que com-
põem um programa escrito em linguagem COBOL.
Como comentado, o foco deste livro é a escrita de programas em estilo fixo, uma
vez que a grande maioria dos compiladores COBOL partem deste princípio. No
entanto, uma alternativa que pode ser usada caso não deseje trabalhar no formato Figura 1.53 – Janela Navigator
fixo é fazer uso do termo SOURCE FORMAT FREE indicado a seguir.
54 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 OCOBOL >> SOURCE FORMAT FREE
2 IDENTIFICATION DIVISION.
3 PROGRAM-ID. ALOMUNDO.
4
5 PROCEDURE DIVISION.
6 DISPLAY "ALO, MUNDO!".
7 STOP RUN.
------ ------------------------------------------------------------------------

Observe que para desabilitar a verificação de uso da forma fixa basta acrescentar na primeira linha de código do pro-
grama a diretiva >> SOURCE FORMAT FREE a partir da sétima ou oitava posição do formulário, tendo OCOBOL (de
OpenCOBOL, também usado GCOBOL) como mero rótulo informativo, podendo ser omitido. Veja que você estará livre
para escrever o programa da forma que quiser, em contra partida a diretiva >> SOURCE FORMAT IS FIXED é usada
para estabelecer o formulário fixo. É possível até escrever programas alternando-se os modos fixo e livre. No entanto,
lembre-se de que há um estilo de escrita que é seguido e respeitado a décadas, deve-se na prática evitar exageros.

1.6 WINDOWS TERMINAL E ATUALIZAÇÃO


Anteriormente foi instruído fazer o desvio da forma de saída do programa OpenCobolIDE para a janela de terminal do
sistema operacional para maior comodidade operacional por não ser a guia Outuput da janela Logs muito conveniente.
Agora é necessário fazer pequenos ajustes na janela do terminal.
Para realizar estes ajustes é importante que algum programa esteja em execução a partir do ambiente OpenCobolIDE,
pois a janela de terminal apresentada pelo ambiente não é o terminal padrão do Windows, sendo uma janela fornecida
pelo próprio ambiente.
Portanto, considerando o ambiente OpenCobolIDE com o último programa editado (c01ex08.cob) observe junto a figura
1.54 a janela de terminal possivelmente apresentada em seu sistema.
Esta janela é apresentada no tamanho de 120 colunas e 30 linhas com fundo em cor preto e fonte em cor cinza, poden-
do ter esses elementos alterados a partir de um menu apresentado quando o ícone a esquerda da barra de títulos da
janela é acionado. A figura 1.55 mostra o menu apresentado quando da seleção do ícone da barra de título.

Figura 1.54 – Janela do modo Terminal Windows Figura 1.55 – Menu a partir do ícone da barra de título

Na sequência selecione no menu a opção Propriedades e será apresentada a caixa de diálogo de mesmo nome como
indica a figura 1.56 que oferece para uso as guias Opções, Fonte, Layout, Cores e Terminal. Selecione a guia Layout
e altere em Tamanho da Janela a Largura para 80 e a Altura para 24 de modo que se tenha um formato de tela com
80 colunas e 24 linhas, como mostra a figura 1.57.
CO BOL 55

Figura 1.56 – Caixa de diálogo Propriedades Figura 1.57 – Tamanho 80 colunas e 24 linhas

Outra alteração que poderá ser útil é estabelecer a alteração das cores da janela. Por exemplo com fundo branco e
texto em preto. Para tanto, selecione a guia Cores e em Tela de Fundo selecione o quadro com a indicação da cor
branca, depois em Texto da Tela selecione o quadro com a indicação da cor preta. Quanto as demais guias não há
necessidade de alteração. Assim sendo, acione o botão OK.
As mudanças solicitadas não são imediatamente aplicadas. Desta forma, feche a janela ativa e execute novamente o
programa, neste caso c01ex08.cob e as mudanças efetuadas são apresentadas na janela do terminal como indica a
figura 1.58.
Antes de concluir este capítulo cabe indicar a possibilidade
de se fazer, caso deseje, a atualização do compilador Gnu-
COBOL para uma versão mais recente do que a usada pelo
ambiente OpenCobolIDE 4.7.6.
Acesse o link https://www.arnoldtrembley.com/GC312-
BDB-rename-7z-to-exe.7z para baixar o programa de insta-
lação.
Após baixar o arquivo altere seu nome de GC312-BDB-
rename-7z-to-exe.7z para GC312-BDB.exe.
Acione o programa com duplo clique do ponteiro do mouse.
Se apresentada a caixa de diálogo Abrir arquivo - Aviso
de Segurança como indica a figura 1.59 acione o botão
Figura 1.58 – Janela Terminal após mudanças
Executar.
Será apresentada a caixa de diálogo 7-Zip self-extracting archive como mostra a figura 1.60. Neste momento informe
no campo Extract to o local C:\GnuCOBOL e acione o botão Extract. Aguarde o conjunto de programas do compilador
GnuCOBOL serem descompactados.

Figura 1.59 – Caixa de diálogo Abrir arquivo Figura 1.60 – Caixa de diálogo 7-Zip self-extracting archive
56 PRO G RA MA Ç ÃO CO B OL

A próxima etapa é copiar a pasta GnuCOBOL do drive C: para dentro do local onde o ambiente OpenCobolIDE está
instalado. Assim sendo, no programa Windows Explorer selecione a pasta GnuCOBOL do drive C: (não entre na
pasta) e execute as teclas de atalho <Ctrl> + <X>.
Na sequência abra e entre na pasta OpenCobolIDE em Arquivos de programas (x86) e altere o nome da pasta Gnu-
COBOL de OpenCobolIDE para GnuCOBOL2 e execute as teclas de atalho <Ctrl> + <V>.
Pronto o ambiente de seu computador está atualizado com a versão mais recente do compilador GnuCOBOL. Deixe a
pasta GnuCOBOL2, pois se ocorrer algum problema fica mais fácil reverter a atualização, bastando apagar a pasta
GnuCOBOL e renomear a pasta GnuCOBOL2 para GnuCOBOL.
AÇ ÃO S EQ U EN C IAL 57

2
AÇÃO SEQUENCIAL

Neste capítulo, você tem contato com o processo de desenvolvimento de programas, utilizando a linguagem
COBOL para operar ações de entrada, processamento e saída de dados. São apresentados tipos de dados e
seus comportamentos em memória, variáveis, constantes, operadores aritméticos, expressões aritméticas,
uso de funções, tratamento das operações de entrada e saída, formatação de valores numéricos, regras so-
bre documentação interna de código, estruturação da tabulação e quebra de linhas.

2.1 ESTRUTURAÇÃO DE PROGRAMAS


No capítulo anterior, fez-se introdução geral a linguagem, foram apresentados alguns detalhes sobre o uso das divisões
COBOL, dando atenção a IDENTIFICATION DIVISION, ENVIRONMENT DIVISION e PROCEDURE DIVISION. A pró-
xima divisão a ser vista com maior detalhamento é a DATA DIVISION.
O estilo geral de codificação de programas COBOL segue uma estrutura baseada em elementos de divisões, seções,
parágrafos, sentenças com definições de frases (formadas por instruções que expressam a partir da aplicação de co-
mandos, verbos, cláusulas ou outro elemento sintático, certas ações). Veja a estrutura geral de um programa COBOL:

DIVISÃO
SEÇÃO
PARÁGRAFO
SENTENÇA (COMANDO)
INSTRUÇÃO (SUBSTANTIVOS, PREPOSIÇÕES, ADJETIVOS E VERBOS)
CLÁUSULA (MODIFICADORES)
PALAVRA (CARACTERES)

A divisão caracteriza-se por ser o principal grupo de operações estabelecida a um programa. É o local onde tudo acon-
tece.
A seção, quando existente ou definida, tem por finalidade organizar as áreas de uma divisão criando pontos de identifi-
cação que facilitam a escrita e manutenção do código.
O parágrafo pode ser composto por uma ou mais sentenças e estar definido dentro de uma seção ou divisão.
A sentença (ou comando) é a definição de uma ou mais instruções (verbos, cláusulas ou palavras) definidas dentro de
uma seção ou divisão.
A instrução é a definição de uma ordem de ação estabelecida a partir de comandos expressos na forma de substanti-
vos, preposições, adjetivos e verbos ou outra determinação da linguagem.
Uma cláusula é um conjunto ordenado de sequências de caracteres consecutivos que especificam um atributo de um
comando modificando a ação deste comando.
A palavra se caracteriza por ser a menor unidade de expressão, formada por qualquer palavra-chave da linguagem e
usada para se comunicar com o computador.
58 PRO G RA MA Ç ÃO CO B OL

O estilo geral de codificação COBOL determina o esqueleto de formatação de um programa. É conveniente saber como
os elementos seções, parágrafos, sentenças, definições e frases se comportam frente a estrutura das divisões tradicio-
nais da linguagem IDENTIFICATION, ENVIRONMENT, DATA e PROCEDURE. No manual de referência da empresa
IBM para o compilador Enterprise COBOL versão 6.3, página 49, para o sistema operacional z/OS a uma observação
que segue como escrita:
A menos que as regras associadas declarem explicitamente o contrário, cada cláusula ou declara-
ção requerida deve ser escrita na sequência mostrada em seu formato. Se cláusulas ou instruções
opcionais forem usadas, elas deverão ser escritas na sequência mostrada em seus formatos. Es-
sas regras são verdadeiras mesmo para cláusulas e declarações tratadas como comentários.
Observe então, a estrutura geral de como deve ser feita a estruturação da codificação de programas codificados na
linguagem COBOL:

IDENTIFICATION DIVISION | definido na área A do formulário fixo |


PARÁGRAFO | definido na área A do formulário fixo |
DEFINIÇÕES | definido na área B do formulário fixo |
CLÁUSULAS | definido na área B do formulário fixo |

ENVIRONMENT DIVISION | definido na área A do formulário fixo |


SEÇÃO | definido na área A do formulário fixo |
PARÁGRAFO | definido na área A do formulário fixo |
INSTRUÇÕES | definido na área B do formulário fixo |
CLÁUSULAS | definido na área B do formulário fixo |
FRASES | definido na área B do formulário fixo |

DATA DIVISION | definido na área A do formulário fixo |


SEÇÃO | definido na área A do formulário fixo |
INTRUÇÕES | definido na área B do formulário fixo |
CLÁUSULAS | definido na área B do formulário fixo |
FRASES | definido na área B do formulário fixo |

PROCEDURE DIVISION | definido na área A do formulário fixo |


SEÇÃO (opcional) | definido na área A do formulário fixo |
PARÁGRAFO (opcional) | definido na área A do formulário fixo |
SENTENÇAS | definido na área B do formulário fixo |
INSTRUÇÕES | definido na área B do formulário fixo |
FRASES | definido na área B do formulário fixo |

A DATA DIVISION é formada por um conjunto de seções que operam detalhes operacionais da linguagem e sua rela-
ção direta com a PROCEDURE DIVISION. Entre as seções existentes encontra-se a WORKING-STORAGE SECTION,
que é a principal seção que nos interessa neste momento e tem a finalidade ser usada na definição da estrutura opera-
cional dos dados que serão manipulados na memória principal do computador.

2.2 DADOS OPERACIONAIS


Para que computadores possam executar ações de processamento, estes necessitam receber a entrada de dados para
fornecer posterior saída desses dados transformados em possíveis informações. É extremamente importante conhecer
o mais detalhadamente possível como a linguagem estrutura esses dados na memória e como os operacionaliza. Neste
sentido, observe atentamente os pontos apresentados a seguir.

2.2.1 Layout de dados


A linguagem COBOL pode ser operada a partir de três tipos de dados distintos: numérico (composto pelos valores nu-
méricos decimais de “0” a “9” para a representação de números inteiros e reais), alfabético (composto pelas letras mai-
úsculas de “A” até “Z” e/ou minúsculas de “a” até “z” componentes do abecedário, mais os símbolos de pontuação e o
AÇ ÃO S EQ U EN C IAL 59

espaço em branco) e alfanumérico (composto apenas pelas letras e pelos números). O layout de tratamento de um
dado é obrigatoriamente vinculado ao conteúdo desse dado armazenado em memória. Quando um dado é definido e
formatado este é tratado como um campo de operações a ser usado nas ações de entrada, processamento e saída. O
layout de dados é definido com a cláusula PIC ou PICTURE para a indicação da máscara de formatação (sendo PIC a
forma mais popular de uso) que tem por finalidade especificar as características elementares dos dados tratados em
memória a partir da forma sintática.

PIC(TURE) <código[(tamanho)]>

Em que código é a indicação obrigatória de um código de formatação que define a máscara de comportamento opera-
cional do dado em uso e tamanho é a definição opcional entre parênteses de um valor que o formato do código deve
ser considerado. Veja na tabela 2.1 a indicação dos códigos de formatação existentes para a linguagem.

Tabela 2.1 – Códigos de formatação dos tipos de dados

Código Descrição operacional

9 Define tipo numérico sem sinal (positivo)

A Define tipo alfabético (até 256 caracteres)

X Define tipo alfanumérico (até 256 caracteres)

B Inserção de um espaço em branco na posição em que é indicado

V Define posição do decimal implícito

S Define tipo numérico com sinal (positivo/negativo)

P Define escala de valor decimal

Z Omite valor zero na apresentação

+ / - Mostra sinalização positivo ou negativo

$ Mostra símbolo de cifrão "$" a frente do valor

* Mostra asterisco no lugar do zero

. Inserção de ponto decimal na posição a qual é indicado

, Inserção de vírgula na posição na qual é indicada

0 Inserção de zero na posição em que é indicado

CR Símbolo de crédito

DB Símbolo de débito

Os códigos de formatação (9), (S), (V), (P) e (Z) são destinados ao tratamento de valores numéricos; (A) destina-se ao
tratamento de valores alfabéticos; (X) é destinado ao tratamento de valores alfanuméricos; os códigos complementares
(+), ($), (*), (.), (,), (0), (CR) e (DB) são auxiliares exclusivos aos códigos de operação numérica.
A partir de cada código de formatação é possível estabelecer a estrutura dos dados que serão usados nas operações
de entrada e saída. A cláusula PIC configura o tipo dos dados no formato esperado pelo usuário tanto na ação de ori-
gem (entrada), como na ação editada (saída). As formatações de máscara se dividem em duas categorias: inserção e
substituição. A edição por inserção é usada no estabelecimento de formatos: simples, especiais, fixo e flutuantes; a
edição por substituição é usada na supressão de zeros com espaços em branco ou asteriscos.
60 PRO G RA MA Ç ÃO CO B OL

A edição por inserção simples (campos receptores) é usada com dados numéricos e alfanuméricos. O comprimento de
uso da cláusula PIC de saída (PICTURE editada) não precisa ser igual ao comprimento da cláusula PIC de entrada
(PICTURE de origem). Cada máscara editada calculará sua real posição a partir da máscara de origem com base em
sua posição original e substituirá a mesma. A tabela 2.2 mostra exemplos de definição de máscara de origem e editada
e seus efeitos de entrada e saída para o modo edição por inserção simples.

Tabela 2.2 – Máscara PIC de origem e editada para edição de inserção simples

PICTURE de origem Dado de origem PICTURE editada Dado editado


(entrada) (entrada) (saída) (saída)

9999999999 9,999,999,999
1234567890 1,234,567,890
9(10) 9,9(3),9(3),9(3)

99999 999,B999,B00
12345 012, 345, 00
9(5) 999,B9(3),B00

XXXXXXXXXXXXXXXXX
ABRACADABRABRASIL X(11)BX(6) ABRACADABRA BRASIL
X(17)

99,999
9(5) 12345 12,345
99,9(3)

A edição por inserção especial é usada com dados numéricos e de ponto flutuante positivos e negativos. O comprimen-
to da cláusula PIC de saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). O
ponto decimal (.) é o símbolo de inserção especial para este tipo de dado. A tabela 2.3 mostra exemplos de definição de
máscara de origem e editada e seus efeitos de entrada e saída para o modo edição de inserção especial.

Tabela 2.3 – Máscara PIC de origem e editada para edição de inserção especial

PICTURE de origem Dado de origem PICTURE editada Dado editado


(entrada) (entrada) (saída) (saída)

9(10).99
9(10) 1234567890 1234567890.00
9(10).9(2)

9(7)V9(2) 12345 9(7).9(2) 0012345.00

9999.99 "1.2345" 9,999.99 0,001.23

9999.99 "12.345" 9,999.99 0,012.34

9999.99 "1.2345" 9,999.99 0,001.23

A edição por inserção fixa é usada apenas com dados numéricos para a apresentação de dados fixos. O comprimento
da cláusula PIC de saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os sím-
bolos usados na formatação são contados no local da PICTURE editada. A tabela 2.4 mostra exemplos de definição de
máscara de origem e editada e seus efeitos de entrada e saída para o modo edição de inserção fixa.
AÇ ÃO S EQ U EN C IAL 61

Tabela 2.4 – Máscara PIC de origem e editada para edição de inserção fixa

PICTURE de origem Dado de origem PICTURE editada Dado editado


(entrada) (entrada) (saída) (saída)

S9(6)V9(2) +123.45 +9(5).9(2) +00123.45

S9(6)V9(2) -123.45 -9(5).9(2) -00123.45

S9(6)V9(2) +123.45 9(5).9(2)+ 00123.45+

S9(6)V9(2) -123.45 9(5).9(2)- 00123.45-

S9(6)V9(2) 123.45 $9(5).9(2) $00123.45

S9(6)V9(2) -123.45 9(5).9(2)CR 00123.45CR

S9(6)V9(2) +123.45 9(5).9(2)CR 00123.45

S9(6)V9(2) -123.45 9(5).9(2)BCR 00123.45 CR

S9(6)V9(2) -123.45 9(5).9(2)DB 00123.45DB

S9(6)V9(3) -123.456 9(5).9(2)- 00123.45-

A edição por inserção flutuante é usada apenas com dados numéricos. O comprimento da cláusula PIC de saída (edita-
da) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os símbolos usados na formatação são
contados no local da PICTURE editada. A tabela 2.5 mostra exemplos de definição de máscara de origem e editada e
seus efeitos de entrada e saída para o modo edição de inserção fixa ("∕" igual a espaço em branco).

Tabela 2.5 – Máscara PIC de origem e editada para edição de inserção flutuante

PICTURE de origem Dado de origem PICTURE editada Dado editado


(entrada) (entrada) (saída) (saída)

S9(6)V9(2) 123.45 $(6).9(2) ∕∕$123.45

S9(6)V9(2) 123.45 ++,+++,9(3).99 ∕∕∕∕∕∕+123.45

S9(6)V9(2) 123.45 +$,$(3),9(3).99 +∕∕∕∕+$123.45

A edição por substituição é usada apenas com dados numéricos, sendo usada para substituir os valores zero nos da-
dos de entrada com espaços (uso do código "Z") ou asteriscos (uso do código "*"). O comprimento da cláusula PIC de
saída (editada) não precisa ser igual ao comprimento da cláusula PIC de entrada (origem). Os símbolos usados na
formatação são contados no local da PICTURE editada. A tabela 2.6 mostra exemplos de definição de máscara de
62 PRO G RA MA Ç ÃO CO B OL

origem e editada e seus efeitos de entrada e saída para o modo edição de inserção fixa ("∕" igual a espaço em branco).
Não use os símbolos "Z" e "*" na mesma máscara.

Tabela 2.6 – Máscara PIC de origem e editada para edição de substituição

PICTURE de origem Dado de origem PICTURE editada Dado editado


(entrada) (entrada) (saída) (saída)

S9(6)V9(2) 0.00 *(6).** ******.**

S9(6)V9(2) 0.00 Z(6).99 ∕∕∕∕∕∕.00

S9(6)V9(2) 0.00 Z(6).ZZ ∕∕∕∕∕∕∕∕∕

S9(6)V9(2) 0.00 *(6).99 ******.00

S9(6)V9(2) 123.45 +Z(6).99 +∕∕∕123.45

S9(6)V9(2) -123.45 -Z(6).99 -∕∕∕123.45

O comando PICTURE é responsável por definir o layout dos dados usados nos programas. Tem por finalidade ajustar,
não só o estilo do dado, mas como o dado se comporta internamente e a quantidade de bytes a ser utilizada na memó-
ria para dar o suporte adequado as operações de entrada, processamento e saída.
Os códigos (9), (S), (V), (P), (Z), (A), (X), (+), ($), (*), (.), (,), (0), (CR) e (DB) estabelecem grande estilo de formatações
e atendem desta forma diversas necessidades operacionais como sugerido na tabela 2.2.
O comando PICTURE, como mencionado, estabelece o layout do dado vinculado ao conteúdo armazenado em memó-
ria como sendo um campo de dado. Este campo de dado é vinculado a definição prévia de uma variável.

2.2.2 Variáveis
Variáveis são áreas ou campos de memória usadas para o armazenamento de dados que são manipulados em compu-
tadores. Os dados armazenados na forma de variáveis poderão ser usados na realização de cálculos quando numéri-
cos, na realização de movimentações quando forem de qualquer tipo, no armazenamento temporário de dados na me-
mória principal ou na apresentação de seus conteúdos.
A identificação de uma variável é realizada com a definição de um nome alfanumérico contendo no máximo trinta carac-
teres. O nome de identificação de uma variável pode ser iniciado por número, desde que este nome tenha em sua com-
posição no mínimo um caractere alfabético. Para a composição dos nomes podem ser usadas letras de A até Z, núme-
ros de 0 até 9, hifens (-) e linha baixa (_).
A definição de variáveis é feita segundo a especificação de um código que estabelece o nível hierárquico e o compor-
tamento de cada variável. Os códigos numéricos usados podem ser os valores de 1 a 49, 66, 77 e 88. Quanto menor o
valor, maior será seu nível hierárquico. Uma variável pode ser definida como elemento isolado, ou seja, um item ele-
mentar (item individual ou independente) ou ser definida como componente de um grupo (item de grupo ou de campo)
não tendo nenhuma relação com outro dado existente. As variáveis do tipo itens de grupo podem ser subdivididas para
agruparem variáveis isoladas ou outros itens de grupos que por sua vez podem ser formados por itens elementares ou
itens de grupo e assim sucessivamente.
Observe na sequência a tabela 2.7 com a definição dos valores de código numérico para o estabelecimento dos níveis
numéricos de definição de elementos ou grupos de elementos suportados pela linguagem.
AÇ ÃO S EQ U EN C IAL 63

Tabela 2.7 – Níveis numéricos hierarquizados para variáveis

Nível Descrição operacional

01 Definição de item de grupo (estilo registro)

02 até 49 Definição de itens elementares dentro de grupos

66 Renomear itens de cláusulas, usado com RENAME

77 Definição de item elementar

88 Definição de múltiplos valores (intervalos: estilo lógico)

Não há regra para determinar a numeração de variáveis dentro dos itens de grupo (nível 01). Dentro de um grupo po-
dem ser definidas variáveis ou outros grupos subordinados. Neste caso, para cada variável ou mesmo grupo subordi-
nado usa-se tão somente a numeração de 02 até 49. Apenas o item de grupo principal é definido com o código 01. Há,
por parte de alguns programadores, o hábito de estabelecer a numeração subordinada em saltos de 5 em 5 ou 10 em
10. No entanto, poderá ser usado, sem nenhum problema, qualquer valor entre 02 e 49. Não é necessário definir os
níveis de forma contínua, o que é importante é manter sua ordem de grandeza crescente.
Se o desejo for apenas definir variáveis isoladas como itens elementares o código a ser usado é 77. Os códigos 66 e 88
são especiais e serão tratados em momento mais oportuno. No entanto, há programadores que definem variáveis isola-
das com o código 01. Assim sendo, neste momento são apresentados o uso dos códigos 77 e 01 a partir da forma sin-
tática:

<nível> <variável> PIC(TURE) <código[(tamanho)]> [VALUES <conteúdo>]

Em que nível é a definição obrigatória do código de estabelecimento de uma variável, variável é a definição obrigatória
de um rótulo de identificação para variável, PIC(TURE) <código[(tamanho)]> é a definição obrigatória da estrutura do
campo para a variável (como apresentado) e VALUES é a definição opcional do estabelecimento de um valor inicial
para a variável definida.
Observe um exemplo de definição de variáveis de itens elementares (código 77) para o armazenamento do NOME com
trinta posições alfabéticos, IDADE com três posições numéricas iniciada com valor 100 e ALTURA com uma posição
numérica inteira e duas posições numéricas decimais.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC A(30).
77 IDADE PIC 9(03) VALUES 100.
77 ALTURA PIC 9V9(02).

Note que foram definidas as PICTURES de formatação A(30) para a variável NOME indicando o uso de variável do tipo
alfabética com trinta posições, 9(03) VALUES 100 para a variável IDADE indicando o uso de uma variável do tipo nu-
mérica inteiro com três posições iniciada com valor 100 e 9V9(02) para o campo ALTURA indicando o uso de uma
variável numérica real com parte da posição para valor inteiro em metros e duas partes da posição para o valor decimal
em centímetros.
Veja um exemplo para a definição de um item de grupo (código 01) identificado como DADOS-PESSOAIS contendo os
itens elementares NOME com trinta posições alfabéticos, IDADE com três posições numéricas iniciada com valor 100 e
ALTURA com uma posição numérica inteira e duas posições numéricas decimais.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 DADOS-PESSOAIS.
02 NOME PIC A(30).
02 IDADE PIC 9(03) VALUES 100.
02 ALTURA PIC 9V9(02).
64 PRO G RA MA Ç ÃO CO B OL

Observe que o item de grupo DADOS-PESSOAIS está alinhando na coluna 12 e os itens elementares associados ao
grupo estão definidos a partir da coluna 18. Este alinhamento visa dar melhor visualização do nivelamento usado e está
de acordo com a tabulação usada no ambiente OpenCobolIDE e com a estrutura de um formulário fixo. No entanto, é
comum ver essa tabulação estabelecida a partir da coluna 15 como indicado. Fica a critério do programador escolher o
estilo.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 DADOS-PESSOAIS.
02 NOME PIC A(30).
02 IDADE PIC 9(03) VALUES 100.
02 ALTURA PIC 9V9(02).

Um detalhe importante é que ao escolher o valor entre 02 e 49 para especificar cada um dos itens elementares este
deverá ser mantido em todo o escopo do grupo. Note que foi usado o valor 02 para todos os itens elementares do grupo
DADOS-PESSOAIS.
Como comentado um item de grupo pode ser formado por outros itens de grupo. Desta forma, considere que o item de
grupo DADOS-PESSOAIS (formado pelos itens elementares NOME, IDADE e ALTURA) é parte de um grupo chamado
CADASTRO que tenha ainda um grupo chamado DOCUMENTO com os itens elementares CPF e RG.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 CADASTRO.
05 DADOS-PESSOAIS.
10 NOME PIC A(30) VALUES "AAA BBB CCC".
10 IDADE PIC 9(03) VALUES 111.
10 ALTURA PIC 9V9(02) VALUES 1.76.
05 DOCUMENTO.
10 CPF PIC 9(11).
10 RG PIC 9(10).

Atente para o uso do código 01 como estabelecimento do grupo principal (lembrando que todo item de grupo deve ser
definido sempre com o código 01). No entanto, qualquer grupo criado (grupo secundário) dentro de um item de grupo
01 poderá ser definido com um valor entre 02 e 49. Neste caso foi escolhido o valor 05 e dentro deste escopo poderá
ser usado apenas valores entre 06 e 49 para definir novos itens elementares ou mesmo outros grupos. O uso dos valo-
res deverá sempre ser na ordem crescente. Não é possível usar sequencialmente um valor menor ao último valor esta-
belecido. Veja que os itens elementares foram definidos com o valor 10, mas poderiam ser valores de 06 até 49.

2.2.3 Espaço de memória


Quando se utiliza PICTURE consome-se certo espaço de memória. Os valores alfabéticos e alfanuméricos estão limita-
dos ao consumo máximo de até 256 bytes, mas valores numéricos são um caso a parte, pois podem ser especificados
como inteiros a partir do código 9 (inteiros não sinalizados) ou S9 (inteiros sinalizados) e reais com o código V (decimal
implícito) ocupando 18 bytes de memória.
Os dados definidos como inteiros aceitam a realização de operações matemáticas de forma direta, sem nenhum trata-
mento especial desse dado, mas o mesmo não ocorre com os dados reais que necessitam ser tratados e devidamente
ajustados.
O tratamento realizado sobre dados numéricos é chamado de compactação, devendo ser aplicado tanto a dados reais
como a dados inteiros. A operação de compactação visa definir ajustes de modo que se controle a quantidade de bytes
consumidos em memória a partir do formato especificado para o campo representante do dado. São três as definições
de campos a serem considerados para o tratamento numérico: zonados, compactados e binários:
 Campo zonado é aquele em que o algarismo consome exatamente um byte de memória, é o tipo de campo usado
para os valores numéricos sem tratamento de compactação, ocupando sempre 18 bytes de memória para represen-
tar um valor numérico de 18 dígitos, sendo a forma padrão da linguagem COBOL;
AÇ ÃO S EQ U EN C IAL 65

 Campo compactado é aquele em que o algarismo é armazenado em formato decimal compactado (BCD - Binary
Coded Decimal) utilizando dois dígitos por byte com mais meio byte reservado a sinalização de valores negativos,
ocupando até 10 bytes para representar valore com 38 dígitos;
 Campo binário é aquele que possui a melhor taxa de compactação possível, é usado para representar em um byte
a maior quantidade de bits possíveis, por exemplo, em um conjunto de dois bytes é possível armazenar valores po-
sitivos de 0 até 65.536, o mesmo espaço em um campo zonado armazena valores positivos de 0 até 99, podendo
ser usado para o tratamento de qualquer tipo de dado.
Para a definição do tamanho de memória a ser qualificado sobre determinado dado (elementar ou grupo) pode-se usar
a cláusula USAGE e o verbo IS. O comando USAGE IS pode ser usado com itens elementares ou de grupos. Se usado
com itens elementares (variáveis/campos) deverá ser declarado após o comando PICTURE desde que a variável não
seja inicializada. Caso a variável seja inicializa o comando USAGE IS deve ser a última expressão na linha de instrução
após a definição do valor de inicialização. No caso de itens de grupo o comando USAGE IS deve ser declarado imedia-
tamente ao lado direito do nome do grupo e os itens elementares subordinados a este grupo deverão ser definidos com
o mesmo tipo de dado do item de grupo, sendo que basta declarar o tipo de dado para o item de grupo para que todos
os seus itens elementares sejam automaticamente qualificados com o mesmo tipo de dado definido. O uso do comando
USAGE IS segue de forma geral a sintaxe:

77 <variável> PIC <código[(tamanho)]> [VALUES <conteúdo>] USAGE IS <opção>


77 <variável> PIC <código[(tamanho)]> USAGE IS <opção>
01 <grupo> USAGE IS <opção>

Em que opção é a definição de uma palavra-chave que orienta o compilador a efetuar o tratamento do dado citado. A
cláusula USAGE e o verbo IS são opcionais (no passado eram usadas com equipamentos IBM) e por esta razão aca-
bam por não serem utilizadas o que leva, normalmente, as linhas de declaração de itens elementares e de grupo serem
codificadas como:

77 <variável> PIC <código[(tamanho)]> [VALUES <conteúdo>] <opção>


77 <variável> PIC <código[(tamanho)]> <opção>
01 <grupo> <opção>

A cláusula USAGE e o verbo IS são usados apenas com os níveis 01 e 77 não sendo aplicadas aos demais níveis de
qualificação.
Os compiladores COBOL disponibilizam algumas opções para a configuração do espaço de armazenamento de dados
em memória. Neste texto são consideradas apenas as opções essenciais ao compilador GnuCOBOL. Sugere-se para
maior aproveitamento fazer consulta junto a documentação técnica do compilador. Veja algumas das opções computa-
cionais importantes de definição de tipos e compactação de dados usadas em conjunto da cláusula PICTURE:
 BINARY é usado para armazenar valores numéricos inteiros no formato binário puro de até 18 bits formatados com
as máscaras 9 ou S. Dependendo da quantidade de bits em uso o dado poderá ocupar até oito bytes. BINARY po-
derá ser substituída por seus sinônimos equivalentes COMP (podendo ser COMPUTATIONAL) ou COMP-4 (po-
dendo ser COMPUTATIONAL-4). Com 2 bytes (de 1 a 4 dígitos na PICTURE) a faixa de valores operada vai de 0 a
255 ou de -128 até 127), com 4 bytes (de 5 a 9 dígitos na PICTURE) a faixa de valores operada vai de 0 a 65.535
ou de -32.768 até 32.767), com 8 bytes (de 10 a 18 dígitos na PICTURE) a faixa de valores operada vai de 0 a
4.294.967.295 ou de -2.147.483.648 até 2.147.483.647) e com 16 bytes a faixa de valores operada vai de 0 a
18.446.744.073.709.551.615 ou de -9.223.372.036.854.775.807 até 9.223.372.036.854.775.807);
 COMP-3 (podendo ser COMPUTATIONAL-3) é usado para armazenar valores numéricos decimais compactados de
até 38 bits formatados com as máscaras 9, S, V e P. Esta opção armazena dois dígitos em um único byte, manten-
do meio byte de memória para indicar a sinalização numérica (para representação de valores negativos), mesmo
que o valor não seja sinalizado. Dependendo da quantidade de bits estabelecidos o dado poderá ocupar até 20
bytes. COMP-3 poderá ser substituída por seu sinônimo equivalente PACKED-DECIMAL;
 COMP-5 (podendo ser COMPUTATIONAL-5) é similar a BINARY, tendo como diferença o fato de que os dados são
armazenados em um formato binário dependente da arquitetura do computador (binário nativo), o que pode ocasio-
nar problemas de transporte de dados entre computadores de diferentes arquiteturas. Este tipo de dado é usado
principalmente para comunicação entre programas externos;
66 PRO G RA MA Ç ÃO CO B OL

 COMP-X (podendo ser COMPUTATIONAL-X) é usado para determinar definições de tipos que usem as máscaras 9
e X tratando os dados como número inteiro binário não sinalizado com armazenamento interno semelhante a opção
BINARY. Se usada a máscara X para definir um item, o número de bytes alocados para o item será o mesmo cor-
respondente ao número de X usados na máscara. Se usada a máscara 9 será alocado o menor número de bytes
necessários ao armazenamento do valor em uso;
 DISPLAY é usada para armazenar dados do tipo caractere em formato ASCII (American Standard Code for Informa-
tion Interchang - Código Padrão Americano para o Intercâmbio de Informação) usados com as máscaras 9, A e X.
Desta forma, cada caractere armazenado ocupará um byte de memória (8 bits). Esta opção computacional é o pa-
drão de operação da linguagem e por esta razão não há a necessidade de fazer seu uso, a menos que se deseje
ser extremamente criterioso. Para maiores detalhes consulte o apêndice desta obra.
Observe algumas das opções computacionais importantes de definição de tipos e compactação de dados usadas em
sem o uso da cláusula PICTURE:
 COMP-1 (podendo ser COMPUTATIONAL-1) é usado para armazenar valores numéricos decimais de ponto flutu-
ante com precisão simples a partir das máscaras 9, S, V e P, ocupando quatro bytes de comprimento. Para uso des-
ta opção não se faz o uso da cláusula PICTURE por ser o tamanho do dado pré-estabelecido. Opera na faixa apro-
ximada de valores de -3.4028235×10^38 até 3.4028235×10^3;
 COMP-2 (podendo ser COMPUTATIONAL-2) é usado para armazenar valores numéricos decimais de ponto flutu-
ante com precisão dupla a partir das máscaras 9, S, V e P, ocupando oito bytes de comprimento. Para uso desta
opção não se faz o uso da cláusula PICTURE por ser o tamanho do dado pré-estabelecido. Opera na faixa aproxi-
mada de valores de -1.797693134862316×10^308 até 1.797693134862316×10^308;
 POINTER é usado para representar endereços de memória relacionados a outros dados, por este motivo este tipo
de dado é representado por valores numéricos inteiros não sinalizados. O dado qualificado como ponteiro não faz
uso da cláusula PICTURE, mas aceita a clausula VALUE desde que o valor de inicialização seja NULL (para indicar
que o ponteiro não aponta para nenhum dado em específico na memória). Este tipo ocupa 4 ou 8 bytes de memória,
o que permite armazenar, respectivamente, endereços de tamanho até 32 ou 64 bits operando na faixa de 0 até o
limite, respectivo, de 32 ou 64 bits.
Observe um exemplo de definição de uma variável do tipo item elementar para o armazenamento do ANO com iniciali-
zação de valor em 2000 para certa data com seu a definição do tipo de dado BINARY:

DATA DIVISION.
WORKING-STORAGE SECTION.
77 ANO PIC 9999 VALUES 2000 USAGE IS BINARY.

Veja neste exemplo a definição de um item de grupo identificado como DADOS-PESSOAIS sem qualificação de tipo de
dado contendo os itens elementares NOME com trinta posições alfabéticos, IDADE com três posições numéricas defi-
nida com o tipo BINARY com o uso do comando USAGE IS e ALTURA com uma posição numérica inteira e duas posi-
ções numéricas decimais definidas com o tipo COMP-3 sem o uso do comando USAGE IS.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 DADOS-PESSOAIS.
02 NOME PIC A(30).
02 IDADE PIC 9(03) USAGE IS BINARY.
02 ALTURA PIC 9V99 COMP-3.

Note no próximo exemplo a definição do item de grupo DATA-CAL com qualificação de tipo de dado BINARY contendo
os campos DIA, MES e ANO sem definição de tipo de dado.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 DATA-CAL USAGE BINARY.
02 DIA PIC 9(02).
02 MES PIC 9(02).
02 ANO PIC 9(04).
AÇ ÃO S EQ U EN C IAL 67

Observe o uso da opção computacional POINTER inicializada com valor da constante NULL indicando que o ponteiro
não está apontando para nenhum endereço de memória.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 PTR VALUE NULL USAGE POINTER.
77 VAL PIC X(10) VALUES "ABC 123456".

PROCEDURE DIVISION.
SET PTR TO ADDRESS OF VAL.
DISPLAY PTR.

Um item elementar do tipo POINTER se caracteriza por ser uma variável especial que armazena apenas endereço de
memória e não o conteúdo da posição apontada. Veja que na divisão de procedimento é usado o verbo SET que tem
por finalidade colocar em certa variável o conteúdo indicado após a cláusula TO, Neste caso, a instrução coloca em
PTR o endereço da variável VAL a partir do uso da cláusula ADDRESS OF (endereço de) e não o conteúdo indicado na
variável VAL. A saída do programa é algo como 0x0040e040 indicando o endereço hexadecimal (0x) de memória situ-
ada em 0040e040.

2.2.4 Constantes
Uma constante caracteriza-se por ser a definição de certo valor imutável de qualquer natureza associado a um determi-
nado rótulo. Uma constante não sofre alteração de seu valor ao longo da execução de certo programa. A linguagem
COBOL pode ser operada a partir de dois tipos de constantes as internas e as externas.
Até a edição da norma ISO 1989:1985 a linguagem COBOL não possuía uma forma explícita de declaração de constan-
te. Quando se tinha a necessidade de fazer uso de constantes, simulava-se a definição da constante utilizando-se uma
variável com a inicialização de um valor.
Após a publicação da norma de 1985 a linguagem recebe a primeira implementação de definição de constante a partir
do uso da cláusula CONSTANT e da preposição AS a serem usadas com a definição de nível 01. Com a publicação da
norma ISO/IEC 1989:2014 vem a segunda e atual definição de constante a partir do uso do código de nível 07 e a cláu-
sula VALUES.
Do conjunto de valores constantes existentes no GnuCOBOL duas estão definidas como funções intrínsecas a partir do
uso do comando FUNCTION. O trecho a seguir mostra os valores retornados das constantes matemática “E” (logaritmo
natural) e “PI” com 95 casas decimais.

PROCEDURE DIVISION.
DISPLAY FUNCTION E. *> 2.718281828459045235360287471352662497757247093699959 (...)
DISPLAY FUNCTION PI. *> 3.141592653589793238462643383279502884197169399375105 (...)

Além das funções intrínsecas “E” e “PI” que representam duas constantes matemáticas importantes há a existência de
algumas constantes figurativas: ZERO/ZEROS/ZEROES (usadas com máscara numérica); SPACE/SPACES (usadas
com máscara alfanumérica); HIGH-VALUE/HIGH-VALUES (usadas com máscara alfanumérica); LOW-VALUE/LOW-
VALUES (usadas com máscara alfanumérica); QUOTE/QUOTES (usadas com máscara alfanumérica); NULL/NULLS
(usadas com máscara alfanumérica).
Note que há constantes figurativas expressas no singular e plural. No singular refere-se a apenas uma ocorrência da
constante sobre o dado no plural refere-se a mais de uma ocorrência da constante sobre o dado. No entanto, as formas
singular e plural podem ser usadas de maneira intercambiável uma vez que representam, em si, a mesma coisa por
serem sinônimos. O uso em singular ou plural é uma maneira de deixar o código do programa mais próximo da escrita
do idioma inglês, lembrando que essa foi uma das intenções do desenvolvimento da linguagem.
As constantes ZERO, ZEROS e ZEROES representam a definição do valor 0 (zero ou zeros) que dependendo do con-
texto de uso poderá ser considerado numérico ou alfanumérico.
As constantes SPACE e SPACES representam a definição de caractere de espaço ou espaços em branco considera-
dos do tipo alfanumérico.
68 PRO G RA MA Ç ÃO CO B OL

As constantes HIGH-VALUE e HIGH-VALUES representam a ocorrência de um ou mais caracteres X"FF" (maior valor
hexadecimal na posição ordinal da sequência de caracteres EBCDIC) de acordo com o que é definido no parágrafo
OBJECT-COMPUTER ou quando nada é especificado utiliza o conjunto de caracteres padrão, normalmente ASCII.
As constantes LOW-VALUE e LOW-VALUES representam a ocorrência de um ou mais caracteres X"00" (menor valor
hexadecimal na posição ordinal da sequência de caracteres EBCDIC) de acordo com o que é definido no parágrafo
OBJECT-COMPUTER ou quando nada é especificado utiliza o conjunto de caracteres padrão, normalmente ASCII.
As constantes QUOTE e QUOTES representam a definição de caractere ou caracteres de aspas inglesas considerados
do tipo alfanumérico.
As constantes NULL e NULLS representam a definição de valor nulo ou nulos (internamente igual a 0), podendo ser
aplicada para indicar que o dado não possui endereço de acesso a memória válido. Esta constante pode ser associada
a inicialização de ponteiros e referências de objetos.
Em relação a definição de constantes externas, estas são apresentadas a seguir das duas formas permitidas. É perti-
nente pontuar que a definição de constantes deve ser realizada na seção WORKING-STORAGE e que esta definição
não usa a cláusula PICTURE.
Observe a forma sintática da definição de valores constantes seguindo a regra da norma ISO 1989:1985 com a cláusula
CONSTANT e a preposição AS:

01 <constante> CONSTANT AS <valor>.

Onde constante é o nome atribuído ao recurso e valor é a definição do valor representado pelo rótulo constante. Para
a definição de valores numéricos o máximo de dígitos permitidos são 38 em toda a sua extensão.
Observe o trecho seguinte demonstrando a definição da constante matemáticas “LN2” respeitando o estilo da norma
ISO 1989:1985. Atente para o uso do código 01 e da cláusula CONSTANT e a preposição AS.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 LN2 CONSTANT AS 0.6931471805599453094.

PROCEDURE DIVISION.
DISPLAY LN2.

Observe a forma sintática da definição de valores constantes seguindo a regra da norma ISO/IEC 1989:2014 com a
cláusula VALUES e a preposição AS:

78 <constante> VALUES <valor>.

Observe o trecho seguinte demonstrando a definição da constante matemáticas “LN10” respeitando o estilo da norma
ISO 1989:2014. Atente para o uso do código 78 e da cláusula VALUES.

DATA DIVISION.
WORKING-STORAGE SECTION.
78 LN10 VALUES 2.3025850929940456840.

PROCEDURE DIVISION.
DISPLAY LN10.

Diferentemente de uma variável, o valor de uma constante não ocupa espaço de memória. Isto é perceptível uma vez
que na definição de constante não se utiliza a cláusula PICTURE, logo não há ocupação de espaço de memória para o
dado. A constante é apenas a definição de um apelido usado para fazer referência de acesso a um determinado valor,
facilitando seu uso.
AÇ ÃO S EQ U EN C IAL 69

2.2.5 Reagrupamento de dados


O reagrupamento de itens elementares cria um grupo “lógico” baseado a partir de um grupo “físico” existente que con-
tenha itens elementares. A renomeação de grupo é executa com o uso da cláusula RENAME, que necessita do código
66. A cláusula RENAME não usa a cláusula PICTURE e não pode renomear entradas de códigos 01, 66, 77 e 88. O
grupo “lógico” usa a mesma área de memória em que o grupo “físico” encontra-se definido. A cláusula RENAME pode
ser aplicada apenas no final do grupo “físico”. Itens elementares declarados com a cláusula OCCURS (usada para a
criação de tabela, que serão vistas mais adiante nesta obra) não podem ser renomeados.
Como exemplo para renomeação de grupo “físico” considere a estrutura do item de grupo DATA-NAS (data de nasci-
mento) qualificado como sendo do tipo DISPLAY contendo os campos DIA (com valor 26), MES (com valor 04), ANO
(com valor 1965), HORA (com valor 17) e MINUTO (com valor 25) reagrupado como data de aniversário DATA-ANV
contendo apenas o acesso aos campos DIA, MES e ANO.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 DATA-NAS USAGE BINARY.
02 DIA PIC 9(02) VALUES 26.
02 MES PIC 9(02) VALUES 04.
02 ANO PIC 9(04) VALUES 1965.
02 HORA PIC 9(02) VALUES 17.
02 MINUTO PIC 9(04) VALUES 25.
66 DATA-ANV RENAMES DIA THRU ANO.
PROCEDURE DIVISION.
DISPLAY "DIA ...............: " DIA.
DISPLAY "MES ...............: " MES.
DISPLAY "ANO ...............: " ANO.
DISPLAY "HORA ..............: " HORA.
DISPLAY "MINUTO ............: " MINUTO.
DISPLAY "DATA NASCIMENTO ...: " DATA-NAS.
DISPLAY "DATA ANIVERSARIO ..: " DATA-ANV.

Ao ser executado um programa, que contenha a estrutura definida anteriormente, deverá ser apresentada uma saída
semelhante a imagem da figura 2.1.

Figura 2.1 – Saída de grupo renomeado

No exemplo apresentado, grupo DATA-NAS é declarado com cinco campos dispostos contiguamente em certa área de
memória. Ao se definir a renomeação da área como DATA-ANV tem-se acesso apenas aos itens indicados do campo
DIA até o campo ANO. Neste caso os três primeiros.
Observe que a indicação DIA NASCIMENTO tem apresentada a sequência de valores 2604196500170025 contigua-
mente e a indicação DIA ANIVERSARIO apresenta apenas os valores 26041965 que corresponde a área de memória
acessada pelo item de grupo DATA-ANV.
70 PRO G RA MA Ç ÃO CO B OL

2.3 PROCESSAMENTO MATEMÁTICO


Após conhecer o conceito de dados operacionais relacionados ao uso de variáveis e constantes, bem como sua estru-
turação em memória na DATA DIVISION é importante atentar a principal operação que pode ser imputada sobre esses
dados: o processamento matemático que contempla as operações de cálculos realizadas por um computador.
A linguagem oferece para a realização de cálculos matemáticos os comandos COMPUTE, DIVIDE, MULTIPLY, ADD e
SUBTRACT. O comando COMPUTE atende a maior parte das necessidades de uso de operações com cálculos, pos-
suindo uma estrutura de escrita em estilo algébrico mais tradicional baseando-se na indicação de equações, diferente
dos demais comandos que expressam a ação algébrica de forma descritiva. No entanto, cada uma das formas possui
suas características.

2.3.1 Estilo algébrico


O estilo algébrico é operacionalizado pelo comando COMPUTE que define uma instrução para certa ação na realização
do processamento aritmético na forma de equação. Devido a sua característica operacional a instrução COMPUTE é
executada na PROCEDURE DIVISION a partir do uso de operadores aritméticos e funções intrínsecas.
A tabela 2.8 mostra os operadores aritméticos suportados e destinados as ações de processamento aritmético executa-
dos com o comando COMPUTE. A ordem de apresentação dos operadores na tabela corresponde a ordem de priorida-
de a ser considerada matematicamente.
Tabela 2.8 – Operadores aritméticos

Operador Operação Resultado com Prioridade

** Exponenciação Inteiro e decimal 1

/ Divisão Inteiro e/ou decimal 2

* Multiplicação Inteiro e decimal 2

+ Adição Inteiro e decimal 3

- Subtração Inteiro e decimal 3

= Atribuição Qualquer tipo de dado -

Como exemplo considere o trecho de código seguinte voltado a apresentar o resultado da área de uma circunferência
com cinco casas decimais sem a existência de zeros à esquerda a partir de um raio definido com o valor 5.32. Consid-
ere a formula AREA ← PI * RAIO ↑ 2 para calcular AREA-CIRC = FUNCTION PI * RAIO-CIRC ** 2.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AREA-CIRC PIC 9(03)V9(05) VALUES ZERO.
77 RAIO-CIRC PIC 9(03)V9(05).
77 RAIO-DISP PIC Z(03).9(05).

PROCEDURE DIVISION.
COMPUTE RAIO-CIRC = 5.32.
COMPUTE AREA-CIRC = FUNCTION PI * RAIO-CIRC ** 2.
MOVE AREA-CIRC TO RAIO-DISP.
DISPLAY RAIO-DISP.

Para a demonstração foram definidas duas variáveis para a efetivação do cálculo, sendo AREA-CIRC e RAIO-CIRC na
DATA DIVISION, em que AREA-CIRC é a variável que armazena o resultado do cálculo realizado e RAIO-CIRC é a
variável que fornece a fórmula um valor para a operação.
AÇ ÃO S EQ U EN C IAL 71

Observe que a variável AREA-CIRC que armazena o resultado foi inicializada com a definição do valor zero a partir da
instrução 77 AREA-CIRC PIC 9(03)V9(05) VALUES ZERO, atente para o uso da cláusula VALUES com a definição de
uso da constante figurativa ZERO.
A variável RAIO-CIRC está definida apenas com a máscara 9(03)V9(05) de formatação e a inicialização de seu valor
está definida na PROCEDURE DIVISION a partir da instrução COMPUTE RAIO-CIRC = 5.32. Veja que COMPUTE
pode ser utilizado para determinar a inicialização de variáveis, além do uso da clausula VALUES.
Note que tanto a variável AREA-CIRC como RAIO-CIRC usam a máscara 9(03)V9(05) que determinam um espaço de
memória adequado para representar um valor numérico no formato 999.99999.
Uma das ações solicitadas é a apresentação do resultado do cálculo sem a ocorrência de zeros à esquerda. Para que
isso seja possível foi definida a variável AREA-DISP a partir da máscara Z(3).9(5) que determina um formato numérico
para valores no estilo 999.99999.
Atente para o uso de duas máscaras diferentes para o mesmo formato numérico, 9(03)V9(05) e Z(03).9(05). Qual é a
diferença, se ambas usam o estilo 999.99999.
A diferença é que a máscara 9(03)V9(05) formata os valores na memória ajustando o espaço exigido, sendo essa más-
cara direcionada ao armazenamento de dados e consequentemente seu processamento. Já a máscara Z(03).9(05) é a
definição de uma ação “cosmética” para a apresentação de dados com o comando DISPLAY.
No contexto apresentado a variável AREA-DISP é, o que se chama, de campo editado. Um campo editado é um recur-
so que só pode ser utilizado para efeitos de exibição do dado no monitor de vídeo, não pode ser usado em operações
aritméticas ou algébricas.
Há um detalhe importante a ser considerado em relação ao uso da variável AREA-DISP que apesar de estar formatada
para a recepção de valor numérico, não é uma variável numérica e por conseguinte não poderá ser usada diretamente
para a realização de cálculos matemáticos.
As variáveis AREA-CIRC e RAIO-CIRC são numéricas decimais e AREA-DISP é alfanumérica e para fazer com que o
conteúdo de uma variável numérica seja atribuído a uma variável alfanumérica usa-se o comando MOVE em conjunto
com a preposição TO. Desta forma, a instrução MOVE AREA-CIRC TO RAIO-DISP move o conteúdo numérico decimal
da variável AREA-CIRC para a variável RAIO-DISP ajustando o valor numérico dentro do formato alfanumérico definido
para RAIO-DISP.
O comando MOVE tem a finalidade transferir dados de uma área de armazenamento (dado remetente) para outra área
de armazenamento (dado receptor). A forma de movimentação do conteúdo é determinada pelo campo receptor po-
dendo-se transferir itens de elementos ou itens de grupo. A movimentação só pode ser realizada se houver compatibili-
dade de tipo entre os dados, isso permitiria no código exemplo usar a instrução MOVE 5.32 TO RAIO-CIRC. Em substi-
tuição a instrução COMPUTE RAIO-CIRC = 5.32.
O comando COMPUTE tem ainda a característica de atribuir um mesmo resultado calculado de certa operação a mais
de uma variável. Observe a seguir a soma de A com valor 1 e B com valor 2 atribuídas de uma única vez as variáveis
R1, R2 e R3.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 9 VALUES 1.
77 B PIC 9 VALUES 2.
77 R1 PIC 9.
77 R2 PIC 9.
77 R3 PIC 9.

PROCEDURE DIVISION.
COMPUTE R1 R2 R3 = A + B.
DISPLAY R1.
DISPLAY R2.
DISPLAY R3.
72 PRO G RA MA Ç ÃO CO B OL

A execução do código anterior apresenta três vezes o número 3 como resultado da operação para as variáveis R1, R2
e R3 a partir da instrução COMPUTE R1 R2 R3 = A + B.
O comando COMPUTE para realizar as operações aritméticas segue a hierarquia matemática na aplicação dos opera-
dores. Desejando alterar a ordem da prioridade das operações use parênteses sobre a operação de menor prioridade.
É indicado que antes de abrir e fechar parêntese deixe pelo menos um espaço em branco.
As operações aritméticas com valores decimais poderão sofrer ações de truncamento, dependendo da quantidade de
casas decimais disponíveis. Por exemplo, um valor 5.29 será expresso em uma casa decimal como 5.2 quando trunca-
do. No entanto, esta é uma situação que a apresentação do valor pode ocorrer como 5.3. Para conseguir este efeito
basta usar o adjetivo ROUNDED logo após a variável que receberá o resultado da operação.
Como exemplo, considere a definição de duas variáveis, sendo A formatada em duas casas decimais contendo o valor
5.20 e B formatada com duas casas decimais contendo o valor 0.09 e a variável R formatada apenas com uma casa
decimal e qualificada para ser arredonda.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 99V99 VALUES 5.20.
77 B PIC 99V99 VALUES .09.
77 R PIC 99V9.

PROCEDURE DIVISION.
COMPUTE R = A + B.
DISPLAY R.
COMPUTE R ROUNDED = A + B.
DISPLAY R.

Se executadas as instruções anteriores serão apresentados os valores 05.2 e 05.3, sendo o primeiro truncado e o se-
gundo arredondado. Observe que o uso de ROUNDED fez sua aproximação no dígito menos significativo somando 1
ao dígito mais significativo, o que fez o valor de 5.2 passar para 5.3. A operação de arredondamento para mais ou para
menos é realizada quando o dígito mais significativo a ser truncado for maior ou igual a 5.
Além do tratamento sobre truncamento de valores decimais podem ocorrer algumas situações de erro. Neste caso, o
tratamento do erro é realizado pela frase [NOT] ON SIZE ERROR que possui a estrutura sintática:

[NOT] ON SIZE ERROR <mensagem>.

Onde mensagem é a definição personalizada de uma mensagem informativa de advertência apresentada quando al-
guma situação de erro ocorre no programa. As mensagens devem ser operacionalizadas com o comando DISPLAY.
As situações de erro que geram ocorrências são:
 Divisão por zero;
 Estouro de ponto flutuante ou insuficiente;
 O resultado da operação aritmética é maior que o campo de ponto fixo definido;
 Um número negativo elevado a uma potência fracionária;
 Zero aumentado para um número negativo;
 Zero elevado à potência zero.
No sentido de fazer uma demonstração desta operação considere uma situação de estouro decimal com resultado de
uma operação aritmética maior que o campo definido.
Como exemplo, considere a definição de duas variáveis, sendo A formatada em duas casas decimais e uma posição
antes do ponto decimal contendo o valor 9.5 e B formatada com duas casas decimais e uma posição antes do ponto
decimal contendo o valor 1.5 e a variável R formatada com duas casas decimais e uma posição antes do ponto decimal.
AÇ ÃO S EQ U EN C IAL 73

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 9V99 VALUES 9.5.
77 B PIC 9V99 VALUES 1.5.
77 R PIC 9V99.

PROCEDURE DIVISION.
COMPUTE R = A + B.
DISPLAY R.

Se executa as instruções anteriores será apresentado o valor 1.00 como resposta, sendo este um resultado inconclusi-
vo, uma vez que deveria ser apresentado o valor 11.0. Assim sendo, observe a seguir o uso do trecho de tratamento de
erro preparado para apresentar no monitor de vídeo uma mensagem de erro. Para fazer uso da frase ON SIZE ERROR
com o comando COMPUTE deve-se colocado no final da expressão aritmética.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 9V99 VALUES 9.5.
77 B PIC 9V99 VALUES 1.5.
77 R PIC 9V99.

PROCEDURE DIVISION.
COMPUTE R = A + B ON SIZE ERROR DISPLAY "Inconclusivo".
DISPLAY R.

Se executadas as instruções ocorrerá a apresentação da mensagem “Inclusivo” em uma linha e a indicação do valor
0.00 na linha de baixo. Diferentemente da versão anterior, neste caso o resultado não é apresentado devido ao uso da
frase [NOT] ON SIZE ERROR.
Veja que a frase ON SIZE ERROR pode opcionalmente ser negada com o operador NOT. De fato, o modo de operação
padrão do compilador é de NOT ON SIZE ERROR quando nenhuma situação de anormalidade ocorre.

2.3.2 Estilo descritivo


O estilo descritivo de ação aritmética é realizado pelos verbos ADD, SUBTRACT, MULTIPLY e DIVIDE que fazem uso
dos chamados operandos (variáveis ou constantes) que podem ser citados com ou sem separação por vírgulas. Devido
a sua característica operacional esses verbos são executados na PROCEDURE DIVISION.

ADD
A declaração ADD efetua a soma dos operandos numéricos definidos e armazena o resultante da soma. Há, basica-
mente, duas formas típicas para uso deste verbo - com auxílio da preposição TO e/ou com auxílio do verbo GIVING.
Para realização dos testes relacionados as operações de adição a seguir considere a definição das variáveis A, B e C
respectivamente com os valores 1.5, 2.5 e 3.5 definidas na DATA DIVISION com a máscara 9V99.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 9V99 VALUES 1.5.
77 B PIC 9V99 VALUES 2.5.
77 C PIC 9V99 VALUES 3.5.

Para que a preposição TO possa ser usada é necessário que haja entre ADD e TO no mínimo um operando. Sua forma
sintática segue o modelo:

ADD VALOR-1 [[[VALOR-2] VALOR-3] ... VALOR-M] TO VALOR-N.


74 PRO G RA MA Ç ÃO CO B OL

Quando a preposição TO é usada, os valores dos operandos que o antecedem são somados com o operando que o
sucede, armazenando o resultado da soma sobre o operando sucessor.
Como exemplo observe a apresentação da ação da soma realizada com o uso da preposição TO para os valores 1.5,
2.5 e 3.5 respectivamente relacionados as variáveis A, B e C, definidas anteriormente.

PROCEDURE DIVISION.
ADD A B TO C.
DISPLAY C.

Após a execução do exemplo é apresentado o resultado 7.50, sendo a soma dos valores das variáveis A, B e C com
atualização do resultado sobre a variável C. Internamente ocorre a operação algébrica C = A + B + C.
Para que o verbo GIVING possa ser usado é necessário que haja entre ADD e GIVING no mínimo dois operandos. Sua
forma sintática segue o modelo:

ADD VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] GIVING VALOR-N.

Quando o verbo GIVING é usado os valores dos operandos que o antecedem são somados e armazenados sobre o
operando definido após o verbo GIVING, sobrepondo o valor deste operando.

PROCEDURE DIVISION.
ADD A B GIVING C.
DISPLAY C.

Após a execução do exemplo é apresentado o resultado 4.00, sendo a soma dos valores das variáveis A e B com atri-
buição do resultado sobre a variável C, sobrepondo seu valor. Internamente ocorre a operação algébrica C = A + B.
Foi comentado que o comando COMPUTE tem a característica de atribuir um mesmo resultado calculado a mais de
uma variável, sendo que o mesmo se aplica ao uso do verbo ADD. Assim sendo, considere a soma da variável A com
valor 1 e variável B com valor 2 atribuídas de uma única vez as variáveis R1, R2 e R3, todas com a máscara 9

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 9 VALUES 1.
77 B PIC 9 VALUES 2.
77 R1 PIC 9.
77 R2 PIC 9.
77 R3 PIC 9.

PROCEDURE DIVISION.
ADD A B GIVING R1 R2 R3.
DISPLAY R1.
DISPLAY R2.
DISPLAY R3.

Caso necessite usar com o verbo ADD o adjetivo ROUNDED para produzir valores arredondados após o uso da prepo-
sição TO ou o verbo GIVING coloque-o no final da expressão seguindo o estilo:

ADD A B TO C ROUNDED.
ADD A B GIVING C ROUNDED.

Caso necessite usar com o verbo ADD a frase ON SIZE ERROR para conter alguma ação indevida deve-se escrevê-la
ao final da expressão, de acordo com o estilo:

ADD A B TO C ON SIZE ERROR DISPLAY "Inconclusivo".


ADD A B GIVING C ON SIZE ERROR DISPLAY "Inconclusivo".

É perfeitamente possível fazer uso em conjunto do adjetivo ROUNDED e da frase ON SIZE ERROR como:
AÇ ÃO S EQ U EN C IAL 75

ADD A B TO C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo".


ADD A B GIVING C ROUNDED ON SIZE ERROR DISPLAY "Inconclusivo".

Caso a composição de uma linha de instrução ultrapasse a septuagésima segunda coluna o conteúdo escrito poderá
ficar dividido em duas ou mais linhas. Observe o exemplo seguinte:

ADD A B TO C ROUNDED ON SIZE ERROR


DISPLAY "Inconclusivo".
ADD A B GIVING C ROUNDED ON SIZE ERROR
DISPLAY "Inconclusivo".

SUBTRACT
A declaração SUBTRACT efetua a subtração de um ou faz a soma de dois ou mais operandos para em seguida subtrair
e armazena o resultado obtido da diferença. Há, basicamente, duas formas típicas para uso deste verbo - com auxílio
da preposição FROM e do verbo GIVING.
Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, C
e D respectivamente com os valores 1.5, 2.5, 3.5 e 0 definidas na DATA DIVISION com a máscara S9V99.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC S9V99 VALUES 1.5.
77 B PIC S9V99 VALUES 2.5.
77 C PIC S9V99 VALUES 3.5.
77 D PIC S9V99 VALUES 0.

Para que a preposição FROM possa ser usada é necessário que haja entre SUBTRACT e FROM no mínimo um ope-
rando. Sua forma sintática segue o modelo:

SUBTRACT VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] FROM VALOR-N.

Quando a preposição FROM é usada, os valores dos operandos que o antecedem são somados e subtraídos do ope-
rando que o sucede, armazenando o resultado da subtração sobre o operando sucessor.
Como exemplo observe a apresentação da ação da subtração realizada com o uso da preposição FROM para os valo-
res 1.5, 2.5 e 3.5 respectivamente relacionados as variáveis A, B e C, definidas anteriormente.

PROCEDURE DIVISION.
SUBTRACT A B FROM C.
DISPLAY C.

Após a execução do anterior é apresentado o resultado -0.50, sendo este a soma dos valores das variáveis A e B sub-
traídos do valor da variável C com atualização do resultado sobre a variável C. Internamente ocorre a operação algébri-
ca C = C - (A + B).
Para que o verbo GIVING possa ser usado é necessário que haja entre SUBTRACT e GIVING no mínimo dois operan-
dos antecedentes a FROM. Sua forma sintática segue o modelo:

SUBTRACT VALOR-1 VALOR-2 [[VALOR-3] ... VALOR-M] FROM VALOR-M GIVING VALOR-N.

Quando o verbo GIVING é usado os valores dos operandos que o antecedem são somados e subtraídos do operando
que antecede FROM tendo o resultado da operação armazenado no operando de sucede GIVING, preservando o con-
teúdo do operando definido após FROM.
Como exemplo observe a apresentação da ação da subtração realizada com o uso da preposição GIVING para os
valores 1.5, 2.5, 3.5 e 0 respectivamente relacionados as variáveis A, B, C e D definidas anteriormente.
76 PRO G RA MA Ç ÃO CO B OL

PROCEDURE DIVISION.
SUBTRACT A B FROM C GIVING D.
DISPLAY D.

Após a execução do exemplo é apresentado o resultado -0.50, sendo este a soma dos valores das variáveis A e B
subtraídos do valor da variável C e transferidos para a variável D e preservando assim o valor da variável C. Interna-
mente ocorre a operação algébrica D = C - (A + B).
Assim como COMPUTE e ADD o verbo SUBTRACT tem a característica de atribuir um mesmo resultado calculado a
mais de uma variável. Assim sendo, considere a soma da variável A com valor 1.5, a variável B com valor 2.5 e a variá-
vel C com valor 3.5 (sem alterar o valor de C) atribuídas de uma única vez as variáveis R1, R2 e R3, todas com a más-
cara S9V99.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC S9V99 VALUES 1.5.
77 B PIC S9V99 VALUES 2.5.
77 C PIC S9V99 VALUES 3.5.
77 R1 PIC S9V99.
77 R2 PIC S9V99.
77 R3 PIC S9V99.

PROCEDURE DIVISION.
SUBTRACT A B FROM C GIVING R1 R2 R3.
DISPLAY R1.
DISPLAY R2.
DISPLAY R3.

Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED
e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD.

MULTIPLY
A declaração MULTIPLY efetua a multiplicação de dois operandos e armazena o resultado do produto. Há, basicamen-
te, duas formas típicas para uso deste verbo - com auxílio da preposição BY e do verbo GIVING.
Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, C
e D respectivamente com os valores 2, 3, 4 e 5 definidas na DATA DIVISION com a máscara 999.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC 999 VALUES 2.
77 B PIC 999 VALUES 3.
77 C PIC 999 VALUES 4.
77 D PIC 999 VALUES 5.

Para que a preposição BY possa ser usada é necessário que haja entre MULTIPLY e BY apenas um operando. Sua
forma sintática segue o modelo:

MULTIPLY VALOR-1 BY VALOR-2 [[VALOR-3] ... VALOR-N].

Quando a preposição BY é usada, o valor do operando que o antecede é multiplicado distributivamente pelos operan-
dos definidos após a preposição BY armazenando os resultados nos operandos sucessores.
Como exemplo observe a apresentação da ação da multiplicação realizada com o uso da preposição BY para os valo-
res 2 e 3 respectivamente relacionados as variáveis A e B, definidas anteriormente.
AÇ ÃO S EQ U EN C IAL 77

PROCEDURE DIVISION.
MULTIPLY A BY B.
DISPLAY B.

Após a execução do anterior é apresentado o resultado 006, sendo este a multiplicação dos valores das variáveis A e B
com atualização do resultado sobre a variável B. Internamente ocorre a operação algébrica B = A × B.
Veja agora outro exemplo em que o valor da variável A é multiplicado pelo valor da variável B e pelo valor da variável C
a partir do uso da preposição BY.

PROCEDURE DIVISION.
MULTIPLY A BY B C.
DISPLAY B.
DISPLAY C.

Após a execução do exemplo anterior são apresentados os resultados 006 e 008, sendo o primeiro o valor da variável A
multiplicado pelo valor da variável B e o segundo o valor da variável A multiplicado pelo valor da variável C.
Para que o verbo GIVING possa ser usado é necessário que haja entre MULTIPLY e BY haja um operando. Sua forma
sintática segue o modelo:

MULTIPLY VALOR-1 BY VALOR-2 [[VALOR-3] ... VALOR-N] GIVING [VALOR-M].

Quando o verbo GIVING é usado os valores dos operandos entre a preposição BY são multiplicados distributivamente
(se assim for o caso) tendo o resultado da operação armazenado no operando de sucede GIVING, preservando o con-
teúdo dos operandos definidos após BY.

PROCEDURE DIVISION.
MULTIPLY A BY B GIVING C.
DISPLAY C.

Após a execução do exemplo é apresentado o resultado 006, sendo este a multiplicação dos valores das variáveis A
com a variável B transferidos para a variável C e preservando assim o valor da variável B. Internamente ocorre a ope-
ração algébrica C = A × B.
Assim como COMPUTE, ADD e SUBTRACT o verbo MULTIPLY tem a característica de atribuir um mesmo resultado
calculado a mais de uma variável, bastando indicar as variáveis receptoras uma a uma após o verbo GIVING.
Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED
e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD.

DIVIDE
A declaração DIVIDE efetua a divisão de dois operandos e armazena o resultado do quociente. Há, basicamente, três
formas típicas para uso deste verbo - com auxílio das preposições BY ou INTO e do verbo GIVING.
Para realização dos testes relacionados as operações de subtração a seguir considere a definição das variáveis A, B, Q
e R respectivamente com os valores 9, 7, 0 e 0 definidas na DATA DIVISION com a máscara S99V99.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 A PIC S99V99 VALUES 9.
77 B PIC S99V99 VALUES 7.
77 Q PIC S99V99 VALUES 0.
77 R PIC S99V99 VALUES 0.

Para que as preposições BY e INTO possam ser usadas é necessário que haja entre DIVIDE e BY ou INTO apenas um
operando. No caso de uso da preposição BY usar o verbo GIVING será obrigatório. Sua forma sintática segue o mode-
lo:
78 PRO G RA MA Ç ÃO CO B OL

DIVIDE VALOR-1 BY[|INTO] VALOR-2 GIVING [VALOR-3].

Quando a preposição BY é usada, o valor do operando que antecede a preposição será dividido pelo valor que sucede
a preposição, ou seja, VALOR-1 será dividido pelo VALOR-2 e o resultado do quociente será atribuído a VALOR-3. No
entanto, se estiver em uso a preposição INTO ocorrerá o contrário o VALOR-2 será dividido pelo VALOR-1 e o resulta-
do ficará armazenado em VALOR-2.
Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição BY para os valores 9 e
7 respectivamente relacionados as variáveis A e B com armazenamento do quociente na variável Q definidas anterior-
mente.

PROCEDURE DIVISION.
DIVIDE A BY B GIVING Q.
DISPLAY Q.

Após a execução do exemplo é apresentado o resultado +01.28, sendo este a divisão dos valores da variável A sobre a
variável B com armazenamento do quociente na variável B. Internamente ocorre a operação aritmética Q = A ÷ B.
Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição INTO para o valor 7
sobre o valor 9 relacionados as variáveis A com valor 9 e B com valor 7 tendo o armazenamento do quociente na variá-
vel B definidas anteriormente.

PROCEDURE DIVISION.
DIVIDE A INTO B.
DISPLAY B.

Após a execução do exemplo é apresentado o resultado +00.77, sendo este a divisão dos valores da variável B sobre a
variável A com armazenamento do quociente na variável B. Internamente ocorre a operação aritmética B = B ÷ A.
O cálculo de divisão permite obter o resultado do resto a partir do uso do comando (substantivo) REMAINDER usado ao
final de uma expressão de divisão. Sua forma sintática segue o modelo:

DIVIDE VALOR-1 BY[|INTO] VALOR-2 GIVING [VALOR-3] REMAINDER [VALOR-4].

Para fazer uso do comando REMAINDER é obrigatório usar em conjunto o verbo GIVING, lembrando que esse coman-
do é ideal para operar com valores inteiros e não decimais. Assim sendo, é necessário ajustar os valores das variáveis
A, B, Q e R na DATA DIVISION para 9 e 7 mantendo as demais variáveis com 0. Use a máscara 9.
Como exemplo observe a apresentação da ação da divisão realizada com o uso da preposição BY para os valores 9 e
7 respectivamente relacionados as variáveis A e B com armazenamento do quociente na variável Q e valor de resto
armazenado na variável R definidas anteriormente.

PROCEDURE DIVISION.
DIVIDE A BY B GIVING Q REMAINDER R.
DISPLAY Q.
DISPLAY R.

Após a execução do exemplo é apresentado o resultado do quociente como 1 e do resto da divisão como 2 sendo o
primeiro valor o resultado da divisão com quociente inteiro da variável A sobre a variável B e o segundo valor sendo o
resultado resto da divisão obtido a partir do valor do dividendo (variável A) subtraído do valor do divisor (variável B)
multiplicado pelo valor do quociente da divisão da variável A sobre a variável B.
Problemas com arredondamento ou truncamentos de valores podem ser corrigidos com o uso do adjetivo ROUNDED
e/ou da frase ON SIZE ERROR seguindo as mesmas regras apontadas no uso do verbo ADD.
AÇ ÃO S EQ U EN C IAL 79

2.3.3 Algébrico versus descritivo


Diferentemente de outras linguagens de programação, a linguagem COBOL possui dois estilos para o estabelecimento
de operações aritméticas a partir de definições algébricas para a realização do processamento matemático, o que pode
ocasionar certa dúvida no sentido de intuir qual dos estilos deve ou pode ser usado. Qual dos estilos usar? Algébrico ou
descritivo?
Para responder esta pergunta é necessário perceber, primeiro, que a forma descritiva usa um estilo sintático como se
fosse a escrita de uma frase com substantivos, verbos, preposições e adjetivos. Aliás essas figuras são perceptíveis
neste estilo, como foi apresentado, dando um toque mais “humano” na linguagem.
O estilo descritivo deixa a forma escrita de uma expressão matemática mais humanizada, menos matematizada, o que,
de certa maneira, é interessante. No entanto causa um efeito colateral, chamado em computação de verbosidade. A
linguagem COBOL é, por sua natureza, verbosa uma vez que busca se aproximar da forma escrita da língua inglesa,
isso faz com que a escrita de instruções se torne maior do que, eventualmente, poderia ser e muitas vezes pode se
tornar muito confusa para as pessoas, dependendo do grau de conhecimento e experiência na linguagem que essas
pessoas tenham.
Para dar ideia sobre o que está sendo comentado, observe o exemplo a seguir para a realização do cálculo do valor de
venda de um produto. O exemplo apresentado é uma adaptação do material de estudo da linguagem COBOL disponibi-
lizado por Carlos Alberto Dornelles no sítio cadcobol (http://www.cadcobol.com.br/).

MULTIPLY QUANT BY VLR-UNIT GIVING VENDAS DIVIDE TAXA INTO VENDAS

Observe na sequência forma descrita ao estilo algébrico.

COMPUTE VENDAS = QUANT * VLR-UNIT / TAXA

É perceptível que o estilo algébrico em sua forma matematizada expressa a operação como uma equação. Isso faz com
que a leitura da expressão seja mais rápida e confortável, desde que o programador se sinta à vontade com o estilo
matemático. No entanto, haverá ocasiões que usar o estilo descritivo será mais vantajoso que usar o estilo algébrico.
Na prática é importante ao programador COBOL conhecer adequadamente as formas algébrica e descritiva de expres-
sar operações matemáticas para perceber quando usar um ou outro estilo. Outro ponto importante em saber bem as
duas formas é que parte do trabalho computacional é realizar serviços de manutenção em programas que estão a muito
em execução. A possibilidade de encontrar essa diversidade operacional nas organizações é muito grande.
Cada pessoa desenvolve sua percepção e aceitação operacional sobre um ou outro estilo. Desta forma, as respostas
para as perguntas feitas anteriormente, é basicamente simples. Escolha o estilo que melhor lhe convém em determina-
do momento. Em sistemas mais antigos a probabilidade de encontrar o estilo descritivo é maior que o uso da forma
algébrica, mas também seu uso é encontrado em programas mais recentes.
Em relação a este tema há algo a ser levado em grande consideração. Preferencialmente em seu código de programa,
adote um estilo em detrimento ao outro, seja qual for. Evite misturar em excesso essas formas em seu código, pois isto
poderá trazer dificuldades nas ações de manutenção dos programas. Use simultaneamente os dois estilos em caso de
alguma das formas não atender adequadamente e eficientemente o que é necessário ser feito.

2.3.4 Funções intrínsecas


A operação mais importante realizada por um computador, não importa seu tamanho e tipo, é sem sombra de dúvidas o
processamento de dados, principalmente as operações que realizam os cálculos matemáticos. Além dos recursos exis-
tentes para a definição de variáveis e constantes, a linguagem COBOL possui internamente uma coleção de funcionali-
dades que dão suporte a realização de tarefas matemáticas, lógicas, estatísticas, calendário, financeiras, entre outras.
Uma função é um recurso que efetua uma operação e devolve uma resposta sobre a operação realizada. Uma função
pode fazer ou não uso de argumentos. Por exemplo, as funções anteriormente usadas como constantes “E” e “PI” são
exemplos de funções que são operacionalizadas sem o uso de argumentos. Há funções que operam com um ou mais
argumentos ou mesmo uma lista de valores.
80 PRO G RA MA Ç ÃO CO B OL

A título de ilustração é apresentado um pequeno conjunto de funções estatísticas e matemáticas que utilizam argumen-
tos como valores isolados, mais de um valor e lista de valores.

FUNÇÕES ESTATÍSTICAS
As funções estatísticas são usadas para auxiliar o tratamento, análise, interpretação e apresentação de dados numéri-
cos. Neste sentido, para auxiliar esta tarefa a linguagem COBOL oferece algumas funções, das quais estão sendo des-
tacadas as funções MAX (extrai o maior valor numérico de uma lista), MEDIAN (calcula a média dos valores de uma
lista), MIN (extrai o menor valor numérico de uma lista) e SUM (calcula o somatório dos valores de uma lista).
O trecho de código a seguir mostra como exemplo alguns resultados estatísticos obtidos a partir de uma pequena lista
de valores (5, 1, 9, 2, 8, 3, 7, 4, 6) definidos na PROCEDURE DIVISION e apresentadas com o comando DISPLAY.

PROCEDURE DIVISION.
DISPLAY FUNCTION MAX(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 9
DISPLAY FUNCTION MEDIAN(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 5
DISPLAY FUNCTION MIN(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 1
DISPLAY FUNCTION SUM(5, 1, 9, 2, 8, 3, 7, 4, 6). | mostra o valor: 45

FUNÇÕES MATEMÁTICAS
As funções matemáticas são usadas para auxiliar diversas operações que necessitam de ações de cunho genéricos.
Neste sentido, para auxiliar esta tarefa a linguagem COBOL oferece algumas funções, das quais estão sendo destaca-
das as funções ABS (retornar o valor indicado sempre como positivo), FACTORIAL (retornar a multiplicação sucessiva
de 1 até o valor fornecido como limite), INTEGER (retornar de um valor numérico decimal apena s a parte inteira), REM
(retornar o valor do resto de uma divisão de dois valores) e SQRT (retornar a raiz quadrada de um valor informado).

PROCEDURE DIVISION.
DISPLAY FUNCTION ABS(-5). | mostra o valor: +5
DISPLAY FUNCTION FACTORIAL(5). | mostra o valor: 120
DISPLAY FUNCTION INTEGER(8.25). | mostra o valor: 8
DISPLAY FUNCTION REM(9, 7). | mostra o valor: 2
DISPLAY FUNCTION SQRT(2). | mostra o valor: 1.41421356237309504880168 (...)

Não é objetivo descrever na totalidade as funções existentes na linguagem. Para conhece-las consulte qualquer manual
de referência, normalmente chamado language reference para acesso a lista completa de funções do compilador em
uso. Para o GnuCOBOL a relação de funções encontra-se no manual GNU COBOL 2.0 Programmer´s Guide disponí-
vel para obtenção no sítio https://open-cobol.sourceforge.io/guides/GNUCobol2.pdf, seção 6.1.7, página 6-21.
Atente para o fato de serem essas funções mecanismos auxiliares para a realização de ações de cálculos na etapa de
processamento matemático. Eventualmente outras funções são apresentadas neste livro na medida em que necessita-
rem serem utilizadas.

2.4 ENTRADAS E SAÍDAS


Após tratar o tema sobre processamento matemático, uma das etapas mais importantes na programação de computa-
dores cabe agora tratar o tema relacionado as ações de entrada e saída de dados que cumprem com o processamento
atender ao tema central deste capítulo: ação sequencial.
Um programa de computador executa as etapas de entrada de dados, processamento de dados e saída de dados que
servirão como base para a geração de informações que serão usadas nas estratégias de tomadas de decisões pelas
organizações.
Parte das ações de saída de dados foram usadas desde o capítulo anterior por meio do comando DISPLAY demons-
trado de forma simples, apenas para contextualizar alguns exemplos operacionais. Neste tópico o comando DISPLAY
AÇ ÃO S EQ U EN C IAL 81

destinado a saída será operacionalizado em conjunto com o comando ACCEPT responsável pela execução da entrada
de dados com um nível de detalhe maior.
O comando DISPLAY possui alguns estilos de definição e escrita, mas neste momento é apresentado apenas a forma
básica para a definição da ação de saída de dados de forma genérica

DISPLAY <"mensagem"> [UPON <dispositivo>] [WITH NO ADVANCING]

Onde, mensagem é algo a ser impresso no monitor de vídeo (conteúdo entre aspas inglesas na forma de cadeia) e
dispositivo é a definição de um nome de referência interno do ambiente vinculado como saída e mencionado na seção
de configuração da ENVIRONMENT DIVISION no parágrafo SPECIAL-NAMES da seção CONFIGURATION SECTION
com a indicação de uso do substantivo CONSOLE e o verbo IS.
O comando DISPLAY tem por finalidade transferir o conteúdo de cada operando (variáveis ou campos) que se encon-
tram na memória para o dispositivo de saída, normalmente monitor de vídeo.
O uso da preposição UPON é opcional e deverá ser usada se houver a definição de um nome de referência para o
dispositivo de saída na seção de configuração. Caso seja omitido é assumido como padrão o dispositivo de saída de
dados conectado ao computador: monitor de vídeo. A preposição UPON pode ser associada a nomes de dispositivos
de saída, como CONSOLE, SYSOUT, SYSLIST, SYSLST ou STDOUT que estejam relacionados ao parágrafo SPECI-
AL-NAMES. Em particular as indicações: CONSOLE, SYSOUT, SYSLIST e SYSLST são formas lógicas de se fazer
referência ao dispositivo de saída físico conectado ao sistema denominado STDOUT.
A frase WITH NO ADVANCING é opcional e tem por finalidade manter o cursor na linha após a apresentação da men-
sagem.
O comando ACCEPT também possui alguns estilos de definição e escrita, mas neste momento é apresentado apenas a
forma básica para a definição da ação de entrada de dados de forma genérica.

ACCEPT <identificador> [FROM <dispositivo>]

Onde, identificador é um dado de entrada fornecido pelo sistema operacional ou via teclado pelo usuário do programa
e dispositivo é a definição de um nome de referência interno do ambiente vinculado como entrada e mencionado na
seção de armazenamento da ENVIRONMENT DIVISION do parágrafo SPECIAL-NAMES da seção CONFIGURATION
SECTION com a indicação de uso do substantivo CONSOLE e o verbo IS.
O comando ACCEPT tem por finalidade transferir o conteúdo do dispositivo de entrada, normalmente o teclado para os
operandos (variáveis ou campos) a fim de armazená-los em memória.
O uso da preposição FROM é opcional e é usada se houver a definição de um nome de referência para o dispositivo de
saída na seção de configuração. Caso seja omitido o programa assume como padrão o dispositivo de entrada de dados
conectado ao computador: o teclado.
A preposição FROM pode ser associada a nomes de dispositivos de entrada, como CONSOLE, SYSIN, SYSIPT ou
STDIN que estejam relacionados ao parágrafo SPECIAL-NAMES.
Em particular as indicações: CONSOLE, SYSIN e SYSIPT são formas lógicas de se fazer referência ao dispositivo de
entrada físico conectado ao sistema denominado STDIN.
Tomando por base o que foi explicado considere como exemplo de uso dos comandos de entrada e saída o trecho de
código exemplificado a seguir que solicita a entrada do nome em formato alfabético do usuário contendo 30 caracteres
de tamanho e apresenta uma mensagem de saudação.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC A(30).

PROCEDURE DIVISION.
DISPLAY "Entre seu nome, por favor: " WITH NO ADVANCING
ACCEPT NOME.
DISPLAY "Ola, " NOME.
82 PRO G RA MA Ç ÃO CO B OL

Ao ser executado um programa, que contenha a estrutura definida anteriormente, será apresentada inicialmente a men-
sagem solicitando a entrada. Neste momento o programa fica aguardando a entrada. Após realizar a entrada ocorre a
apresentação da mensagem de saudação do nome e mostram as imagens das figuras 2.2 e 2.3.

Figura 2.2 – Mensagem de entrada Figura 2.3 – Mensagem de saída

Com o objetivo de apresentar a utilização dos adjetivos FROM e UPON respectivamente para os comandos ACCEPT e
DISPLAY considere como exemplo a mesma situação anterior e observe os trechos sinalizados colorizados apontando
o uso desses recursos.
Para o direcionamento da saída é definido o dispositivo com o nome MEU-VIDEO e para o direcionamento da entrada é
definido o dispositivo com o nome MEU-TECLA.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
CONSOLE IS MEU-VIDEO.
CONSOLE IS MEU-TECLA.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC A(30).

PROCEDURE DIVISION.
DISPLAY "Entre seu nome, por favor: " UPON MEU-VIDEO
WITH NO ADVANCING.
ACCEPT NOME FROM MEU-TECLA.
DISPLAY "Ola, " NOME UPON MEU-VIDEO.

Uma atenção especial no trecho de código apresentado é a separação da linha de instrução com o comando DISPLAY
que mostra a mensagem solicitando a entrada do nome. Note que a frase WITH NO ADVANCING é posicionada logo
abaixo do comando DISPLAY. Isto foi feito, pois a linha de código completa ultrapassa a septuagésima segunda coluna
do formulário, e tudo que passa da coluna 72 não é avaliado pelo compilador.
Outro detalhe, é a citação do dispositivo CONSOLE indicando ações de entrada e saída. Essa forma pode ser definida
com outros sinônimos deixando o código do programa menos genérico, dando-lhe mais especificidade. Observe o tre-
cho do parágrafo SPECIAL-NAMES com as indicações de STDIN para a entrada e STDOUT para a saída, podendo-se
usar qualquer outra referência das indicadas, cada qual, representado seu dispositivo de ação. O único nome de dispo-
sitivo que pode ser usado em comum é CONSOLE.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
STDOUT IS MEU-VIDEO.
STDIN IS MEU-TECLA.
AÇ ÃO S EQ U EN C IAL 83

A partir de agora já se tem em mãos o que é necessário para começar a escrever os primeiros programas codificados e
contextualizados em COBOL, pois todas as ferramentas, mínimas, necessárias foram apresentadas: ações de entrada,
ações de processamento (variáveis, constantes, operadores aritméticos e funções) e ações de saída.

2.5 HORA DE PROGRAMAR


Nesta etapa são colocadas em prática, grande parte do que foi visto nos tópicos e capítulo anterior e mais alguns deta-
lhes, apresentados. A partir deste ponto você terá em mãos o ferramental mínimo necessário para começar a escrever
seus primeiros programas, ainda simples, mas muito impactantes. Nesta parte são apresentados três problemas com-
putacionais genéricos e codificação dos problemas na forma de programas com grau de rigor mínimo.
É fundamental perceber que quem trabalha com desenvolvimento de software estará sempre a frente de algum proble-
ma que deve primeiro ser resolvido por ele mesmo para depois dar uma solução computacional. Desta forma, mantenha
sua atenção a cada problema apresentado, bem como a solução indicada.

CÁLCULO DE ADIÇÃO SIMPLES


Elaborar programa de computador que efetue a entrada de dois valores numéricos inteiros desconhecidos negativos ou
positivos de até três posições (unidade, dezena e centena) e apresente em seguida o resultado da soma dos valores
fornecidos.
Para o desenvolvimento deste programa há um detalhe importante a ser considerado: tomando por base que a entrada
dos dados usará a máscara 999, torna-se necessário intuir que para a saída do resultado será necessário uma máscara
com a configuração 9999, pois a soma do valor 800 com o valor 200 resulta no valor 1000, ou seja, somar dois valores
de três posições (unidade, dezena e centena) pode resultar na obtenção máxima de um valor de quatro posições (uni-
dade, dezena, centena e unidade de milhar).
Selecione e defina um projeto do programa vazio com o nome c02ex01.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C02EX01 AS "Capitulo 2 – Exemplo 1".
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 EA PIC S9(3).
6 77 EB PIC S9(3).
7 77 RC PIC S9(4).
8 77 SR PIC Z(4).
9 78 CR VALUE X"0D".
10 77 EN PIC X.
11 PROCEDURE DIVISION.
12 PROG-PRINCIPAL-PARA.
13 DISPLAY "Entre valor <A>: " WITH NO ADVANCING.
14 ACCEPT EA.
15 DISPLAY "Entre valor <B>: " WITH NO ADVANCING.
16 ACCEPT EB.
17 COMPUTE RC = EA + EB.
18 MOVE RC TO SR.
19 DISPLAY CR.
20 DISPLAY "Resultado = " SR.
21 DISPLAY X"0D".
22 DISPLAY "Tecle <ENTER> para encerrar... "
------ ------------------------------------------------------------------------
84 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
23 WITH NO ADVANCING.
24 ACCEPT EN.
25 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Você verá diversos detalhes conhecidos e outros
nem tanto.
Um detalhe comentado, mas não exemplificado encontra-se na linha 2. Veja que após a identificação do programa com
o comando PROGRAM-ID que deve ter no máximo oito caracteres usa-se a preposição AS com um termo de identifica-
ção para o programa que poderá ter no máximo 31 caracteres. Esse recurso permite identificar um programa de manei-
ra mais legível que o indicativo de PROGRAM-ID.
Na linha 15 é definido um parágrafo personalizado PROG-PRINCIPAL-PARA na PROCEDURE DIVISION. Dentro das
recomendações de codificação COBOL há a orientação de que as instruções da divisão de procedimento sejam escri-
tas dentro de um parágrafo (no mínimo). A ausência deste parágrafo personalizado não interfere na execução do pro-
grama, serve apenas como elementos de formatação de código.
As variáveis EA (Entra A) e EB (Entra B) definidas respectivamente nas linhas 6 e 7 são usadas para a efetivação das
ações de entrada nas linhas 17 e 19 a partir do uso do comando ACCEPT.
A linha 8 apresenta a definição da variável RC (R Calculado) usada na linha 20 para a efetivação do processamento e
atribuição do resultado calculado com o comando COMPUTE, além de ser usada para ter seu conteúdo movimentado
para a variável SR (Saída de R) na linha 21 que efetivamente retira os zeros a esquerda existentes quando do uso das más-
caras formatadas com o código 9.
Na linha 9 é definida a variável SR usada como campo editado para auxiliar a formatação do valor numérico do resultado de
RC transferido para esta variável a partir da execução da instrução da linha 21 com o objetivo de ser apresentado na linha 23.
A linha 11 apresenta a definição da constante chamada CR (Carriege Return, ou seja, a tecla <ENTER>) associada ao valor
X"0D". O valor X"0D" indica por meio do código X o uso de um número hexadecimal, neste caso 0D (código ASCII referente
a tecla <ENTER>) que permitirá definir um caractere de salto de linha para pular linhas na apresentação de informações no
monitor de vídeo como efetuado na linha 22.
Na linha 12 é definida a variável EN (Entrada) com apenas uma posição alfanumérica que será usada na ação da linha 27.
O conjunto de linhas de código entre 16 e 19 são usadas para proceder a entrada dos dados no programa. Observe que nas
linhas 16 e 18 usa-se a frase WITH NO ADVANCING com o objetivo de manter o cursor na mesma linha após a apresenta-
ção das mensagens. Nas linhas 17 e 19 são efetivadas as entradas com o comando ACCEPT.
A linha 20 efetua o processamento da soma das variáveis EA e EB atribuindo o resultado da operação na variável RC.
Na linha 21 ocorre a movimentação do conteúdo da variável RC para a variável SR. Nesta etapa os valores zeros de uma
máscara com código 9 são suprimidos devido a definição da máscara da variável SR com o código Z.
A linha 22 efetua a apresentação do conteúdo da variável CR que neste caso efetua um salto de linha em branco no monitor
de vídeo.
Na linha 23 ocorre a apresentação do resultado no monitor de vídeo sem a existência de zeros à esquerda caso o valor apre-
sentado seja menor que quatro posições.
A linha 24 efetua um salto de linha em branco com o uso direto do valor X"0D". Neste momento, é deixado como exemplo
uma segunda alternativa para executar saltos de linha, ficando a critério do programador escolher qual forma a ser usada.
Nas linhas 25 e 26 encontra-se definida a apresentação da mensagem solicitando que a tecla <ENTER> seja acionada para
que o programa tenha continuidade. Pelo fato dessa instrução ultrapassar o limite de 72 posições permitida no formulário,
fez-se sua divisão em duas linhas. Nesta obra, as linhas divididas, para melhor visualização, serão grafadas com endentação
de duas posições abaixo de sua continuidade.
AÇ ÃO S EQ U EN C IAL 85

A linha 27 é feita uma parara temporária de execução no programa, neste caso aguardando que o usuário tecle, no teclado, a
tecla <ENTER>. Não existe na linguagem COBOL um comando específico para o estabelecimento de pausas temporárias em
programas, o que leva a necessidade de definição de um mecanismo de interrupção como o apresentado. O conteúdo arma-
zenado na variável EN não é, tipicamente, tratado.
Os detalhes usados entre as linhas de 25 até 27 são um mero artifício de interrupção.

CÁLCULO SALARIAL
Elaborar programa de computador que calcule o salário líquido de um profissional que trabalhe por hora. Para tanto, é
necessário possuir alguns dados, tais como valor da hora de trabalho (variável HT), número de horas trabalhadas no
mês (variável VH) e o percentual de desconto do INSS (variável PD), para que seja possível apresentar os resultados
do salário bruto (variável SB), do valor descontado (variável VH) e do salário líquido (variável SL).
Para o desenvolvimento deste programa é levado em consideração algumas informações adicionais para a devida
configuração do espaço de memória a ser utilizado e do uso adequado da aplicação uso. Imagine operar a saída de
valores com a máscara financeira $ 99.999,99. Neste caso, a máscara ideal para a entrada de dados é 9,999.99. Para a
taxa o ideal é uma máscara que opera na faixa de valores entre 0.0000 até 1.0000 (equivalente de 0% a 100%).
As variáveis de entrada HT e VH são formatadas com base na estrutura 9999.99 a partir da máscara 9(4)V99. A variá-
vel de entrada PD baseada na estrutura 9.9999 é formatada com a máscara 9V9(4).
As variáveis de recepção dos cálculos SB, TD e SL são formatadas com base na estrutura 99999.99 a partir da másca-
ra 9(5)V99.
Observe, como regra geral, que é sempre adequado colocar um dígito a mais de tamanho nas variáveis que recepcio-
nam resultados de processamento. Por exemplo, se for somada a unidade 1 com a unidade 9 tem-se o valor 0 na uni-
dade e o vai-um do 1 excedente para a dezena formando o valor 10. Outra preocupação que se deve ter no modelo de
programação COBOL é a definição das variáveis de saída formatadas a partir de campos de edição. Essas variáveis
não são, e não podem ser usadas na realização das operações algébricas e aritméticas, elas servem apenas para auxi-
liar a saída desses dados. Para este programa essas variáveis são representadas pelos rótulos S-SB, S-TD e S-SL
utilizando-se a máscara $BZZ,ZZ9.99 a fim de proporcionar o formato de saída como $ 99.999,99.
Selecione e defina um projeto do programa vazio com o nome c02ex02.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C02EX02 AS "Capitulo 2 – Exemplo 2".
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 HT PIC 9(4)V99.
6 77 VH PIC 9(4)V99.
7 77 PD PIC 9V9(4).
8 77 SB PIC 9(5)V99.
9 77 TD PIC 9(5)V99.
10 77 SL PIC 9(5)V99.
11 77 S-SB PIC $BZZ,ZZ9.99.
12 77 S-TD PIC $BZZ,ZZ9.99.
13 77 S-SL PIC $BZZ,ZZ9.99.
14 77 EN PIC X.
15 PROCEDURE DIVISION.
16 PROG-PRINCIPAL-PARA.
17 DISPLAY "Entre horas trabalhadas ........: "
18 WITH NO ADVANCING.
19 ACCEPT HT.
------ ------------------------------------------------------------------------
86 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
20 DISPLAY "Entre valor da hora ............: "
21 WITH NO ADVANCING.
22 ACCEPT VH.
23 DISPLAY "Entre percentual de desconto ...: "
24 WITH NO ADVANCING.
25 ACCEPT PD.
26 COMPUTE SB = HT * VH.
27 COMPUTE TD = (PD / 100) * SB.
28 COMPUTE SL = SB - TD.
29 MOVE SB TO S-SB.
30 MOVE TD TO S-TD.
31 MOVE SL TO S-SL.
32 DISPLAY X"0D".
33 DISPLAY "Salario bruto ....: " S-SB.
34 DISPLAY "Desconto .........: " S-TD.
35 DISPLAY "Salario liquido ..: " S-SL.
36 DISPLAY X"0D".
37 DISPLAY "Tecle <ENTER> para encerrar... "
38 WITH NO ADVANCING.
39 ACCEPT EN.
40 STOP RUN.
------ ------------------------------------------------------------------------

Após compilar, coloque o programa em execução, forneça os valores 100 (horas trabalhadas), 250 (valor da hora) e 5.5
(percentual de desconto) e veja o conjunto de dados apresentados com os valores do salário bruto, desconto calculado
e salário líquido. Esse conjunto de dados forma a base de uma informação: o contra cheque de um trabalhador.

Salario bruto ....: $ 25,000.00


Desconto .........: $ 1,375.00
Salario liquido ..: $ 23,625.00

Observe que o programa opera seus valores financeiros no formato usado nos Estados Unidos da América com milha-
res separadas por vírgulas e decimais separados por ponto, diferente do padrão usado no Brasil em que milhares são
separadas por pontos e decimais separadas por vírgula. O fato é que a linguagem COBOL possui um recurso especifi-
co para tratar exclusivamente este tipo de formatação. Veja no código seguinte algumas alterações no programa.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C02EX02 AS "Capitulo 2 – Exemplo 2".
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 SPECIAL-NAMES.
6 DECIMAL-POINT IS COMMA.
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 77 HT PIC 9(4)V99.
10 77 VH PIC 9(4)V99.
11 77 PD PIC 9V9(4).
12 77 SB PIC 9(5)V99.
------ ------------------------------------------------------------------------
AÇ ÃO S EQ U EN C IAL 87

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
13 77 TD PIC 9(5)V99.
14 77 SL PIC 9(5)V99.
15 77 S-SB PIC $BZZ.ZZ9,99.
16 77 S-TD PIC $BZZ.ZZ9,99.
17 77 S-SL PIC $BZZ.ZZ9,99.
18 77 EN PIC X.
19 PROCEDURE DIVISION.
20 PROG-PRINCIPAL-PARA.
21 DISPLAY "Entre horas trabalhadas ........: "
22 WITH NO ADVANCING.
23 ACCEPT HT.
24 DISPLAY "Entre valor da hora ............: "
25 WITH NO ADVANCING.
26 ACCEPT VH.
27 DISPLAY "Entre percentual de desconto ...: "
28 WITH NO ADVANCING.
29 ACCEPT PD.
30 COMPUTE SB = HT * VH.
31 COMPUTE TD = (PD / 100) * SB.
32 COMPUTE SL = SB - TD.
33 MOVE SB TO S-SB.
34 MOVE TD TO S-TD.
35 MOVE SL TO S-SL.
36 DISPLAY X"0D".
37 DISPLAY "Salario bruto ....: " S-SB.
38 DISPLAY "Desconto .........: " S-TD.
39 DISPLAY "Salario liquido ..: " S-SL.
40 DISPLAY X"0D".
41 DISPLAY "Tecle <ENTER> para encerrar... "
42 WITH NO ADVANCING.
43 ACCEPT EN.
44 STOP RUN.
------ ------------------------------------------------------------------------

Após recompilar, coloque o programa em nova execução e entre respectivamente os valores 100, 250 e 5,5 atentando
para o fato de fornecer a vírgula decimal na entrada do valor 5,5. Se a vírgula não for fornecida ocorrerá erro no pro-
cessamento do cálculo. Veja o conjunto de dados apresentados após a alteração de ponto decimal para vírgula deci-
mal.

Salario bruto ....: $ 25.000,00


Desconto .........: $ 1.375,00
Salario liquido ..: $ 23.625,00

Observe no código as indicações das linhas 3 a 6 na cor vermelho. Na linha 3 é definida a ENVIRONMENT DIVISION,
responsável por configurar e alterar o comportamento do ambiente do programa, veja na CONFIGURATION SECTION
indicada na linha 4 a definição do parágrafo SPECIAL-NAMES indicado na linha 5 contendo na linha 6 a definição da
frase para configuração DECIMAL-POINT IS COMMA. A frase DECIMAL-POINT IS COMMA orienta que o ponto deci-
mal (DECIMAL-POINT) é a partir de agora (IS) representado por vírgula (COMMA).
Com a troca da simbologia de representação de valores financeiro no padrão brasileiro torna-se necessário no progra-
ma proceder a uma outra alteração. As máscaras definidas como $BZZ,ZZ9.99 devem ser alteradas para $BZZ.ZZ9,99,
trocando-se o ponto para vírgula e a vírgula para ponto como indicado na cor verde.
88 PRO G RA MA Ç ÃO CO B OL

DIVISÃO DE INTEIROS
Elaborar programa de computador que a partir da entrada dos valores inteiros do dividendo e do divisor apresente como
resultado os valores do quociente inteiro e do resto da divisão.
Para o desenvolvimento deste programa deve ser levado em consideração que há duas maneiras de resolve-lo: utili-
zando-se o estilo algébrico ou estilo descritivo. No estilo descritivo existem todos os recursos para conseguir este inten-
to. No entanto, o estilo algébrico não possui um recurso definido para o cálculo do resto da divisão, devendo esta ques-
tão ser tratada pelo programador. O estilo a seguir baseia-se na forma algébrica, no intuito de demonstrar uma solução
por parte do programador e não da linguagem. A final de contas, para que serve um programador?
Selecione e defina um projeto do programa vazio com o nome c02ex03.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C02EX03 AS "Capitulo 2 – Exemplo 3".
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 EN PIC 9(3).
6 77 ED PIC 9(3).
7 77 QC PIC 9(3).
8 77 RC PIC 9(3).
9 77 SQ PIC Z(3).
10 77 SR PIC Z(3).
11 PROCEDURE DIVISION.
12 PROG-PRINCIPAL-PARA.
13 DISPLAY "Entre o dividendo ..: "
14 WITH NO ADVANCING.
15 ACCEPT EN.
16 DISPLAY "Entre o divisor ....: "
17 WITH NO ADVANCING.
18 ACCEPT ED.
19 COMPUTE QC = EN / ED.
20 COMPUTE RC = EN - ED * QC.
21 MOVE QC TO SQ.
22 MOVE RC TO SR
23 DISPLAY X"0D".
24 DISPLAY "Quociente ..........: " SQ.
25 DISPLAY "Resto ..............: " SR.
26 DISPLAY X"0D".
27 DISPLAY "Tecle <ENTER> para encerrar... "
28 WITH NO ADVANCING.
29 ACCEPT EN.
30 STOP RUN.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe os valores do dividendo e do divisor é o programa apresentará os resultados do
quociente e resto calculados a partir do estilo algébrico e não descritivo.
Entre os recursos usados no programa, sua maioria já conhecidos, ocorre o uso da operação COMPUTE QC = EN / ED
usada na linha 19 que efetua a divisão de duas variáveis definidas como valores inteiros e neste caso gera como quoci-
ente um valor inteiro. O operador de divisão se adapta ao tipo de dado usado.
AÇ ÃO S EQ U EN C IAL 89

2.6 DOCUMENTAÇÃO: COLUNA 7


Um dos pontos importantes em programação é a definição no código escrito de linhas de comentários que descrevam e
lembrem ao programador detalhes e/ou características definidos no programa para uma eventual manutenção do códi-
go fonte.
A linhagem COBOL possui três formas de estabelecer este princípio: uma com o uso do símbolo asterisco (*) ou (*>)
para documentação de linhas. O asterisco (*) deve sempre ser definido na sétima coluna do formulário (coluna CONT
de continuity - continuidade) quando se usa o estilo de codificação em formato fixo, o símbolo (*>) pode ser usado em
qualquer lugar do código para comentar uma linha ou ser usado nos comentários do formato livre
Parte da documentação do código é auxiliada pelo próprio compilador, pois este pode apresentar mensagens de adver-
tência informando que determinado recurso em uso é obsoleto. Neste caso, é hora de aprender a fazer a mesma coisa
de outra forma, pois isto significa que o recurso apontado como obsoleto não estará presente na próxima revisão de
padrão da linguagem. Aqui tem-se a primeira barreira de auxílio a documentação avisando alterações mais radicais da
linguagem. Outro detalhe importante é que parte da documentação de um código COBOL pode ser definido dentro da
EVIRONMENT DIVISION.
Os programas escritos em COBOL seguem a uma estrutura baseada em divisões, seções, parágrafos, sentenças, ins-
truções, cláusulas e frases que permitem a definição de documentação setorizada. Uma pequena introdução a forma de
documentação foi apresentada anteriormente, no capítulo 1, quando da criação de um projeto de programa no ambiente
OpenCobolIDE. Neste tópico este assunto será tratado com maior profundidade.
Para que linhas de comentário e outras definições de documentação sejam usadas em COBOL é importante inicia-las
sempre a partir da sétima posição do formulário com o símbolo asterisco. Observe a seguir as instruções com os princí-
pios básicos dessa tarefa. As orientações descritas a seguir podem ser adotadas de forma diferente em certas organi-
zações. Existe um grau liberdade em configurá-las. Segue aqui uma pequena sugestão de como proceder este evento,
de acordo com o que se tem em média no mercado.
O primeiro ponto considerado na documentação COBOL é a definição de linhas de separação para as divisões padrão
da linguagem. Normalmente, usa-se para separar divisões uma sequência de símbolos de igualdade (=).

*=================================================================
IDENTIFICATION DIVISION.
*=================================================================

O segundo ponto de documentação COBOL a ser considerado é a identificação das pessoas envolvidas com o desen-
volvimento da aplicação como analistas de sistemas responsáveis, programadores envolvidos, identificação da empre-
sa, data de criação do programa, data de modificação do programa, descrição da finalidade do programa, etc. Este
nível de documentação é definido abaixo da PROGRAM-ID na IDENTIFICATION DIVISION. Normalmente, usa-se para
este trecho uma sequência de símbolos asterisco (*). Os campos marcados com X e 9 devem ser substituídos pelas
informações desejadas ou necessárias.

******************************************************************
** **
** AUGUSTO MANZANO – TECNOLOGIA DA INFORMACAO **
** **
** ANALISTA: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** PROGRAMADOR: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** **
** DATA: 99/99/9999 **
** MODIFICACAO: 99/99/9999 **
** **
** FINALIDADE: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **
** **
******************************************************************
90 PRO G RA MA Ç ÃO CO B OL

O terceiro ponto considerado na documentação COBOL é a definição de linhas de separação para as seções padrão da
linguagem. Normalmente, usa-se para separar divisões uma sequência de símbolos de traços (-).

*-----------------------------------------------------------------
CONFIGURATION SECTION.
*-----------------------------------------------------------------

O quarto ponto considerado na documentação COBOL é a definição de linhas em branco no código devem ser indica-
das apenas com um caractere asterisco (*) sem nada escrito a frente.

O quinto ponto considerado é a possibilidade de inserir rótulos de informação no meio do código em quantas linhas
forem necessárias com a finalidade de apresentar descrições das partes que sucedem este tipo de comentário. Nor-
malmente, usa-se para separar divisões uma sequência de símbolos de traços (.).

*.................................................................
* Este trecho do programa executa importante acao de processamento
* Para obtenção de informacoes para relatorio geral.
*.................................................................

O sexto ponto considerado na documentação COBOL é a definição da descrição de certa funcionalidade no programa,
definição de seus dados (variáveis e constantes como itens elementares e de grupo). Usa-se o asterisco na sétima
coluna e coloca-se a descrição desejada sobre o bloco de detalhes que se deseja referenciar na décima segunda colu-
na.

* DADOS DO CLIENTE

Além da documentação do código baseando-se nos grupos de divisão, seção e parágrafo há também definições inter-
nas que podem ser definidas a fim de facilitar diversas ações como a leitura do código, localização de itens e manuten-
ções.
O sétimo ponto a ser considerado é a definição dos nomes dos itens elementares e de grupo que podem ser criados em
certas áreas do código. Até aqui foi indicado o uso desses elementos na WORKING-SOTORAGE SECTION. Neste
sentido, há o costume de alguns programadores iniciarem alguns de seus itens com a qualificação (sigla de identifica-
ção) WS de Working Storage para indicar que é um item definido exclusivamente na área WORKING-SOTORAGE
SECTION e não em outro lugar. Esse tipo de documentação se assemelha a forma seguinte.

DATA DIVISION.
FILE SECTION.
WORKING-STORAGE SECTION.
01 WS-CLIENTE.
05 WS-DADOS-PESSOAIS.
10 WS-NOME.
10 WS-SOBRENOME.
05 WS-DOCUMENTOS.
10 WS-CPF.
10 WS-RG.
05 WS-ENDERECO

Observe as definições WS a frente dos nomes dos itens de grupo e dos itens elementares. Usando-se esta estratégia é
possível usar nomes semelhantes desses elementos em outras partes do programa, desde que não se use o qualifica-
dor WS.
Há programadores que ao invés de fazerem referência a essas variáveis com o qualificador WS usam como substituto o
qualificador AS, referência a Área de Salvamento. Este evento ou forma de definição não é uma regra, mais uma cultu-
ra seguida por programadores COBOL no sentido de estabelecer uma maneira mais adequada de fazer referência ao
AÇ ÃO S EQ U EN C IAL 91

tipo de conteúdo que certa variável ou grupo de variáveis possui. A tabela 2.9 apresenta algumas sugestões para a
definição de qualificadores de identificação.

Tabela 2.9 – Qualificadores de variáveis e campos (sugestões de uso)

Qualificador Descrição Exemplo


Utilizado para representar variáveis usadas em ope-
rações de entrada e saída de dados na área de sal-
AS-ENTRA-NUMERO
WS- ou AS-
vamento ou na seção working storange.
WS-ENTRA-NUMERO

Utilizado para representar o uso de variáveis associ- TB-DADOS-CLIENTE


adas a tabelas.
TB-
TB-ALUNOS-CURSO

Utilizado para representar variáveis que fazem refe- IX-DADOS-CLIENTE


rências a indexação de tabelas.
IX-
IX-ALUNOS-CURSO

Utilizado para representar chaves de variáveis lógi- CH-ACHEI-DADO


cas (booleanas).
CH-
CH-FLAG-LIGADO

Utilizado para representar o uso de variáveis decla-


radas na seção linkage.
LK- LK-ENTRA-NUMERO

Utilizado para representar o uso de variáveis decla-


radas na seção local estorange.
LS- LS-ENTRA-NUMERO

Utilizado para representar variáveis que utilizam


valores numéricos na totalização como acumulado-
AC-TOTAL-ITENS
AC-
res.
AC-SOMATORIO

Utilizado para representar estruturas de dados na FS-CADFUN


definição de arquivos na file section.
FS-
FS-CAD-CLIENTES

Utilizado para representar campos de registros.


F001-NUM-MATRICULA
F999-
F001-CLI-NOME

Utilizado para representar campos do modo de des- S001-NUM-MATRICULA


crição de classificação.
S999-
S001-CLI-NOME

Utilizado para representar a indicação de relatórios REL01-CABEÇALHO


de dados que podem existir em um programa.
REL99-
REL02-CABEÇALHO

Utilizado para representar a indicação do cabeçalho RELATÓRIO-CB01


de um relatório de dados.
CB99-
RELATÓRIO-CB02

Utilizado para representar a indicação de telas na SS-TELA01


SCREEN SECTION.
SS-TELA
SS-TELA01-MENU

Essa forma de definição é chamada de mnemônico e serve para auxiliar na identificação dos muitos elementos existen-
tes em um programa de forma particularizada.
Outras regras podem ser aplicadas para a definição de apoio a documentação de código. Neste tópico estão apresen-
tadas as formas e estilos mais comuns. No sentido de demonstrar o uso da ação de documentação de código, em um
sentido mais amplo, considere como exemplo um programa que apresente a data e a hora existentes no sistema. Ob-
serve as partes colorizadas em vermelho e amarelo.
Selecione e defina um projeto do programa vazio com o nome c02ex04.cob na pasta COBOL da pasta Documentos e
escreva o código de programa seguinte.
92 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 *=================================================================
2 IDENTIFICATION DIVISION.
3 *=================================================================
4 *
5 PROGRAM-ID. C02EX04 AS "Capitulo 2 – Exemplo 4".
6 *
7 ******************************************************************
8 ** **
9 ** AUGUSTO MANZANO – TECNOLOGIA DA INFORMACAO **
10 ** **
11 ** ANALISTA: JOSE AUGUSTO MANZANO **
12 ** PROGRAMADOR: JOSE AUGUSTO MANZANO **
13 ** **
14 ** DATA: 23/02/2021 **
15 ** MODIFICACAO: 15/04/2021 **
16 ** **
17 ** FINALIDADE: PROGRAMA DESTINADO A APRESENTAR A DATA E HORA **
18 ** RETORNA A PARTIR DO SISTEMA OPERACIONAL EM USO. **
19 ** **
20 ******************************************************************
21 *
22 *=================================================================
23 ENVIRONMENT DIVISION.
24 *=================================================================
25 *
26 *-----------------------------------------------------------------
27 CONFIGURATION SECTION.
28 *-----------------------------------------------------------------
29 *
30 SOURCE-COMPUTER. IBM-PC COMPATIVEL.
31 OBJECT-COMPUTER. IBM-PC COMPATIVEL.
32 *
33 *=================================================================
34 DATA DIVISION.
35 *=================================================================
36 *
37 *-----------------------------------------------------------------
38 FILE SECTION.
39 *-----------------------------------------------------------------
40 *
41 * DADOS OBTIDOS PARA A DATA E HORA DO SISTEMA
42 WORKING-STORAGE SECTION.
43 01 WS-DATA-CORRENTE-SISTEMA.
44 05 WS-DATA-CORRENTE.
45 10 WS-DATA-CORRENTE-ANO PIC 9(04).
46 10 WS-DATA-CORRENTE-MES PIC 9(02).
47 10 WS-DATA-CORRENTE-DIA PIC 9(02).
48 05 WS-HORA-CORRENTE.
49 10 WS-HORA-CORRENTE-HRA PIC 9(02).
50 10 WS-HORA-CORRENTE-MIN PIC 9(02).
51 10 WS-HORA-CORRENTE-SEG PIC 9(02).
52 10 WS-HORA-CORRENTE-CEN PIC 9(02).
53 *
------ ------------------------------------------------------------------------
AÇ ÃO S EQ U EN C IAL 93

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 *=================================================================
55 PROCEDURE DIVISION.
56 *=================================================================
57 *
58 *.................................................................
59 * Este trecho de codigo apresenta as informacoes de data e hora
60 * obtidas a partir do sistema operacional.
61 *.................................................................
62 *
63 PROG-PRINCIPAL-PARA.
64 MOVE FUNCTION CURRENT-DATE TO WS-DATA-CORRENTE-SISTEMA.
65 DISPLAY "Data e hora total .....: " WS-DATA-CORRENTE-SISTEMA.
66 DISPLAY "Somente a data ........: " WS-DATA-CORRENTE.
67 DISPLAY "Dia ...................: " WS-DATA-CORRENTE-DIA.
68 DISPLAY "Mes ...................: " WS-DATA-CORRENTE-MES.
69 DISPLAY "Ano ...................: " WS-DATA-CORRENTE-ANO.
70 DISPLAY "Somente a hora ........: " WS-HORA-CORRENTE.
71 DISPLAY "Horas .................: " WS-HORA-CORRENTE-HRA.
72 DISPLAY "Minutos ...............: " WS-HORA-CORRENTE-MIN.
73 DISPLAY "Segundos ..............: " WS-HORA-CORRENTE-SEG.
74 DISPLAY "Centesimos ...........: " WS-HORA-CORRENTE-CEN.
75 STOP RUN.
------ ------------------------------------------------------------------------

Quando se define linhas de comentários em um programa o código escrito fica muito mais extenso do que se não tives-
se essas linhas definidas. No entanto, essas informações são desconsideradas pelo compilador no momento da compi-
lação, servindo tão somente como elementos de informação para nós humanos. Isso significa dizer que não importa se
seu programa possui ou não linhas de comentários, o tamanho do programa compilado será o mesmo.
O programa quando executado apresenta um conjunto de informações relacionadas a data e hora do sistema como
sendo uma única sequencia numérica, que no programa foi desmembrada para apresentação das partes.

Data e hora total .....: 2021041520472203


Somente a data ........: 20200415
Dia ...................: 15
Mes ...................: 04
Ano ...................: 2021
Somente a hora ........: 20472203
Horas .................: 20
Minutos ...............: 47
Segundos ..............: 22
Centesimos ...........: 03

Este programa apresenta um recurso novo. O uso da função CURRENT-DATE explica detalhadamente a seguir.
Entre as linhas 42 e 52 é definida uma estrutura de dados para operação do programa com os dados de data e hora do
sistema. Na linha 42 é definido o item de grupo WS-DATA-CORRENTE-SISTEMA que possui como itens de subgrupo
WS-DATA-CORRENTE definido na linha 44 e WS-HORA-CORRENTE definido na linha 48.
Entre as linhas 45 e 47 encontra-se os itens elementares que representam os componentes ANO, MES e DIA e entre
as linhas 49 e 52 encontram-se os componentes HRA (hora), MIN, SEG e CEN. Esses componentes são os elementos
de decomposição da data e hora do sistema obtidos a partir do uso da função CURRENT-DATE na linha 63.
A função CURRENT-DATE opera seus valores dentro de certos limites. O componente ano usa a faixa de valores entre
as datas de 01/01/1601 até 31/12/9999, o componente mês opera a faixa de valores entre 1 e 12, o componente dia
94 PRO G RA MA Ç ÃO CO B OL

opera a faixa de valores entre 1 e 31, o componente hora opera a faixa de valores entre 0 e 23, o componente minuto
opera a faixa de valores entre 0 e 59, o componente segundos opera a faixa de valores entre 0 e 59 e o componente
centésimos opera a faixa de valores entre 0 e 99.
Além do caractere asterisco para a definição de comentários em linhas de programas há a possibilidade de se fazer uso
do caractere barra (/). O caractere barra é usado para duas finalidades conjuntas: gerar um salto de página na impres-
são do código e apresentar no topo da nova página o comentário definido, sendo usado para separar o código do pro-
grama em partes estruturais a critério da equipe de desenvolvimento. O comentário definido com a barra deverá estar
expresso em apenas uma linha, observe o trecho a seguir com o uso do caractere barra demarcado em vermelho.

-------A---B------------------------------------------------------------
123456789012345678901234567890123456789012345678901234567890123456789012
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
IDENTIFICATION DIVISION.
PROGRAM-ID. BARRATST.
/ Este trecho sera forçosamente impresso na proxima pagina
ENVIRONMENT DIVISION.
DATA DIVISION.
PROCEDURE DIVISION.
------------------------------------------------------------------------

O salto de página será controlado pelo compilador quando solicitada a impressão do programa na impressora a partir
do próprio compilador. A tentativa de usar qualquer editor de texto para a impressão do código não surtirá o efeito dese-
jado. Mas cabe ressaltar que o compilador GnuCOBOL não possui este evento implementado.
A área de codificação do programa no formulário (mesmo em um computador) fica limitada entre a oitava e septuagé-
sima segunda colunas distribuídas nas áreas A (colunas de 8 a 11) para a definição das divisões, seções e parágrafos
B (colunas de 12 a 72) para a definição das instruções de um programa. Ao todo tem-se apenas 64 colunas para a
escrita do código, mas usa-se efetivamente 60 colunas.
Com 60/64 colunas disponíveis para a escrita de código em algum momento ocorrerá a situação em que uma linha de
instrução não poderá ser escrita em uma única linha. No caso da escrita de instruções comuns ou expressões algébri-
cas basta parar a codificação na septuagésima segunda coluna, ou antes dela, e dar continuidade na linha de baixo a
partir da décima segunda coluna sem nenhum problema, exceto a definição de uma linha de texto entre aspas inglesas.
Quando se utiliza textos entre aspas inglesas tem-se a definição de uma literal (cadeia de caracteres - string) que pode-
rá ter uma extensão de escrita maior que 60 colunas. Neste caso escreve-se o texto até a septuagésima coluna e sem
fechar as aspas inglesas dá-se continuidade na linha de baixo, colocando-se na sétima coluna o caractere hífen e con-
tinuando o texto a partir décima segunda coluna com a colocação de aspas inglesas antes da continuidade. Segue-se
esta mesma regra até terminar a sequencia de caracteres que deverá ser finalizada com aspas inglesas.
Observe um exemplo da necessidade de uso do caractere hífen para a apresentação de uma literal que excede as 72
colunas do formulário. Atente para as partes marcadas na cor vermelha.

-------A---B------------------------------------------------------------
123456789012345678901234567890123456789012345678901234567890123456789012
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
PROCEDURE DIVISION.
DISPLAY "Ignorar o COBOL e ' ignorar, entre outras coisas, a a
- "rte de programar computadores - Joel Saade".
------------------------------------------------------------------------

Atente na indicação da terceira linha de código a colocação sutil do hífen na sétima coluna e a continuidade da defini-
ção da sequencia de caracteres da literal anterior com a abertura e fechamento das aspas inglesas. Observe que a
mensagem antes da continuidade é expressa apenas com abertura de aspas inglesas.
AÇ ÃO S EQ U EN C IAL 95

Os programas produzidos nos demais capítulos desta obra não farão uso dos recursos de documentação por questão
de espaço e para não deixar o texto extenso em demasiado. No entanto, isso que aqui é apresentado deve ser levado
muito a sério profissionalmente.
96 PRO G RA MA Ç ÃO CO B OL

Anotações

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________
AÇ ÃO IN / CO ND I CI O NAL 97

3
AÇÃO IN/CONDICIONAL

Este capítulo aborda o tema relacionado ao uso de ações condicionais e incondicionais com condição, deci-
são, operadores relacionais, operadores lógicos, ações com detecção se sinal, reconhecimento de formato de
caracteres, execução de laços condicional e incondicional, além de fornecer outros detalhes relacionados as
operações de controle da linguagem COBOL.

3.1 PROCESSAMENTO LÓGICO


Para que um programa de computador possa realizar ações de processamento lógico é necessário definir certas rela-
ções condicionais. É a partir dessas relações que decisões poderão ser tomadas pela máquina. Uma condição do ponto
de vista da ciência da computação é o estabelecimento de uma relação lógica entre elementos computáveis formados
por variáveis, constantes e operadores relacionais na forma de operandos, que são as expressões lógicas. A tomada de
decisão é pautada sobre o uso de uma condição ou de um conjunto de condições por meio de operadores lógicos.
Condições são ações usadas principalmente e especialmente pelos comandos IF, EVALUATE e PERFORM, os quais
efetuam no fluxo do programa algum tipo de desvio operacional. Essas condições podem ser usadas na realização de
operações de desvio simples, composto e seletivo, além dos testes de classe e sinal, acrescentando-se as ações para
a definição de nomes de condições.
Para que uma condição possa ser estabelecida é necessário fazer uso de ferramentas especiais chamadas operadores
relacionais. Na linguagem COBOL há dois modos de definição de condições com operadores relacionais: uso de símbo-
los ou uso de descrições. A tabela 3.1 mostra os operadores relacionais nas formas simbólicas e descritivas usados nas
definições do estabelecimento de condições.

Tabela 2.1 – Símbolos de formatação dos tipos de dados

Simbólico Descritivo Significado

[IS] = [IS] EQUAL [EQUALS] TO Igual a

[IS] > [IS] GREATER THAN Maior que

[IS] < [IS] LESS THAN Menor que

[IS] >= [IS] GREATER THAN OR EQUAL TO Maior ou igual a

[IS] <= [IS] LESS THAN OR EQUAL TO Menor ou igual a

[IS] NOT = [IS] NOT EQUAL TO Diferente de

O uso do verbo IS é opcional. No entanto, sua utilização é mais adequada e elegante na forma descritiva que acaba por
ser menos usada que a forma simbólica.
98 PRO G RA MA Ç ÃO CO B OL

Os operadores relacionais são responsáveis por determinarem relações lógicas entre variáveis e/ou constantes. Uma
relação lógica pode ser definida a partir do uso de variável versus variável ou de variável versus constante (pode tam-
bém ser constante versus variável). Uma condição formada a partir de uma relação lógica por meio de operadores rela-
cionais é chamada tecnicamente de operando. Veja os exemplos contextualizados possíveis de definições de relações
lógicas que podem ser usadas no estabelecimento de condições.

<operando1> = <operando2> | pode substituir = por IS EQUAL TO


<operando1> > <operando2> | pode substituir > por IS GREATER THAN
<operando1> < <operando2> | pode substituir < por IS LESS THAN
<operando1> >= <operando2> | pode substituir >= por IS GREATER THAN OR EQUAL TO
<operando1> <= <operando2> | pode substituir <= por IS LESS THAN OR EQUAL TO
<operando1> NOT = <operando2> | pode substituir NOT = por IS NOT EQUAL TO

Uma decisão pode ser tomada com base em uma ou mais condições. Quando houver a necessidade de fazer uso de
mais de uma condição será necessário usar um recurso que vincule duas ou mais condições por meio dos operadores
lógicos de ligação AND (conjunção) e OR (disjunção) que podem ser contextualmente definidos a partir das relações.

<condição 1> AND <condição 2> [ ... AND <condição N>]


<condição 1> OR <condição 2> [ ... OR <condição N>]

Se estiver em uso o operador lógico AND será realizada ação de conjunção que resultará na obtenção de um resultado
verdadeiro quando todas as condições da expressão lógica forem verdadeiras.
Se estiver em uso o operador lógico OR será realizada ação de disjunção que resultará na obtenção de um resultado
verdadeiro quando uma ou mais condições da expressão lógica forem verdadeiras.
No uso de expressões lógicas contendo em conjunto os operadores lógicos AND e OR o operador AND terá sempre
maior precedência sobre o operador OR. Caso deseje alterar o nível de precedência use parênteses na parte de menor
precedência. Assim sendo, considere as seguintes expressões lógicas.

1 - <condição1> OR <condição2> AND <condição3>


2 - (<condição1> OR <condição2>) AND <condição3>

Na expressão 1 a resposta lógica final será obtida a partir da avaliação de <condição2> AND <condição3> para em
seguida avaliar o resultado obtido com o restante da expressão em OR com relação a <condição1>.
Na expressão 2 a resposta lógica final será obtida a partir da avaliação de <condição1> OR <condição2> para em
seguida avaliar o resultado obtido com o restante da expressão em AND com relação a <condição3>.
Considerando como base de avaliação apenas duas condições a tabela 2.2 apresenta os resultados lógicos possíveis
de serem obtidos com o uso dos operadores lógicos AND e OR.

Tabela 2.2 – Operadores lógicos AND e OR

Condição 1 Condição 2 Resultado AND Resultado OR

V V V V

V F F V

F V F V

F F F F

A definição de relações condicionais em COBOL vai mais à frente se comparada com outras linguagens de programa-
ção, pois apresentam recursos operacionais que em outras linguagens para serem usados necessitam de funções in-
trínsecas, destacando-se neste caso as ações de verificação de classe e de sinal.
AÇ ÃO IN / CO ND I CI O NAL 99

O teste de classe permite validar se o operando em uso possui um valor numérico ou alfabético (maiúsculo, minúsculo
ou ambos). Essa condição é, principalmente, útil para validar as entradas de dados realizadas por um usuário. Veja os
exemplos contextualizados possíveis de aplicação para testes de classe.

IS [NOT] NUMERIC
IS [NOT] ALPHABETIC
IS [NOT] ALPHABETIC-LOWER
IS [NOT] ALPHABETIC-UPPER

O teste de sinal permite determinar se o valor numérico de um operando é maior que zero quando positivo, menor que
zero quando for negativo ou se o valor é igual a zero, quando for zero. Veja os exemplos contextualizados possíveis de
aplicação para testes de sinal.

<condição> IS [NOT] POSITIVE / NEGATIVE / ZERO

Qualquer relação condicional poderá ser negada com o uso do operador lógico de negação NOT. Neste caso se a con-
dição tiver resultado verdadeiro será considerado este como falso e vice-versa quando a condição for falsa.
Para a devida verificação condicional é importante que os elementos avaliados na relação lógica sejam do mesmo tipo.
Nunca estabeleça relações condicionais com tipos de dados diferentes.

3.2 DESVIOS CONDICIONAIS


Desvios condicionais estão associados ao uso de condições definidas em um programa de computador. Uma decisão
(expressão condicional) a ser tomada pode ser verdadeira ou falsa dependendo da condição estabelecida. Se a condi-
ção for verdadeira determinada ação será executada (ocorrerá um desvio do fluxo do programa); se falsa poderá de-
terminar outra ação (um desvio de fluxo) a ser feita ou não executar nenhuma ação (mantendo o programa no mesmo
fluxo de execução). Um desvio condicional pode ser simples, composto ou seletivo.

3.2.1 Desvio simples


Um desvio condicional simples direciona a execução do fluxo de programa para certo ponto do código toda vez que a
condição for verdadeira, após a conclusão do desvio o programa retorna à linha de fluxo que estava em operação antes
do desvio. Se a condição for falsa nada acontecerá, o programa mantém seu fluxo sem desviar e segue sua execução.
Um desvio condicional simples é definido com a estrutura sintática:

IF <expressão condicional> [THEN]


Ação executada se expressão condicional for verdadeira
[END-IF].

As cláusulas THEN e END-IF foram inseridas na linguagem a partir da publicação do padrão COBOL-85, sendo opcio-
nais em seu uso. Sua inclusão se deu ao fato de aproximar a estrutura sintática da linguagem as regras de conspecção
do modelo estruturado do paradigma imperativo. Nesta obra, as decisões serão escritas com a cláusula END-IF, tendo
a cláusula THEN omitida, no entanto use-a se preferir.
Observe que após a definição do comando END-IF usa-se um ponto de finalização para encerrar todo o conjunto condi-
cional. Dentro do escopo do bloco delimitado entre IF e END-IF não use ponto de finalização em nenhuma instrução,
observe que o comando IF abre uma frase de instrução que é encerrada com um ponto de finalização após o comando
END-IF. Caso END-IF seja omitido (seguindo o padrão COBOL-74) o ponto de finalização deve ser colocado obrigatori-
amente na última linha de operação do bloco condicional.
O padrão estético de endentação para o conteúdo do bloco dentro dos comandos IF/THEN e END-IF é normalmente de
quatro posições. Nesta obra a formatação será de três posições.
100 PRO G RA MA Ç ÃO CO B OL

Considere, como exemplo, a definição de uma condição que verifique se a idade informada do usuário é maior ou igual
a 18, sendo a condição verdadeira apresente a mensagem "Maior de idade". Caso a idade não esteja dentro da condi-
ção esperada nada deverá ser feito.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-IDADE PIC 9(3).

PROCEDURE DIVISION.
DISPLAY "Informe sua idade: " WITH NO ADVANCING.
ACCEPT WS-IDADE.
IF WS-IDADE >= 18
DISPLAY "Maior de idade"
END-IF.

Note que a mensagem somente é apresentada quando o valor da variável WS-IDADE for maior ou igual a 18. Veja na
sequencia o trecho da PROCEDURE DIVISION usando a forma descritiva de uso de operador relacional expresso de
forma completa com o uso do verbo IS.

PROCEDURE DIVISION.
DISPLAY "Informe sua idade: " WITH NO ADVANCING.
ACCEPT WS-IDADE.
IF WS-IDADE IS GREATER THAN OR EQUAL TO 18
DISPLAY "Maior de idade"
END-IF.

Atente que tanto faz fazer uso da forma simbólica ou descritiva. Aqui tem-se a mesma questão discutida em relação ao
uso dos operadores aritméticos, valendo as mesmas observações. Os próximos exemplos usam a forma simbólica.
Dentro do bloco IF/THEN e END-IF poderá existir diversas outras operações de entrada, processamento matemático,
saída, bem como a definição de outras decisões. Neste caso, passa-se a ter o que se chamada encadeamento de deci-
sões indicadas com a estrutura sintática seguinte. Observe os pontos colorizados, veja que o bloco condicional verde
está definido dentro (encadeado) do escopo do bloco condicional vermelho.

IF <expressão condicional 1>


Ação executada se expressão condicional 1 for verdadeira
IF <expressão condicional 2>
Ação executada se expressão condicional 1 E 2 forem verdadeiras
END-IF
END-IF.

Atente a um detalhe importante, quando se usa encadeamento de tomadas de decisão apenas o final da última decisão
terá o uso de ponto de finalização.
Há ainda a possibilidade de se trabalhar com sequencias de tomadas de decisão uma após a outra como demonstrado
em seguida.

IF <expressão condicional 1>


Ação executada se expressão condicional 1 for verdadeira
END-IF.
IF <expressão condicional 2>
Ação executada se expressão condicional 2 for verdadeira
END-IF.

Para o caso de uso de tomadas de decisões sequencias cada tomada de decisão terá o registro de seu ponto de finali-
zação.
As estruturas sequenciais e aninhadas poderão ser utilizadas de diversas formas, mescladas entre si. Não há limites
para o uso integrado das ações de tomada de decisão com elas mesmas.
AÇ ÃO IN / CO ND I CI O NAL 101

3.2.2 Desvio composto


Um desvio condicional composto direciona a execução do fluxo de programa para certo ponto do código toda vez que a
condição for verdadeira. Se a condição for falsa a execução do programa será direcionada a outro ponto do código. Em
ambos os casos após concluir um dos desvios a execução do programa volta à linha de fluxo que estava em operação
antes do desvio ocorrer e segue sua execução.
Um desvio condicional composto é definido com a estrutura sintática:

IF <expressão condicional> [THEN]


Ação executada se expressão condicional for verdadeira
ELSE
Ação executada se expressão condicional for falsa
[END-IF].

Considere, como exemplo, a definição de uma condição que verifique se a idade do usuário informada é maior ou igual
a 18, sendo a condição verdadeira apresente a mensagem "Maior de idade". Caso a condição seja falsa deve ser
apresentada a mensagem "Menor de idade".

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-IDADE PIC 9(3).

PROCEDURE DIVISION.
DISPLAY "Informe sua idade: " WITH NO ADVANCING.
ACCEPT WS-IDADE.
IF WS-IDADE >= 18
DISPLAY "Maior de idade"
ELSE
DISPLAY "Menor de idade"
END-IF.

Assim como o desvio condicional simples, o desvio condicional composto pode operar com encadeamentos e sequên-
cias de decisões tanto no escopo do bloco IF/THEN e ELSE como no bloco ELSE e END-IF. Não há limites, o uso de-
penderá da necessidade existente. É possível combinar decisões simples com decisões compostas e vice-versa.
A linguagem COBOL possui um recurso que é existente em poucas linguagens de programação: a capacidade de prio-
rizar tomada de decisão simples sobre o uso de condição falsa. A maior parte das linguagens de programação apenas
prioriza ações em tomada de decisão simples baseadas em condições verdadeiras. No entanto, para esta ação é ne-
cessário o uso de estrutura condicional composta auxiliada pelo comando CONTINUE ou instrução NEXT SENTENCE
a partir da estrutura sintática:

IF <expressão condicional> [THEN]


CONTINUE / NEXT SENTENCE
ELSE
Ação executada se expressão condicional for falsa
[END-IF].

Considere, como exemplo, a definição de uma condição que verifique se a idade informada do usuário é maior ou igual
a 18, sendo não faça absolutamente nada. Caso a idade não esteja dentro da condição esperada apresente a mensa-
gem "Menor de idade".

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-IDADE PIC 9(3).

PROCEDURE DIVISION.
DISPLAY "Informe sua idade: " WITH NO ADVANCING.
102 PRO G RA MA Ç ÃO CO B OL

ACCEPT WS-IDADE.
IF WS-IDADE >= 18
CONTINUE
ELSE
DISPLAY "Maior de idade"
END-IF.

Observe que se a idade informada for maior ou igual a 18 ocorrerá a execução do bloco definido ente IF e ELSE que
direcionará o fluxo para a execução do comando CONTINUE que “pegará” este fluxo e o direcionará para fora do bloco
de tomada de decisão, após END-IF, abandonando-o. Sendo a condição falsa é processado o que se encontra definido
no bloco ELSE e END-IF.
O comando CONTINUE pode ser plenamente substituído pela instrução NEXT SENTENCE. No entanto, cabe algumas
observações a este respeito. A instrução NEXT SENTENCE é típica para uso no COBOL-74, tendo sido retirada do
padrão COBOL-85 e retornada a partir do padrão COBOL-2002 e considerada no COBOL-2014. No entanto, o compila-
dor GnuCOBOL considerada a instrução NEXT SENTENCE arcaica, mantende-a por questões de compatibilidade, e
por esta razão incentiva fortemente seu desuso. Mas, poderá haver algum compilador mais recente, dentro das regras
de padrões atualizados, não aceitar o uso do comando CONTINUE em detrimento a instrução NEXT SENTENCE.

3.2.3 Desvio seletivo


Ao trabalhar com grande quantidade de desvios encadeados ou sequenciais, pode-se deixar o programa com uma
estrutura difícil de ser interpretada e escrita. Considere, como exemplo uma estrutura sequencial de quatro opções em
que dependendo da opção selecionada uma determinada ação deve ser realizada. A estrutura somente pode aceitar
valores dento do limite das opções existentes, ou seja, opção 1, opção 2, opção 3 e opção 4. Caso um valor diferente
de opção seja fornecido o programa deve indicar erro de ação. Observe o esqueleto seguinte para esta situação se-
guinte.

IF <opção 1> AND <opção 4>


IF <opção 1>
Ação 1
END-IF
IF <opção 2>
Ação 2
END-IF
IF <opção 3>
Ação 3
END-IF
IF <opção 4>
Ação 4
END-IF
ELSE
<erro>
END-IF.

Veja o trecho proposto implementado na linguagem na forma de definição de entrada de um valor numérico e apresen-
tação de mensagens indicando qual opção foi escolhida e mensagem de erro informando que a entrada foi incorreta.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-OPCAO PIC 9.

PROCEDURE DIVISION.
DISPLAY "Informe opcao: " WITH NO ADVANCING.
ACCEPT WS-OPCAO.
IF WS-OPCAO >= 1 AND WS-OPCAO <= 4
AÇ ÃO IN / CO ND I CI O NAL 103

IF WS-OPCAO = 1
DISPLAY "Escolheu opcao '1'"
END-IF
IF WS-OPCAO = 2
DISPLAY "Escolheu opcao '2'"
END-IF
IF WS-OPCAO = 3
DISPLAY "Escolheu opcao '3'"
END-IF
IF WS-OPCAO = 4
DISPLAY "Escolheu opcao '4'"
END-IF
ELSE
DISPLAY "Entrada incorreta"
END-IF.

Existe uma maneira mais adequada, simplificada e eficiente de atender a esse tipo de situação, que é o uso de coman-
do de controle condicional com múltipla escolha para desvio seletivo, denominada EVALUATE/END-EVALUATE que
efetiva uma série de testes lógicos para a execução de determinada ação. Este recurso surge a partir do COBOL-85,
tendo como sintaxe:

EVALUATE <opção>
WHEN 1
Ação 1
WHEN 2
Ação 2
WHEN 3
Ação 3
WHEN 4
Ação 4
WHEN OTHER
<erro>
END-EVALUATE.

Não é só a simplificação de escrita que os comandos EVALUATE e END-EVALUATE se diferenciam dos comandos IF
e END-IF. A diferença principal está em sua funcionalidade.
O uso dos comandos IF e END-IF dispostos de forma sequencial são em média mais lentos que a execução dos comandos
EVALUATE e END-EVALUATE. Isto ocorre, pois nos IFs cada referência do bloco é verificada particularmente, mesmo
que a referência anterior tenha sido realizada. O efeito no uso de EVALUATE é diferente, pois sendo uma certa condi-
ção satisfeita o fluxo do programa é desviado para fora do bloco, evitando a verificação desnecessária das condições
que estão a frente da condição satisfeita.
Tomando por base a mesma situação apresentada anteriormente observe detalhadamente a forma de definição dos
comandos EVALUATE e END-EVALUATE e os compare com os comandos sequenciais IF e END-IF.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-OPCAO PIC 9.

PROCEDURE DIVISION.
DISPLAY "Informe opcao: " WITH NO ADVANCING.
ACCEPT WS-OPCAO.
EVALUATE WS-OPCAO
WHEN 1
DISPLAY "Escolheu opcao '1'"
WHEN 2
DISPLAY "Escolheu opcao '2'"
104 PRO G RA MA Ç ÃO CO B OL

WHEN 3
DISPLAY "Escolheu opcao '3'"
WHEN 4
DISPLAY "Escolheu opcao '4'"
WHEN OTHER
DISPLAY "Entrada incorreta"
END-EVALUATE.

Apesar dos comandos EVALUATE e END-EVALUATE serem superiores a funcionalidade dos comandos IF e END-IF,
há uma fragilidade que deve ser considerada com muita atenção. Este comando só pode ser usado para condições
baseadas em igualdade. Não há possibilidade de usá-la para situações que encovam os demais operes relacionais.

3.3 AÇÕES CONDICIONAIS


Além das definições de tratamento de tomadas de decisão apresentadas e comum de serem encontradas em diversas
linguagens de programação, COBOL possui alguns recursos a mais que possibilitam a realização de algumas opera-
ções mais seguras como detecção de dado fornecido, validação numérica e análise condicional descritos neste tópico.

3.3.1 Teste de classe


O teste de classe é uma ação que permite verificar o estado de um dado em relação ao tipo definido na sua qualificação
na seção WORKING-STORAGE da divisão DATA. Desta forma, pode-se detectar o estado da entrada do usuário evi-
tando-se que um valor incorreto, segundo seu tipo, seja fornecido e cause problemas ao programa. São quatro as pos-
sibilidades de validação sendo: numérica, alfabética (letras maiúsculas e minúsculas), alfabética maiúscula e alfabética
minúscula, respectivamente pelos operadores NUMERIC, ALPHABETIC-UPPER/LOWER e ALPHABETIC.
Como exemplo considere um trecho de programa para detecção de entrada de dados alfabéticos maiúsculos e/ou mi-
núsculos que apresente a mensagem "Entrada OK.". Qualquer valor quer não seja um caractere alfabético maiúsculo
ou minúsculo deve apresentar a mensagem "Erro na entrada.". São valores alfabéticos as letras e o espaço em bran-
co. Qualquer outro caractere gerado pelo teclado não é aceito como caractere válido para este teste de classe.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-VALOR PIC X(10).

PROCEDURE DIVISION.
DISPLAY "Entre sequencia de caracteres: " WITH NO ADVANCING.
ACCEPT WS-VALOR.
IF WS-VALOR IS ALPHABETIC
DISPLAY "Entrada OK."
ELSE
DISPLAY "Erro na entrada."
END-IF.

Para conseguir ter acesso aos caracteres que não são alfabéticos basta usar a condição IS NOT ALPHABETIC rever-
tendo o teste.

3.3.2 Teste de sinal


O teste de sinal efetua a comparação de certo valor numérico a zero e determina se o valor é positivo (quando for maior
que zero), negativo (quando for menor que zero) ou igual a zero, quando efetivamente for zero. Este teste também pode
ser processado com o uso dos operadores relacionais. É possível com este teste verificar as condições POSITIVE,
NEGATIVE e ZERO.
AÇ ÃO IN / CO ND I CI O NAL 105

Como exemplo considere um trecho de programa que ao receber uma entrada numérico informe o estado do número
como sendo positivo, negativo ou zero.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-VALOR PIC S9(5)V99.

PROCEDURE DIVISION.
DISPLAY "Entre valor numerico: " WITH NO ADVANCING.
ACCEPT WS-VALOR.
IF WS-VALOR IS POSITIVE
DISPLAY "Valor positivo."
END-IF.
IF WS-VALOR IS NEGATIVE
DISPLAY "Valor negativo."
END-IF.
IF WS-VALOR IS ZERO
DISPLAY "Valor zero."
END-IF.

O uso das condições de teste de sinal pode ser negado com a utilização do operador lógico NOT. No entanto é funda-
mental prestar atenção e um detalhe: dizer IS NOT NEGATIVE não é o mesmo que dizer IS POSITIVE. Um valor positi-
vo é qualquer valor acima de zero, dizer não negativo significa incluir o valor zero na análise. A menos que se deseje
expressar valores positivos e maiores que zero, usar IS NOT NEGATIVE poderá ser um grande problema.

3.3.3 Nomes condicionais


O nome condicional é a definição de um nome de variável associado ao valor que esta variável possa ter. A definição
do nome condicional é feita com o código de nível 88 na DATA DIVISION semelhantemente a forma de definição de
itens elementares em itens de grupo. O nível 88 não cria um item elementar em um item de grupo, cria um nome condi-
cional dentro de um item de grupo. Os nomes condicionais são usados com qualquer comando que use condições.
Quando um nome condicional é declarado com código de nível 88 dentro de um item de grupo o que se faz é dizer que
cada item elementar do grupo se refere a um ou mais valores. Nomes condicionais não usam o comando PICTURE
para definição de máscaras, mas usam o comando VALUE. A máscara é definida apenas no item de grupo.
O formato geral de definição de um campo condicional na forma de item elementar segue a estrutura sintática:

88 <CH-[nome condicional]> VALUES <conteúdo>

Imagine a definição de um item de grupo chamado CH-FORMACAO (para formação escolar), com os nomes condicio-
nais CH-FORM-BASICO com valor 1, CH-FORM-MEDIO com valor 2 e CH-FORM-SUPERIOR com valor 3, além da
lista de valores destinada a auxiliar a validação da entrada CH-FORM-VALIDADE com os valores 1, 2 e 3.

01 CH-FORMACAO PIC 9.
88 CH-FORM-VALIDADE VALUE 1 2 3.
88 CH-FORM-BASICO VALUE 1.
88 CH-FORM-MEDIO VALUE 2.
88 CH-FORM-SUPERIOR VALUE 3.

Veja que os nomes condicionais indicam os estados de valores 1, 2 ou 3 para cada grau escolar. Neste sentido, pode-
se usar as referências CH-FORM-BASICO, CH-FORM-MEDIO e CH-FORM-SUPERIOR para indicar os valores 1, 2 e
3, como se fossem as definições de constantes. O nome condicional CH-FORM-VALIDADE está sendo definido para
auxiliar e garantir que não ocorra nenhum erro se algum valor fora da faixa for informado, veja que é possível criar no-
mes condicionais com mais de um valor e neste sentido pode-se usar, para facilitar, a cláusula THRU para definir faixas
de valores a um nome condicional como 88 CH-FORM-VALIDADE VALUES 1 THRU 3.
106 PRO G RA MA Ç ÃO CO B OL

Quando o valor do item de grupo CH-FORMACAO for igual a 1 ter-se-á a condição CH-FORM-BASICO, se igual a 2
ter-se-á a condição CH-FORM-MEDIO e assim por diante. O nome condicional CH-FORM-VALIDADE opera com um
de três valores possíveis.
O uso de nomes condicionais proporciona a utilização de uma estrutura lógica customizada e suavizada, pois é possível
facilmente criar uma condição simplificada de validação. Por exemplo, definir a checagem se os valores permitidos 1, 2
ou 3 são os usados, basta escrever:

IF CH-FORM-VALIDADE

De outra forma, mais tradicional, seria escrever algo como:

IF CH-FORMACAO = 1 OR CH-FORMACAO = 2 OR CH-FORMACAO = 3

A partir do exemplo estruturado de nome condicional considere o trecho de código a seguir que solicitada a entrada de
um nível de formação e a partir do uso dos nomes condicionais apresenta a informação correspondente.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 CH-FORMACAO PIC 9.
88 CH-FORM-VALIDADE VALUE 1 2 3.
88 CH-FORM-BASICO VALUE 1.
88 CH-FORM-MEDIO VALUE 2.
88 CH-FORM-SUPERIOR VALUE 3.

PROCEDURE DIVISION.
DISPLAY "1 - Ensino basico"
DISPLAY "2 - Ensino medio"
DISPLAY "3 - Ensino superior"
DISPLAY X"0D".
DISPLAY "Qual sua formacao: " WITH NO ADVANCING.
ACCEPT CH-FORMACAO.
IF CH-FORM-VALIDADE
IF CH-FORM-BASICO
DISPLAY "Formacao no ensino basico"
END-IF
IF CH-FORM-MEDIO
DISPLAY "Formacao no ensino medio"
END-IF
IF CH-FORM-SUPERIOR
DISPLAY "Formacao no ensino superior"
END-IF
END-IF.

No exemplo faz-se a solicitação de um valor armazenando-o no item de grupo CH-FORMACAO. Em seguida faz-se a
validação do valor fornecido junto a nome condicional CH-FORM-VALIDADE para determinar se o valor fornecido está
dentro da faixa de valores a serem aceitos, sendo o valor verdadeiro o bloco da tomada de decisão é processado. Se
algum valor fora da faixa for informado a tomada de decisão não processa sei bloco interno.
Dentro do bloco de validação do valor informado é realizada a verificação de cada referência existente, dependendo do
valor indicado a mensagem correspondente a formação é apresentada.

3.4 DESVIOS INCONDICIONAIS


Desvios condicionais são controlados por meio de operadores relacionais e lógicos; ações condicionais usam para os
testes de classe e de sinal o verbo IS que pode ser usado com os operadores relacionais, além dos campos condicio-
nais que são usados em situações lógicas de comparação com igualdade. Em contrapartida desvios incondicionais
AÇ ÃO IN / CO ND I CI O NAL 107

podem ser executados sem o controle de certa condição simplesmente seguindo o fluxo a eles indicados ou se utilizar
de algum critério condicional para controla-lo um pouco melhor.
Este é um momento crítico neste estudo, pois entra em um tema considerado obscuro por abordar um comando exis-
tente em diversas linguagens que é renegado, injuriado, deprecado e malfadado. No entanto, linguagens de programa-
ção modernas mantêm em seu kernel a existência deste comando: o famigerado GO TO, por qual motivo?
Muitos dizem para não o usar sob pena de assumir grande desgraça de proporção catastrófica, como se cometesse um
crime capital. Na verdade, o problema é o mau uso que muitos programadores fazem deste comando por não compre-
enderem quando e onde podem fazê-lo. É mais fácil proibir e achincalhar do que efetivamente ensinar.
Há duas formas de se utilizar GO TO em seus programas: a forma certa e a forma errada. Se a forma usada não é a
certa, então é a errada não importando seus motivos. Se o comando existe na linguagem, este poderá ser usado. Não
de qualquer forma, mas sob rígidos conceitos de aplicação.
O comando GO TO transfere o fluxo de ação de um programa de um ponto da PROCEDURE DIVISION a outro por meio de
parágrafo ou seção de ligação. Obviamente em programas estruturados este comando deve ser evitado ao máximo. Veja que
a orientação de se evitar seu uso ao máximo significa entender para não o usar inadvertidamente, apenas usá-lo em situa-
ções raras. A transferência realizada é direcionada para a primeira instrução no parágrafo ou seção identificada em certo
procedimento (tema que será visto mais adiante). São duas as formas previstas de GO TO no compilador GnuCOBOL: in-
condicional e condicional.
A sintaxe do comando para ação incondicional segue a estrutura sintática seguinte, sendo a forma mais popular:

GO [TO] <referência>

Onde, referência é a indicação do nome de um procedimento nomeado ou seção existente na PROCEDURE DIVISION em
que o comando GO TO faça referência para acesso. A palavra TO do comando é opcional e poderá ser omitido, o que é um
pouco raro de acontecer uma vez que diminui a legibilidade do código.
Mantenha muita atenção no uso do comando GO TO incondicional, pois quando este comando não é a última instrução, as
instruções que o seguem não são executadas.
A sintaxe do comando para ação condicional segue a estrutura sintática:

GO [TO] <referências> DEPENDING ON <identificador>

Onde, referências é a indicação de um ou mais nomes de procedimentos nomeados ou seções existentes na PROCEDURE
DIVISION, até 255 referências onde estejam os comandos GO TO. O identificador de DEPENDING ON é a definição de um
item de dado numérico inteiro, que faz associação direta ao item indicado em referências.
Se o valor do parâmetro identificador for 1 o controle é transferido para a primeira instrução do primeiro procedimento
indicado em referências, se for 2 o controle é transferido para a primeira instrução do segundo procedimento e assim
por diante não excedendo 255.
Neste momento será usado apenas o modo incondicional do comando GO TO, ficando o modo condicional a ser visto
mais adiante nesta obra.
No tópico anterior foi indicado o uso de nome condicional e sugerido um exemplo. No exemplo apresentado foi utilizado
uma sequência de decisões sequenciais para a realização de cada ação encadeada a uma decisão que efetua a vali-
dação para a entrada ou não na estrutura sequencial de decisões. Veja que este modelo é apresentado após a indica-
ção da estrutura dos comandos EVALUATE e END-EVALUATE, que teoricamente poderia ter sido usada no exemplo,
mas não foi pelo motivo de que os comandos EVALUATE e END-EVALUATE não aceitam o uso de nome condicional.
Já é sabido que as ações de decisão executadas por IFs sequenciais são mais lentas que a ação executada pela estru-
tura EVALUATE e END-EVALUATE, mas não podendo usá-la torna-se propício o uso do comando GO TO para que se
busque uma performance semelhante a EVALUATE e END-EVALUATE mesmo usando IFs sequenciais. Mantendo
exemplo semelhante ao do tópico anterior observe como ilustração os detalhes indicados para uso do comando GO TO
em estilo incondicional simulando a ação dos comandos EVALUATE e END-EVALUATE. Atente para o uso da variável
de entrada de dados WS-ENTRADA.

DATA DIVISION.
WORKING-STORAGE SECTION.
108 PRO G RA MA Ç ÃO CO B OL

01 WS-FORMACAO PIC 9.
88 WS-FORM-VALIDADE VALUE 1 2 3.
88 WS-FORM-BASICO VALUE 1.
88 WS-FORM-MEDIO VALUE 2.
88 WS-FORM-SUPERIOR VALUE 3.
77 WS-ESCOLAR PIC 9.

PROCEDURE DIVISION.
DISPLAY "1 - Ensino basico"
DISPLAY "2 - Ensino medio"
DISPLAY "3 - Ensino superior"
DISPLAY X"0D".
DISPLAY "Qual sua formacao: " WITH NO ADVANCING.
ACCEPT WS-ESCOLAR.
IF WS-ESCOLAR >= 1 AND WS-ESCOLAR <= 3
MOVE WS-ESCOLAR TO WS-FORMACAO
IF WS-VALIDADE
IF WS-FORM-BASICO GO TO MENS1-PARA END-IF
IF WS-FORM-MEDIO GO TO MENS2-PARA END-IF
IF WS-FORM-SUPERIOR GO TO MENS3-PARA END-IF
END-IF
ELSE
GO TO SAIDA-PARA
END-IF.
MENS1-PARA.
DISPLAY "Formacao no ensino basico".
GO TO SAIDA-PARA.

MENS2-PARA.
DISPLAY "Formacao no ensino medio".
GO TO SAIDA-PARA.

MENS3-PARA.
DISPLAY "Formacao no ensino superior".
GO TO SAIDA-PARA.

SAIDA-PARA.
STOP RUN.

Observe que o uso do comando GO TO é mais confuso que outros comandos da linguagem. É exatamente por este
motivo que o comando deve ser ao máximo evitado. Seu uso desnecessário torna o código de difícil manutenção e
pode gerar o que se chama de “código espaguete”, ou seja, um código com um emaranhado de comandos que nin-
guém consegue entender onde começa e termina. Somente use este recurso, como última alternativa, caso não haja na
linguagem uma maneira de realizar ação desejada de outra forma.
Para simular a ação dos comandos EVALUATE e END-EVALUATE é definido no trecho final de código antes de STOP
RUN um ponto de saída com o parágrafo SAIDA-PARA. Note que MES1-PARA, MENS2-PARA e MENS3-PARA após
executarem suas ações direcionam o fluxo do programa para o parágrafo SAIDA-PARA a partir do uso da instrução GO
TO SAIDA-PARA. Isso permite que após executar a ação de cada parágrafo de mensagem o fluxo do programa seja
direcionado para um ponto de convergência, que neste caso é o encerramento do programa.
Outro detalhe, a ser observado, no código é o direcionamento realizado dentro da estrutura de tomada de decisão para
cada um dos parágrafos contendo as mensagens a serem apresentadas. Veja que para fazer uso adequado do coman-
do GO TO incondicional de forma mais eficiente é necessário o apoio de instruções IFs.
O trecho anterior mostra a entrada do usuário na variável WS-ESCOLAR que é verificada para se saber se possui o
valor fornecido de forma válida. Sendo válido executa suas operações e não sendo válido o fluxo do programa é direci-
onada para o parágrafo SAIDA-PARA. Veja que, sendo a condição verdadeira a primeira ação dentro do bloco validado
AÇ ÃO IN / CO ND I CI O NAL 109

realizada é a transferência do conteúdo da variável WS-ESCOLAR para o nome condicional WS-FORMACAO por meio
da instrução MOVE WS-ESCOLAR TO WS-FORMACAO.
Anteriormente o comando MOVE foi mostrado como alternativa de atribuição de valor em substituição ao uso de atribui-
ções em expressões algébricas. A ação de atribuição só é permitida em variáveis numéricas devido ao uso do comando
COMPUTE. No caso indicado isto não é possível, e por esta razão usa-se o comando MOVE.
O comando GO TO não deve ser utilizado por programadores inexperientes, pois exige alto grau de abstração sobre a
lógica de programação e grande disciplina para conseguir fazer com que o código fique o mais legível possível, o que é
uma tarefa bastante difícil como pode ser observado no trecho de código exemplificado.

3.5 LAÇOS PARA REPETIÇÕES


Os laços para repetições (também conhecidos como loopings, malhas ou ciclos) possibilitam executar determinado
trecho de código de um programa várias vezes. A ideia geral do conceito de laço decorre do fato de um laço ser um nó
corredio facilmente desatável a partir de uma ou mais alças. Dessa forma, é possível definir quantidades de repetições,
com laços determinísticos (quando se sabe o número de vezes que o laço deve ser executado: iterativo) e laços inde-
terminados (quando não se sabe quantas vezes o laço deve ser executado, dependendo de uma resposta positiva do
usuário para fazê-lo: interativos).
A execução de laços em COBOL é realizada com o eclético comando PERFORM finalizado com END-PERFORM. Este
comando é usado, não só, para a execução de sequências de instruções ou seções por certo número de vezes, mas
pode também ser usado para desviar a execução do fluxo de programa para determinado parágrafo ou seção, executar
as instruções desses locais e ao final retornar para a primeira instrução após sua chamada. Neste momento, apenas a
aplicação relacionada a execução de laços será tratada.
Laços de repetição PERFORM são estruturas que repetem um conjunto de instruções certo número de vezes. A quanti-
dade de repetições poderá ser conhecida ou desconhecida. Os laços cuja a quantidade de vezes é conhecida são
chamados de laços iterativos, mas os laços em que não se sabe de antemão quantas vezes ocorrerá a execução são
chamados de laços interativos. A estrutura geral de laços em COBOL é escrita de acordo com a forma sintática simplifi-
cada seguinte:

PERFORM [[<local>] [VARYING <var> FROM <v1> BY <v2>] UNTIL [NOT] <cond>] | [<n> TIMES]
<ações a serem repetidas>
END-PERFORM.

Onde, local é uma definição opcional de onde o comando deverá atuar (este efeito não será tratado neste capítulo), o
trecho VARYING <var> FROM <v1> BY <v2> é opcional e destinado a execução de laços iterativos. O parâmetro con-
dição é obrigatório tanto para laços interativos como iterativos e determina a condição de encerramento de um laço.
O trecho VARYING <var> FROM <v1> BY <v2> é usado para determinar uma variável (var) que será usada para ar-
mazenar de forma acumulada a contagem de valores iniciados a partir (FROM) do valor inicial <v1>, variando
(VARYING) a contagem com passos do valor de (BY) <v2> até chegar ao final da contagem verificada com a condição
(cond) estabelecida em UNTIL (até que), podendo a condição ser usada fora do trecho VARYING <var> FROM <v1>
BY <v2> .
O laço PERFORM pode fazer uso apenas do trecho <n> TIMES, onde “n” determina o número de vezes (TIMES) que
as instruções internas ao laço serão executadas.

3.5.1 Ciclo interativo


O estilo padrão de laço com ciclo interativo é usado em COBOL com os comandos FERFORM e UNTIL que se caracte-
rizam por ser do tipo pré-teste com fluxo de ação falso, pois somente é encerrado quando a condição se torna verdadei-
ra. Esta forma de laço pode ser usada para a definição de laços interativos e iterativos.
No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma condi-
cional iterativa observe os detalhes seguintes:
110 PRO G RA MA Ç ÃO CO B OL

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
PERFORM UNTIL AC-CONT > 5
DISPLAY AC-CONT
COMPUTE AC-CONT = AC-CONT + 1
END-PERFORM.

Nesta forma de laço faz-se a definição de uma variável que será usada na ação de contagem, neste caso AC-CONT. A
variável contadora deve ser inicializada (COMPUTE AC-CONT = 1) para assegurar ação adequada do laço e seu limite
de contagem verificado por UNTIL AC-CONT > 5. Veja que a contagem será realizada até que a variável AC-CONT
atinja um valor maior que o limite, neste caso 5.
A cada verificação falsa o bloco entre FERFORM e END-PERFORM é executado quando o valor da variável contadora
é apresentado com DISPLAY AC-CONT e o valor da variável que controla a operação é acrescida com o valor de in-
cremento, neste caso COMPUTE AC-CONT = AC-CONT + 1.
Caso necessite produzir um laço condicional pré-teste com fluxo verdadeiro use o operador lógico NOT. Para o código
anterior bastaria alterar o trecho UNTIL AC-CONT > 5 para UNTIL NOT AC-CONT <= 5.
No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores numéricos inteiros inicia-
dos em 1 até o momento de saída do programa na forma condicional interativa com fluxo de laço verdadeiro observe os
detalhes seguintes:

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 999.
77 WS-RESP PIC A.

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
MOVE "S" TO WS-RESP.
PERFORM UNTIL NOT FUNCTION UPPER-CASE(WS-RESP) = "S"
DISPLAY AC-CONT " - " NO ADVANCING
COMPUTE AC-CONT = AC-CONT + 1
DISPLAY "Continua (S/N): " NO ADVANCING
ACCEPT WS-RESP
END-PERFORM.

Veja neste trecho o uso do comando MOVE novamente para atribuir o valor "S" na variável WS-RESP. O laço interativo
para realizar ação com fluxo verdadeiro usa o trecho UNTIL NOT com a indicação de uso da função UPPER-CASE que
tem por finalidade transformar a entrada de um caractere minúsculo em maiúsculo.
Dentro do bloco do laço encontra-se após a apresentação do valor numérico a apresentação da pergunta solicitando se
o usuário deseja ou não continuar. Esta é uma situação em que não se sabe quantas vezes o usuário desejará executar
o programa, sendo um exemplo de um laço indeterminado de vezes.
Os laços pré-teste possuem como característica validarem a condição antes da execução das instruções internas ao
seu bloco, ou seja, BEFORE. Isso é muito útil até que se tenha a necessidade de ter que entrar primeiro no laço para
depois verificar a validade da condição. Neste sentido, basta solicitar para que a ação do comando PERFORM seja
executada com o uso do trecho WITH TEST AFTER, em que o termo AFTER indica para validar a condição depois de
passar pelo bloco. Observe o exemplo seguinte.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.
AÇ ÃO IN / CO ND I CI O NAL 111

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
PERFORM WITH TEST AFTER UNTIL AC-CONT > 5
DISPLAY AC-CONT
COMPUTE AC-CONT = AC-CONT + 1
END-PERFORM.

A solicitação WITH TEST AFTER faz com que o comando PERFORM “entenda” que é para deixar o teste condicional
para a próxima vez de verificação. Laços pós-teste tem a característica de deixarem as ações passarem dentro do bolo
uma vez antes de serem avaliadas. Para verificar essa ocorrência basta alterar o valor 1 da instrução COMPUTE AC-
CONT = 1 para 6. Você perceberá que o valor acima da condição será apresentado e em seguida o programa é inter-
rompido.
Além do trecho WITH TEST AFTER há o trecho WITH TEST BEFORE que diz para que a condição seja imediatamente
avaliada antes do processamento entra no bloco do laço. Como o uso desses recursos é opcional a omissão mantém a
linguagem no modo WITH TEST BEFORE.
Já que anteriormente foi apresentado o comando GO TO cabe neste momento mais um exemplo de uso adequado para
este renegado. Algumas poucas linhas de programação possuem uma estrutura de laço que é a das mais versáteis,
pois a condição de encerramento pode ser posicionada em qualquer lugar do bloco do laço, trata-se do laço condicional
seletivo.

3.5.2 Ciclo iterativo


O estilo padrão de laço iterativo usado em COBOL é conseguido de duas formas: forma condicional e forma incondicio-
nal. A forma condicional é operada com os comandos PERFORM, VARYING, FROM, BY e UNTIL e a forma incondici-
onal é operada com os comandos PERFORM e TIMES.
No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma condi-
cional iterativa observe os detalhes seguintes:

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.

PROCEDURE DIVISION.
PERFORM VARYING AC-CONT FROM 1 BY 1 UNTIL AC-CONT > 5
DISPLAY AC-CONT
END-PERFORM.

Observe o trecho de código é veja que é solicitado que se faça a variação (VARYING) da variável AC-CONT iniciada
em 1 (FROM 1), de 1 em 1 (BY 1) até que (UNTIL) o valor de AC-CONT seja maior que 5. Perceba que está estrutura
possui um nível de compactação maior que as formas mostradas anteriormente. O valor de BY pode ser definido com o
passo desejado.
No sentido de exemplificar um trecho de código que apresente no monitor de vídeo os valores de 1 a 5 na forma iterati-
va incondicional observe os detalhes seguintes:

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
PERFORM 5 TIMES
DISPLAY AC-CONT
COMPUTE AC-CONT = AC-CONT + 1
END-PERFORM.
112 PRO G RA MA Ç ÃO CO B OL

No trecho anterior note a instrução PERFORM 5 TIMES que efetua cinco repetições do bloco interno ao laço. Diferen-
temente do PERFORM com VARYING aqui é necessário definir a inicialização da variável e seu incremento de forma
semelhante a forma usada na definição do laço condicional iterativo.

3.5.3 Ciclo seletivo


Laço seletivo é uma estrutura que não possui indicação direta de finalização nos limites de sua definição. A verificação
de interrupção é realiza por uma instrução IF/END-IF que pode ser colocada em qualquer linha dentro dos limites do
bloco que o laço executa.
Um laço seletivo é escrito como qualquer outro laço, tendo como diferenciação o uso do comando FOREVER ou das
palavras UNTIL e EXIT no local que seria a definição da condição de encerramento do laço.
Como demonstração da estrutura de operação deste tipo de laço considere como necessidade apresentar os valores
inteiros de 1 a 5 utilizando-se um laço condicional seletivo.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
PERFORM FOREVER
DISPLAY AC-CONT
COMPUTE AC-CONT = AC-CONT + 1
IF AC-CONT > 5
EXIT PERFORM
END-IF
END-PERFORM.

Ao ser executado o trecho anterior os valores de 1 a 5 são apresentados e quando o valor da variável AC-CONT for
maior que 6 ocorrerá uma saída do laço conforme a ação definida por FOREVER. Na sequência troque o comando
FOREVER por UNTIL EXIT.
O trecho dentro do laço representado pelos comandos IF/END_IF podem ser colocados em qualquer posição dentro
dos limites de PERFORM e END-PERFORM. Devido a esta possibilidade o laço é chamado de seletivo.
Anteriormente foi apresentado com ressalvas o comando GO TO. A título de ilustração veja a estrutura de laço seletivo
simulada com o uso do comando GO TO e observe os motivos que levam a solicitar o seu não uso na programação
estrutura e orientada a objetos, permitido algumas vezes em raras exceções, quando uma estrutura lógica não existe na
linguagem em uso.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CONT PIC 9.

PROCEDURE DIVISION.
COMPUTE AC-CONT = 1.
LOOP-PARA.
DISPLAY AC-CONT.
COMPUTE AC-CONT = AC-CONT + 1.
IF AC-CONT > 5
GO TO END-LOOP-PARA
END-IF.
GO TO LOOP-PARA.
END-LOOP-PARA.
AÇ ÃO IN / CO ND I CI O NAL 113

Veja que neste código está se lançando mão do comando GO TO (com os devidos cuidados) para estabelecer os des-
vios junto aos parágrafos LOOP-PARA e END-LOOP-PARA para simular a ação de um laço PERFORM/END-
PERFORM com FOREVER. O parágrafo LOOP-PARA simula um laço do tipo condicional seletivo, deixando o fluxo de
processamento passar direto para a instrução DISPLAY AC-CONT após a variável ser inicializada com COMPUTE AC-
CONT = 1. Na sequência é feita a atribuição do valor do contador sobre a variável AC-CONT e na sequência a instru-
ção IF AC-CONT > 5 GO TO END-LOOP-PARA END-IF verifica se o valor do contador é maior que 5 e sendo esta
condição verdadeira direciona o fluxo para o parágrafo END-LOOP-PARA que dará continuidade e encerramento do
programa. Se a condição não é verdadeira a instrução GO TO LOOP-PARA volta o fluxo para o parágrafo LOOP-
PARA.
A instrução IF AC-CONT > 5 GO TO END-LOOP-PARA END-IF é responsável pela saída do fluxo do laço, podendo ser
colocada em qualquer linha do bloco entre LOOP-PARA e END-LOOP-PARA, excetuando-se a linha de código com a
instrução GO TO LOOP-PARA que deve ficar na última linha antes de END-LOOP-PARA.
Veja que neste exemplo, onde se utiliza novamente o comando GO TO, conseguiu-se uma forma de mais suavizada de
representação do que a forma apresentada anteriormente. Neste momento, a estrutura lógica escrita tem uma comple-
xidade funcional mais simples que a proposta anteriormente.

3.6 DIVISIBILIDADE
Divisibilidade é a qualidade daquilo é divisível. Dois conceitos devem ser entendidos pelos programadores de computa-
dor: múltiplos e divisores de números naturais.
Múltiplos são os resultados obtidos da multiplicação de dois números naturais, enquanto divisores são números naturais
que dividem outros números naturais com o objetivo de gerar um resultado exato de divisão, ou seja, obter resto de
divisão sempre zero. Quando o resto de uma divisão de números naturais é igual a zero, tem-se divisibilidade, ou seja,
resultado de divisão exata.
Pelo fato de todo número natural ser múltiplo de si mesmo, uma forma de trabalhar esses valores é pelas operações de
cálculo com divisores. Em uma divisão, existem alguns termos que precisam ser conhecidos: dividendo (valor que será
dividido), divisor (valor que divide o dividendo), quociente (resultado da divisão do dividendo pelo divisor) e resto (valor
que sobra da divisão). A Figura 3.1 mostra o processo de divisão de dois números naturais.
De acordo com o exposto na Figura 3.1, fica fácil deduzir
como obter a divisibilidade de um dividendo (valor 5) por um
divisor (valor 2). Considere a expressão matemática Resto =
Dividendo – Divisor . Quociente para obter a divisibilidade,
na qual as variáveis Dividendo, Divisor e Quociente serão
substituídas por valores inteiros positivos. Assim sendo,
considere os valores de dividendo 5 e divisor 2 na expres-
são matemática Resto = 5 – 2 . 2. Basta, primeiro, multipli-
car 2 . 2 para obter o valor 4, que será subtraído do valor 5 e
resultará no valor 1 para a variável Resto, ou seja, Resto é
diferente de zero. Nesse caso, não ocorreu a divisibilidade
Figura 3.1 - Exemplo de divisão de dois números naturais do valor 5 pelo valor 2 porque 2 não é múltiplo de 5.
A expressão matemática Resto = Dividendo – Divisor . Quociente é obtida da equação matemática:
 a
r  a n  
 n
em que a variável r representa o resto da divisão; a variável a, representa o dividendo; e a variável n, o divisor. Observe
o cálculo do quociente com o uso da função parte inteira inferior, que obtém o resultado inteiro da divisão do dividendo
a pelo divisor n. A função parte inteira inferior tem o objetivo de retornar a parte inteira de um número decimal. Compu-
tacionalmente esta expressão matemática deve ser escrita na forma algébrica como r = a – n * (a / n).
114 PRO G RA MA Ç ÃO CO B OL

A função parte inteira pode ser representada de duas formas: parte inteira inferior e superior. Na forma inferior retorna a
parte inteira do valor, desconsiderando a parte decimal. Já na forma superior retorna o arredondamento do valor inteiro
mais próximo para cima. As funções parte inteira inferior e superior são graficamente representadas como:

x Parte inteira superior = porção inteira do valor + 1


x Parte inteira inferior = porção inteira do valor
A forma algébrica r = a – n * (a / n) é uma operação algorítmica genérica, que pode ser facilmente adaptada a qualquer
linguagem de programação. Em COBOL deve ser escrita como r = a – n * FUNCTION INTEGER(a / n).
A título de demonstração considere a necessidade de efetuar a entrada de um valor numérico inteiro de máscara 9999
e informar se o valor informado é par ou ímpar.

ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
REPOSITORY.
FUNCTION INTEGER INTRINSIC.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-VAL PIC 9999.
77 WS-RES PIC 9999.

PROCEDURE DIVISION.
ACCEPT WS-VAL.
COMPUTE WS-RES = WS-VAL - 2 * INTEGER(WS-VAL / 2).
IF WS-RES = 0
DISPLAY "Valor par."
ELSE
DISPLAY "Valor Impar."
END-IF.

Se fornecido valores múltiplos de 2 será mostrada a mensagem "Valor par.", caso contrário será apresentada a men-
sagem "Valor impar.". Este efeito é conseguido com COMPUTE WS-RES = WS-VAL - 2 * INTEGER(WS-VAL / 2) que
tem por finalidade calcular o resto da divisão do valor informado por 2. Sendo o resto igual a zero o valor fornecido é
par.
Veja que na expressão para calcular o resto da divisão (variável WS-RES) é omitido a cláusula FUNCTION. Isto é pos-
sível quando se utiliza FUNCTION INTEGER INTRINSIC definida no parágrafo REPOSITORY da CONFIGURATION
SECTION em ENVIRONMENT DIVISION.
O parágrafo REPOSITORY (repositório) permite especificar nomes de protótipos de programas, de funções, de delega-
dos, de enumerações, de interfaces e propriedades usadas no escopo da ENVIRONMENT DIVISION. Permite também
a declaração de nomes de funções intrínsecas, como foi o caso, para poder inibir o uso da cláusula FUNCTION. Caso
queira indicar o uso de todas as funções intrínsecas, use a instrução FUNCTION ALL INTRINSIC.
O uso da instrução FUNCTION ALL INTRINSIC faz com que o compilador carregue para a memória, no momento da
compilação, a lista completa das funções intrínsecas existentes, simplificando o uso das mesmas. Isto facilita, em muito,
o uso de algumas operações, como por exemplo, apresentar o valor inteiro do cálculo da raiz quadrada de 9.75.
Sem o uso da instrução FUNCTION ALL INTRINSIC a extração do valor inteiro da raiz quadrada de 9.75 é definida:

DISPLAY FUNCTION INTEGER(FUNCTION SQRT(9.75)).

Observe que o comando FUNCTION deve ser usado sempre antes do nome da função. Isso é inviável quando há a
necessidade de se trabalhar com um conjunto grande de funções dentro de expressões algébricas. Com o uso da ins-
trução FUNCTION ALL INTRINSIC a mesma situação fica apenas definida como:

DISPLAY INTEGER(SQRT(9.75)).
AÇ ÃO IN / CO ND I CI O NAL 115

Atente para o uso da função intrínseca INTEGER que tem por finalidade extrair de um número decimal qualquer a sua
porção inteira. Neste caso, a função INTEGER recebe como argumento a divisão do valor WS-VAL por dois e extrai o
valor inteiro da operação. Mesmo trabalhando, com valores inteiros é conveniente fazer uso da função INTEGER para
calcular o quociente inteiro de divisão.

3.7 INTERRUPÇÃO DE LAÇOS


Os laços são estruturas operacionais que podem ser interrompidas em sua execução caso certa condição ocorra. Esta
ocorrência pode ser efetivada com o uso das frases EXIT PERFORM (apresentada no uso de laços seletivos) e EXIT
PERFORM CYCLE. O laço que opera com EXIT PERFORM é mais radical uma vez que faz o término abrupto da exe-
cução do laço. Já EXIT PERFORM CYCLE faz uma interrupção temporária no laço mantendo o controle operacional
dentro do laço em execução.
Como exemplo de uso do recurso EXIT PERFORM, considere o trecho de programa seguinte, que visa apresentar uma se-
quência de valores numéricos inteiros entre 1 e 10, até o encontro da condição que fará a interrupção brusca do laço quando
o valor da contagem estiver em 6.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-I PIC 99.

PROCEDURE DIVISION.
COMPUTE AC-I = 1.
PERFORM VARYING AC-I FROM 1 BY 1 UNTIL AC-I > 10
IF AC-I = 6
EXIT PERFORM
END-IF
DISPLAY AC-I
END-PERFORM.

O trecho anterior faz a apresentação dos valores de 1 a 5. O laço será interrompido e encerrado quando a variável AC-I esti-
ver com o valor 6. Neste momento EXIT PERFORM será executado fazendo com que forçosamente o laço seja encerrado
não chegando à variável AC-I atingir o valor 10.
Como exemplo de uso da frase EXIT PERFORM CYCLE, considere o trecho de código seguinte, que apresenta uma se-
quência de valores numéricos ao efetuar a contagem de 1 a 10, até o encontro da condição que fará a interrupção temporária
do laço quando o valor da contagem estiver em 6.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-I PIC 99.

PROCEDURE DIVISION.
COMPUTE AC-I = 1.
PERFORM VARYING AC-I FROM 1 BY 1 UNTIL AC-I > 10
IF AC-I = 6
EXIT PERFORM CYCLE
END-IF
DISPLAY AC-I
END-PERFORM.

A execução do trecho anterior apresenta os valores de 1 a 5 e de 7 a 10, sendo o valor 6 omitido da apresentação. A omissão
da apresentação do valor 6 decorre da ação da frase EXIT PERFORM CYCLE que faz uma interrupção temporária na ação
do programa. Isto posto, quando a variável AC-I está com o valor 6 sua apresentação é omitida, pois o recurso indicado pela
frase EXIT PERFORM CYCLE faz com que o laço em execução seja momentaneamente interrompido na iteração atual e
passando sua ação para a próxima interação a ser efetivada.
116 PRO G RA MA Ç ÃO CO B OL

3.8 HORA DE PROGRAMAR


Nesta etapa são colocadas em prática, grande parte do que foi apresentado neste capítulo. Os elementos aqui mostra-
dos complementam a parte do estudo da ação sequencial e proporciona maior visão sobre diversos, mesmo que bási-
cos, elementos da linguagem de programação COBOL. Atente para cada problema apresentado e respectiva solução.

CÁLCULO DE ADIÇÃO COM DESVIO CONDICIONAL SIMPLES


Elaborar programa de computador que que leia dois valores numéricos inteiros desconhecidos, some-os e apresente o
resultado, caso o valor somado seja maior ou igual a 10.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato 9(3) e uma
máscara definida para a saída do resultado configurada como 9(4).
Selecione e defina um projeto do programa vazio com o nome c03ex01.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX01 AS "Capitulo 3 – Exemplo 1".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-A PIC 9(3).
7 77 WS-B PIC 9(3).
8 77 WS-R PIC 9(4).
9 77 WS-DSP-R PIC ZZZZ.
10 77 WS-ENTER PIC X.
11 *
12 PROCEDURE DIVISION.
13 PROG-PRINCIPAL-PARA.
14 DISPLAY "Entre valor <A>: " WITH NO ADVANCING.
15 ACCEPT WS-A.
16 DISPLAY "Entre valor <B>: " WITH NO ADVANCING.
17 ACCEPT WS-B.
18 COMPUTE WS-R = WS-A + WS-B.
19 IF WS-R >= 10
20 MOVE WS-R TO WS-DSP-R
21 DISPLAY "Resultado = " WS-DSP-R
22 END-IF.
23 DISPLAY X"0D".
24 DISPLAY "Tecle <ENTER> para encerrar... "
25 WITH NO ADVANCING.
26 ACCEPT WS-ENTER.
27 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa, dependendo das
entradas ocorrerá ou não a apresentação do resultado.
Aqui é mais um lembrete do que uma novidade, na linha 9 é definida a variável de saída com formatação da máscara
editada para a apresentação do valor calculado sem zeros à esquerda.
O ponto principal do programa é o uso da tomada de decisão simples definida entre as linhas 19 e 22 que controlam a
apresentação do valor do resultado, caso este seja maior ou igual a 10. Observe que a transferência do cálculo com o
comando MOVE só é executada caso a condição seja verdadeira. Esta estratégia visa poupar tempo de processamen-
AÇ ÃO IN / CO ND I CI O NAL 117

to, pois somente será apresentado o resultado se a condição for verdadeira. Não há necessidade de realizar esta mo-
vimentação de dado se não for para efetuar a apresentação. No mais o programa possui recurso já conhecidos que
dispensam explicações.

CÁLCULO DE ADIÇÃO COM DESVIO CONDICIONAL COMPOSTO


Elaborar programa de computador que que efetue a leitura de dois valores numéricos inteiros positivos e negativos e
processe sua adição. Caso o resultado obtido seja maior ou igual a 10, esse valor deve ser apresentado, somando a ele
5. Caso o resultado do valor somado não seja maior ou igual a 10, ele deve ser apresentado subtraindo 7.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato 9(3) e uma
máscara definida para a saída do resultado configurada como 9(4).
Selecione e defina um projeto do programa vazio com o nome c03ex02.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX02 AS "Capitulo 3 – Exemplo 2".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-A PIC 9(3).
7 77 WS-B PIC 9(3).
8 77 WS-R PIC 9(4).
9 77 WS-DSP-R PIC ZZZZ.
10 77 WS-ENTER PIC X.
11 *
12 PROCEDURE DIVISION.
13 PROG-PRINCIPAL-PARA.
14 DISPLAY "Entre valor <A>: " WITH NO ADVANCING.
15 ACCEPT WS-A.
16 DISPLAY "Entre valor <B>: " WITH NO ADVANCING.
17 ACCEPT WS-B.
18 COMPUTE WS-R = WS-A + WS-B.
19 IF WS-R >= 10
20 ADD 5 TO WS-R
21 MOVE WS-R TO WS-DSP-R
22 DISPLAY "Resultado = " WS-DSP-R
23 ELSE
24 SUBTRACT 7 FROM WS-R
25 MOVE WS-R TO WS-DSP-R
26 DISPLAY "Resultado = " WS-DSP-R
27 END-IF.
28 DISPLAY X"0D".
29 DISPLAY "Tecle <ENTER> para encerrar... "
30 WITH NO ADVANCING.
31 ACCEPT WS-ENTER.
32 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado.


O uso da ação de tomada de decisão composta é definido nas linhas 19 e 27. Veja que nas linhas 20 e 24 estão sendo
usados os verbos ADD e SUBTRACT que respectivamente acrescenta 5 e subtraí 7 do resultado somado na linha 18 e
validado na linha 19.
118 PRO G RA MA Ç ÃO CO B OL

Nas linhas 20 e 24 poderiam ter sido usados o comando COMPUTE para somar 5 e subtrair 7 do resultado somado.
Apesar de COMPUTE ser preterido sobre os operadores aritméticos descritivos aqui é uma oportunidade em usá-los e
mostrar que neste contexto escrevê-los deu mais sentido dentro do que é solicitado.

TRIÂNGULO COM DESVIO CONDICIONAL ENCADEADO


Elaborar programa de computador que efetue a leitura de três valores decimais positivos para os lados A, B e C de um
triângulo. O programa deve verificar se os lados fornecidos formam realmente um triângulo e acusar com mensagem de
erro caso esta condição. Se a condição for verdadeira, deve ser indicado o tipo de triângulo formado: isósceles, escale-
no ou equilátero.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato S9(3)V9(2) e é
preciso considerar também que triângulo é uma forma geométrica composta de três lados, e cada lado é menor que a
soma dos outros dois lados, ou seja, será um triângulo quando A < B + C, quando B < A + C e quando C < A + B. Ten-
do certeza de que os valores informados para os três lados formam um triângulo, basta saber o seu tipo (isósceles,
escaleno ou equilátero). Para tanto, é necessário considerar que um triângulo é isósceles quando possui dois lados
iguais e um diferente, sendo A = B ou A = C ou B = C; é escaleno quando todos os lados são diferentes, sendo A <> B
e B <> C; e é equilátero quando todos os lados são iguais, sendo A = B e B = C.
Selecione e defina um projeto do programa vazio com o nome c03ex03.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX03 AS "Capitulo 3 – Exemplo 3".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-A PIC S9(3)V9(2).
7 77 WS-B PIC S9(3)V9(2).
8 77 WS-C PIC S9(3)V9(2).
9 77 WS-ENTER PIC X.
10 *
11 PROCEDURE DIVISION.
12 PROG-PRINCIPAL-PARA.
13 DISPLAY "Entre lado <A>: " WITH NO ADVANCING.
14 ACCEPT WS-A.
15 DISPLAY "Entre lado <B>: " WITH NO ADVANCING.
16 ACCEPT WS-B.
17 DISPLAY "Entre lado <C>: " WITH NO ADVANCING.
18 ACCEPT WS-C.
19 IF WS-A < WS-B + WS-C AND
20 WS-B < WS-A + WS-C AND
21 WS-C < WS-A + WS-B
22 IF WS-A = WS-B AND WS-B = WS-C
23 DISPLAY "Triangulo Equilatero."
24 ELSE
25 IF WS-A = WS-B OR WS-A = WS-C OR WS-C = WS-B
26 DISPLAY "Triangulo Isosceles."
27 ELSE
28 DISPLAY "Triangulo Escaleno."
29 END-IF
30 END-IF
31 ELSE
------ ------------------------------------------------------------------------
AÇ ÃO IN / CO ND I CI O NAL 119

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
32 DISPLAY "Os valores fornecidos nao formam triangulo."
33 END-IF.
34 DISPLAY X"0D".
35 DISPLAY "Tecle <ENTER> para encerrar... "
36 WITH NO ADVANCING.
37 ACCEPT WS-ENTER.
38 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado.


O programa mostra o uso dos operadores lógicos AND e OR nas linhas 19 até 21 e 25. O trecho entre as linhas 19 e 21
verifica se a condição WS-A < WS-B + WS-C AND WS-B < WS-A + WS-C AND WS-C < WS-A + WS-B é verdadeira, e
sendo o programa indica qual é o tipo de triângulo, cujo, os dados foram fornecidos. Se a condição for falsa será apre-
sentada a mensagem da linha 32 indicando "Os valores fornecidos nao formam triangulo.".
A linha 22 com a condição WS-A = WS-B AND WS-B = WS-C verifica se o triângulo é equilátero, sendo apresenta a
mensagem da linha 23 e não sendo direciona o fluxo para a linha 25 onde será verificado se o triângulo é isósceles ou
escaleno.
Na linha 25 a condição WS-A = WS-B OR WS-A = WS-C OR WS-C = WS-B se verdadeira apresenta a mensagem da
linha 26, se a condição for falas a mensagem apresentadas será da linha 28.

CALCULADORA COM DECISÃO SELETIVA


Elaborar programa de computador que simule uma simples calculadora, que efetue a leitura de dois valores decimais de
no máximo uma dezena e apresente na sequência um menu com as operações aritméticas de: adição, subtração, mul-
tiplicação e divisão, a partir do qual o. usuário escolherá a operação desejada e o programa deverá apresentar o resul-
tado da operação escolhida. Para a divisão o programa deve retornar mensagem de erro caso ocorra a tentativa de
usar valor de divisor como zero.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato S9(2)V9(2) e
uma máscara de saída no formato --9.9(2) para suporte a apresentação de eventuais valores decimais negativos.
Selecione e defina um projeto do programa vazio com o nome c03ex04.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX04 AS "Capitulo 3 – Exemplo 4".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-A PIC S9(2)V9(2).
7 77 WS-B PIC S9(2)V9(2).
8 77 WS-R PIC S9(3)V9(2).
9 77 WS-DSP-R PIC --9.9(2).
10 77 WS-OPCAO PIC 9.
11 77 WS-ENTER PIC X.
12 *
13 PROCEDURE DIVISION.
14 PROG-PRINCIPAL-PARA.
------ ------------------------------------------------------------------------
120 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
15 DISPLAY "Entre o valor <A>: " WITH NO ADVANCING.
16 ACCEPT WS-A.
17 DISPLAY "Entre o valor <B>: " WITH NO ADVANCING.
18 ACCEPT WS-B.
19 DISPLAY X"0D".
20 DISPLAY "[1] - Adicao"
21 DISPLAY "[2] - Subtracao"
22 DISPLAY "[3] - Multiplicacao"
23 DISPLAY "[4] - Divisao"
24 DISPLAY X"0D".
25 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING.
26 ACCEPT WS-OPCAO.
27 DISPLAY X"0D"
28 IF WS-B = 0
29 DISPLAY "Erro na divisao."
30 ELSE
31 IF WS-OPCAO >= 1 AND WS-OPCAO <= 4
32 EVALUATE WS-OPCAO
33 WHEN 1
34 COMPUTE WS-R = WS-A + WS-B
35 WHEN 2
36 COMPUTE WS-R = WS-A - WS-B
37 WHEN 3
38 COMPUTE WS-R = WS-A * WS-B
39 WHEN 4
40 COMPUTE WS-R = WS-A / WS-B
41 END-EVALUATE
42 MOVE WS-R TO WS-DSP-R
43 DISPLAY "O resultado equivale a: " WS-DSP-R
44 ELSE
45 DISPLAY "Opcao Invalida."
46 END-IF
47 END-IF.
48 DISPLAY X"0D".
49 DISPLAY "Tecle <ENTER> para encerrar... "
50 WITH NO ADVANCING.
51 ACCEPT WS-ENTER.
52 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e faça algumas experiên-
cias, por exemplo com os valores 3 e 4.
Vale aqui uma atenção a linha 9 onde se define o formato de saída para a indicação de valores negativos, daí o uso do
símbolo “menos”. Os dois símbolos “menos” criam a máscara para as posições de centena e dezena. Na posição da
unidade encontra 9 que é usado quando se deseja a apresentação de um valor zero na posição. Se for informado os
valores 3 e 4 e escolhia a divisão o resultado apresentado como 0.75. A linha 28 verifica se o valor do divisor é zero e
se for a mensagem de erro "Erro na divisao" é apresentada. Não sendo o divisor igual a zero ocorre na linha 31 a
verificação da validade das opções de menu fornecida. Se a condição é verdadeira os cálculos podem ser realizados,
mas se não for será apresentada a mensagem "Opção invalida" na linha 45.
O trecho de linhas de 32 a 41 controla o direcionamento do cálculo após as validações de divisor diferente de zero e de
valor de opção com o uso da instrução de decisão seletiva. Após a execução dessa instrução ocorre o preparo para
apresentação do resultado na linha 42 e a apresentação do resultado na linha 43.
AÇ ÃO IN / CO ND I CI O NAL 121

TABUADA COM LAÇO CONDICIONAL PRÉ-TESTE


Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados
da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de
aritmética.
Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e
para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de
resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-
cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste
caso serão usadas Z9 e ZZ9.
Selecione e defina um projeto do programa vazio com o nome c03ex05.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX05 AS "Capitulo 3 – Exemplo 5".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 *
7 77 WS-EN PIC 9(2).
8 77 AC-CI PIC 9(2).
9 77 WS-CR PIC 9(3).
10 77 WS-SN PIC Z9.
11 77 AC-SI PIC Z9.
12 77 WS-SR PIC ZZ9.
13 77 WS-ENTER PIC X.
14 *
15 PROCEDURE DIVISION.
16 PROG-PRINCIPAL-PARA.
17 DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING.
18 ACCEPT WS-EN.
19 COMPUTE AC-CI = 1.
20 PERFORM UNTIL AC-CI > 10
21 COMPUTE WS-CR = WS-EN * AC-CI
22 MOVE WS-EN TO WS-SN
23 MOVE AC-CI TO AC-SI
24 MOVE WS-CR TO WS-SR
25 DISPLAY WS-SN " X " AC-SI " = " WS-SR
26 COMPUTE AC-CI = AC-CI + 1
27 END-PERFORM.
28 DISPLAY X"0D".
29 DISPLAY "Tecle <ENTER> para encerrar... "
30 WITH NO ADVANCING.
31 ACCEPT WS-ENTER.
32 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada
valores de 1 a 10.
Apesar de ter sido comentado é bom lembra a estratégia e regra de definição de variáveis entre as linhas 7 e 13. O uso
da indicação WS é para sinalizar que são variáveis criadas na WORKING-STORAGE SECTION. Neste caso particular,
122 PRO G RA MA Ç ÃO CO B OL

a variável precedida de E (para EN) é a variável de entrada, as variáveis incidas com C (para CI e CR) são variáveis
usadas para a realização de algum cálculo e as variáveis com S (para SN, SI e SR) são variáveis de saída.
O laço definido entre as linhas 20 e 27 controla o cálculo e a apresentação dos elementos que compõem o visual de
uma tabuada.
Na linha 19 é definida a inicialização do contador da tabuada com valor como indica a instrução COMPUTE AC-CI = 1.
Na sequência a linha 20 possui a instrução PERFORM UNTIL AC-CI > 10 que verifica a condição estabelecida, encer-
rando o laço quando o valor de AC-CI for maior que 10, isto significa dizer que enquanto o valor do contador é menor
ou igual a 10 o laço permanece em execução.
Dentro do laço entre as linhas 20 e 27 é realizado o cálculo da operação WS-CR = WS-EN * AC-CI com o comando
COMPUTE e posterior apresentação de cada valor de forma tabulada na linha 25. Quando o programa encontra a linha
com a instrução AC-CI = AC-CI + 1 na linha 26, efetua o acréscimo de uma unidade à variável contador. No primeiro
momento de execução a variável AC-CI possui o valor 1 e, somado a mais 1, passa a ter o valor 2.
Após a variável AC-CI estar carregada com o valor 2 na execução do programa volta para a instrução da linha 20, que
verifica a condição da variável novamente. Sendo a condição verdadeira, o bloco de código existente entre as linhas 21
e 26 será executado, mais uma vez. Quando o processamento do programa chegar em WS-CR = WS-EN * AC-CI, fará
com que a variável AC-CI passe a ter valor 3. O programa vai processar novamente a rotina de instruções, passando o
contador para 4, e assim por diante até chegar ao valor 11, quando o laço será automaticamente encerrado.

FATORIAL COM LAÇO CONDICIONAL PRÉ-TESTE


Elaborar programa de computador que efetue os cálculos e apresente os resultados das fatoriais de 0 a 19.
Para este programa é usada a máscara 99 para a variável WS-EN (entrada do valor no laço) e WS-CI (contagem do
laço, além dessas variáveis a variável WS-CFAT (cálculo da fatorial) usa a opção de compactação COMP ajustada para
18 dígitos. Para a saída dos dados são definidas as variáveis AC-SI com máscara Z9 e WS-SFAT com máscara Z(18).
Selecione e defina um projeto do programa vazio com o nome c03ex06.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX06 AS "Capitulo 3 – Exemplo 6".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-EN PIC 99.
7 77 AC-CI PIC 99.
8 77 AC-CFAT PIC 9(18) COMP.
9 77 AC-SI PIC Z9.
10 77 AC-SFAT PIC Z(18).
11 77 WS-ENTER PIC X.
12 *
13 PROCEDURE DIVISION.
14 PROG-PRINCIPAL-PARA.
15 MOVE 19 TO WS-EN
16 MOVE 1 TO AC-CFAT
17 MOVE 0 TO AC-CI
18 PERFORM UNTIL AC-CI GREATER THAN WS-EN
19 MOVE AC-CI TO AC-SI
20 MOVE AC-CFAT TO AC-SFAT
21 DISPLAY AC-SI "! = " AC-SFAT
22 ADD 1 TO AC-CI
------ ------------------------------------------------------------------------
AÇ ÃO IN / CO ND I CI O NAL 123

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
23 COMPUTE AC-CFAT = AC-CFAT * AC-CI
24 END-PERFORM.
25 DISPLAY X"0D".
26 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
27 ACCEPT WS-ENTER.
28 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Note que ao se executado são apresentados os
resultados das fatoriais de 0 a 19.
O programa não apresenta novidades em relação aos recursos já abordados, mas faz uso de algumas opções interes-
santes como a definição da opção de compactação COMP na linha 8 para dar a variável AC-CFAT a capacidade de
operar no limite máximo permitido na linguagem.
Entre as linhas 15 e 17 são realizadas as inicializações das variáveis a serem usadas no programa, por serem variáveis
numéricas todas poderiam ter sido inicializadas com o uso do comando COMPUTE.
Outro ponto a ser observado é o uso do operador lógico descritivo GREATER THAN na linha 18 em substituição ao uso
do operador relacional maior que e o acréscimo de uma unidade na variável AC-CI com uso do verbo ADD na linha 22.

TABUADA COM LAÇO CONDICIONAL PÓS-TESTE


Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados
da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de
aritmética, mas operando com estrutura de laço pós-teste.
Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e
para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de
resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-
cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste
caso serão usadas Z9 e ZZ9.
Selecione e defina um projeto do programa vazio com o nome c03ex07.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX07 AS "Capitulo 3 – Exemplo 7".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 *
7 77 WS-EN PIC 9(2).
8 77 AC-CI PIC 9(2).
9 77 WS-CR PIC 9(3).
10 77 WS-SN PIC Z9.
11 77 AC-SI PIC Z9.
12 77 WS-SR PIC ZZ9.
13 77 WS-ENTER PIC X.
14 *
------ ------------------------------------------------------------------------
124 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
15 PROCEDURE DIVISION.
16 PROG-PRINCIPAL-PARA.
17 DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING.
18 ACCEPT WS-EN.
19 COMPUTE AC-CI = 1.
20 PERFORM WITH TEST AFTER UNTIL AC-CI > 10
21 COMPUTE WS-CR = WS-EN * AC-CI
22 MOVE WS-EN TO WS-SN
23 MOVE AC-CI TO AC-SI
24 MOVE WS-CR TO WS-SR
25 DISPLAY WS-SN " X " AC-SI " = " WS-SR
26 COMPUTE AC-CI = AC-CI + 1
27 END-PERFORM.
28 DISPLAY X"0D".
29 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
30 ACCEPT WS-ENTER.
31 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada
valores de 1 a 10.
O programa c03ex07 é idêntico ao programa c03ex05, tendo como diferença o trecho WITH TEST AFTER usado na
linha 20 junto a instrução PERFORM.

TABUADA COM LAÇO ITERATIVO


Elaborar programa de computador que efetue a leitura de um valor numérico inteiro positivo e apresente os resultados
da tabuada do valor fornecido entre 1 e 10, respeitando a formatação típica de uma tabuada apresentada no estudo de
aritmética, mas operando com estrutura de laço iterativo.
Para o desenvolvimento deste programa é considerada o uso da máscara 9(2) para a entrada do valor de tabuada e
para o valor da variável de controle do laço que serão operados com posições de unidade e dezena. Para a variável de
resposta considere a máscara 9(3) para acomodar unidade, dezena e centena. Além das variáveis de entrada e pro-
cessamento do programa é preciso preparar as variáveis de máscaras editadas para a apresentação dos dados. Neste
caso serão usadas Z9 e ZZ9.
Selecione e defina um projeto do programa vazio com o nome c03ex08.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX08 AS "Capitulo 3 – Exemplo 8".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 *
7 77 WS-EN PIC 9(2).
8 77 AC-CI PIC 9(2).
9 77 WS-CR PIC 9(3).
------ ------------------------------------------------------------------------
AÇ ÃO IN / CO ND I CI O NAL 125

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
10 77 WS-SN PIC Z9.
11 77 AC-SI PIC Z9.
12 77 WS-SR PIC ZZ9.
13 77 WS-ENTER PIC X.
14 *
15 PROCEDURE DIVISION.
16 PROG-PRINCIPAL-PARA.
17 DISPLAY "Entre o valor da tabuada: " WITH NO ADVANCING.
18 ACCEPT WS-EN.
19 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10
20 COMPUTE WS-CR = WS-EN * AC-CI
21 MOVE WS-EN TO WS-SN
22 MOVE AC-CI TO AC-SI
23 MOVE WS-CR TO WS-SR
24 DISPLAY WS-SN " X " AC-SI " = " WS-SR
25 END-PERFORM.
26 DISPLAY X"0D".
27 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
28 ACCEPT WS-ENTER.
29 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça para a tabuada
valores de 1 a 10.
Este programa é semelhante ao demais que exemplificam o processamento de uma tabuada, tendo como diferencial a
definição do laço na linha 19 que conta de 1 até 10 de 1 em 1, a partir da indicação VARYING AC-CI FROM 1 BY 1 na
frase do FERMORM e UNTIL.
Quando executado o programa, o conjunto de instruções situado dentro do laço delimitado entre as linhas 19 e 25 é
executado dez vezes, pois a variável AC-CI (variável de controle) é inicializada com valor 1 na linha 19 com a indicação
FROM 1, que é incrementada com 1 quando passa por BY 1 até ultrapassar 10 quando verificado UNTIL AC-CI > 10.

DECREMENTO DE VALORES COM LAÇO ITERATIVO


Elaborar programa de computador que apresente no monitor de vídeo os valores inteiros de 10 a 1, a partir do uso de
laço iterativo.
Para o desenvolvimento deste programa é considerada o uso da máscara 99 para a variável que controla a contagem
decrescente.
Selecione e defina um projeto do programa vazio com o nome c03ex09.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX09 AS "Capitulo 3 – Exemplo 9".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 AC-CI PIC 99.
------ ------------------------------------------------------------------------
126 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
7 77 AC-SI PIC Z9.
8 77 WS-ENTER PIC X.
9 *
10 PROCEDURE DIVISION.
11 PROG-PRINCIPAL-PARA.
12 PERFORM VARYING AC-CI FROM 10 BY -1 UNTIL AC-CI < 1
13 MOVE AC-CI TO AC-SI
14 DISPLAY AC-SI
15 END-PERFORM.
16 DISPLAY X"0D".
17 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
18 ACCEPT WS-ENTER.
19 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e veja a apresentação de
valores decrescentes de 10 até 1.
Para realizar ações de contagem decrescente basta iniciar a variável contadora com o maior e solicitar a subtração
sucessiva do passo sobre o valor até este ser menor que o limite desejado.

PORCENTAGEM DE VALORES PARES E IMPARES


Elaborar programa de computador que efetue a entrada de dez valores numéricos inteiros e apresente após as entra-
das a quantidade de valores pares e impares informados, bem como o percentual de cada categoria numérica.
Para o desenvolvimento deste pequeno programa é necessário considerar o uso de certa quantidade de variáveis. A
entrada dos valores será processada por uma variável com máscara 9(4) para garantir a entrada de valores com o
formato de unidade, dezena, centena e unidade de milhar. Para contar a quantidade de pares e impares suas variáveis
terão a máscara 9(2) uma vez que são contadas apenas dez entradas. A detecção de pares e impares é realizada pelo
resto da divisão de um valor por 2, neste caso esta variável terá a máscara 99 (mas poderia ser sem problemas usada a
máscara 9). Para medir o percentual de valores fornecidos usar-se-á a máscara 9(3)V99. Para auxiliar a apresentação
dos dados do programa são definidas variáveis como campos de edição compatíveis com as formatações das variáveis
usadas para a entrada dos dados.
Selecione e defina um projeto do programa vazio com o nome c03ex10.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX10 AS "Capitulo 3 – Exemplo 10".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 *
9 DATA DIVISION.
10 WORKING-STORAGE SECTION.
11 77 WS-VALOR PIC 9(4).
------ ------------------------------------------------------------------------
AÇ ÃO IN / CO ND I CI O NAL 127

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
12 77 WS-PARES PIC 9(2).
13 77 WS-IMPARES PIC 9(2).
14 77 WS-RESTO PIC 99.
15 77 WS-PERCT-P PIC 9(3)V99 VALUE ZERO.
16 77 WS-PERCT-I PIC 9(3)V99 VALUE ZERO.
17 77 AC-CI PIC 99.
18 77 WS-SPAR PIC Z9.
19 77 AC-SIMP PIC Z9.
20 77 AC-SI PIC Z9.
21 77 WS-PORCENT PIC ZZ9.99.
22 77 WS-ENTER PIC X.
23 *
24 PROCEDURE DIVISION.
25 PROG-PRINCIPAL-PARA.
26 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10
27 MOVE AC-CI TO AC-SI
28 DISPLAY "Entre o " AC-SI "o. valor: " WITH NO ADVANCING
29 ACCEPT WS-VALOR
30 COMPUTE WS-RESTO = WS-VALOR - 2 * INTEGER(WS-VALOR / 2)
32 IF WS-RESTO = 0
32 ADD 1 TO WS-PARES
33 ELSE
34 ADD 1 TO WS-IMPARES
35 END-IF
36 END-PERFORM.
37 COMPUTE WS-PERCT-P = (WS-PARES / (AC-CI - 1)) * 100.
38 COMPUTE WS-PERCT-I = (WS-IMPARES / (AC-CI - 1)) * 100.
39 DISPLAY X"0D".
40 MOVE WS-PARES TO WS-SPAR.
41 DISPLAY "Quantidade de valores pares .....: " WS-SPAR.
42 MOVE WS-IMPARES TO AC-SIMP.
43 DISPLAY "Quantidade de valores impares ...: " AC-SIMP.
44 DISPLAY X"0D".
45 MOVE WS-PERCT-P TO WS-PORCENT.
46 DISPLAY "Valores pares ...................: " WS-PORCENT "%".
47 MOVE WS-PERCT-I TO WS-PORCENT.
48 DISPLAY "Valores impares .................: " WS-PORCENT "%".
49 DISPLAY X"0D".
50 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
51 ACCEPT WS-ENTER.
52 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça os 10 valores
solicitados e acompanhe os resultados apresentados.
Este programa apresenta uma série de recursos integrando-os de forma mais expressiva em relçao aos programas os
anteriores. Observe, principalmente, a lista de definições de variáveis entre as linhas 11 e 22. Veja os detalhes apresen-
tados. As variáveis que auxiliam a entrada de dados e os processamentos estão entre as linhas 11 e 17; as variáveis de
saída estão entre as linhas 18 e 21.
Na linha 28 está sendo usado um estilo de tela que apresenta os valores de entrada na forma ordinal para indicar a
entrada da linha 29. A cada valor estrado a linha 30 calcula o resto da divisão do valor fornecido por 2 e se o resto da
divisão for igual a zero, como mostra a linha 31 será adicionada uma unidade para a contagem de valores pares infor-
128 PRO G RA MA Ç ÃO CO B OL

mados como mostra a linha 33, sendo a condição da linha 31 falsa o processamento passa para a linha 33 que adiciona
uma unidade ao contador de impares informados.
Completado o ciclo de dez entradas o programa calcula nas linhas 37 e 38 os percentuais de valores informados. Ob-
serve junto as fórmulas a indicação AC-CI – 1 que tem por finalidade dizer a quantidade total de valores informados. A
variável AC-CI quando sai do laço possui um valor maior que a quantidade de vezes que executou o laço de acordo
com a ocorrência do valor de passo, estabelecido com BY na linha 26. Usar AC-CI – 1 é vantajoso no sentido de tornar
mais fácil aumentar o número de entradas no laço da linha 26.
As linhas de 39 a 48 são usadas pelo programa para efetivar a apresentação dos dados do programa.

TABUADA ITERATIVA EM LAÇO INTERATIVO INDETERMINADO


Elaborar programa de computador que efetue e apresente a tabuada de um valor numérico inteiro qualquer entre 1 e 10
baseando-se na forma tradicional de apresentação de uma tabuada. O programa deve após a entrada de algum valor
verificar se o conteúdo fornecido é numérico e caso não seja um número deve apresentar mensagem informando para
que seja fornecido apenas valores numéricos. Se o valor fornecido for numérico o programa deve verificar se é um valor
entre a faixa de 1 a 10 e não sendo deve apresentar mensagem informando para respeitar a faixa de trabalho do pro-
grama. Estando a entrada adequada ao contexto do programa a tabuada deverá ser apresentada. Após a apresentação
da tabuada o programa deve perguntar ao usuário se deseja novo cálculo, o qual poderá responder “S” para sim ou “N”
para não. Qualquer resposta diferente de “S” ou “N” deve ser recusada e deve ser apresentada mensagem informando
para responder apenas “S” ou “N”.
Para o desenvolvimento deste programa é usado grande parte dos recursos apresentados. São usadas decisões (sim-
ples e compostas) e laços (iterativo, seletivo, interativo pré-teste e interativo pós-pós-teste) definidos de forma encade-
ada e sequencial. São aplicados os usados dos operadores lógicos e relacionais. Comentários em vermelho.
Selecione e defina um projeto do programa vazio com o nome c03ex11.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX11 AS "Capitulo 3 – Exemplo 11".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 *
9 DATA DIVISION.
10 WORKING-STORAGE SECTION.
11 * Variaveis de entrada e processamento de dados.
12 77 WS-EN-TEXTO PIC XX.
13 77 WS-EN-NUMER PIC 9(2).
14 77 AC-CI PIC 99.
15 77 WS-CR PIC 9(3).
16 * Variaveis de saida de dados.
17 77 WS-SN PIC Z9.
18 77 AC-SI PIC Z9.
19 77 WS-SR PIC ZZ9.
20 * Variaveis de interacao.
21 77 WS-RESP PIC A.
22 77 WS-ENTER PIC X.
23 * Definicao de constante para salto de linha.
24 78 CR VALUE X"0D".
------ ------------------------------------------------------------------------
AÇ ÃO IN / CO ND I CI O NAL 129

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
25 *
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 DISPLAY "=============================="
29 DISPLAY "| PROGRAMA TABUADA |"
30 DISPLAY "| Entre valores entre 1 e 10 |"
31 DISPLAY "=============================="
32 DISPLAY CR.
33 MOVE "S" TO WS-RESP.
34 PERFORM UNTIL UPPER-CASE(WS-RESP) NOT = "S"
35 PERFORM UNTIL EXIT
36 DISPLAY "Entre valor: " WITH NO ADVANCING
37 ACCEPT WS-EN-TEXTO
38 IF WS-EN-TEXTO IS ALPHABETIC
39 DISPLAY "Por favor, entre valor numerico."
40 ELSE
41 MOVE WS-EN-TEXTO TO WS-EN-NUMER
42 IF WS-EN-NUMER >= 1 AND WS-EN-NUMER <= 10
43 EXIT PERFORM
44 END-IF
45 IF WS-EN-NUMER < 1 OR WS-EN-NUMER > 10
46 DISPLAY "Por favor, valores entre 1 e 10."
47 END-IF
48 END-IF
49 DISPLAY CR
50 END-PERFORM
51 DISPLAY CR
52 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10
53 COMPUTE WS-CR = WS-EN-NUMER * AC-CI
54 MOVE WS-EN-NUMER TO WS-SN
55 MOVE AC-CI TO AC-SI
56 MOVE WS-CR TO WS-SR
57 DISPLAY WS-SN " X " AC-SI " = " WS-SR
58 END-PERFORM
59 DISPLAY CR
60 PERFORM WITH TEST AFTER UNTIL UPPER-CASE(WS-RESP) = "S" OR
61 UPPER-CASE(WS-RESP) = "N"
62 DISPLAY "Continua (S/N): " WITH NO ADVANCING
63 ACCEPT WS-RESP
64 IF UPPER-CASE(WS-RESP) NOT = "S" AND
65 UPPER-CASE(WS-RESP) NOT = "N"
66 DISPLAY 'Entrada invalida! Entre apenas "S" ou "N".'
67 END-IF
68 DISPLAY CR
69 END-PERFORM
70 END-PERFORM.
71 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
72 ACCEPT WS-ENTER.
73 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa forneça inicialmente uma
letra e veja o que acontece. Depois forneça valores maiores que 10 e menores que 1 e veja o que acontece. Após a
apresentação da tabuada responda algo diferente de “S” ou “N” e veja o que acontece.
130 PRO G RA MA Ç ÃO CO B OL

O programa possui quatro áreas bem distintas, sendo: definição de variáveis e constante entre as linhas 11 e 24; trecho
de entrada de dados e validação entre as linhas 35 e 50; o trecho de processamento da tabuada e sua apresentação
entre as linhas 52 e 58 e por último o trecho de continuidade ou não do programa entre as linhas 60 e 69. Das quatro
áreas, três são controladas pelo laço definido entre a linhas 33 e 60.
Entre as linhas 12 e 15 são definidas as variáveis de entrada e processamento de dado do programa. As variáveis para
a saída são definidas entre as linhas 17 e 19. Nas linhas 21 e 22 são definidas as variáveis de interação do programa.
Na linha 24 é definida a constante usada para pular linhas em branco ao longo do programa.
Nas linhas 28 a 32 é definido um pequeno rótulo de título avisando ao usuário do que se trata o programa (linha 29) e a
regra de operação do programa (linha 30). Este é um efeito decorativo e informativo do programa.
A linha 33 atribuí o valor “S” para inicialização da variável WS-RESP usada no laço pré-teste com fluxo verdadeiro defi-
nido na linha 34 e encerrado na linha 70. Este laço diz ao programa que executará seu bloco de instruções enquanto a
resposta do usuário seja sim (S) indicada entre as linhas 60 e 69. No momento em que o usuário responder não (N) o
fluxo de execução do programa é desviado para a linha 71 que faz a apresentação da mensagem de saída do progra-
ma antes de seu encerramento.
O controle e validação da entrada do valor para o cálculo da tabuada é realizado nos trechos entre as linhas 35 e 50 a
partir de um laço do tipo seletivo, cujo controle de saída encontra-se definido nas linhas de 42 a 44, a qual verifica se o
valor fornecido está na faixa de aceitação.
Após a entrada de dados realizada a partir das linhas 36 e 37, a linha 38 verifica se ocorreu a entrada de algum carac-
tere alfabético e se isso ocorreu a mensagem de erro da linha 39 é apresentada informando que deve ser fornecido um
valor numérico. Se a entrada ocorreu de forma adequada o fluxo de execução do programa é desviado para a linha 41
que movimenta o dado entrado como alfanumérico (variável WS-EN-TEXTO) para o campo numérico (variável WS-EN-
NUMER). Observe que o trecho das 38 a 48 utilizam a técnica de tomada de decisão encadeada com decisões se-
quenciais após a linha 40.
Entre as linhas 42 e 44 é verificado se o valor numérico validado está na faixa de aceitação, sem sim a linha 43 é exe-
cutada e o processamento do programa é retirado do laço seletivo definido entre as linhas de 35 a 50. No entanto, se
esta condição for falsa o processamento continuará no laço e solicitará a repetição da entrada de um novo valor, mas
antes confirmará se o valor é fora da faixa como indicado na linha 45 e sendo apresenta a mensagem da linha 46, re-
tornando a ação para a linha 36. Este laço permanece4rá indeterminadamente em execução até que o usuário entre um
valor que seja válido.
Após o controle de aceitação de um valor correto o programa executa entre as linhas 52 e 58 o cálculo da tabuada e
sua apresentação dentro do estilo tradicional efetuado pela linha 57. A linha 53 efetiva o cálculo da tabuada e as linhas
de 54 a 56 preparam as variáveis de saída como campos de edição para a apresentação realizada na linha 57. Neste
trecho é usado um laço iterativo.
Concluída a apresentação da tabuada é realizado o tratamento das opções de continuidade ou não do programa usan-
do um laço pós-teste com fluxo verdadeiro entre as linhas 60 e 69. A resposta fornecida a partir da linha 63 é validada
com a tomada de decisão definida entre as linhas 64 e 67 quando verifica se a resposta fornecida é diferente de “S” ou
de “N”. Qualquer resposta diferente das possíveis de aceitação faz com que o fluxo de processamento do programa
seja retornado a linha 62 para que nova tentativa seja executada. Nesta etapa se a resposta fornecida como “S” faz
com que o fluxo de processamento seja retornado a linha 35, mantendo-se o fluxo de nova apresentação de tabuada.
Há um detalhe na linha 66 que é o uso de aspas simples para a apresentação da mensagem 'Entrada invalida! Entre
apenas "S" ou "N".'. A linguagem COBOL aceita as duas formas de definição de cadeias de caracteres aspas simples
e aspas inglesas. Normalmente aspas inglesas é a forma oficialmente usada e neste exemplo foi usada as aspas sim-
ples por se desejar escrever na tela as sinalizações de sim (S) e não (N) entre aspas inglesas.
Apesar de conhecida, vale lembrar o uso da instrução DISPLAY CR nas linhas 32, 49, 51, 59 e 68 que efetuam o avan-
ço de uma linha em branco na tela. Para este efeito é usada a constante definida na linha 25 que determina o uso códi-
go ASCII da tecla <Enter> com o valor numérico hexadecimal 0D, ou seja, o valor decimal 13.
Outro ponto a ser observado é que se ocorrer a entrada de algum valor numérico decimal para a variável WS-EN-
TEXTO utilizando-se ponto não há com que se preocupar, pois o símbolo ponto e o restante do valor é automaticamen-
te eliminado sendo considerada apenas a parte inteira do valor fornecido. O que comanda o estilo numérico da entrada
AÇ ÃO IN / CO ND I CI O NAL 131

é o formato estabelecido para a variável WS-EN-TEXTO no comando PICTURE da linha 13 sinalizado como 9(2) que
determina a aceitação apenas de valores inteiros.
Em linhas gerais o programa utilizou quase todos os recursos apresentados neste capítulo, demonstrando algumas
técnicas de programação importantes como a validação da entrada de dados de um usuário impedindo que o programa
avance com a ocorrência de erro.

FATORIAL DE UM VALOR NUMÉRICO INTEIRO QUALQUER


Elaborar programa de computador que efetue a entrada de um valor numérico inteiro entre 1 e 19 e apresente o resul-
tado da fatorial do número fornecido.
Para o desenvolvimento deste programa são usados recursos diferentes do anterior. Neste programa a multiplicação é
realizada de forma descritiva utilizando um recurso do verbo MULTIPLY ainda não apresentado. Veja então o programa
e seus detalhes.
Selecione e defina um projeto do programa vazio com o nome c03ex12.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C03EX06 AS "Capitulo 3 – Exemplo 12".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-EN PIC 99.
7 77 AC-CI PIC 99.
8 77 AC-CFAT PIC 9(18) COMP.
9 77 AC-SI PIC Z9.
10 77 AC-SFAT PIC Z(18).
11 77 WS-ENTER PIC X.
12 *
13 PROCEDURE DIVISION.
14 PROG-PRINCIPAL-PARA.
15 MOVE 1 TO AC-CFAT
16 DISPLAY "Entre valor entre 1 e 19: " WITH NO ADVANCING.
17 ACCEPT WS-EN.
18 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-EN
19 MULTIPLY AC-CI BY AC-CFAT ON SIZE ERROR
20 DISPLAY "Erro, o valor informado e' muito grande - "
21 WITH NO ADVANCING
22 END-PERFORM.
23 SUBTRACT 1 FROM AC-CI.
24 MOVE AC-CI TO AC-SI.
25 MOVE AC-CFAT TO AC-SFAT.
26 DISPLAY FUNCTION TRIM(AC-SI) "! = " FUNCTION TRIM(AC-SFAT)
27 DISPLAY X"0D".
28 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
29 ACCEPT WS-ENTER.
30 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Execute o programa e forneça de imediato um
valor maior que 19 e veja a mensagem de erro apresentada indicando o estouro do cálculo.
132 PRO G RA MA Ç ÃO CO B OL

Neste programa há dois novos detalhes, não apresentados anteriormente: um é a frase ON SIZE ERROR definida na
linha 19 e a função TRIM indicada na linha 26.
A frase ON SIZE ERROR é encontrada junto aos recursos ADD, SUBTRACT, MULTIPLY, DIVIDE e COMPUTE, tendo
por finalidade habilitar a emissão de mensagem quando ocorre estouro na capacidade numérica de valores decimais,
de ponto flutuante e binários. Quando ON SIZE ERROR é omitido as mensagens de estouro para valores binários e
decimais não são emitidas e as mensagens de estouro de ponto flutuante são ignoradas.
A função TRIM tem a capacidade de retornar uma nova sequência de caracteres com base no conteúdo passado, re-
movendo os espaços em branco existentes nas extremidades da cadeia. A função TRIM pode ser usada a partir das
formas:

DISPLAY "|" ' X ' "|". – mostra: | X | - com espaços


DISPLAY "|" FUNCTION TRIM(' X ') "|". – mostra: |X| - sem espaços
DISPLAY "|" FUNCTION TRIM(' X ' LEADING) "|". – mostra: |X | - sem espaços (esq.)
DISPLAY "|" FUNCTION TRIM(' X ' TRAILING) "|". – mostra: | X| - sem espaços (dir.)

Para auxiliar as ações da função TRIM é possível fazer uso dos modificadores LEADING (remoção de espaços à es-
querda) e TRAILING (remoção de espaços à direita). O uso da função sem os modificadores remove os espaços exis-
tentes tanto do lado esquerdo quanto do lado Direito.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 133

4
PROCESSAMENTO COM COLEÇÕES DE DA-
DOS

Uma variável simples de certo tipo ocupa um bloco de memória onde seu valor será armazenado, enquanto
uma variável composta ocupa um conjunto de blocos do tipo definido. Neste capítulo são apresentados o uso
de agrupamento de dados em forma de coleções de dados, na forma de lista e tabelas a partir de estruturas
de dados estáticas e dinâmicas.

4.1 COLEÇÃO DE DADOS


Nos capítulos anteriores foram desenvolvidos programas que utilizaram variáveis simples. Uma variável simples arma-
zena um só valor em seu escopo. No entanto, há situações em que é necessário armazenar mais de um valor de forma
contígua na memória principal, sendo esta coleção de valores representada por uma mesma variável, neste caso, com-
posta.
Uma variável composta caracteriza- se por ser uma coleção de dados que tem por finalidade armazenar em seu escopo
certa quantidade de elementos dispostos contiguamente na memória. A coleção é uma estrutura de dados que possui
certa dimensão para armazenar em seus slots (posição de armazenamento) os valores a ela atribuído. Normalmente se
chama de elemento o conteúdo de uma variável composta e de valor o conteúdo de uma variável simples.
A dimensão máxima permitida em COBOL é sete. Na prática cotidiana é muito raro ter que trabalhar acima de três
dimensões, existindo outras técnicas de programação para acomodar necessidades acima disto. As coleções de dados
são por vezes referenciadas como: matrizes, arranjos (arrays), tabelas, vetores, listas, variáveis indexadas, variáveis
dimensionadas ou como já indicado variáveis compostas. Nesta obra serão usados os termos lista para as coleções de
dados de uma dimensão e tabela para as coleções de dados que usarem mais de uma dimensão, apesar dessas estru-
turas serem chamada genericamente, em COBOL, de tabelas.
A definição de coleções de dados é realizada na DATA DIVISION dentro de um item de grupo (código de item 01) que
determina o nome da coleção. Dentro do item de grupo deve ser definido um item elementar numerado entre 02 e 49
que será a primeira dimensão da coleção. A partir da primeira dimensão pode-se abaixo dela definir um subitem para
criar a segunda dimensão e assim sucessivamente até atingir a quantidade permitida de dimensões.
De forma geral, não importando o tipo de coleção de dados em uso, seja uma lista ou uma tabela, sua definição pode
ser realizada no GnuCOBOL em todas as seções pertencentes a DATA DIVISION. No entanto, pode ocorrer de certa
forma escrita em uma determinada seção ser um pouco diferente da forma escrita para outra seção. Para a definição de
uma coleção de dados usa-se a cláusula OCCURS e seus complementos, desde que não se use em conjunto na mes-
ma variável a cláusula VALUES. A cláusula OCCURS possui, como forma geral, a estrutura sintática:

OCCURS <número1> [TO <número2>] [TIMES]


[DEPENDING [ON] <[identificador1]>]
[ASCENDING | DESCENDING [KEY] [IS] <[identificador2]> ...] ...
[INDEXED [BY] <identificador3]> ...]
134 PRO G RA MA Ç ÃO CO B OL

As palavras chave BY da frase INDEXED BY, IS, KEY, ON e TIMES são opcionais e podem ser a critério do profissio-
nal de desenvolvimento omitidas. No entanto, por questões de legibilidade é adequado mantê-las. Mas é uma decisão
de cunho pessoal.
O parâmetro número1 é usado para definir o tamanho de elementos que a tabela terá ou especificar o valor do primeiro
elemento da tabela quando o parâmetro número2 é usado após TO e com. DEPENDING ON
Na especificação de uma coleção de dados cada elemento ocupará na memória uma quantidade fixa de bytes, a menos
quando se usa DEPENDING ON que permite criar áreas de armazenamento (slots) com tamanho variável.
Quando usado ASCENDING KEY IS e DESCENDING KEY IS tem-se a capacidade de definir a ordem de organização
interna dos elementos nas tabelas para uso exclusivo do comando SEARCH ALL.
Quando usado INDEXED BY permite que se possa acessar aos elementos de uma tabela via índice especificado na
forma de variáveis especiais definidas junto ao parâmetro identificador3. Um índice é uma forma de deslocamento de
elementos a partir do início da tabela. Esta cláusula é indicada para uso com o comando SEARCH

4.2 ESTRUTURAS DE DADOS


Uma estrutura de dados se caracteriza por ser uma coleção finita de dados, onde se conhece de antemão o número de
elementos que a estrutura terá. Assim sendo, é possível criar coleções fechadas (internas) e/ou abertas (externas) de
dados. São estruturas fechadas quando se define internamente no código os valores que a coleção conterá na forma de
constantes e abertas quando o usuário de forma interativa fornece os valores de preenchimento da estrutura em uso.

4.2.1 Manipulação de listas


Esse tipo de estrutura de dados é conhecido tipicamente como tabela de uma dimensão (lista) usada comumente na
criação de lista simples de dados. A lista usa uma variável como referência, tendo a ela associado determinado tama-
nho e pode armazenar mais de um elemento dentro do tamanho definido. O tamanho de uma lista é conhecido como
dimensão, constituída por constantes inteiras e positivas.
A definição de uma matriz unidimensional (lista) é declarada a partir da estrutura sintática:

01 <TB-[lista]>.
02 <lista-><LIN> PIC[TURE] <formato> OCCURS <número1> TIMES.

Onde, lista é o nome de identificação da estrutura na memória definido como item de grupo; LIN é um nome de refe-
rência genérico de acesso a posição do dado armazenado em cada linha da lista (as posições de armazenamento de
uma coleção de dados chamam-se slots), sendo definido como item elementar (podendo-se usar valores de 02 até 49);
formato é a definição do layout do dado a ser armazenado e número1 é a quantidade ordinal de elementos armazena-
dos na lista. Os elementos de uma lista serão sempre do mesmo tipo de dados de forma homogênea.
O qualificador TB e LIN indicados nos formatos TB-<lista> e <lista>-<LIN> são, como comentado, opcionais e servem
para auxiliar a referência interna, como documentação, de acesso aos dados da estrutura dentro do código de progra-
ma.
Considere, como exemplo a definição de uma lista de valores numéricos inteiros chamada “A” com a capacidade de
armazenar cinco elementos numéricos, a partir do formato numérico unidade, dezena e centena, na qual devem ser
informados pelo usuário os valores esperados. Na sequência os valores fornecidos devem ser apresentados.

DATA DIVISION.
WORKING-STORAGE SECTION.
* Definicao da tabela A de inteiros
01 TB-A.
* Definicao do slot (posicao na linha) de armazenamento de dados
02 A-LIN PIC 9(3) OCCURS 5 TIMES.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 135

* Variáveis de apoio
77 AC-LIN PIC 9.
77 WS-S-TB-A PIC Z(3).

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
* Trecho de entrada de dados
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5
DISPLAY "Entre " AC-LIN "o. elemento: " WITH NO ADVANCING
ACCEPT A-LIN(AC-LIN)
END-PERFORM.
DISPLAY X"0D".
* Trecho de saida de dados
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5
MOVE A-LIN(AC-LIN) TO WS-S-TB-A
DISPLAY "Elemento [" AC-LIN "] = " WS-S-TB-A
END-PERFORM.

Observe no trecho anterior a definição da tabela A com uma dimensão, tendo como nome de referência o rótulo TB-A e
a definição dos campos para acesso aos dados A-LIN configurado para 5 posições de armazenamento.
Para a leitura é estabelecido um laço iterativo controlado pela variável AC-LIN de 1 até 5. Nesta etapa, a ação executa-
da pelo comando ACCEPT que faz com que cada entrada controlada por AC-LIN seja colocada na lista TB-A por meio
da referência de A-LIN; para a saída é usado um laço nas mesmas definições do laço de entrada. Nesta etapa, cada
valor existente na tabela TB-A é movimentado do slot (A-LIN) para o campo editado WS-S-TB-A que é apresentado na
mesma ordem em que foram fornecidos.
O acesso individualizado realizado sobre uma tabela por meio de parênteses nas operações de entrada e saída, bem
como nas ações de processamento chama-se subscrição. Os valores subscritos podem variar de 1 até o limite estabe-
lecido na cláusula OCCURS.
Atente para o fato de ter sido definido um laço na entrada e outro laço completo na saída. Evite realizar as ações de
entrada e saída em só laço, a menos que seja essa a real intenção. A figura 4.1 mostra a estrutura de uma lista.

Tabela: TB-A

TB-A-LIN Slot 1

TB-A-LIN Slot 2

TB-A-LIN Slot 3

TB-A-LIN Slot 4

TB-A-LIN Slot 5

Figura 4.1 – Estrutura de uma lista

Considere, como exemplo a definição de uma lista de valores alfabéticos chamada “NOME” com a capacidade de ar-
mazenar cinco nomes de pessoas, na qual devem ser informados pelo usuário os valores esperados. Na sequência os
valores fornecidos devem ser apresentados.

DATA DIVISION.
WORKING-STORAGE SECTION.
136 PRO G RA MA Ç ÃO CO B OL

01 TB-NOME.
02 NOME-LIN PIC A(50) OCCURS 5 TIMES.
77 AC-LIN PIC 9.
77 WS-S-TB-NOME-LIN PIC Z(3).

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5
DISPLAY "Entre " AC-LIN "o. nome: " WITH NO ADVANCING
ACCEPT NOME-LIN(AC-LIN)
END-PERFORM.
DISPLAY X"0D".
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 5
DISPLAY "Elemento [" AC-LIN "] = " NOME-LIN(AC-LIN)
END-PERFORM.

O trecho de código anterior efetua a leitura de cinco nomes e os apresenta. Comparando-se os dois últimos trechos vê-
se que são muito parecidos na ação lógica, mas possuem pequenos detalhes que fazem alguma diferença. Note que
para o uso de entradas alfabéticas o código é mais suave que o trecho usado para a entrada de dados numéricos, que
exigem certo grau de tratamento quando precisam ser apresentados.

4.2.2 Manipulação de tabelas


Esse tipo de estrutura de dados é usado comumente na criação de tabela simples de dados. Uma tabela simples carac-
teriza-se em ser uma estrutura de dados que distribui seus elementos na forma de linhas e colunas (isso quando for
bidimensional). A tabela usa uma variável como referência, tendo a ela associado as posições de linhas e colunas,
podendo armazenar mais de um elemento dentro do tamanho definido. No entanto, as tabelas podem ser expressas
com mais de duas dimensões, estendendo-se até sete dimensões.
A definição de uma matriz multidimensional (tabela) de duas dimensões é declarada a partir da estrutura sintática:

01 <TB-[tabela]>.
02 <tabela-><COL> OCCURS <número1> TIMES
03 <tabela-><LIN> PIC[TURE] <formato> OCCURS <número1> TIMES.

Onde, tabela é o nome de identificação da estrutura na memória definido como item de grupo; COL (colunas) e LIN
(linhas) são referências genéricas de acesso ao dado armazenado em certa posição da tabela referenciando as posi-
ções de linha e coluna; formato é a definição do layout do dado a ser armazenado e as indicações número1 são a
quantidade ordinal de elementos armazenados na tabela a partir da quantidade estabelecida tanto para linhas, como
para colunas. A primeira dimensão poderá ser numerada com qualquer valor entre 02 e 49, a segunda dimensão pode-
rá usar qualquer valor entre 02 e 49, exceto o valor já usado na definição da primeira dimensão e assim por diante. Os
elementos de uma tabela poderão ser formados por dados de tipos diversos (heterogêneos).
Considere, como exemplo a definição de uma tabela de valores numéricos inteiros chamada “A” com a capacidade de
armazenar seis elementos numéricos disposto em três linhas e duas colunas, a partir do formato numérico unidade,
dezena e centena, na qual devem ser informados pelo usuário os valores esperados. Na sequência os valores forneci-
dos devem ser apresentados.

DATA DIVISION.
WORKING-STORAGE SECTION.
* Definicao da tabela A de inteiros
01 TB-A.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 137

* Definicao das colunas da tabela


02 A-COL OCCURS 3 TIMES.
* Definicao das linhas da tabela
03 A-LIN PIC 9(3) OCCURS 2 TIMES.
* Variáveis de apoio as operacoes do programa
77 AC-COL PIC 9.
77 AC-LIN PIC 9.
77 WS-S-TB-A PIC Z(3).

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 3
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 2
DISPLAY "Entre o elemento [" AC-COL "," AC-LIN "] = "
WITH NO ADVANCING
ACCEPT A-LIN(AC-COL, AC-LIN)
END-PERFORM
END-PERFORM.
DISPLAY X"0D".
PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 3
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 2
MOVE A-LIN(AC-COL, AC-LIN) TO WS-S-TB-A
DISPLAY "Elemento [" AC-COL "," AC-LIN "] = " WS-S-TB-A
END-PERFORM
END-PERFORM.

Observe no trecho anterior a definição da tabela A com duas dimensões, tendo como nome de referência o rótulo TB-A
e a definição dos slots para acesso aos dados na coluna A-COL e na linha A-LIN configurados, respectivamente para 3
e 2 como posições de armazenamento.
Atente para o fato de ter sido definido dois laços laço na entrada e saída de dados. O laço que usa AC-COL controla o
posicionamento nas colunas e o laço que usa AC-LIN controla o posicionamento nas linhas. A figura 4.2 mostra a estru-
tura da tabela bidimensional TB-A.

Tabela: TB-A

A-COL A-COL A-COL

A-LIN Slot 1,1 Slot 2,1 Slot 3,1

A-LIN Slot 1,2 Slot 2,2 Slot 3,2

Figura 4.2 – Estrutura de uma tabela

Tabelas de duas dimensões podem ser usadas na representação de dados heterogêneos onde cada coluna poderá ser
formada por um conjunto de dados diferentes entre si.
Considere como exemplo a definição de uma tabela que armazene os meses anuais na sua forma numérica e também
por extenso.
O trecho de programa a seguir gera automaticamente o número do mês na tabela, mas o valor por extenso deve ser
fornecido pelo usuário. Observe os detalhes de definição da tabela.
138 PRO G RA MA Ç ÃO CO B OL

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-MESES.
02 MESES-CONTEUDO OCCURS 12 TIMES.
03 MESES-NUM PIC 9(2).
03 MESES-EXT PIC A(9).

77 AC-LIN PIC 9(2).


77 WS-S-MES-NUM PIC Z(3).
77 WS-S-MES-EXT PIC A(9).

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 12
COMPUTE MESES-NUM(AC-LIN) = AC-LIN
MOVE MESES-NUM(AC-LIN) TO WS-S-MES-NUM
DISPLAY "Entre extenso do mes " WS-S-MES-NUM ": "
WITH NO ADVANCING
ACCEPT MESES-EXT(AC-LIN)
END-PERFORM.
DISPLAY X"0D".
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 12
MOVE MESES-NUM(AC-LIN) TO WS-S-MES-NUM
MOVE MESES-EXT(AC-LIN) TO WS-S-MES-EXT
DISPLAY WS-S-MES-NUM " - "
FUNCTION UPPER-CASE(WS-S-MES-EXT)
END-PERFORM.

Observe que na tabela TB-MESES é definida sua primeira dimensão como TB-MESES-CONTEUDO e dentro da pri-
meira dimensão são definidas duas colunas chamadas TB-MESES-NUM e TB-MESES-EXT que forma a segunda di-
mensão. Veja que cada coluna pode armazenar apenas os dados de seu tipo, ou seja, cada coluna é em si homogê-
nea, mas é possível combinar colunas de tipos de dados diferentes dentro de certa dimensão, tendo-se uma coleção de
dados heterogêneos.
A proposta define que as informações da coluna TB-MESES-NUM sejam geradas automaticamente. Neste sentido é
que ocorre o uso da instrução COMPUTE TB-MESES-NUM(AC-LIN) = AC-LIN, aproveitando o próprio valor da conta-
gem da variável AC-LIN como elemento de inserção do valor na posição da tabela. Os demais detalhes usados são já
conhecidos.
Para a definição de mais dimensões é necessário considerar sempre o uso de um laço a mais a cada dimensão dese-
jada. A título de ilustração considere a definição de uma coleção de dados que represente uma tabela multidimensional
com três dimensões a partir da sintaxe:

01 <TB-[tabela]>.
02 <tabela-><PAG> OCCURS <número1> TIMES
03 <tabela-><COL> OCCURS <número1> TIMES
04 <tabela-><LIN> PIC[TURE] <formato> OCCURS <número1> TIMES.

Uma tabela de três dimensões pode ser entendida como um conjunto de páginas (PAG), onde cada página possui uma
tabela de duas dimensões (colunas, COL e linhas, LIN).
Para exemplificar considere situação semelhante exposta no sítio http://www.pgrocer.net/Cis12/note23dm.html, aqui
adaptada, em que haja uma tabela indicando os custos de tarifas telefônicas de quatro cidades a partir de uma cidade
qualquer específica para as localidades de São Paulo, Rio de Janeiro, Minas Gerais e Goiás. A tabela em questão pre-
cisa informar os custos diferenciados da manhã, da tarde e da noite para ligações de telefone móvel para telefone mó-
vel (M >> M) ou fixo (M >> F) e de ligações de telefone fixo para telefone fixou (F >> F) ou móvel (F >> M). A figura 4.3
mostra a estrutura da tabela para as tarifas telefônicas.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 139

Período: Manha Período: Tarde Período: Noite


TB-TARIFA M >> M F >> F M >> M F >> F M >> M F >> F
M >> F F >> M M >> F F >> M M >> F F >> M
São Paulo 2,18 2,10 3,20 3,15 1,67 1,55
Rio de Janeiro 3,25 2,18 3,35 3,20 1,80 2,00
Minas Gerais 2,15 2,20 3,15 3,45 1,15 1,67
Goiás 2,20 2,30 3,25 3,28 1,20 1,98
Figura 4.3 – Tarifas telefônica com matriz tridimensional

A partir da estrutura tridimensional da tabela indicada na figura 4.3, considere como página o período manhã, tarde e
noite, como coluna a forma (status) de ligação M >> M / M >> F e F >> F / F >> M e linhas a indicação dos preços para
cada cidade. A partir dessa consideração basta considerar a sintaxe:

01 TB-TARIFA.
02 TARIFA-PERIODO-PAG OCCURS 3 TIMES
03 TARIFA-STATUS-COL OCCURS 2 TIMES
04 TARIFA-PRECO-LIN PIC 9V99 OCCURS 4 TIMES.

Para as operações de entrada, saída e eventualmente processamento para uso do estilo indicado na figura 1.3 serão
necessários três laços, seguindo a sintaxe:

PERFORM VARYING AC-PAG FROM 1 BY 1 UNTIL AC-PAG > 3


PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 2
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 4
<ação de entrada, processamento ou saída>
END-PERFORM
END-PERFORM
END-PERFORM.

Observe que na definição das coleções de dados a cláusula PICTURE é apenas indicada na definição das linhas de
qualquer tamanho de tabelas.

4.2.3 Listas e tabelas internas


Nos dois subtópicos anteriores foram representados o uso de coleções de dados externas, ou seja, listas e tabelas que
para serem usadas necessitam ser previamente preenchidas na etapa de entrada de dados, sendo uma ação útil no
uso de coleções de dados imediatas. No entanto, há situações em que as coleções de dados devem estar prontas em
memória na forma de estruturas fixas por serem definidas a partir de valores constantes e não necessitam, em absoluto,
serem previamente informados para uso dentro do programa.
A definição de coleções de dados internas é realizada em duas etapas. A primeira etapa refere-se à definição da rela-
ção dos dados constantes que na segunda etapa são vinculados a coleção de dados estabelecidos. O vinculo entre a
relação de dados constantes e a coleção de dados pode definido com a cláusula REDEFINES, dependendo do padrão
da linguagem COBOL em uso.
A cláusula REDEFINES é usada quando há a necessidade de representar certa variável, seja um item de grupo ou item
elementar, com dois ou mais layouts diferentes na DATA DIVISION. Este recurso não define uma nova área de memó-
ria e sim faz uso da área de memória já definida, auxiliando no controle do consumo de espaço interno das memórias
primária e secundária. No entanto, é fundamental atentar que quando se faz a redefinição de uma variável, não há entre
a variável original e a variável redefinida nenhuma relação de equivalência, elas apenas usam a mesma área de memó-
ria e neste sentido tanto o espaço original e redefinido devem possuir o mesmo layout de definição para seus tipos de
dados.
140 PRO G RA MA Ç ÃO CO B OL

Por exemplo, imagine um registro que armazene a data de calendário no formato 99/99/99, onde dia, mês e ano usam
dois dígitos. O padrão usado no Brasil para datas é DD/MM/AA, onde DD é o dia, MM é o mês e AA é o ano, mas há no
programa a necessidade de trabalhar a data no formato ANSI a partir da máscara AA/MM/DD. Observe no exemplo de
redefinição de datas os pontos colorizados:

DATA DIVISION.
WORKING-STORAGE SECTION.

01 WS-DATA-BRA.
02 DIA-BRA PIC 99.
02 MES-BRA PIC 99.
02 ANO-BRA PIC 99.

01 WS-DATA-ANS REDEFINES WS-DATA-BRA.


02 ANO-ANS PIC 99.
02 MES-ANS PIC 99.
02 DIA-ANS PIC 99.

Como comentado a redefinição de variáveis usa o mesmo espaço de memória. Desta forma, o registro WS-DATA-ANS
tem seu primeiro campo definido como WS-ANO-ANS e estando este redefinido a partir do registro WS-DATA-BRA usa
o mesmo espaço de memória destinado ao campo WS-DIA-BRA e por esta razão os campos redefinidos precisam
possui os mesmo formatos, sob risco de usarem os dados de forma inconsistente. Veja uma situação de inconsistência.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 WS-DATA-BRA.
02 DIA-BRA PIC 99.
02 MES-BRA PIC 99.
02 ANO-BRA PIC 9999.

01 WS-DATA-ANS REDEFINES WS-DATA-BRA.


02 ANO-ANS PIC 9999.
02 MES-ANS PIC 99.
02 DIA-ANS PIC 99.

Observe que no caso anterior ocorrerá perda de dados entre o campo WS-ANO-BRA de WS-DATA-BRA em relação
ao campo WS-DIA-ANS de WS-DATA-ANS pelo fato de usarem a mesma área de memória.
A partir da visão de uso da cláusula REDEFINES e orientações sobre suas restrições fica fácil criar coleções de dados
baseada em listas ou tabelas internas. Há duas formas básicas de definição de coleções de dados internas, uma clássi-
ca com uso da cláusula REDEFINES de forma explícita usada até o COBOL-74 e outra moderna, pós COBOL-74 sem o
uso da cláusula REDEFNIES de forma implícita, seguem como exemplos ambas as formas.
No formato clássico a definição de coleções internas de dados segue o estilo de codificação:

01 TB-<tab-interna>.
02 <lista-constante> PIC <formato> VALUE <valores>.
02 <campo> REDEFINES <lista-constante> OCCURS <número> TIMES PIC <formato>.

Onde, tab-interna é o nome de identificação da tabela interna na memória, lista-constante é o nome de referência
para a lista de valores definidos, formato é a definição dos formatos dos tipos de dados listados, valores é a relação de
valores constantes, campo é a definição da variável vinculada a tab-interna a ser usada para acessar os valores cons-
tantes indicados em valores redefinida explicitamente a partir da lista-constante e número se refere a quantidade de
valores existente na lista-constante.
Como exemplo de forma clássica com o uso de REDEFINES, considere uma tabela interna com os nomes abreviados
dos meses de calendário com uso explícito de redefinição de variáveis.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 141

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-MES-EXTENSO.
05 MESES-ABRV PIC X(36)
VALUE "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ".
05 MES REDEFINES MESES-ABRV OCCURS 12 TIMES PIC X(3).

77 AC-CI PIC 99.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12
DISPLAY MES(AC-CI)
END-PERFORM.

Observe a definição da tabela interna TB-MÊS-EXTENSO contendo como coleção de dados os nomes abreviados dos
meses "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ " associados ao campo MESES-ABRV redefinido expli-
citamente com MES REDEFINES MESES-ABRV a partir da máscara X(3) que dá acesso a cada três caracteres dentro
da lista de valores constantes definida com tamanho 13. Se multiplicar o valor 12 pelo valor de três caracteres da más-
cara da variável MES ter-se-á resultado 36 que corresponde a máscara X(36) definida para o campo MESES-ABRV.
Ao ser executado um programa com o trecho anterior os nomes dos meses abreviados serão apresentados de três em
três caracteres.
No formato moderno a definição de coleções internas de dados segue o estilo de codificação:

01 TB-<tab-interna> VALUE <valores>.


02 <campo> OCCURS <número> TIMES PIC <formato>.

Como exemplo de forma moderna sem o uso de REDEFINES, considere uma tabela interna com os nomes abreviados
dos meses de calendário com uso explícito de redefinição de variáveis.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-MES-EXTENSO VALUE "JANFEVMARABRMAIJUNJULAGOSETOUTNOVDEZ".


05 MES OCCURS 12 TIMES PIC X(3).

77 AC-CI PIC 99.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12
DISPLAY MES(AC-CI)
END-PERFORM.

Apesar da forma moderna ser popular é muito comum encontrar programas escritos ao estilo clássico. Um profissional
de desenvolvimento COBOL deve saber e dominar todas as formas existentes, pois a quantidade de programas escri-
tos na linguagem é expressiva.
Nos modelos anteriores de definição de coleção de dados internos foi usado um estilo em que todas as referências dos
nomes abreviados dos meses estão contidas em uma só cadeia de caracteres. Apesar de ser uma forma prática ela
pode tornar-se confusa se a coleção de dados interna for grande ou necessitar de definições de valores mais extensos
e de tamanhos variados. Neste sentido, pode-se definir coleções de dados descritivas.
A definição descritiva de dados é feita em uma tabela exclusiva separada da tabela que fará o acesso. Assim sendo,
serão duas tabelas a serem vinculadas, e neste caso o uso da cláusula REDEFINES é obrigatório.
142 PRO G RA MA Ç ÃO CO B OL

Para a definição de uma coleção de dados descritiva será usada a palavra FILLER que é uma forma de se fazer refe-
rência a determinado campo da coleção de forma anônima, uma vez que nomes particularizados não são necessários.
Como exemplo de definição de coleção descritiva, considere uma tabela interna com os nomes abreviados dos meses
de calendário com uso explícito de redefinição de variáveis.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-MES-EXTENSO.
02 FILLER PIC X(3) VALUE "JAN".
02 FILLER PIC X(3) VALUE "FEV".
02 FILLER PIC X(3) VALUE "MAR".
02 FILLER PIC X(3) VALUE "ABR".
02 FILLER PIC X(3) VALUE "MAI".
02 FILLER PIC X(3) VALUE "JUN".
02 FILLER PIC X(3) VALUE "JUL".
02 FILLER PIC X(3) VALUE "AGO".
02 FILLER PIC X(3) VALUE "SET".
02 FILLER PIC X(3) VALUE "OUT".
02 FILLER PIC X(3) VALUE "NOV".
02 FILLER PIC X(3) VALUE "DEZ".

01 MESES-ABRV REDEFINES TB-MES-EXTENSO.


02 MES OCCURS 12 TIMES PIC X(3).

77 AC-CI PIC 99.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12
DISPLAY MES(AC-CI)
END-PERFORM.

O resultado apresentado dos dois últimos trechos são os mesmos. A diferença fica a cargo da forma utilizada para a
apresentação da coleção de dados com os valores constantes.
As tabelas internas também podem ser referenciadas com elementos para multe dimensões. Considere tabela interna
com as indicações dos valores numéricos dos meses de calendário e seus respectivos nomes abreviados.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-MES-EXTENSO.
02 FILLER PIC X(5) VALUE "01JAN".
02 FILLER PIC X(5) VALUE "02FEV".
02 FILLER PIC X(5) VALUE "03MAR".
02 FILLER PIC X(5) VALUE "04ABR".
02 FILLER PIC X(5) VALUE "05MAI".
02 FILLER PIC X(5) VALUE "06JUN".
02 FILLER PIC X(5) VALUE "07JUL".
02 FILLER PIC X(5) VALUE "08AGO".
02 FILLER PIC X(5) VALUE "09SET".
02 FILLER PIC X(5) VALUE "10OUT".
02 FILLER PIC X(5) VALUE "11NOV".
02 FILLER PIC X(5) VALUE "12DEZ".

01 MESES-ABRV REDEFINES TB-MES-EXTENSO.


02 CONTEUDO OCCURS 12 TIMES.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 143

03 NUM PIC 9(2).


03 MES PIC A(3).

77 AC-CI PIC 99.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 12
DISPLAY NUM(AC-CI) " - " MES(AC-CI)
END-PERFORM.

Observe que no exemplo anterior os números dos meses e seus respetivos nomes abreviados são definidos dentro de
uma mesma cadeia. A separação dos conteúdos de cada elemento é realizada após a redefinição da tabela desmem-
brando os campos NUM com dois caracteres e MES com três caracteres.
Como exemplo de definição de coleção de dados constantes na forma multidimensional considere o último exemplo do
subtópico anterior em relação as definições das tarifas telefônicas e seus períodos de uso. Considere que cada valor da
tabela é um fator multiplicativo que pode ser usado para calcular o valor de referência a ser pago.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-VALORES.
02 TARIFA-MANHA.
03 MANHA-MM-E-MF.
04 PARA-SP PIC S9V99 VALUE 2.18.
04 PARA-RJ PIC S9V99 VALUE 3.25.
04 PARA-MG PIC S9V99 VALUE 2.15.
04 PARA-GO PIC S9V99 VALUE 2.20.
03 MANHA-FF-E-FM.
04 PARA-SP PIC S9V99 VALUE 2.10.
04 PARA-RJ PIC S9V99 VALUE 2.18.
04 PARA-MG PIC S9V99 VALUE 2.20.
04 PARA-GO PIC S9V99 VALUE 2.20.
02 TARIFA-TARDE.
03 TARDE-MM-E-MF.
04 PARA-SP PIC S9V99 VALUE 3.20.
04 PARA-RJ PIC S9V99 VALUE 3.35.
04 PARA-MG PIC S9V99 VALUE 3.15.
04 PARA-GO PIC S9V99 VALUE 3.25.
03 TARDE-FF-E-FM.
04 PARA-SP PIC S9V99 VALUE 3.15.
04 PARA-RJ PIC S9V99 VALUE 3.20.
04 PARA-MG PIC S9V99 VALUE 3.45.
04 PARA-GO PIC S9V99 VALUE 3.28.
02 TARIFA-NOITE.
03 NOITE-MM-E-MF.
04 PARA-SP PIC S9V99 VALUE 1.67.
04 PARA-RJ PIC S9V99 VALUE 1.80.
04 PARA-MG PIC S9V99 VALUE 1.15.
04 PARA-GO PIC S9V99 VALUE 1.20.
03 NOITE-FF-E-FM.
04 PARA-SP PIC S9V99 VALUE 1.55.
04 PARA-RJ PIC S9V99 VALUE 2.00.
04 PARA-MG PIC S9V99 VALUE 1.67.
04 PARA-GO PIC S9V99 VALUE 1.98.
144 PRO G RA MA Ç ÃO CO B OL

01 TB-TARIFA REDEFINES TB-VALORES.


02 PERIODO OCCURS 3 TIMES.
03 TIPO-LIGACAO OCCURS 2 TIMES.
04 COEFICIENTE-MULT PIC S9V99 OCCURS 4 TIMES.

77 AC-PAG PIC 9.
77 AC-COL PIC 9.
77 AC-LIN PIC 9.
77 WS-S-VALOR PIC 9.99.

Observe os detalhes usados na definição da coleção interna de valores com base na figura 1.3.
Veja a seguir um trecho de código apenas para apresentação dos dados definidos na coleção de dados como tabela
interna de três dimensões.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-PAG FROM 1 BY 1 UNTIL AC-PAG > 3
EVALUATE AC-PAG
WHEN 1 DISPLAY "Periodo: Manha"
WHEN 2 DISPLAY "Periodo: Tarde"
WHEN 3 DISPLAY "Periodo: Noite"
END-EVALUATE
PERFORM VARYING AC-COL FROM 1 BY 1 UNTIL AC-COL > 2
EVALUATE AC-COL
WHEN 1 DISPLAY "Movel para Movel ou para Fixo"
WHEN 2 DISPLAY "Fixo para Fixo ou Movel"
END-EVALUATE
PERFORM VARYING AC-LIN FROM 1 BY 1 UNTIL AC-LIN > 4
EVALUATE AC-LIN
WHEN 1 DISPLAY "SP = " WITH NO ADVANCING
WHEN 2 DISPLAY "RJ = " WITH NO ADVANCING
WHEN 3 DISPLAY "MG = " WITH NO ADVANCING
WHEN 4 DISPLAY "GO = " WITH NO ADVANCING
END-EVALUATE
MOVE COEFICIENTE-MULT(AC-PAG, AC-COL, AC-LIN)
TO WS-S-VALOR
DISPLAY "Valor: " WS-S-VALOR
END-PERFORM
END-PERFORM
DISPLAY X"0D"
END-PERFORM.

O uso de listas e/ou tabelas internas é uma forma interessante de estabelecer em um programa valores que ficam dis-
poníveis para uso imediato. Um cuidado a ser tomado é com a definição de tabelas muito grandes, pois podem com-
prometer o desempenho de um programa. Para esses casos é melhor trabalhar com dados gravados em memória se-
cundária na forma de arquivos (tema que será apresentado mais adiante nesta obra).

4.3 AÇÕES COMPLEMENTARES


A partir de uma visão geral sobre a concepção e uso básico de coleções de dados na forma de listas e tabelas, é inte-
ressante ver algumas operações que podem ser realizadas com esses tipos de variáveis. Neste sentido, são apresen-
tados recursos que facilitam o uso dessas estruturas de dados como ações de: inicialização, pesquisa, classificação e
aplicação com campos variáveis.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 145

4.3.1 Inicialização de variáveis


As variáveis simples (itens elementares) ou compostas (itens de grupos na forma de tabelas ou registros) usadas nos
programas podem ser inicializadas manualmente ou automaticamente com o uso de INITIALIZE. Quando se inicializa
um item de grupo todos os seus itens subordinados serão também inicializados. O comando INITIALIZE inicializa variá-
veis de acordo com a estrutura de dados que cada variável possui, tendo como estrutura sintática:

INITIALIZE <identificador1> ... [[WITH] FILLER]


[[ALL <categoria>] [TO] VALUE]
[[THEN] REPLACING [<categoria> [DATA] BY [LENGTH [OF]] <identificador2>] ... ]
[[THEN TO] DEFAULT]

As palavras chave WITH, TO, THEN, THEN TO, DATA e OF são opcionais e podem ser a critério do profissional de
desenvolvimento omitidas, mas por questões de legibilidade é adequado mantê-las.
O uso do comando INITIALIZE sem as cláusulas VALUE e REPLACING com ou sem a cláusula DEFAULT executa
sua ação em modo padrão, em que as posições numéricas são inicializadas com zero e as posições alfabéticas e alfa-
numéricas são inicializadas com espaços em branco.
Se usada as cláusulas VALUE e REPLACING com a frase ALL TO VALUE todos os itens de dados na lista de campos
com uma cláusula VALUE explícita definida em sua descrição ou implícita herdada de um item do grupo será inicializa-
da em tempo de compilação. Caso haja a indicação ALL <categoria> TO VALUE todos os itens de dados na lista de
campos que se enquadram na categoria indicada e que tenham a cláusula VALUE explícita definida em sua descrição
ou implícita herdada de um item do grupo será inicializada em tempo de compilação. Se usada apenas a cláusula RE-
PLACING todos os itens de dados da lista de campos não inicializados como descrito anteriormente e que se enqua-
dram na categoria indicada (NUMERIC, ALPHABETIC, ALPHANUMERIC, NUMERIC-EDITED ou ALPHANUMERIC-
EDITED) serão inicializados com o valor indicado em identificador2. Quaisquer itens de dados inicializados por esta
regra serão excluídos das demais regras. Se houver algum item não inicializado com as cláusulas VALUE e/ou RE-
PLACING, e havendo a cláusula DEFAULT as posições numéricas serão inicializadas com zero e as posições alfabéti-
cas e alfanuméricas com espaços em branco.
Há três exceções em que não ocorre inicialização: itens contendo a cláusula REDEFINES, indexadores e campo anô-
nimo FILLER. No caso de campos FILLER se estiver em uso a cláusula WITH FILLER ocorrerá a inclusão deste campo
na ação de inicialização.
Como ilustração considere a definição de duas variáveis como itens elementares e uma variável como item de grupo
contendo três campos como itens elementares subordinados, todos inicializados com valores padrão.

DATA DIVISION.
WORKING-STORAGE SECTION.

77 WS-VALOR1 PIC 9 VALUE 1.


77 WS-VALOR2 PIC 9 VALUE 2.
01 WS-GRUPO.
02 WS-GRUPO-VALOR1 PIC A VALUE "A".
02 WS-GRUPO-VALOR2 PIC 9 VALUE 3.
02 WS-GRUPO-VALOR3 PIC 9 VALUE 4.

Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 1, 2, A, 3 e 4 são apre-
sentados como descrito em seguida.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY WS-VALOR1.
DISPLAY WS-VALOR2.
DISPLAY WS-GRUPO-VALOR1.
DISPLAY WS-GRUPO-VALOR2.
DISPLAY WS-GRUPO-VALOR3.
146 PRO G RA MA Ç ÃO CO B OL

Agora se após a apresentação dos valores anteriores for definido o uso do comando INITIALIZE como indicado, ocorre-
rá a destruição dos valores definidos.

INITIALIZE WS-VALOR1, WS-VALOR2.


INITIALIZE WS-GRUPO.
DISPLAY WS-VALOR1.
DISPLAY WS-VALOR2.
DISPLAY WS-GRUPO-VALOR1.
DISPLAY WS-GRUPO-VALOR2.
DISPLAY WS-GRUPO-VALOR3.

Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 0, 0, espaço em bran-
co, 0 e 0 são apresentados como descrito em seguida.
Outra maneira de inicializar variáveis é com o estabelecimento de valores predeterminados de inicialização. Observe os
próximos detalhes.

INITIALIZE WS-VALOR1 REPLACING NUMERIC DATA BY 9.


INITIALIZE WS-VALOR2 REPLACING NUMERIC BY 8.
INITIALIZE WS-GRUPO-VALOR1 REPLACING ALPHABETIC BY "X".
INITIALIZE WS-GRUPO-VALOR2, WS-GRUPO-VALOR3
REPLACING NUMERIC BY 7.
DISPLAY WS-VALOR1.
DISPLAY WS-VALOR2.
DISPLAY WS-GRUPO-VALOR1.
DISPLAY WS-GRUPO-VALOR2.
DISPLAY WS-GRUPO-VALOR3.

Ao ser executada a apresentação das variáveis indicadas com o comando DISPLAY os valores 9, 8, X, 7 e 7 são apre-
sentados como descrito em seguida.
Além das formas apresentadas que podem ser usadas para inicializar variáveis de itens elementares e/ou de itens de
grupo, tanto como variáveis simples como variáveis compostas é possível, também, fazer a inicialização de conteúdo a
partir do uso da cláusula VALUE no momento da declaração da variável, sendo muito útil principalmente para a iniciali-
zação de listas/tabelas.
Observe em seguida definição de uma lista alfanumérica inicializada com o conteúdo "Teste 1" e alterada para o conte-
údo "Teste 2".

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-TEXTO.
02 WS-A PIC X(8) VALUE "Teste 1" OCCURS 3 TIMES.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY "Conteudo total: " TB-TEXTO.
DISPLAY WS-A(1).
DISPLAY WS-A(2).
DISPLAY WS-A(3).

INITIALIZE TB-TEXTO REPLACING ALPHANUMERIC BY "Teste 2".

DISPLAY "Conteudo total: " TB-TEXTO.


DISPLAY WS-A(1).
DISPLAY WS-A(2).
DISPLAY WS-A(3).
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 147

O trecho anterior mostra a definição da lista TB-TEXTO com o campo WS-A inicializado com o valor "Teste 1" em todos
os slots no momento da definição da variável composta. Mas mostra a alteração de todas as suas posições com o uso
do comando INITIALIZE. Um detalhe adicional é que este trecho mostra duas formas de exibir o conteúdo de uma cole-
ção de dados: total a partir do nome da coleção, neste caso TB-TEXTO e isoladamente a partir do campo WS-A.

4.3.2 Classificação de dados


Uma das ações mais requisitas em programação é a classificação de elementos em listas, tabelas e arquivos. Existem
diversos algoritmos para a realização deste tipo de operação. No entanto, COBOL possui o comando SORT para efeti-
var classificações. O comando SORT pode ser usado tanto em operações com arquivos como com tabelas. Neste mo-
mento, será usado apenas na manipulação dos elementos de tabelas.
O comando SORT possui de forma simplificada a estrutura sintática.

SORT <campo> [[ON] [AS/DE|SCENDING] KEY <campo-chave>]

A palavra-chave ON é opcional e pode ser a critério do profissional de desenvolvimento omitida, mas por questões de
legibilidade é adequado mantê-las. O parâmetro campo deve possuir a cláusula OCCURS para que o comando SORT
consiga operar sobre a estrutura de dados definida. O parâmetro campo-chave, se em uso faz referência ao campo de
item elementar subordinado ao item de grupo que será usado para determinar por qual elemento a classificação será
realizada. É possível fazer o uso de vários campos como campo-chave, bastando separá-los por vírgulas. Os dados do
campo em uso serão classificados em memória a partir do campo-chave informado após KEY, podendo-se escolher a
ordem de classificação ASCENDING (do menor para o maior) ou DESCENDING (do maior para o menor).
No sentido de exemplificar o uso de classificação de dados numéricos inteiros considere um trecho de código que apre-
sente uma sequência de dez valores numéricos com unidade, dezena e centena sorteados “automaticamente” entre 1 e
100 em uma tabela de uma dimensão (lista). O trecho de código indica a apresentação dos valores antes e depois da
classificação.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-VALORES-NUMERICOS.
02 WS-NUMERO PIC 9(3) VALUE ZERO OCCURS 10 TIMES.
77 AC-CI PIC 99.
77 WS-S-NUMERO PIC ZZ9.
77 WS-S-CI PIC Z9.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10


COMPUTE WS-NUMERO(AC-CI) = (FUNCTION RANDOM * 100) + 1
END-PERFORM.

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10


MOVE WS-NUMERO(AC-CI) TO WS-S-NUMERO
MOVE AC-CI TO WS-S-CI
DISPLAY "NUMERO[" WS-S-CI "] = " WS-S-NUMERO
END-PERFORM.
DISPLAY X"0D".

SORT WS-NUMERO ON ASCENDING.


148 PRO G RA MA Ç ÃO CO B OL

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10


MOVE WS-NUMERO(AC-CI) TO WS-S-NUMERO
MOVE AC-CI TO WS-S-CI
DISPLAY "NUMERO[" WS-S-CI "] = " WS-S-NUMERO
END-PERFORM.

Na PROCEDURE DIVISION é colocado em uso, logo no primeiro laço, a função RANDOM que tem por finalidade gerar
valores pseudoaleatórios entre 0 e 1. Como se deseja obter valores entre 1 e 100 faz-se para o cálculo uso da expres-
são aritmética COMPUTE WS-NUMERO(AC-CI) = (FUNCTION RANDOM * 100) + 1 que calcula um valor sorteado e
armazena-o no campo WS-NUMERO da tabela TB-VALORES-NUMERICOS.
O trecho apresentado quando executado sorteará sempre a mesma sequência de valores. Isto ocorre devido o fato da
função RANDOM gerar valores pseudoaleatórios. Há uma forma de fazer com que os valores sorteados a cada execu-
ção sejam diferentes, bastando associar a função RANDOM o timer do relógio interno da máquina. Este assunto será
visto um pouco mais adiante neste capítulo. Assim que os valores são sorteados o segundo laço apresenta esses valo-
res na ordem em que são estabelecidos para a coleção de dados. Antes do terceiro laço encontra-se a instrução SORT
WS-NUMERO ON ASCENDING que efetua a classificação dos valores do campo WS-NUMERO na ordem ascendente
(ASCENDING). O quarto laço apresenta então os valores organizados dentro da tabela.
Como exemplo de classificação em tabelas com mais de uma dimensão, considere trecho de programa que a partir de
uma tabela de duas dimensões contendo nomes, idades e as alturas de cinco pessoas apresente a tabela por ordem de
nome.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-DADOS.
02 TB-PESSOAS OCCURS 5 TIMES.
03 NOME PIC A(40).
03 IDADE PIC 9(3).
03 ALTURA PIC 9V99.

77 AC-CI PIC 99.


77 WS-S-NOME PIC A(40).
77 WS-S-IDADE PIC ZZ9.
77 WS-S-ALTURA PIC 9.99.
77 WS-S-CI PIC Z9.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5


MOVE AC-CI TO WS-S-CI
DISPLAY "Entre registro: " WS-S-CI
DISPLAY X"0D"
DISPLAY "Nome .....: " WITH NO ADVANCING
ACCEPT NOME(AC-CI)
DISPLAY "Idade ....: " WITH NO ADVANCING
ACCEPT IDADE(AC-CI)
DISPLAY "Altura ...: " WITH NO ADVANCING
ACCEPT ALTURA(AC-CI)
DISPLAY X"0D"
END-PERFORM.
DISPLAY X"0D".

SORT TB-PESSOAS ON ASCENDING KEY NOME.

DISPLAY "Listagem de dados"


DISPLAY X"0D"
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 149

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5


MOVE AC-CI TO WS-S-CI
MOVE NOME(AC-CI) TO WS-S-NOME
MOVE IDADE(AC-CI) TO WS-S-IDADE
MOVE ALTURA(AC-CI) TO WS-S-ALTURA
DISPLAY WS-S-CI " - " WS-S-NOME " | " WITH NO ADVANCING
DISPLAY WS-S-IDADE " | " WS-S-ALTURA
END-PERFORM.

Ao ser executado o trecho anterior e após fornecer os dados solicitados será apresentada uma listagem com os nomes
em ordem ascendente a partir do uso da instrução SORT TB-PESSOAS ON ASCENDING KEY NOME em que a tabela
TB-PESSOAS é classificada a partir do campo NOME.
Como experiência outras ações de classificação podem ser realizadas:

SORT TB-PESSOAS ON ASCENDING KEY IDADE


SORT TB-PESSOAS ON ASCENDING KEY IDADE, NOME

A primeira forma anterior classifica os dados por ordem de idade e a segunda forma classifica os dados em ordem de
idade e em idade em ordem de nome. Agora veja este efeito.

SORT WS-PESSOAS ON ASCENDING KEY IDADE, DESCENDING KEY NOME

Serão apresentados os dados classificados por idade em ordem crescente e os nomes em ordem descendente.

4.3.3 Pesquisas de dados


Outra ação muito requisitada no desenvolvimento de programas é a possibilidade de realização de pesquisas em listas
e tabelas. Neste sentido, COBOL disponibiliza o verbo SEARCH para buscas sequenciais (também referenciada como
busca serial) ou verbo SEARCH ALL para buscas binárias. A busca sequencial para ser operacionalizada necessita de
que se faça o posicionamento do ponteiro da coleção de dados no início da estrutura com o comando SET para que
seja possível percorrer a coleção slot por slot até atingir o final da estrutura. A pesquisa binária não necessita do co-
mando SET mas exige que a coleção esteja classificada.
Os verbos SEARCH e SEARCH ALL possuem, de forma simplificada, a estrutura sintática.

SEARCH | SEARCH ALL <tabela>


[AT] END
<instrução-quando-falsa>
WHEN <condição>
<instrução-quando-verdadeira>] ...
[END SEARCH].

Um detalhe complementar é que as palavras-chave AT e END-SEARCHO são opcionais e podem a critério do profissi-
onal de desenvolvimento serem omitidas, mas por questões de legibilidade, como orientado, é adequado mantê-las.
O uso de SEARCH ou SEARCH ALL determina o modo de ação da pesquisa junto a coleção de dados em uso, sendo
forma serial (sequencial) (serial) ou forma binária. Independentemente da forma sintática usada o resultado apresenta-
do de SEARCH ou SEARCH ALL é semelhante. Ambos os comandos efetuam a pesquisa em um array (lista) ou tabela
a partir do estabelecimento de certa condição citada após a cláusula WHEN (podendo-se utilizar várias cláusulas
WHEN) e sendo a condição verdadeira, executa as instruções indicadas a partir de instrução-quando-verdadeira.
Caso a condição seja falsa é executado o que estiver definido após AT END sinalizado como instrução-quando-falsa.
Os comandos SEARCH e SEARCH ALL possuem como característica operacional serem definidos para a realização
de ações de busca em campos de chaves primárias (campos em uma estrutura de dados que não possuam interna-
mente dados que sejam repetidos). Caso existam campos com conteúdo semelhante a busca apresentada estará rela-
cionada apenas a primeira ocorrência.
150 PRO G RA MA Ç ÃO CO B OL

Para utilizar os comandos SEARCH e SEARCH ALL é necessário considerar o uso da cláusula INDEXED BY. No caso,
do comando SEARCH ALL é necessário considera as cláusulas ASCENDING ou DESCENDING.
Como exemplo de pesquisa sequencial com busca serial considere um trecho de programa que gerencie os dados de
uma frutaria. A tabela interna do sistema deve considerar três campos: código da fruta, descrição da fruta e preço de
venda para seis registros. Observe em seguida o trecho de código e principalmente as partes colorizadas.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TB-FRUTAS.
02 TB-FTS-REGISTRO OCCURS 6 TIMES
INDEXED BY IX-DADOS.
03 TB-CODIGO PIC X(3).
03 TB-DESCRICAO PIC A(10).
03 TB-PRECO PIC 99V99.

77 WS-E-CODIGO PIC X(3).


77 WS-E-PRECO PIC Z9.99.
77 WS-S-IDX PIC 9.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.

MOVE "505" TO TB-CODIGO (1).


MOVE "Banana" TO TB-DESCRICAO (1).
MOVE 3.45 TO TB-PRECO (1).

MOVE "450" TO TB-CODIGO (2).


MOVE "Mamao" TO TB-DESCRICAO (2).
MOVE 2.12 TO TB-PRECO (2).

MOVE "209" TO TB-CODIGO (3).


MOVE "Maca" TO TB-DESCRICAO (3).
MOVE 1.68 TO TB-PRECO (3).

MOVE "150" TO TB-CODIGO (4).


MOVE "Pera" TO TB-DESCRICAO (4).
MOVE 1.33 TO TB-PRECO (4).

MOVE "320" TO TB-CODIGO (5).


MOVE "Ameixa" TO TB-DESCRICAO (5).
MOVE 1.95 TO TB-PRECO (5).

MOVE "420" TO TB-CODIGO (6).


MOVE "Figo" TO TB-DESCRICAO (6).
MOVE 10.95 TO TB-PRECO (6).

DISPLAY "Entre o codigo: " WITH NO ADVANCING.


ACCEPT WS-E-CODIGO.
SET IX-DADOS TO 1.
SEARCH TB-FTS-REGISTRO
AT END
DISPLAY "Codigo inexistente"
WHEN WS-E-CODIGO = TB-CODIGO(IX-DADOS)
MOVE TB-PRECO(IX-DADOS) TO WS-E-PRECO
MOVE IX-DADOS TO WS-S-IDX
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 151

DISPLAY "Cod Descricao Preco - #"


DISPLAY "----------------------------"
DISPLAY "------------------------"
DISPLAY TB-CODIGO (IX-DADOS) " - "
TB-DESCRICAO (IX-DADOS) " - "
WS-E-PRECO " - " WS-S-IDX
END-SEARCH.

Observe no trecho anterior o uso da cláusula INDEXED BY com a definição do índice IX-DADOS a ser usado na pes-
quisa, sendo esta ação necessária para uso do comando SEARCH.
O índice criado é uma tabela interna que permite o acesso direto aos registros da tabela de dados, tanto que a primeira
ação antes de executar a pesquisa é garantir o posicionamento no primeiro registro dessa tabela com a instrução SET
IX-DADOS TO 1, onde o comando SET é usado para colocar a partir do índice referenciado (IX-DADOS) o ponteiro
(TO), neste caso, na posição 1. Vale salientar que é possível usar com SET qualquer valor de posicionamento entre o
primeiro e último registros existentes.
Ao fazer uma busca que seja localizada o trecho descreve a apresentação dos dados de código, descrição, preço e o
número do registro que o dado apresentado se encontra dentro da tabela TB-FTS-REGISTRO.
A partir de situação semelhante considere trecho de programa que efetua a pesquisa sob a ótica binária. Atente para os
pontos colorizados indicando os detalhes a serem seguidos para este estilo de pesquisa. Para que a pesquisa binária
seja possível é necessário tomar dois cuidados: primeiro que a tabela esteja previamente classificada; segundo que a
ordem de busca da tabela seja a mesma ordem da classificação. Observe os detalhes colorizados

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-FRUTAS.
02 TB-FTS-REGISTRO OCCURS 6 TIMES
ASCENDING KEY TB-CODIGO
INDEXED BY IX-DADOS.

03 TB-CODIGO PIC X(3).


03 TB-DESCRICAO PIC A(10).
03 TB-PRECO PIC 99V99.

77 WS-E-CODIGO PIC X(3).


77 WS-E-PRECO PIC Z9.99.
77 WS-S-IDX PIC 9.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
MOVE "505" TO TB-CODIGO (1).
MOVE "Banana" TO TB-DESCRICAO (1).
MOVE 3.45 TO TB-PRECO (1).
MOVE "450" TO TB-CODIGO (2).
MOVE "Mamao" TO TB-DESCRICAO (2).
MOVE 2.12 TO TB-PRECO (2).
MOVE "209" TO TB-CODIGO (3).
MOVE "Maca" TO TB-DESCRICAO (3).
MOVE 1.68 TO TB-PRECO (3).
MOVE "150" TO TB-CODIGO (4).
MOVE "Pera" TO TB-DESCRICAO (4).
MOVE 1.33 TO TB-PRECO (4).
MOVE "320" TO TB-CODIGO (5).
MOVE "Ameixa" TO TB-DESCRICAO (5).
MOVE 1.95 TO TB-PRECO (5).
MOVE "420" TO TB-CODIGO (6).
152 PRO G RA MA Ç ÃO CO B OL

MOVE "Figo" TO TB-DESCRICAO (6).


MOVE 10.95 TO TB-PRECO (6).

SORT TB-FTS-REGISTRO ON ASCENDING KEY TB-CODIGO.

DISPLAY "Entre o codigo: " WITH NO ADVANCING.


ACCEPT WS-E-CODIGO.

SEARCH ALL TB-FTS-REGISTRO


AT END
DISPLAY "Codigo inexistente"
WHEN WS-E-CODIGO = TB-CODIGO(IX-DADOS)
MOVE TB-PRECO(IX-DADOS) TO WS-E-PRECO
MOVE IX-DADOS TO WS-S-IDX
DISPLAY "Cod Descricao Preco - #"
DISPLAY "----------------------------"
DISPLAY TB-CODIGO (IX-DADOS) " - "
TB-DESCRICAO (IX-DADOS) " - "
WS-E-PRECO " - " WS-S-IDX
END-SEARCH.

Observe inicialmente a definição da ordem de classificação ASCENDIG KEY para o comando SORT e para a definição
da tabela após o a cláusula OCCURS. Caso deseje uma tabela com busca binária no sentido ascendente é necessário
ajustar, não só a tabela, como também sua ordem de classificação.
Veja que para utilizar o verbo SEARCH ALL não é necessário fazer uso da instrução SET IX-DADOS TO 1 como reali-
zado com SEARCH, pois automaticamente SEARCH ALL coloca o ponteiro do índice no meio da tabela, seguindo o
acesso de busca para frente ou para trás dependendo do dado pesquisado sempre dividindo ao meio o espaço restante
na medida em que o dado desejado não é encontrado.
O uso de SEARCH e SEARCH ALL requer atenção em um pequeno, mas importante detalhe. A condição usada após a
cláusula WHEN, seja com SEARCH, SEARCH ALL ou EVALUATE somente pode ser operada com o uso do operador
relacional de igualdade. Não é permitido fazer uso dos demais operadores relacionais.

4.3.4 Campos variáveis


A definição de variáveis como formas de campos para acesso aos dados de entrada, processamento e saída são esta-
belecidos com o uso do comando PICTURE que tem por finalidade definir o tipo de dado a ser usado e consequente-
mente seu consumo de espaço em memória. No entanto, há ocasiões onde se é necessário definir um dado que se
sabe seu tipo (numérico, alfabético ou alfanumérico), mas não se sabe ao certo quanto de espaço deve este dado ocu-
par memória. Neste sentido, pode-se fazer uso da definição de campos em tabelas dinâmicas cujo tamanho do campo
é por sua natureza variável. A definição de campos variáveis em tabelas dinâmicas é realizada com o uso das cláusulas
TO e DEPENDIG ON.
Para exemplificar este uso considere o trecho de código seguinte que visa apresentar um gráfico de barras formado por
asteriscos a partir da quantidade de itens vendidos, até o máximo de dez unidades permitidas por clientes. Atente para
as partes colorizadas

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-FRUTAS.
02 TB-FTS-REGISTRO OCCURS 6 TIMES.
03 TB-CODIGO PIC X(3).
03 TB-DESCRICAO PIC A(10).
03 TB-QUANT PIC 9(2).
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 153

01 TB-GRAF
02 FILLER OCCURS 1 TO 10 TIMES DEPENDING ON WS-E-QUANT.
03 FILLER PIC X VALUE "*".

77 WS-E-QUANT Z(4)9.
77 WS-S-IDX PIC 9.
77 AC-CI PIC 9.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
MOVE "505" TO TB-CODIGO (1).
MOVE "Banana" TO TB-DESCRICAO (1).
MOVE 3 TO TB-QUANT (1).
MOVE "450" TO TB-CODIGO (2).
MOVE "Mamao" TO TB-DESCRICAO (2).
MOVE 9 TO TB-QUANT (2).
MOVE "209" TO TB-CODIGO (3).
MOVE "Maca" TO TB-DESCRICAO (3).
MOVE 5 TO TB-QUANT (3).
MOVE "150" TO TB-CODIGO (4).
MOVE "Pera" TO TB-DESCRICAO (4).
MOVE 7 TO TB-QUANT (4).
MOVE "320" TO TB-CODIGO (5).
MOVE "Ameixa" TO TB-DESCRICAO (5).
MOVE 10 TO TB-QUANT (5).
MOVE "420" TO TB-CODIGO (6).
MOVE "Figo" TO TB-DESCRICAO (6).
MOVE 6 TO TB-QUANT (6).

SORT TB-FTS-REGISTRO ON ASCENDING KEY TB-CODIGO.

DISPLAY "Cod Descricao Quant Grafico"


DISPLAY " -------------------------------------"
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 6
MOVE TB-QUANT(AC-CI) TO WS-E-QUANT
DISPLAY TB-CODIGO (AC-CI) " | "
TB-DESCRICAO (AC-CI) " | "
WS-E-QUANT " | " TB-GRAF
END-PERFORM.
DISPLAY "-------------------------------------"

O primeiro detalhe a ser observado no trecho de código é a definição da tabela dinâmica TB-GRAF que possui a defini-
ção de uma coluna anônima FILLER OCCURS 1 TO 10 TIMES DEPENDING ON WS-E-QUANT com a capacidade de
armazenar de 1 até 10 caracteres alfanuméricos dependendo do valor indicado para a variável WS-E-QUANT. A coluna
anônima por sua vez possui um campo anônimo FILLER PIC X VALUE "*" que determina o espaço de um byte (carac-
tere) alfanumérico inicializado com o símbolo de asterisco. O valor da variável WS-E-QUANT determinará a quantidade
de bytes a ser alocado na memória, não podendo exceder 10.
Um detalhe importante, a cláusula TO é usada obrigatoriamente em conjunto com a frase DEPENDING ON para deter-
minar a quantidade mínima e máxima de memória a ser usada. O número de ocorrências de uso de memória será con-
trolado dinamicamente quando o programa estiver em execução.
No trecho que efetua a apresentação dos dados há a indicação de uso da tabela TB-GRAF que possui internamente a
definição do símbolo de asterisco que está vinculado ao valor estabelecido na variável WS-E-QUANT. É por esta razão
que se faz uso da instrução MOVE TB-QUANT(AC-CI) TO WS-E-QUANT que carrega a variável WS-E-QUANT com os
154 PRO G RA MA Ç ÃO CO B OL

valores de quantidades vendidas de cada produto gerando a quantidade equivalente de asteriscos para composição do
gráfico de barras.
Além do efeito dinâmico apresentado a variável WS-E-QUANT da tabela TB-GRAF está sendo usada para definir um
vínculo com a tabela TB-FRUTAS a partir da sua relação com o campo TB-QUANT.

4.3.5 Aleatoriedade variável


É patente a necessidade de se fazer uso de valores aleatórios em programação, muitas vezes relacionados a efetiva-
ção de ações de simulação. O grande problema neste sentido, como já deve ter sido observado neste capítulo é apre-
sentação de valores aleatórios “viciados”, ou seja, valores que se repetem sempre mesmo quando se executa o pro-
grama em momentos diferentes. Esse efeito ocorre devido ao fato de os computadores por nós usados não operam
com valores verdadeiramente aleatórios.
A geração de valores aleatórios, precisamente pseudoaleatórios, é conseguido com o uso de funções internas disponi-
bilizadas normalmente pela linguagem em uso. Por melhor que seja os algoritmos matemáticos usados para gerar valo-
res pseudoaleatórios sempre ocorrerá a geração dos mesmos valores, mesmo que o algoritmo seja executado em mo-
mento distintos. Isso pode ser facilmente contatado, basta colocar em execução o trecho de código descrito no subtópi-
co 4.3.2.
No entanto, há uma forma de aumentar a variedade de geração de valores pseudoaleatórios em COBOL, bastado fazer
uso da função intrínseca RANDOM() antes de usar a função RANDOM. A função RANDOM com parênteses necessita
para ser usada da definição de um valor numérico, sua semente, como parâmetro. O valor de semente deve ser inteiro,
positivo e estar na faixa de 0 a 2.147.483.645, podendo-se no compilador GnuCOBOL chegar a 2.147.483.648. Os
valores, fora dessa faixa não surtirão efeito na geração de “valores aleatórios”.
Então, agora se tem uma forma de gerar valores com dispersão maior, mas há o problema em fazê-los de forma auto-
mática dentro de um programa. A maneira tradicional de fazer isso é usar o timer do relógio da máquina que é um com-
ponente interno que se altera ciclicamente em tempo real e pode ser usado como semente de randomização, tendo
assim uma simulação de geração de valores aleatórios bastante adequada.
Em COBOL há uma função que retorna o valor do timer da máquina (data e hora), apresentada no capítulo 2 chamada
CURRENT-DATE, tendo sido mostrada de forma bem simplificada. Na ocasião foram operacionalizados apenas os 16
primeiros dígitos de um total de 21 dígitos existentes. Veja na figura 4.4 a estrutura completa de apresentação da infor-
mação de data e hora do sistema.

Estrutura de retorno da função CURRENT-DATE

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

A A A A M M D D h h m m s s c c z x x y y
Figura 4.4 – Estrutura de apresentação dos dados da função CURRENT-DATE

Assim sendo, CURRENT-DATE retorna como resultado o valor AAAAMMDDhhmmsscczxxyy: em que AAAA é o ano;
MM é o mês; DD é o dia; hh são as horas; mm são os minutos; ss são os segundos; cc são os centésimos de segun-
do; z é o indicativo positivo, negativo ou nulo da diferença do fuso horário; xx indica diferença de horas em relação ao
meridiano de Greenwich e yy indica diferença de minutos em relação ao meridiano de Greenwich do horário do sistema.
Como teste, execute em um programa instrução.

DISPLAY FUNCTION CURRENT-DATE.

Como saída será apresentada a sequência numérica.

2020060412551750+0300

Indicando a data atual como sendo 04/06/2020 às 12h55min17s50cs com diferença de 3h no fuso horário do Brasil em
relação ao meridiano de Greenwich.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 155

O componente AAAA (posição de 1 a 4) aceita a faixa de datas de 01/01/1601 até 31/12/9999, o componente MM (po-
sição de 5 a 4) aceita a faixa de valores de 01 e 12, o componente DD (posição de 7 a 8) aceita a faixa de valores de 01
e 31, o componente hh (posição de 9 a 10) aceita a faixa de valores de 00 e 23, o componente mm (posição de 11 a
12) aceita a faixa de valores de 00 e 59, o componente ss (posição de 13 a 14) aceita a faixa de valores entre 00 e 59 e
o componente cc (posição de 15 a 16) aceita a faixa de valores entre 0 e 99. O símbolo positivo (+) na posição 17 indi-
ca que a hora mensurada é menor ou igual ao horário estabelecido no meridiano de Greenwich, se apresentado o sím-
bolo negativo (-) indica que a hora mensurada é maior que o horário estabelecido no meridiano de Greenwich e se
apresentará zero caso o sistema no qual a função é executada não tem a capacidade de fornecer os detalhes de fuso
horário da hora local. Se a décima sétima posição possuir o símbolo negativo será apresentado um valor numérico de
dois dígitos entre 00 e 12, indicando o número de horas que o tempo apresentado está a direita do meridiano de
Greenwich, sendo o símbolo positivo será apresentado um valor numérico entre 00 e 13 indicando o número de horas
que o tempo apresentado está a esquerda do meridiano de Greenwich. Após a décima sétima posição, são retornados
para xx (posição de 18 a 19) dois dígitos no intervalo de 00 a 59 indicando o número horas e yy (posição de 20 a 21)
dois dígitos no intervalo de 00 a 59 indicando o número minutos. Se a décima sétima posição for zero serão retornados
para xx e yy valores zero.
A partir do entendimento do valor retornado pela função CURRENT-DATE basta usá-lo como semente. Neste caso, não
será usado todo o conjunto de valores uma vez que ultrapassam o limite máximo aceito, apenas são usados os compo-
nentes numéricos, Dhhmmsscc, que se estendem da oitava até a décima sexta posição. Observe a figura 4.5.

Estrutura de retorno da função CURRENT-DATE

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

A A A A M M D D h h m m s s c c z x x y y
Figura 4.5 – Estrutura de apresentação dos dados da função CURRENT-DATE

Veja pela figura 4.5 que a parte que interessa como semente está situada a partir da posição 8 estendendo-se mais 9
casas a frente até a décima sexta posição. Desta forma, para extrair do valor retornado pela função CURRENT-DATE o
trecho numérico indicado, basta informar como argumento da função a posição que se deseja extrair e a quantidade de
dígitos a serem extraídos. Desta forma, a execução da instrução.

DISPLAY FUNCTION RANDOM(FUNCTION CURRENT-DATE(8:9)).

Retorna como resultado algo semelhante ao formato.

412551750

Formado pelo segundo dígito do dia do mês, o valor das horas, dos minutos, dos segundos e dos centésimos de se-
gundos atual. Assim sendo, veja a seguir trecho de código que apresenta cinco valores sorteados e armazenados em
um array, sempre de forma diferente a cada execução. Atente para as partes colorizadas.

DATA DIVISION.
WORKING-STORAGE SECTION.

01 TB-VALORES-NUMERICOS.
02 WS-NUMERO PIC 9(3) VALUE ZERO OCCURS 5 TIMES.

77 AC-CI PIC 9.
77 WS-S-NUMERO PIC ZZ9.
77 WS-SEM PIC 9(9).

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
156 PRO G RA MA Ç ÃO CO B OL

COMPUTE WS-SEM = FUNCTION RANDOM(FUNCTION CURRENT-DATE(8:9)).

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5


COMPUTE WS-NUMERO(AC-CI) = (FUNCTION RANDOM * 100) + 1
END-PERFORM.

SORT WS-NUMERO ASCENDING.

PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5


MOVE WS-NUMERO(AC-CI) TO WS-S-NUMERO
DISPLAY "NUMERO[" AC-CI "] = " WS-S-NUMERO
END-PERFORM.

O trecho de código indicado apresenta a inicialização da função RANDOM com a semente gerada a partir do timer da
máquina com a instrução COMPUTE WS-SEM = FUNCTION RANDOM(FUNCTION CURRENT-DATE(8:9)), em que a
variável WS-SEM é usada apenas para guardar o primeiro valor decimal aleatório gerado.
A ação anterior é extremamente importante para ser possível dar uma semente inicial para a função RANDOM da qual
serão gerados uma sequência de valores pseudoaleatórios. Como o valor da semente se altera em função do timer do
relógio interno, tem-se a impressão de que valores realmente aleatórios são gerados pelo programa.
O primeiro laço de execução do programa efetua a geração dos valores aleatórios a partir da semente anteriormente
definida. É sabido que a função RANDOM retorna valores entre 0 e 1 ao estilo 0.123456789. Cada valor obtido é multi-
plicado por 100 e em seguida somado a 1, sendo considerado apenas a parte inteira do valor calculado.
Após preencher os slots do array com os valores randomizados o programa efetua a ordenação da lista e em seguida
mostra o conjunto de valores “aleatórios” em ordem crescente.

4.4 ESTRUTURAS DE DADOS DINÂMICAS


Estruturas de dados dinâmicas caracterizam-se por serem coleções de dados que podem ter seu tamanho ajustado em
tempo de execução do programa. No caso, particular da linguagem COBOL a lista ou tabela poderá “crescer” na memó-
ria até um determinado limite definido pela própria equipe de desenvolvimento em certo programa. Se comparado este
recurso com os usados em linguagens mais modernas que COBOL pode-se até considera-lo como semi-dinâmico.
Para fazer uso de estruturas de dados dinâmicas usa-se as cláusulas TO e DEPENDIG ON usadas anteriormente para
a definição de campos com tamanho variável. A forma de uso é muito semelhante. Assim sendo, considere o trecho de
programa seguinte que solicita a quantidade de estudantes a serem cadastrados em uma tabela contendo nome e mé-
dia de cada estudante e apresente os dados informados, limitando a quantidade máxima de mil estudantes.

DATA DIVISION.
WORKING-STORAGE SECTION.

77 WS-NUM-ESTUD PIC 9(4).


77 WS-E-NOME PIC X(40).
77 WS-E-MEDIA PIC 99V99.
77 WS-S-NOME PIC X(40).
77 WS-S-MEDIA PIC Z9.99.
77 AC-CI PIC 9(4).
77 WS-S-CI PIC Z(3)9.

01 TB-ESTUDANTES.
05 TB-ESTUDANTE OCCURS 1 TO 1000 TIMES
DEPENDING ON WS-NUM-ESTUD.
10 ESTUDANTE-NOME PIC X(40).
10 ESTUDANTE-MEDIA PIC 99V99.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 157

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY "Informe quantidade de estudantes: "
WITH NO ADVANCING.
ACCEPT WS-NUM-ESTUD.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-NUM-ESTUD
DISPLAY X"0D"
MOVE AC-CI TO WS-S-CI
DISPLAY "Entre dados do estudante # "
FUNCTION TRIM(WS-S-CI)
DISPLAY X"0D"
DISPLAY "Nome ....: " WITH NO ADVANCING
ACCEPT ESTUDANTE-NOME(AC-CI)
DISPLAY "Media ...: " WITH NO ADVANCING
ACCEPT ESTUDANTE-MEDIA(AC-CI)
END-PERFORM.
DISPLAY X"0D"
DISPLAY "Relacao de estudantes:"
DISPLAY X"0D"
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-NUM-ESTUD
MOVE ESTUDANTE-NOME(AC-CI) TO WS-S-NOME
MOVE ESTUDANTE-MEDIA(AC-CI) TO WS-S-MEDIA
DISPLAY WS-S-NOME WITH NO ADVANCING
DISPLAY WS-S-MEDIA
END-PERFORM.

O trecho do código apresenta detalhes importantes a serem considerados, pois na definição da tabela TB-ESTUDANTE
é especificado que poderão ser aceitos até 1000 entradas (OCCURS 1 TO 1000 TIMES) de dados, dependendo obvia-
mente do valor (DEPENDING ON) indicado para a variável WS-NUM-ESTUD. Um cuidado a ser tomado é não ultra-
passar o limite pré-estabelecido. A linguagem COBOL não verifica este estouro antecipadamente e coloca o programa
em execução quando poderá sua ação ser abordada da memória. A responsabilidade em validar a entrada e verificar
seus limites e inteiramente do profissional de desenvolvimento.
a quantidade de limite que se pode especificar para uma estrutura de dados dinâmica operadas em memória principal é
bastante elástica. É possível estabelecer um valor bem alto que se imagine não atingir. O problema poderá existir em
relação ao espaço de memória disponível no computador, o que é difícil de ser estimado. Neste caso, procure usar o
bom sendo verificando a quantidade média e o maior pico de entradas no programa e defina um limite que venha aten-
der o pico com uma margem aceitável percentual a mais (que também deverá ser estimada).

4.5 HORA DE PROGRAMAR


Após a apresentação dos diversos recursos no tratamento e uso de coleções de dados é hora de colocar essas ferra-
mentas em uso. Os próximos programas completos mostram como fazer uso de listas e tabelas de maneira variada.
Mantenha sua atenção a cada problema apresentado, bem como a solução indicada.

CÁLCULO DE MÉDIA DE SALA DE AULA


Elaborar programa de computador que efetue a leitura das médias de uma sala de aula com oito alunos e no final apre-
sente o valor da média da sala. As médias escolares podem variar de zero a dez.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato 99V99 e para
a saída a máscara definida com o formato Z9.99.
Selecione e defina um projeto do programa vazio com o nome c04ex01.cob na pasta COBOL da pasta Documentos.
158 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX01 AS "Capitulo 4 – Exemplo 1".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-C-SOMA PIC 9(3)V99 VALUE ZERO.
7 77 WS-E-MEDIA PIC 99V99.
8 77 WS-S-MEDIA PIC Z9.99.
9 77 AC-CI PIC 9.
10 77 WS-S-CI PIC 9.
11 77 WS-ENTER PIC X.
12 *
13 01 TB-MEDIAS.
14 05 TB-MEDIA PIC 99V99 OCCURS 8 TIMES.
15 *
16 PROCEDURE DIVISION.
17 PROG-PRINCIPAL-PARA.
18 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 8
19 MOVE AC-CI TO WS-S-CI
20 DISPLAY "Informe a " WS-S-CI "a. media: "
21 WITH NO ADVANCING
22 ACCEPT TB-MEDIA(AC-CI)
23 ADD TB-MEDIA(AC-CI) TO WS-C-SOMA
24 END-PERFORM.
25 DISPLAY X"0D".
26 COMPUTE WS-E-MEDIA = WS-C-SOMA / 8.
27 MOVE WS-E-MEDIA TO WS-S-MEDIA.
28 DISPLAY "Media da sala = " FUNCTION TRIM(WS-S-MEDIA).
29
30 DISPLAY X"0D".
31 DISPLAY "Tecle <ENTER> para encerrar... "
32 WITH NO ADVANCING.
33 ACCEPT WS-ENTER.
34 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe as médias
solicitada e veja o resultado final apresentado.
Na linha 6 a instrução "77 WS-C-SOMA PIC 9(3)V99 VALUE ZERO" é usada para definir a variável que guardará o
somatório de cada média fornecida na execução das linhas 20 e 21. Variáveis usadas para armazenar somas ou sub-
trações sucessivas devem ser inicializadas com zero e as variáveis usadas com multiplicações ou divisões sucessiva
devem ser inicializadas com 1. As linhas 11 e 12 definem a lista que conterá os valores das médias dos oito alunos. Os
demais detalhes já são conhecidos.

OPERAÇÃO DE PROCESSAMENTO SOBRE ÍNDICE DE LISTAS


Elaborar programa de computador que efetue a leitura de cinco elementos inteiros em uma matriz "A" do tipo vetor em
forma de lista com uma dimensão e construa uma matriz "B" com as mesmas características que "A", observando a
seguinte lei de formação: se o valor de um elemento de "A" estiver numa posição de índice par, ele deve ser multiplica-
do por 5; sendo o valor de índice ímpar, o elemento deve ser somado a 5. Ao final, os conteúdos das duas listas devem
ser exibidos.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 159

Para o desenvolvimento deste programa é considerada para as listas "A" e "B" a máscara de entrada 9(3) e para a
saída a máscara Z(3).
Selecione e defina um projeto do programa vazio com o nome c04ex02.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX02 AS "Capitulo 4 – Exemplo 2".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 AC-CI PIC 9.
7 77 WS-S-A PIC Z(3).
9 77 WS-S-B PIC Z(3).
9 77 WS-ENTER PIC X.
10 *
11 01 TB-A.
12 05 A PIC 9(3) OCCURS 5 TIMES.
13 *
14 01 TB-B.
15 05 B PIC 9(3) OCCURS 5 TIMES.
16 *
17 PROCEDURE DIVISION.
18 PROG-PRINCIPAL-PARA.
19 DISPLAY "EXEMPLO DE CHECAGEM DE INDICE"
20 DISPLAY X"0D"
21 *
22 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5
23 DISPLAY "Informe um valor para o elemento nr. "
24 AC-CI ": " WITH NO ADVANCING
25 ACCEPT A(AC-CI)
26 END-PERFORM.
27 *
28 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5
29 IF FUNCTION REM(AC-CI, 2) = 0
30 COMPUTE B(AC-CI) = A(AC-CI) * 5
31 ELSE
32 COMPUTE B(AC-CI) = A(AC-CI) + 5
33 END-IF
34 END-PERFORM.
35 *
36 DISPLAY X"0D"
37 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5
38 MOVE A(AC-CI) TO WS-S-A
39 MOVE B(AC-CI) TO WS-S-B
40 DISPLAY "A[" AC-CI "] = " WS-S-A " | " WITH NO ADVANCING
41 DISPLAY "B[" AC-CI "] = " WS-S-B
42 END-PERFORM.
43 *
44 DISPLAY X"0D".
45 DISPLAY "Tecle <ENTER> para encerrar... "
46 WITH NO ADVANCING.
47 ACCEPT WS-ENTER.
48 STOP RUN.
------ ------------------------------------------------------------------------
160 PRO G RA MA Ç ÃO CO B OL

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe os cinco
valores e observe com muita atenção os valores apresentados.
São utilizados no programa três laços PERFORM nas linhas 22, 28 e 37. O primeiro laço controla a entrada dos dados,
o segundo verifica se cada índice da lista "A" é par ou ímpar e faz as operações, implicando os elementos calculados
na lista "B", e o terceiro apresenta as duas listas.
No laço destinado ao processamento (entre as linhas 28 e 34) é utilizada a instrução IF FUNCTION REM(AC-CI, 2) = 0,
sendo a função REM responsável em calcular o resto da divisão de números inteiros. Essa operação recebe o nome de
módulo. No caso apresentado, qualquer valor existente na variável AC-CI que, dividida por 2, resultar zero será par. Se
o resto da divisão for diferente de zero, o valor da variável AC-CI será ímpar.

OPERAÇÃO DE PROCESSAMENTO DE SOMA ELEMENTOS DE LISTA


Elaborar programa de computador que efetue a leitura de cinco elementos inteiros em uma matriz "A" do tipo vetor em
forma de lista com uma dimensão apresente a soma de todos os elementos ímpares.
Para o desenvolvimento deste programa é considerada para a lista "A" a máscara de entrada 9(3) e para a saída a
variável com o resultado da soma usa a máscara Z(3).
Selecione e defina um projeto do programa vazio com o nome c04ex03.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX03 AS "Capitulo 4 – Exemplo 3".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-C-SOMA PIC 9(3) VALUE ZERO.
7 77 WS-S-SOMA PIC Z(3).
8 77 AC-CI PIC 9.
9 77 WS-ENTER PIC X.
10 *
11 01 TB-A.
12 05 A PIC 9(3) OCCURS 5 TIMES.
13 *
14 PROCEDURE DIVISION.
15 PROG-PRINCIPAL-PARA.
16 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5
17 DISPLAY "Informe a " AC-CI "a. media: "
18 WITH NO ADVANCING
19 ACCEPT A(AC-CI)
20 END-PERFORM.
21 *
22 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 5
23 IF FUNCTION REM(AC-CI, 2) NOT = 0
24 ADD A(AC-CI) TO WS-C-SOMA
25 END-IF
26 END-PERFORM.
27 *
28 DISPLAY X"0D".
29 MOVE WS-C-SOMA TO WS-S-SOMA
30 DISPLAY "A soma dos elementos equivale a: "
31 FUNCTION TRIM(WS-S-SOMA)
32 *
------ ------------------------------------------------------------------------
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 161

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
33 DISPLAY X"0D".
34 DISPLAY "Tecle <ENTER> para encerrar... "
35 WITH NO ADVANCING.
36 ACCEPT WS-ENTER.
37 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe os cinco
valores e observe a apresentação do resultado da soma.
Observe na linha 23 o uso da instrução IF FUNCTION REM(AC-CI, 2) NOT = 0, para verificar se o elemento informado
é um valor ímpar; sendo, ele é acumulado na variável WS-C-SOMA que, ao final, apresenta o somatório dos elementos
ímpares informados durante a execução do programa.

OPERAÇÃO DE PROCESSAMENTO DE NOTAS ESCOLARES EM TABELA


Elaborar programa de computador que efetue a leitura de quatro notas escolares bimestrais de dez estudantes e em
seguida apresente os valores informados na forma de listagem horizontal contendo em cada linha as quatro notas de
cada estudante.
Para o desenvolvimento deste programa é considerada a tabela TB-ESTUDANTES com o campo WS-NOTA. As confi-
gurações das dimensões serão definidas como uso do campo FILLER.
Selecione e defina um projeto do programa vazio com o nome c04ex04.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX04 AS "Capitulo 4 – Exemplo 4".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 01 TB-ESTUDANTES.
7 05 FILLER OCCURS 10 TIMES.
8 10 FILLER OCCURS 4 TIMES.
9 15 WS-NOTA PIC 99V99.
10 *
11 77 AC-CI PIC 99.
12 77 AC-CJ PIC 9.
13 77 WS-S-CI PIC Z9.
14 77 WS-S-NOTA PIC Z9.99.
15 77 WS-ENTER PIC X.
16 *
17 PROCEDURE DIVISION.
18 PROG-PRINCIPAL-PARA.
19 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10
20 MOVE AC-CI TO WS-S-CI
21 DISPLAY "Informe notas do " WS-S-CI "o. estudante:"
22 DISPLAY X"0D"
23 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
------ ------------------------------------------------------------------------
162 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
24 DISPLAY "Nota: " AC-CJ " = " WITH NO ADVANCING
25 ACCEPT WS-NOTA(AC-CI, AC-CJ)
26 END-PERFORM
27 DISPLAY X"0D"
28 END-PERFORM.
29 *
30 DISPLAY X"0D".
31 DISPLAY "--------------------------------------------------".
32 DISPLAY "| | 1 | 2 | 3 | 4 |".
33 DISPLAY "--------------------------------------------------".
34 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > 10
35 MOVE AC-CI TO WS-S-CI
36 DISPLAY "| Estudante # " WS-S-CI " | " WITH NO ADVANCING
37 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
38 MOVE WS-NOTA(AC-CI, AC-CJ) TO WS-S-NOTA
39 DISPLAY WS-S-NOTA " | " WITH NO ADVANCING
40 END-PERFORM
41 DISPLAY X"0D"
42 END-PERFORM.
43 DISPLAY "--------------------------------------------------".
44 *
45 DISPLAY X"0D".
46 DISPLAY "Tecle <ENTER> para encerrar... "
47 WITH NO ADVANCING.
48 ACCEPT WS-ENTER.
49 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe as quatro
notas dos dez alunos e observe a apresentação dos dados no sentido horizontal.
A atenção maior neste programa é a definição da tabela de duas dimensões entre as linhas 6 e 9, sendo as linhas para
os alunos e as colunas para s notas de cada aluno. Nas linhas 7 e 8 especifica-se o ponto de entrada para as dimen-
sões da tabela.
A tabela a ser usada fica estabelecida, após sua configuração (linhas 7 e 8) na linha 9 a partir da definição da variável
WS-NOTA. Os campos FILLER das linhas 7 e 8 são uma forma de definir citações anônimas uma vez que esses cam-
pos não são necessariamente usados de forma nominal neste programa, desde que respeitando as restrições no uso
de campos FILLER.
Observe o uso das variáveis AC-CI e AC-CJ definidas nas linhas 11 e 12 para controlar as posições dos elementos na
matriz. A variável AC-CI controla o posicionamento do elemento em relação à linha da tabela, e a variável AC-CJ con-
trola o posicionamento do elemento em relação à coluna da tabela. As variáveis AC-CI e AC-CJ em conjunto possibili-
tam o acesso a um único elemento da tabela representado na variável WS-NOTA.
Analisando o programa, tem-se a inicialização das variáveis AC-CI e AC-CJ como 1 por meio dos laços PERFORM
encadeados, ou seja, a leitura é feita na primeira linha da primeira coluna (1, 1). No primeiro laço é iniciado, em primeiro
lugar a contagem da variável AC-CI para controlar a posição em relação às linhas; depois, é iniciado o laço que efetua
a contagem da variável AC-CJ para controlar a posição das colunas.
Ao serem iniciados os valores para o preenchimento da tabela, eles são colocados na posição WS-NOTA(1, 1), primeira
linha e primeira coluna, lembrando que o primeiro valor dentro dos parênteses representa a linha; o segundo, a coluna.
Assim sendo, para o primeiro aluno é informada a sua primeira nota. Depois, incrementa-se 1 à coluna e coloca-se para
a entrada a posição WS-NOTA(1, 2), primeira linha e segunda coluna da tabela para a segunda nota do primeiro aluno
e assim por diante.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 163

Quando o contador AC-CJ (coluna) atingir o valor 4 será encerrado. Em seguida o contador AC-CI (linha) será incre-
mentado em 1, tornando-se 2. Então, será inicializado novamente o contador AC-CJ em 1, permitindo informar um novo
dado na posição WS-NOTA(2, 1).
O mecanismo de preenchimento se estende até que o contador de linhas atinja o seu último valor, no caso 10. Esse
laço é o principal, tendo a função de controlar o posicionamento na tabela por aluno. O segundo laço, mais interno con-
trola o posicionamento das notas. Em seguida, é apresentada a relação dos alunos e suas respectivas notas.

OPERAÇÃO DE PROCESSAMENTO DE NOTAS ESCOLARES EM TABELA DINÂMICA


Elaborar programa de computador que efetue a leitura de quatro notas escolares bimestrais de uma quantidade de
estudantes indicada pelo usuário e em seguida apresente os valores informados na forma de listagem horizontal con-
tendo em cada linha a quatro notas de cada estudante. Limite o programa no máximo a 100 entradas.
Para o desenvolvimento deste programa é considerada a tabela TB-ESTUDANTES ajustada para dinamicamente che-
gar no máximo a cem entradas.
Selecione e defina um projeto do programa vazio com o nome c04ex05.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX05 AS "Capitulo 4 – Exemplo 5".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 01 TB-ESTUDANTES.
7 05 FILLER OCCURS 1 TO 100 TIMES
8 DEPENDING ON WS-NUM-ESTUD.
9 15 FILLER OCCURS 4 TIMES.
10 20 WS-NOTA PIC 99V99.
11 *
12 77 WS-NUM-ESTUD PIC 9(3).
13 77 AC-CI PIC 999.
14 77 AC-CJ PIC 9.
15 77 WS-S-CI PIC ZZ9.
16 77 WS-S-NOTA PIC Z9.99.
17 77 WS-ENTER PIC X.
18 *
19 PROCEDURE DIVISION.
20 PROG-PRINCIPAL-PARA.
21 PERFORM FOREVER
22 DISPLAY "Informe quantidade de estudantes: "
23 WITH NO ADVANCING
24 ACCEPT WS-NUM-ESTUD
25 DISPLAY X"0D"
26 IF WS-NUM-ESTUD >= 1 AND WS-NUM-ESTUD <= 100
27 EXIT PERFORM
28 END-IF
29 IF WS-NUM-ESTUD < 1 OR WS-NUM-ESTUD > 10
30 DISPLAY "Por favor, valores entre 1 e 100."
31 END-IF
32 DISPLAY X"0D"
33 END-PERFORM.
34 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-NUM-ESTUD
------ ------------------------------------------------------------------------
164 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
35 MOVE AC-CI TO WS-S-CI
36 DISPLAY "Informe notas do " WS-S-CI "o. estudante:"
37 DISPLAY X"0D"
38 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
39 DISPLAY "Nota: " AC-CJ " = " WITH NO ADVANCING
40 ACCEPT WS-NOTA(AC-CI, AC-CJ)
41 END-PERFORM
42 DISPLAY X"0D"
43 END-PERFORM.
44 *
45 DISPLAY X"0D".
46 DISPLAY "--------------------------------------------------".
47 DISPLAY "| | 1 | 2 | 3 | 4 |".
48 DISPLAY "--------------------------------------------------".
49 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-NUM-ESTUD
50 MOVE AC-CI TO WS-S-CI
51 DISPLAY "| Estudante #" WS-S-CI " | " WITH NO ADVANCING
52 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
53 MOVE WS-NOTA(AC-CI, AC-CJ) TO WS-S-NOTA
54 DISPLAY WS-S-NOTA " | " WITH NO ADVANCING
55 END-PERFORM
56 DISPLAY X"0D"
57 END-PERFORM.
58 DISPLAY "--------------------------------------------------".
59 *
60 DISPLAY X"0D".
61 DISPLAY "Tecle <ENTER> para encerrar... "
62 WITH NO ADVANCING.
63 ACCEPT WS-ENTER.
64 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe a quanti-
dade de estudantes desejados, entre as notas e verifique a apresentação das mesmas.
Este programa é semelhante ao anterior, tendo como principal diferença o uso de estrutura dinâmica de dados definida
nas linhas 7 e 8. Outro ponto de observação é o trecho de validação de entrada entre as linhas 21 e 33 evitando que
um valor fora da faixa operacional do programa seja aceito.

PROCESSAMENTO DE NOTAS ESCOLARES


Elaborar programa de computador que efetue a leitura dos nomes de estudantes com até 25 caracteres de comprimen-
to e suas quatro notas escolares bimestrais a partir da quantidade de estudantes indicada pelo usuário. O programa
deve indicar o nome do estudante, suas notas bimestrais, média escolar e a indicação de sua situação (SIT) sendo "A"
para aprovado ou "R" para reprovado se a média calculada e não armazenada na tabela for maior ou igual a 5. Os
dados deverão ser apresentados no sentido vertical em ordem de classificação alfabética por nome e o limite de entra-
das de estudantes permitida deverá ser de no máximo 50 entradas, devendo haver mensagem de advertência apresen-
tada se os limites não forem respeitados. O programa deve considerar como coleção de dados uma estrutura formada
por uma lista com os nomes dos estudantes e uma tabela com as notas bimestrais de cada estudante informado.
Este programa busca fazer uso de parte dos recursos tratados nesta obra até o presente momento. Note atentamente
cada detalhe apresentado. A apresentação das médias e situação escolar dos alunos é realizada no momento da apre-
sentação dos dados. Atente especialmente a ação de classificação.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 165

Selecione e defina um projeto do programa vazio com o nome c04ex06.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C04EX05 AS "Capitulo 4 – Exemplo 6".
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 01 TB-ESTUDANTES.
7 05 TB-ESTUDANTE OCCURS 1 TO 50 TIMES DEPENDING ON WS-N-EST.
8 10 WS-NOME PIC X(25).
9 10 TB-NOTAS OCCURS 4 TIMES.
10 15 WS-NT PIC 99V99.
11 *
12 77 WS-N-EST PIC 9(3).
13 77 AC-CI PIC 999.
14 77 AC-CJ PIC 9.
15 77 WS-C-MEDIA PIC 99V99.
16 77 WS-S-CI PIC ZZ9.
17 77 WS-S-NOTA PIC Z9.99.
18 77 WS-S-MEDIA PIC Z9.99.
19 77 WS-ENTER PIC X.
20 *
21 PROCEDURE DIVISION.
22 PROG-PRINCIPAL-PARA.
23 PERFORM FOREVER
24 DISPLAY "Informe quantidade de estudantes: "
25 WITH NO ADVANCING
26 ACCEPT WS-N-EST
27 DISPLAY X"0D"
28 IF WS-N-EST >= 1 AND WS-N-EST <= 100
29 EXIT PERFORM
30 END-IF
31 IF WS-N-EST < 1 OR WS-N-EST > 10
32 DISPLAY "Por favor, valores entre 1 e 50."
33 END-IF
34 DISPLAY X"0D"
35 END-PERFORM.
36 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-N-EST
37 MOVE AC-CI TO WS-S-CI
38 DISPLAY "Informe os dados do " WS-S-CI "o. estudante:"
39 DISPLAY X"0D"
40 DISPLAY "Nome ...: " WITH NO ADVANCING
41 ACCEPT WS-NOME(AC-CI)
42 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
43 DISPLAY "Nota ...: " AC-CJ " = " WITH NO ADVANCING
44 ACCEPT WS-NT(AC-CI, AC-CJ)
45 END-PERFORM
46 DISPLAY X"0D"
47 END-PERFORM.
48 *
49 SORT TB-ESTUDANTE ON ASCENDING KEY WS-NOME.
50 *
51 DISPLAY X"0D".
------ ------------------------------------------------------------------------
166 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
52 DISPLAY "----------------------------------------------------
53 - "-------------------------".
54 DISPLAY "| Estudante / Notas | 1 | 2 | 3
55 - "| 4 | Media | SIT |".
56 DISPLAY "----------------------------------------------------
57 - "-------------------------".
58 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-N-EST
59 MOVE AC-CI TO WS-S-CI
60 DISPLAY "| " WS-NOME(AC-CI) " | " WITH NO ADVANCING
61 COMPUTE WS-C-MEDIA = (WS-NT(AC-CI, 1) + WS-NT(AC-CI, 2)
62 + WS-NT(AC-CI, 3) + WS-NT(AC-CI, 4)) / 4
63 PERFORM VARYING AC-CJ FROM 1 BY 1 UNTIL AC-CJ > 4
64 MOVE WS-NT(AC-CI, AC-CJ) TO WS-S-NOTA
65 DISPLAY WS-S-NOTA " | " WITH NO ADVANCING
66 END-PERFORM
67 MOVE WS-C-MEDIA TO WS-S-MEDIA
68 DISPLAY WS-S-MEDIA " | " WITH NO ADVANCING
69 IF WS-C-MEDIA >= 5
70 DISPLAY " A |" WITH NO ADVANCING
71 ELSE
72 DISPLAY " R |" WITH NO ADVANCING
73 END-IF
74 DISPLAY X"0D"
75 END-PERFORM.
76 DISPLAY "----------------------------------------------------
77 - "-------------------------".
78 *
79 DISPLAY X"0D".
80 DISPLAY "Tecle <ENTER> para encerrar... "
81 WITH NO ADVANCING.
82 ACCEPT WS-ENTER.
83 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe a quanti-
dade de estudantes desejados, entre o nome e as notas e verifique a apresentação das mesmas com a indicação da
média e situação de cada aluno.
Entre as linhas 6 e 10 está a definição da estrutura formada pela lista de nomes como indicado na linha 8 e a tabela de
notas como indicado na linha 10. As dimensões destas ações estão indicadas na linha 7 com a definição da quantidade
de registros que TB-ESTUDANTES definida na linha 6 poderá possuir e na definição da quantidade de notas indicadas
na linha 9. A figura 4.6 mostra estruturalmente a definição da tabela TB-ESTUDANTES com o detalhamento definido
para a representação de uma lista e tabela integradas.
Entre as linhas 12 e 19 estão as definições das variáveis de uso no programa.
O trecho entre as linhas 23 e 35 a partir de uso de um laço infinito valida a entrada de dados. Enquanto a entrada é
incorreta a mensagem de advertência definida entre as linhas 31 e 33 é apresentada, sendo a entrada correta o trecho
entre as linhas 28 e 30 é executado e a saída do laço infinito é efetuada.
Um detalhe importante a ser observado é em relação a entrada dos dados na tabela. A linha 41 especifica a entrada do
nome na tabela como sendo uma lista e na linha 44 está a entrada das notas em uma tabela. Veja que essas duas
operações estão sincronizadas com o laço definido entre as linhas 36 e 47.
A linha 49 especifica a ação de classificação ascendente no campo WS-NOME da tabela TB-ESTUDANTE.
PRO C ESS AM EN TO C OM COL E ÇÕ ES D E D ADOS 167

TB-ESTUDANTES

TB-ESTUDANTE

slot TB-NOTAS
WS-NOME
WS-NT(1) WS-NT(2) WS-NT(3) WS-NT(4)

(...)

Figura 4.6 – Estrutura de dados integrada com lista e tabela

As linhas 52 e 53, 56 e 57, mais as linhas 76 e 77 mostram a apresentação de uma linha sublinhada. No entanto a
definição dessas linhas ultrapassa as 72 colunas do formulário e por esta razão fazem uso do símbolo traço para indicar
a continuidade da cadeia nas linhas 53, 57 e 77. Algo semelhante ocorre no título das linhas 54 e 55.
O pedido do programa indica para apresentar a média dos alunos e a situação de cada um sem armazenar na tabela
essas informações. Devido a este pedido o cálculo da média é processado nas linhas 61 e 62 e a situação é verificada
entre as linhas 69 e 73.
O cálculo da média definido nas linhas 61 e 62 ultrapassa as 72 colunas e devido a isso está divido entre essas linhas e
nos demais pontos o programa se assemelha a muito do que foi visto e comentado dispensando maiores detalhamento.
168 PRO G RA MA Ç ÃO CO B OL

Anotações

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________
MO D ULA RI ZA ÇÃ O 169

5
MODULARIZAÇÃO

Este capítulo aborda o uso do tema mais importante na produção de programas de computador em ambien-
tes de desenvolvimento organizados. São tratados os detalhes a respeito da organização do código escrito
em linguagem COBOL e das regras, geralmente não tácitas, usadas para deixar o código em condições de
manutenção e desenvolvimento futuro por outros profissionais de desenvolvimento. Neste sentido são apre-
sentados recursos de organização de divisões em seções; sub-rotinas internas e externas; reutilização de
código; passagem de parâmetro por conteúdo e por referência; copybook e recursividade.

5.1 PROGRAMAÇÃO ESTRUTURADA


Quando se fala em programação estruturada é importante não confundir este conceito com o conceito do erroneamente
chamado paradigma de programação estruturada, muito comum de se ouvir nos “corredores” da área da computação.
O paradigma de programação estruturada deve ser referenciado como paradigma imperativo estruturado, em contra-
ponto ao paradigma imperativo orientado a objetos. Observe que os termos estruturado e orientado a objetos são, na
verdade, ramos do mesmo galho de uma árvore de modelos computacionais maior que em sua essência fazem uso de
um ato de desenvolvimento chamado programação imperativa. O problema no uso inadequado desta terminologia é o
desenvolvimento de um senso de preconceito tecnológico acirrado entre profissionais da área que gastam tempo preci-
so em discussões filosóficas desnecessárias nos ambientes de trabalho e em redes sociais.
Quando se fala em programação estruturada, deixando-se de lado qualquer sombra sobre o efetivo paradigma em uso,
seja ele qual for fala-se da aplicação de uma filosofia de trabalho, de uma conduta organizada para o desenvolvimento
de códigos de computador dentro de um ambiente equilibrado de produção. Muitos se esquecem que a área da compu-
tação, mais precisamente o desenvolvimento de software é em sua essência fabril, ou seja, é um trabalho de “chão de
fábrica” não sendo diferente, por exemplo, de uma montadora de veículos.
Esta discussão, a princípio, aparentemente ingênua e considerada por alguns desnecessária leva a uma questão maior
relacionada as ocorrências que se fizeram necessárias a partir da crise do software percebida durante os anos de 1970.
Neste período foi percebido dificuldades no desenvolvimento do software frente a alta demanda que estava ocorrendo e
da complexidade dos problemas a serem desenvolvidos. Daí surgem diversas alternativas para tentar mitigar as ocor-
rências e efeitos colaterais percebidos como o uso de técnicas, ferramentas e métodos que culminaram no surgimento
da engenharia de software.
O estudo e aplicação da engenharia de software em um ambiente de produção visa desenvolver produtos de software
de maior qualidade, desenvolvidos em tempo adequado com controle de custos que sejam justos de uma ótica de sen-
so prático, o que se torna uma faca de dois gumes.
Em função do surgimento da engenharia de software (que é sem sombra de dúvida importuníssima e deve ser plena-
mente considerada) e de sua concentração em aspectos mais práticos do desenvolvimento do software começaram,
por falta adequada de conhecimento técnico, a surgir novos efeitos colaterais em relação a produção de software. A
impressão que dá é que os mesmos problemas percebidos durante a década de 1970 ainda assombram o “sono” de
muitos profissionais.
170 PRO G RA MA Ç ÃO CO B OL

Muitas dessas situações ocorrem devido a má interpretação sobre o que de fato é programação estruturada. Programa-
ção estruturada é a aplicação de uma filosofia de trabalho que visa produzir adequadamente documentação interna e
externa do software. A documentação interna relaciona a definição de comentários explicativos dentro do próprio código
como orientado no capítulo 2 e a documentação externa se relaciona com os detalhes definidos para o software advin-
dos das reuniões com os clientes e com a chefia imediata, bem como, com os subordinados a partir do registro de to-
dos os pontos acordados, como apregoada na engenharia de software.
Não é objetivo deste capítulo abordar o tema programação estruturada além desta introdução. O ponto a ser considera-
do é o de apenas auxiliar a se situar dentro deste contexto e saber diferenciar o que aqui é exposto do que é dito erro-
neamente por aí.

5.2 SEÇÕES CUSTOMIZADAS


Já é sabido que um programa escrito em linguagem COBOL é, por sua natureza mais simples, estruturado a partir de
segmentos estruturais: DIVISÕES, SEÇÕES, PARÁGRAFOS e SENTENÇAS, formadas por INSTRUÇÕES (substanti-
vos, preposições, adjetivos e verbos) e CLÁUSULAS (modificadores de ação sobre determinada instrução).
De maneira sutil os capítulos 1 e 2 fizeram parca introdução a esta temática e lá foram colocados por uma razão muito
simples: se você andou pesquisado sobre programas COBOL deve ter visto alguns dos códigos utilizando os elementos
indicados nesses capítulos. O objetivo foi deixar um pouco mais claro a estrutura de codificação COBOL e por conse-
guinte tornar a percepção adotadas nos capítulos anteriores mais clara. No entanto, é chegada a hora de aprofundar
sobre este tema.
As boas práticas apregoadas pela programação estruturada orientam que um programa de computador deve ser escrito
em partes ou módulos em que cada parte/módulo, por sua vez, execute apenas uma tarefa em específico, deve-se
evitar em colocar muitas ações diferentes em um mesmo local. Não importa para isso a linguagem ou paradigma de
programação adotados. No caso particular da linguagem COBOL, parte dessas definições devem ser implementadas na
PROCEDURE DIVISION a partir seções customizadas na forma de procedimentos internos que se assemelham a sub-
seções ou sub-rotinas.
Não há uma regra especifica para a definição de nomes para seções ou mesmo para parágrafos. No caso dos parágra-
fos, normalmente, são usados nomes seguidos do rótulo PARA como em PROG-PRINCIPAL-PARA. No caso da defi-
nição de nomes para seções customizadas usa-se normalmente como prefixo a indicação de uma numeração sequen-
cial, como indicado pelo Prof. Jaime Wojciechowski (veja a indicação de seu livro no prefácio deste trabalho) que nor-
teia, em particular, esta discussão, indicando o nível do módulo, representada pela seção dentro da divisão de procedi-
mento, como por exemplo usar três dígitos de valores, como: 100; 200; 300 e etc. O padrão de numeração usado pode-
rá ser definido com quatro dígitos (1000, 2000, 3000, etc) ou cinco dígitos (10000, 20000, 30000, etc), ou qualquer outra
configuração, dependendo obviamente da necessidade apresentada. Esta forma de definição visa auxiliar a estrutura
de uso do comando PERFORM que além de executar ciclos de ação no controle de laços pode ser usado para fazer
chamadas a módulos (sub-rotinas internas) que sejam definidos de maneira.
O uso da numeração possibilita que sejam criados níveis principais e subníveis na medida em que certa seção necessi-
ta, por alguma situação, ser desmembrada em outras seções. De forma geral, um programa de computador realizada
três operações muito distintas: a entrada, o processamento e a saída de dados, que podem em COBOL serem defini-
das isoladamente, mas integradas, em três seções de modularização dentro da PROCEDURE DIVISION como:

PERFORM 100-ENTRADA
PERFORM 200-PROCESSAMENTO
PERFORM 300-SAIDA

Na seção 100-ENTRADA podem ser definidas as instruções executadas no início do programa para a realização da
entrada de dados necessária ao processamento, na seção 200-PROCESSAMENTO são ser definidas as ações opera-
cionais para a realização do que se espera do programa e por fim na seção 300-SAIDA são definidas as operações de
apresentação dos dados processados.
Além das três seções propostas um programa pode conter áreas de inicialização e finalização. Neste caso, podem ser
definidos dois outros módulos, como:
MO D ULA RI ZA ÇÃ O 171

PERFORM 000-INICIALIZA
PERFORM 400-FINALIZA

Na seção 000-INICIALIZA podem ser definidas ações executadas na inicialização e seção 400-FINALIZADA podem
ser definidas as operações executadas na finalização do programa. Normalmente essas operações são executadas
uma única vez, diferentemente das outras seções que podem ser realizadas mais de uma vez dentro de um programa.
Outro detalhe organizacional é a possibilidade de definir uma seção comum exclusiva para tratamento da ocorrência
eventual de falhas e erros nas ações como exceções como:

PERFORM 900-CANCELA

A seção 900-CANCELA pode ser usada para executar instruções que ocorram a partir da ocorrência de algum proble-
ma de operação no programa, emitindo assim mensagens de erro que quando fornecidas ao suporte técnico venham a
ajudar a solução do problema. Observe que diferentemente da numeração das demais seções esta está definida com o
valor 900. O valor 900 (que pode ser 9000 ou outra composição) é usado na definição de seções comuns e de ações
genéricas a qualquer código de programa.
O que aqui se apresenta é uma sugestão aceita como prática, mas não é uma regra considerada obrigatória. A partir do
exposto um programa COBOL pode estar configurado a partir das seções de modularização:

PERFORM 000-INICIALIZA
PERFORM 100-ENTRADA
PERFORM 200-PROCESSAMENTO
PERFORM 300-SAIDA
PERFORM 400-FINALIZA
PERFORM 900-CANCELA

A partir das definições das seções customizadas podem ser estabelecidas nelas outras seções que deverão seguir um
critério de numeração de dependência formando níveis, normalmente acrescentando um valor de unidade na primeira
posição marcada com zero no limite esquerdo da numeração definida para a seção, preservando o número já definido
para a seção. Por exemplo, na seção 200-PROCESSAMENTO havendo a definição de subseções para o cálculo da
média escolar e apresentação do resultado da aprovação ou não de um estudante:

PERFORM 210-CALCULA-MEDIA
PERFORM 220-MOSTRA-MEDIA-COM-RESULTADO

A partir da seção 210-CALCULA-MEDIA havendo necessidade da definição de outras subseções use a regra de níveis
definindo um novo valor como por exemplo 211. Veja a indicação documental do cálculo da média realizado em duas
etapas, uma para a soma e outra para a divisão:

PERFORM 211-SOMA-DAS-NOTAS
PERFORM 212-MEDIA-DA-SOMA

Observe que pela numeração é possível identificar a que subseção e seção certa operação de um programa pertence.
Esta estratégia em programas pequenos é trabalhosa, mas se torna útil em programas grandes, onde a manutenção do
código começa a ser árdua e problemática.
As definições das chamadas de seções com o comando PERFORM são escritas a partir da décima segunda coluna do
formulário e as seções propriamente ditas são declaradas a partir da oitava coluna, no mesmo alinhamento do procedi-
mento de divisão. É conveniente definir linhas de comentários antes da definição de cada seção para sua devida identi-
ficação no código.
Após a definição das seções com o comando PERFORM estas devem ser codificadas dentro da divisão de procedimen-
to, como se fossem as seções convencionais da linguagem seguidas normalmente da cláusula SECTION colocada na
quadragésima coluna. A diferença entre seções customizadas e seções padrão é que, normalmente, as seções custo-
mizadas são encerradas com o comando EXIT e um ponto final ou então omitir o comando EXIT e deixar o ponto final
como indicativo de finalização a partir da décima segunda coluna do formulário. As instruções no bloco da seção cus-
tomizada não devem possuir pontos de encerramento.
172 PRO G RA MA Ç ÃO CO B OL

Como exemplo operacional básico dos detalhes comentados observe o trecho de código seguinte para a exemplifica-
ção de uso e aplicação das seções customizadas definidas para entrada, processamento e saída. Preste atenção em
todos os detalhes indicados, mas principalmente nas partes colorizadas.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-ENTER PIC X.
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
PERFORM 100-ENTRADA
PERFORM 200-PROCESSAMENTO
PERFORM 300-SAIDA
PERFORM 400-FINALIZA
STOP RUN.
******************************************************************
* EXECUCAO DA SECAO DE ENTRADA DE DADOS *
******************************************************************
100-ENTRADA SECTION.
DISPLAY "Aqui vem as acoes da entrada de dados"
EXIT.
******************************************************************
* EXECUCAO DA SECAO DE PROCESSAMENTO DE DADOS *
******************************************************************
200-PROCESSAMENTO SECTION.
DISPLAY "Aqui vem as acoes do processamento"
PERFORM 210-CALCULO-1
PERFORM 220-CALCULO-2
EXIT.
******************************************************************
* EXECUCAO DA SECAO DE ACAO 1 PARA O PROCESSAMENTO DE DADOS *
******************************************************************
210-CALCULO-1 SECTION.
DISPLAY "Aqui executa acao 1 do processamento"
EXIT.
******************************************************************
* EXECUCAO DA SECAO DE ACAO 2 PARA O PROCESSAMENTO DE DADOS *
******************************************************************
220-CALCULO-2 SECTION.
DISPLAY "Aqui executa acao 2 do processamento"
EXIT.
******************************************************************
* EXECUCAO DA SECAO DE SAIDA DE DADOS *
******************************************************************
300-SAIDA SECTION.
DISPLAY "Aqui vem as acoes da saida de dados"
EXIT.
******************************************************************
* EXECUCAO DA SECAO DE FINALIZACAO E ENCERRAMENTO DO PROGRAMA *
******************************************************************
400-FINALIZA SECTION.
DISPLAY X"0D"
DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING
ACCEPT WS-ENTER
.

Quando na execução do programa é encontrada uma das instruções PERFORM para chamada de seção o fluxo de
operação é transferido para a seção indicada, após a execução da seção o controle é devolvido com o uso do comando
EXIT (que efetua o encerramento e a saída da seção) ou com o uso do ponto de finalização. Pelo fato da chamada de
MO D ULA RI ZA ÇÃ O 173

um módulo pelo comando PERFORM aguardar a ordem de retorno do comando EXIT o uso da instrução STOP RUN de
encerramento do programa deve ser declarado antes das definições das seções customizadas.
Atente para os pontos colorizados e as relações definidas no trecho de exemplificação. Observe a ordem de referência
de cada de seção usada. Quando se usa subníveis em seções, como é o caso dos indicativos 210 e 220 deve-se citá-
las imediatamente a sua definição, neste caso após o indicativo 200.

5.3 SUB-ROTINAS (MÓDULOS)


A definição de seções é uma das etapas da implementação de uso do padrão de programação estruturada em COBOL
a partir de procedimentos como sub-rotinas internas, mas esta não é a única forma. É sabido que um sistema, do ponto
de vista computacional, é formado por um conjunto de programas integrados, cada qual atendendo a uma ação especí-
fica de um todo maior. Cada programa como um conjunto de sub-rotinas internas ou externas deve possuir o código da
ação a ele é determinado. Isso leva a situação em que um programa necessitará chamar outro programa para realizar
certo conjunto de ações do sistema. O programa chamado executará parte da operação que a ele compete e retornará
sua ação para o programa chamador que dará continuidade ao processamento.
Quando um programa chama outro programa, utiliza para esta ação o que se chama sub-rotinas ou módulos. Uma sub-
rotina caracteriza-se por ser o programa chamado por outro programa, sendo que o programa chamado, por sua vez,
poderá chamar a outros programas, tendo-se a partir disso a possibilidade de operar um sistema de chamadas na for-
ma de cascata. É óbvio que fica patente a necessidade de uma documentação bem elaborada, pois o risco de se per-
der no emaranhado de código torna-se grande. Note que qualquer programa pode ser uma sub-rotina. No entanto, só
poderá ser chamado de sub-rotina o programa que especificamente é chamado por outro programa.
O objetivo de uso de sub-rotinas é facilitar a organização do código de um programa em partes, onde cada parte execu-
ta em si certa funcionalidade pertencente a um todo maior. O uso dessa estratégia facilita a manutenção do código e é
fator preponderante na ação de reaproveitamento de código, uma vez que uma sub-rotina com densidade mais genéri-
ca poderá ser usada por mais de um programa poupando o tempo de desenvolvimento.
De maneira geral existem dois tipos de sub-rotinas usadas em COBOL: as internas (definidas a partir do uso do co-
mando PERFORM na forma de seções customizadas) e externas tratadas neste tópico a partir do uso do verbo CALL.
No sentido de evitar generalizações, nesta obra as sub-rotinas internas serão sempre referenciadas como seções e as
sub-rotinas externas, simplesmente como sub-rotinas. O verbo CALL possui a seguinte estrutura sintática:

CALL <"programa"> [USING <argumento1> ...]

Em que programa é o mesmo nome usado na cláusula PROGRAM-ID do programa a ser chamado. A cláusula USING
é opcional, sendo usada para fazer com que o programa em uso passe dados a outro programa, em que argumento1
representa o ponto de acesso para que ocorra a passagem de parâmetros entre os programas, podendo-se definir mais
de um argumento, separados por vírgula.
Quando se escreve um programa como sub-rotina este terá características operacionais e estruturais definidas diferen-
temente de um programa convencional. O programa principal que faz a chamada da sub-rotina tem estrutura semelhan-
te ao que já foi exposto, acrescentando-se o uso do verbo CALL para realizar a chamada do programa que será a sub-
rotina externa.
Um programa de sub-rotina tem seus dados de vínculo declarados na seção LINKAGE SECTION na DATA DIVISION e
não na WORKING-STORAGE SECTION como feito até então; o código da sub-rotina em si usa a cláusula USING junto
a PROCEDURE DIVISION vinculando, obrigatoriamente, os dados indicados na seção LINKAGE com encerramento da
sub-rotina a partir do uso da instrução EXIT PROGRAM e não da instrução STOP RUN. Esses três elementos deverão
estar presentes no código-fonte de um programa de sub-rotina. A definição da LINKAGE SECTION deve ser declarada
abaixo da WORKING-STORAGE SECTION.
Veja que existem características sintáticas que diferenciam estruturalmente um programa convencional de um programa
de sub-rotina externa. Essas diferenças sintáticas imputam diferenças na forma de compilação desses programas. O
ambiente OpenCobolIDE lida automaticamente com essas questões, desde que alguns cuidados sejam tomados.
Desde o início deste estudo foi orientado para que os programas desenvolvidos fossem gravados na subpasta COBOL
da pasta Documentos. Se você entrar na subpasta COBOL verá uma lista com todos os programas desenvolvidos e
174 PRO G RA MA Ç ÃO CO B OL

uma subpasta chamada bin criada automaticamente contendo os arquivos executáveis dos programas gerados pelo
compilador. A subpasta bin é usada para armazenar apenas os executáveis compilados separando-os dos programas
fonte.
Para usar sub-rotinas externas é necessário informar a compilação a subpasta bin como alvo de acesso dessas sub-
rotinas. Aqui há uma característica negativa do ambiente OpenCobolIDE, pois a ferramenta faz a compilação dos códi-
gos-fonte, tanto de programas convencionais como de programas de sub-rotinas na subpasta bin, ponto positivo, mas
não faz o endereçamento da subpasta bin para que os programas convencionais consigam encontrar os programas de
sub-rotinas. Assim sendo, essa ação deve ser realizada manualmente por você. Para tanto, execute o comando de
menu Edit, selecione a opção Preferences ou acione a tecla de função <F2>. Quando apresentada a caixa de diálogo
Preferences selecione a guia Compiler como indicado na figura 5.1.

Figura 5.1 – Caixa de diálogo Preferences (expandida)

A guia Compiler disponibiliza os ajustes que podem ser definidos para a compilação de certo programa. Note do lado
esquerdo a indicação dos rótulos de identificação: Compiler path, VCVARSALL path, Output directory, Associated
extensions, Standard, Free format, Compiler flags, Extra compiler flags, Copybook paths, Library paths e Librar-
ies. Somente altere essas definições se você realmente conhece as opções de uso do compilador GnuCOBOL e sabe o
motivo pelo qual está realizando cada ajuste.
Anteriormente foi instruído como habilitar o modo de compilação para o padrão 2014 ajustando a opção cobol2014 em
Standard. Agora é necessário realizar um novo ajuste, neste caso para operar com os programas de sub-rotinas compi-
lados. Desta forma junto ao rótulo Library paths há uma área em branco e no lado direito desta área há a indicação de
três botões: Add an absolute library path, Add a relative library path e Cancel library path, como apresenta a figura
5.2.

Figura 5.2 – Área de configuração Library paths

Acione o botão Add an absolute library path, selecione a pasta Documentos, na sequência selecione a subpasta
COBOL e selecione a subpasta bin. Em seguida acione o botão Selecionar pasta e o caminho de localização do pro-
grama de sub-rotinas é colocado dentro da área Library paths como mostra a figura 5.3.
MO D ULA RI ZA ÇÃ O 175

Figura 5.3 – Área Library paths com definição do local de acesso a sub-rotinas

Após concluir essa etapa acione o botão OK da caixa de diálogo Preferences.


Na prática os programas convencionais e de sub-rotinas podem possuir qualquer extensão de identificação, não há a
necessidade em absoluto de programas-fonte serem escritos com as extensões “.cob” (usadas nos programas anterio-
res), “.cbl” ou outra qualquer. Normalmente, por tradição, se usam essas extensões e algumas outras relacionando-as a
programas escritos em COBOL.
Neste sentido, apenas para organizar estruturalmente os códigos sem nenhuma outra pretensão, daqui em diante os
programas-fonte convencionais continuam a ser gerados com a extensão “.cob” e os programas-fonte de sub-rotinas
serão definidos a partir do uso de extensão “.cbl”. Algo como cob igual a COBol program e cbl igual a CoBol Library.
Por serem essas ações as primeiras apresentadas as instruções seguintes consideram as informações completas de uso e
posteriormente são indicadas apenas os trechos de cada código a ser usado.
Como exemplo operacional de definição de programa de sub-rotina considere a seguir um código bem simples de um
programa que apresente a mensagem “Estou na sub-rotina”. Assim sendo, no ambiente OpenCobolIDE crie um proje-
to vazio (Empty) chamado rotina a partir da extensão “.cbl” na subpasta COBOL da pasta Documentos e escreva o
código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. ROTINA.
3 *
4 DATA DIVISION.
5 *
6 WORKING-STORAGE SECTION.
7 77 WS-ENTER PIC X.
8 *
9 LINKAGE SECTION.
10 77 LK-ENTER PIC X.
11 *
12 PROCEDURE DIVISION USING LK-ENTER.
13 PROG-PRINCIPAL-PARA.
14 DISPLAY X"0D".
15 DISPLAY "Estou na sub-rotina".
16 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
17 ACCEPT WS-ENTER.
18 EXIT PROGRAM.
------ ------------------------------------------------------------------------

Note que um programa de sub-rotina tem os dados de vínculo definidos na LINKAGE SECTION (linha 9). No entanto,
poderá ter dados definidos de forma não vinculada e declarados na WORKING-STORAGE SECTION da linha 6 desde
que estes sejam definidos antes da LINKAGE SECTION.
Agora crie o programa convencional que apresentará as mensagens “Estou no programa principal” e “Voltei ao pro-
grama principal”. Assim sendo, no ambiente OpenCobolIDE crie um projeto vazio (Empty) chamado base a partir da
extensão “.cob” na subpasta COBOL da pasta Documentos e escreva o programa a seguir.
176 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. BASE.
3 *
4 DATA DIVISION.
5 WORKING-STORAGE SECTION.
6 77 WS-ENTER PIC X.
7 *
8 PROCEDURE DIVISION.
9 PROG-PRINCIPAL-PARA.
10 DISPLAY "Estou no programa principal".
11 DISPLAY "Tecle <ENTER> para avancar... " WITH NO ADVANCING.
12 ACCEPT WS-ENTER.
13 *
14 CALL "ROTINA" USING WS-ENTER.
15 *
16 DISPLAY X"0D".
17 DISPLAY "Voltei ao programa principal".
18 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
19 ACCEPT WS-ENTER.
20 STOP RUN.
------ ------------------------------------------------------------------------

Quando o compilador encontra a instrução CALL da linha 14 com a indicação de chamada a execução da sub-rotina,
neste caso ROTINA efetua um vínculo entre a sub-rotina e o programa chamador.
Atente que tanto o nome da cláusula PROGRAM-ID na linha 2 do programa base como o nome do programa-fonte de
sub-rotina gravados devem ser os mesmos. Neste momento, peça a compilação do programa-fonte convencional: pro-
grama base.cob e observe que o programa de sub-rotina é também compilado. Veja o resultado da ação indicada na
guia Compiler da janela Logs como apresenta a figura 5.4.

Figura 5.4 – Indicação das ações de compilação programa convencional e sub-rotina

Veja que na figura 5.4 há a indicação da compilação do programa convencional como um executável (extensão “.exe”)
e do programa de sub-rotina com uma biblioteca de vínculo dinâmico (extensão “.dll” de Dynamic-Link Library).
A partir de uma visão genérica do uso de sub-rotinas e dos cuidados a serem tomados é apresentado o uso dos recur-
sos de passagem de parâmetro vistos indiretamente no exemplo deste tópico.

5.4 PASSAGENS DE PARÂMETRO


O uso de passagem de parâmetros proporciona o uso de um canal comunicação bidirecional entre um programa cha-
mador e o programa chamado. Essa técnica é muito útil ao proporcionar melhor legibilidade do código de um programa.
A utilização desta técnica traz a luz dois conceitos fundamentais denominados: parâmetro formal e parâmetro real.
Os parâmetros formais são responsáveis pela formalização da ação na chamada da sub-rotina e os parâmetros reais
são assim chamados por realizarem a chamada da sub-rotina. Isto posto, significa que quando um programa chamador
MO D ULA RI ZA ÇÃ O 177

passa parâmetro, este o faz de forma real e guando o programa chamado recebe um parâmetro o faz de forma formali-
zada. O programa chamado formaliza a ação que o programa chamador necessita realizar.
Os parâmetros podem ser passados de duas maneiras. Sua ação pode ocorrer por referência ou por conteúdo. A pas-
sagem de parâmetro por conteúdo. A forma de passar um parâmetro determina seu grau de funcionalidade e restrição.
Quando se usa passagem de parâmetro por referência ocorre que as alterações sofridas na variável da sub-rotina são
refletidas automaticamente no programa chamador. Este tipo de passagem de parâmetro proporcionar um canal de ida
e volta para o valor passado.
Quando se usa passagem de parâmetro por conteúdo ocorre que as alterações sofridas na variável da sub-rotina não
são refletidas no programa chamador. Este tipo de passagem de parâmetro proporcionar um canal apenas de ida para
o valor passado.

5.4.1 Chamada por referência


Em COBOL usa-se passagem de parâmetro por referência quando há necessidade de uma sub-rotina ter que enviar ou
receber de um programa determinado valor e/ou devolver a chamada uma resposta a ação executada. A passagem de
parâmetro por referência faz a alteração do valor do parâmetro real, quando o parâmetro formal for manipulado dentro
da sub-rotina. Qualquer modificação feita no parâmetro formal implica alteração no parâmetro real correspondente. A
alteração feita é devolvida para o programa chamador. Esta forma de passagem de parâmetro é o modo padrão de
operação da linguagem.
Como exemplo de aplicação considere os trechos dos códigos seguintes para a realização do cálculo de uma fatorial de
um valor qualquer em uma sub-rotina e sua chamada em um programa principal. Observe detalhadamente os códigos
apresentados, principalmente os trechos colorizados e como eles se relacionam.
Para uso de passagem de parâmetro por referência abra um projeto vazio chamado fat1 com a extensão “.cbl” na sub-
pasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para o código aos detalhes do código
para a sub-rotina (programa chamado).

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 PROGRAM-ID. FAT1.
2 DATA DIVISION.
3 WORKING-STORAGE SECTION.
4 77 AC-CI PIC 9(4).
5 77 WS-C-FAT PIC 9(8) VALUE 1.
6 LINKAGE SECTION.
7 77 LK-E-NUMERO PIC 9(4).
8 77 LK-S-FAT PIC Z(7)9.
9 PROCEDURE DIVISION USING LK-E-NUMERO, LK-S-FAT.
10 PROG-PRINCIPAL-PARA.
11 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > LK-E-NUMERO
12 COMPUTE WS-C-FAT = WS-C-FAT * AC-CI
13 END-PERFORM.
14 MOVE WS-C-FAT TO LK-S-FAT.
15 EXIT PROGRAM.
------ ------------------------------------------------------------------------

Veja que neste trecho de programa o sub-rotina fat1 recebe como passagem de parâmetro por referência os valores
enviados pelo programa principal as variáveis LK-E-NUMERO e LK-S-FAT definidas nas linhas 7 ne 8 e operacionali-
zadas na linha 9. Qualquer alteração em uma dessas variáveis será refletida no programa chamador.
178 PRO G RA MA Ç ÃO CO B OL

Para demonstrar passagem de parâmetro por referência abra um projeto vazio atribuindo-lhe o nome cap05ap01 e
extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para os deta-
lhes do código do programa principal (programa chamador).

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP01.
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 WS-E-NUMERO PIC 9(4).
6 77 WS-S-FAT PIC Z(7)9.
7 77 WS-ENTER PIC X.
8 PROCEDURE DIVISION.
9 PROG-PRINCIPAL-PARA.
10 DISPLAY "Entre um numero: " WITH NO ADVANCING.
11 ACCEPT WS-E-NUMERO.
12 CALL "FAT1" USING WS-E-NUMERO, WS-S-FAT.
13 DISPLAY "Fatorial = " FUNCTION TRIM(WS-S-FAT).
14 DISPLAY X"0D".
15 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
16 ACCEPT WS-ENTER.
17 STOP RUN.
------ ------------------------------------------------------------------------

Veja que neste trecho não a se quer uma linha de cálculo. O cálculo é realizado na sub-rotina e devolvido seu resultado
ao programa chamador. Observe as definições das variáveis WS-E-NUMERO e WS-S-FAT (parâmetros reais) que são
na chamada da sub-rotina vinculadas, respectivamente, as variáveis LK-E-NUMERO e LK-S-FAT (parâmetro formais).
Observe na linha 12 o uso da instrução CALL "FAT1" USING WS-E-NUMERO, WS-S-FAT a chamada realizada a sub-
rotina FAT1 e a indicação da passagem de parâmetro por referência.

5.4.2 Chamada por conteúdo


Em COBOL usa-se a passagem de parâmetro por conteúdo quando há necessidade de passar algum valor à sub-
rotina, mas não há a necessidade de tê-lo de volta. A passagem de parâmetro por conteúdo consiste na não alteração
do valor do parâmetro real, quando o parâmetro formal for manipulado dentro da sub-rotina. Assim sendo, o valor pas-
sado pelo parâmetro real é copiado para o formal. Qualquer modificação na variável no parâmetro formal não afetará o
valor do parâmetro real correspondente, ou seja, o processamento é executado somente dentro da sub-rotina sem que
haja o mínimo reflexo da alteração no programa chamador. Esta ação para ser utilizada necessita da utilização da pre-
posição BY e do substantivo CONTENT.
Como exemplo de aplicação considere os trechos de código seguintes para a realização do cálculo de uma fatorial de
um valor qualquer em uma sub-rotina e sua chamada em um programa chamador. Observe detalhadamente os códigos
apresentados, principalmente os trechos colorizados e como eles se relacionam.
Para uso de passagem de parâmetro por referência abra um projeto vazio chamado fat2 com a extensão “.cbl” na sub-
pasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para o código aos detalhes do código
para a sub-rotina (programa chamado).
MO D ULA RI ZA ÇÃ O 179

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 PROGRAM-ID. FAT2.
2 DATA DIVISION.
3 WORKING-STORAGE SECTION.
4 77 AC-CI PIC 9(4).
5 77 WS-S-FAT PIC Z(7)9.
6 LINKAGE SECTION.
7 77 LK-E-NUMERO PIC 9(4).
8 77 LK-C-FAT PIC 9(8).
9 PROCEDURE DIVISION USING LK-E-NUMERO, LK-C-FAT.
10 PROG-PRINCIPAL-PARA.
11 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > LK-E-NUMERO
12 COMPUTE LK-C-FAT = LK-C-FAT * AC-CI
13 END-PERFORM.
14 MOVE LK-C-FAT TO WS-S-FAT.
15 DISPLAY "Fatorial = " FUNCTION TRIM(WS-S-FAT).
16 EXIT PROGRAM.
------ ------------------------------------------------------------------------

Veja que nesta versão a sub-rotina recebe os parâmetros LK-E-NUMERO e LK-C-FAT, que determinam a recepção de
dois valores vindos do programa chamador. Note que para efetuar a apresentação do resultado da operação é feito o
uso do comando DISPLAY (linha 15) dentro da própria sub-rotina. Isso decorre do fato de não estar sendo usada a
passagem de parâmetro por referência.
Para demonstrar passagem de parâmetro por referência abra um projeto vazio atribuindo-lhe o nome cap05ap02 e
extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para os deta-
lhes do código do programa principal (programa chamador).

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP02.
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 WS-E-NUMERO PIC 9(4).
6 77 WS-C-FAT PIC 9(8) VALUE 1.
7 77 WS-ENTER PIC X.
8 PROCEDURE DIVISION.
9 PROG-PRINCIPAL-PARA.
10 DISPLAY "Entre um numero: " WITH NO ADVANCING.
11 ACCEPT WS-E-NUMERO.
12 CALL "FAT2" USING BY CONTENT WS-E-NUMERO, WS-C-FAT.
13 DISPLAY X"0D".
14 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
15 ACCEPT WS-ENTER.
16 STOP RUN.
------ ------------------------------------------------------------------------

Perceba que nesta versão é indicado o uso de passagem de parâmetro por conteúdo a partir do uso de BY CONTENT
(linha 12). Neste caso, os valores das variáveis WS-E-NUMERO e WS-C-FAT são passados para as variáveis LK-E-
NUMERO e LK-C-FAT da sub-rotina por conteúdo e qualquer alteração ocorrida nessas variáveis não é refletida no
programa que chama a sub-rotina fat2.
180 PRO G RA MA Ç ÃO CO B OL

5.4.3 Uso integrado de conteúdo e referência


O uso de sub-rotinas é uma ação muito popular no estilo estruturado de programação. Desta forma, o ideal é produzir
sub-rotinas que usem quando necessários as passagens de parâmetro por referência e conteúdo de maneira equilibra-
da. Neste sentido, pode-se estabelecer a passagem de parâmetro por conteúdo para realizar a entrada de um valor em
uma sub-rotina e usar a passagem por referência para a realizar saída da sub-rotina.
Como exemplo de aplicação considere os trechos de código seguintes para a realização do cálculo de uma fatorial de
um valor qualquer em uma sub-rotina e sua chamada em um programa chamador. Observe detalhadamente os códigos
apresentados, principalmente os trechos colorizados e como eles se relacionam.
Para uso de passagem de parâmetro por referência abra um projeto vazio chamado fat3 com a extensão “.cbl” na sub-
pasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para o código aos detalhes do código
para a sub-rotina (programa chamado).

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 PROGRAM-ID. FAT3.
2 DATA DIVISION.
3 WORKING-STORAGE SECTION.
4 77 AC-CI PIC 9(4).
5 LINKAGE SECTION.
6 77 LK-E-NUMERO PIC 9(4).
7 77 LK-C-FAT PIC 9(8).
8 PROCEDURE DIVISION USING LK-C-FAT, LK-E-NUMERO.
9 PROG-PRINCIPAL-PARA.
10 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > LK-E-NUMERO
11 COMPUTE LK-C-FAT = LK-C-FAT * AC-CI
12 END-PERFORM.
13 EXIT PROGRAM.
------ ------------------------------------------------------------------------

Note que nesta versão a maior diferença básica é a mudança da posição dos parâmetros LK-C-FAT e LK-E-NUMERO,
antes definidos como LK-E-NUMERO e LK-C-FAT. Essa mudança se faz necessário devido a um detalhe técnico-
operacional. Quando se usa BY CONTENT todas a variáveis a sua frente se tornam parâmetro por conteúdo e neste
projeto deseja-se usar ambas as formas de parâmetros. É por esta razão que as variáveis estão aqui trocadas de posi-
ção.
Para demonstrar passagem de parâmetro por referência abra um projeto vazio atribuindo-lhe o nome cap05ap03 e
extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente para os deta-
lhes do código do programa principal (programa chamador).

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP03.
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 WS-E-NUMERO PIC 9(4).
6 77 WS-C-FAT PIC 9(8) VALUE 1.
7 77 WS-S-FAT PIC Z(7)9.
8 77 WS-ENTER PIC X.
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 181

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
9 PROCEDURE DIVISION.
10 PROG-PRINCIPAL-PARA.
11 DISPLAY "Entre um numero: " WITH NO ADVANCING.
12 ACCEPT WS-E-NUMERO.
13 CALL "FAT3" USING WS-C-FAT, BY CONTENT WS-E-NUMERO.
14 MOVE WS-C-FAT TO WS-S-FAT.
15 DISPLAY "Fatorial = " FUNCTION TRIM(WS-S-FAT).
16 DISPLAY X"0D".
17 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
18 ACCEPT WS-ENTER.
19 STOP RUN.
------ ------------------------------------------------------------------------

Atente para a configuração na linha 13 da instrução CALL "FAT3" USING WS-C-FAT, BY CONTENT WS-E-NUMERO,
observe que a variável WS-C-FAT é passada antes de BY CONTENT, desta forma é passada como parâmetro por
referência e a variável WS-E-NUMERO que é passada após BY CONTENT, desta forma é passada como parâmetro
por conteúdo. A variável WS-E-NUMERO ficará com seu valor preso dentro da sub-rotina e a variável WS-C-FAT terá
seu valor alterado no programa chamador.
O uso de BY CONTENT é obrigatório para o estabelecimento da passagem de parâmetro por conteúdo. Para a passa-
gem de parâmetro por referência não é necessário mencionar absolutamente nada, pois é o modo padrão usado na
linguagem COBOL. Mas desejando ser mais específico pode-se usar BY REFERENCE. Desta forma a linha de instru-
ção CALL poderia ser escrita como:

CALL "ROTINA" USING BY REFERENCE WS-C-FAT,


BY CONTENT WS-E-NUMERO.

De um ponto de vista simplista BY REFERENCE pode ser omitido em um programa, mas do ponto de vista documental
esta forma pode ser mantida para deixar o código mais legível e altamente documentado. Mas como sempre a decisão
é sua.
Vale aqui uma observação em relação ao uso de passagens de parâmetros em COBOL. Na maior parte das linguagens
de programação o modo padrão de ação é de passagem de parâmetro por valor (que em COBOL chamasse passagem
de parâmetro por conteúdo) e não por referência.

5.5 LIVRO DE CÓPIA


Um livro de cópia (copybook) é uma interface de código-fonte usada como base operacional de suporte a outros códi-
gos-fontes na utilização de dicionários de dados. Este tipo de arquivo é usado para armazenar o layout dos nomes e
tipos de dados de variáveis (nível 77), registros (nível 01) e constantes (nível 78) mais usadas na programação diária de
seu ambiente de trabalho.
Há, na prática diária, um conjunto de dados que acabam sendo de uso repetitivo e corriqueiro na programação, esses
dados são candidatos a serem colocados dentro de um copybook evitando-se escrevê-los repetidamente em diversos
programas. Um programa pode usar mais de um livro de cópia, que por sua vez pode ser usado por mais de um pro-
grama.
Os livros de cópia são geralmente definidos com o mesmo nome do programa fonte a ele vinculado a partir da extensão
de identificação “.cpy” quando há neste sentido apenas uma relação bilateral. No entanto, se a relação em uso for mul-
tilateral esse estilo não se aplica e outros nomes poderão ser definidos para os livros de cópia. A propósito os arquivos
de copybooks podem ter qualquer extensão de identificação, a extensão “.cpy” é usada por tradição.
Para fazer uso de copybooks no OperCobolIDE é necessário realizar mais uma configuração no ambiente. Assim sen-
do, acione a tecla de função <F2> e será apresentada a caixa de diálogo Preferences. Localize o rótulo Associated
182 PRO G RA MA Ç ÃO CO B OL

extensions e acrescente na lista a extensão “.cpy”. Para tanto, após a indicação das extensões “.cbl;.pco;.lst;.cob”
coloque um ponto-e-vírgula e acrescente a extensão pretendida. Observe a imagem da figura 5.5 com a alteração indi-
cada registrada.

Figura 5.5 – Acréscimo da extensão “.cpy” no ambiente

A partir deste momento o ambiente disponibiliza para seleção a nova extensão cadastrada. Veja, por exemplo, a nova
extensão indicada na caixa de diálogo New file como mostra a figura 5.6.

Figura 5.6 – Extensão incorporada

Assim como foi inserida uma extensão, extensões também podem ser facilmente retiradas de Associated extensions.
Veja que o ambiente OpenCobolIDE possui um bom nível de configuração que permite realizar alguns ajustes finos.
A estrutura técnica de um arquivo de copybook é extremamente simples. Basta apenas respeitar as margens entre a
sétima e septuagésima colunas do formulário. Não é necessário o uso de nenhum comando, nem tão pouco definições
de divisões, seções ou parágrafos.
Como exemplo de definição de um livro de cópia considere um arquivo simples com as definições de algumas constan-
tes matemáticas igualmente encontradas na linguagem C++ e inexistentes em COBOL. Para o uso deste recurso, abra
um novo projeto vazio chamado book com a extensão “.cpy” na subpasta COBOL da pasta Documentos e escreva a
partir da sétima coluna dos dados indicados a seguir. Não se preocupe com as indicações de erro que o ambiente
aponta, mas garanta de colocar no arquivo exatamente o que aqui é indicado.
MO D ULA RI ZA ÇÃ O 183

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 78 M_E VALUES 2.71828182845904523536.
2 78 M_LOG2E VALUES 1.44269504088896340736.
3 78 M_LOG10E VALUES 0.434294481903251827651.
4 78 M_LN2 VALUES 0.693147180559945309417.
5 78 M_LN10 VALUES 2.30258509299404568402.
6 78 M_PI VALUES 3.14159265358979323846.
7 78 M_PI_2 VALUES 1.57079632679489661923.
8 78 M_PI_4 VALUES 0.785398163397448309616.
9 78 M_1_PI VALUES 0.318309886183790671538.
10 78 M_2_PI VALUES 0.636619772367581343076.
11 78 M_2_SQRTPI VALUES 1.12837916709551257390.
12 78 M_SQRT2 VALUES 1.41421356237309504880.
13 78 M_SQRT1_2 VALUES 0.707106781186547524401.
------ ------------------------------------------------------------------------

Na sequência será criado o programa que efetua o uso do arquivo de copybook. Para tanto, crie um projeto vazio com o
nome book a partir da extensão “.cob” na subpasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. BOOK.
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 COPY "book.cpy".
6 PROCEDURE DIVISION.
7 DISPLAY M_PI.
8 STOP RUN.
------ ------------------------------------------------------------------------

Veja a indicação de uso do comando COPY com a citação de acesso ao arquivo copybook book.cpy. O arquivo do livro
de cópia deve ser mencionado na DATA DIVISION a partir da área de armazenamento, uma vez que estabelece dados
para essa área do programa. Veja que a partir dessa estratégia é possível definir estruturas de dados comuns que fi-
quem disponíveis a vários programas.

5.6 ESCOPO E COMPORTAMENTO DE VARIÁVEIS


Uma das grandes preocupações no desenvolvimento de software é, e sempre foi, o consumo de memória. Memórias
são finitas e tendem a se esgotar, de certa forma, com certa rapidez se não forem bem administradas. Isso faz com que
os sistemas operacionais efetuem parte desta administração, administrando o gerenciamento do espaço de uso entre
memória principal e secundária.
Mas não se deve achar que devido a administração de espaço executada pelo sistema operacional que está tudo bem
e que a equipe de desenvolvimento não tem responsabilidade sobre isso, pelo contrário. A preocupação com o controle
no uso do espaço de memória é tão grande que é comum linguagens de programação fornecem ferramentas para auxi-
liar esta tarefa. No caso da linguagem COBOL é disponibilizada duas seções para auxiliar a forma de acesso do espaço
de memória para uso e definição de dados, uma dessas seções, foi usada em todos os programas anteriores, trata-se
da seção WORKING-STORAGE.
184 PRO G RA MA Ç ÃO CO B OL

Na seção WORKING-STORAGE faz-se a definição de dados estaticamente (dados permanentes). Dados estáticos são
definidos e inicializados em um programa e ocupam a memória durante todo o tempo de execução deste programa. No
caso da execução de uma sub-rotina com este escopo de comportamento suas variáveis ficarão alocadas na memória
até que o programa chamador seja encerrado. Veja que esta é uma forma que consome muito do recurso de espaço de
memória, pois as variáveis definidas possuem um comportamento de escopo global do espaço usado. Como alternativa
na busca do equilíbrio de consumo de memória a linguagem possui a seção LOCAL-STORAGE.
Na seção LOCAL-STORAGE faz-se a definição de dados dinamicamente, os quais são definidos e inicializados em um
programa e ocupam a memória enquanto o programa está em execução. No momento que o programa é encerrado os
dados são eliminados da memória. Se o programa chama uma sub-rotina que utiliza este escopo de comportamento
suas variáveis serão destruídas da memória quando o controle voltar para o programa que efetuou a chamada da sub-
rotina, pois as variáveis definidas possuem um comportamento de escopo local em relação ao espaço usado.
Desta forma, passa-se a ter duas áreas para a definição de dados em um programa: a seção WORKING-STORAGE
que pode e deve ser usada para representar dados que necessitem estar ativos durante toda a execução do programa
e sub-rotinas chamadas por estes programas; e a seção LOCAL-STORAGE que pode e deve ser usada para represen-
tar dados temporários tanto no programa chamador como na sub-rotina.
Para auxiliar o processo de documentação interna do código há o costume de usar o mnemônico WS para representar
os dados declarados na WORKING-STORAGE SECTION, os dados da LOCAL-STORAGE SECTION são normalmen-
te identificados com o mnemônico LS.
Em termos práticos nada é possível de se notar ao usar uma ou outra seção de definição de dados, pois esse grau de
detalhamento ocorre apenas internamente e de forma muitíssimo transparente aos olhos do desenvolvimento. Apenas
acredite que isso funciona desta forma, pois é assim que é.
A título de mera ilustração o trecho de código seguinte demonstra o código de um programa que apresenta o resultado
do cálculo da fatorial de um número qualquer utilizando-se dados com escopo de comportamento local. Atente para o
trecho grafado em vermelho no código do programa de sub-rotina (programa chamado).

DATA DIVISION.
LOCAL-STORAGE SECTION.
77 AC-CI PIC 9(4).
LINKAGE SECTION.
77 LK-E-NUMERO PIC 9(4).
77 LK-C-FAT PIC 9(8).
PROCEDURE DIVISION USING LK-C-FAT, LK-E-NUMERO.
PROG-PRINCIPAL-PARA.
PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > LK-E-NUMERO
COMPUTE LK-C-FAT = LK-C-FAT * AC-CI
END-PERFORM.
EXIT PROGRAM.

Neste trecho a variável AC-CI é criada no momento desta chamada e ao término da execução da sub-rotina seu espaço
de uso na memória é liberado. Desta forma, é possível economizar espaço de memória que poderá ser compartilhado
com outros dados do próprio programa. Atente para o código do programa principal (programa chamador).

DATA DIVISION.
LOCAL-STORAGE SECTION.
77 LS-E-NUMERO PIC 9(4).
77 LS-C-FAT PIC 9(8) VALUE 1.
WORKING-STORAGE SECTION.
77 WS-S-FAT PIC Z(7)9.
77 WS-ENTER PIC X.
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY "Entre um numero: " WITH NO ADVANCING.
ACCEPT LS-E-NUMERO.
CALL "ROTINA" USING BY REFERENCE LS-C-FAT,
BY CONTENT LS-E-NUMERO.
MO D ULA RI ZA ÇÃ O 185

MOVE LS-C-FAT TO WS-S-FAT.


DISPLAY "Fatorial = " FUNCTION TRIM(WS-S-FAT).
DISPLAY X"0D".
DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
ACCEPT WS-ENTER.
STOP RUN.

O programa chamador também está fazendo uso de escopo de seção LOCAL-STORAGE. Neste caso, essas variáveis
são destruídas somente quando este código for encerrado e teriam efeito de liberação de espaço de memória se este
fosse um sub-rotina de um outro programa chamador. Desta forma, essas variáveis ficam definidas na memória quando
a sub-rotina ROTINA é chamada.
Há um cuidado a ser tomado, pois a cada chamada os dados definidos na seção LOCAL-STORAGE são inicializados.
Neste caso, cada dado que contenha a cláusula VALUE será inicializado com o valor a ela especificado. Para sub-
rotinas aninhadas os dados são alocados a cada chamada isso fara com que a cada chamada o valor indicado em
VALUE seja reaplicado ao dado não mantendo, por ventura, um valor anteriormente atribuído.
No frigir dos ovos as seções WORKING-STORAGE e LOCAL-STORAGE possuem funcionamento idênticos e realizam
o mesmo trabalho operacional, mas não da mesma forma. Daqui em diante a seção WORKING-STORAGE, neste capí-
tulo, é usada apenas quando necessária, exceto para o próximo tópico que reforça o uso da seção LOCAL-STORAGE.

5.7 SUB-ROTINAS RECURSIVAS


Sub-rotinas recursivas são módulos de programas que percorrem sucessivamente a si mesmos um determinado núme-
ro de vezes. Uma sub-rotina recursiva não pode chamar a si mesma indiscriminadamente, pois, se assim o fizer, entrará
em um processo infinito de chamadas exaustivas comprometendo o espaço de memória principal da máquina. Portanto,
é necessário que a sub-rotina recursiva tenha a definição de uma condição de interrupção, que é em si a solução mais
simples e menor do próprio problema. Recursão é uma forma de fazer iterações sem o uso de laços.
A forma mais popular, didática e simples de demonstrar o uso de sub-rotina recursiva é a realização do cálculo da fato-
rial de um número natural qualquer. Do ponto de vista matemático fatorial é o produto sucessivo dos números naturais
iniciados em n, sendo este decrescido de 1 em 1 até 1. Por definição o fatorial de 0 e o fatorial de 1 como 1.
Assim sendo, considere um programa que mostra os resultados das fatoriais calculadas entre 0 e 33 de forma recursi-
va. Atente para os trechos colorizados, inclusive para o uso do comando GOBACK e da cláusula RECURSIVE definida
após PROGRAM-ID, em que IS é opcional. Assim sendo, defina um projeto vazio com o nome fatorial a partir da ex-
tensão “.cob” na subpasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. FATORIAL IS RECURSIVE.
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 77 WS-NUM PIC 9(2) VALUE 33.
6 77 WS-FAT PIC 9(38) VALUE 0.
7 77 WS-S-N PIC Z9.
8 77 WS-S-F PIC Z(38).
9 LOCAL-STORAGE SECTION.
10 77 LS-NUM PIC 9(2).
11 PROCEDURE DIVISION.
12 PROG-PRINCIPAL-PARA.
13 MOVE WS-NUM TO LS-NUM.
14 IF WS-NUM = 0
------ ------------------------------------------------------------------------
186 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
15 MOVE 1 TO WS-FAT
16 ELSE
17 SUBTRACT 1 FROM WS-NUM
18 CALL "FATORIAL" USING LS-NUM
19 MULTIPLY LS-NUM BY WS-FAT
20 END-IF.
21 MOVE WS-FAT TO WS-S-F.
22 DISPLAY WS-S-N "! = " WS-S-F.
23 GOBACK.
------ ------------------------------------------------------------------------

Observe na linha 18 o uso da instrução CALL "FATORIAL" USING LS-NUM realizando uma chamada, neste caso
recursiva, ao programa de mesmo nome (PROGRAM-ID. FATORIAL). A recursividade para ocorrer necessita do uso
da cláusula de identificação RECURSIVE (linha 2) após o nome do programa e deve ser encerrada com o uso do co-
mando GOBACK (linha 23) que efetua um retorno a si mesmo até que uma condição de encerramento seja encontrada.
Como dito é necessário que a sub-rotina recursiva tenha a definição de uma condição de encerramento, que é em si a
solução mais simples e menor para o problema avaliado. Este ponto é estabelecido no trecho entre as linhas 14 e 20.
A linha 14 contém a instrução IF WS-NUM = 0, que sendo verdadeira retorna para a sub-rotina o último valor calculado
para a fatorial, neste caso, valor 1. No entanto, se a condição for falsa o programa efetua na linha 17 a subtração de 1
unidade no valor da variável WS-NUM, efetua a chamada “mais uma vez” do próprio programa e multiplica o valor de
LS-NUM (atualizado com o último valor da variável WS-NUM pela instrução MOVE WS-NUM TO LS-NUM das linha 13)
pelo valor atualizado a cada iteração da variável WS-FAT.
Há neste programa um detalhe importantíssimo a ser considerado, pois só é possível fazer uso de ação recursiva sobre
certa variável se esta estiver definida exclusivamente na seção LOCAL-STORAGE. Essa é a razão pela qual a variável
LS-NUM está declarada sob esta seção. Caso seja colocada na seção WORKING-STORAGE o cálculo não acontece-
rá. Faça um teste.
Outro detalhe também a ser considerado é que as variáveis de apoio a operação WS-NUM e WS-FAT devem obrigato-
riamente serem definidas na seção WORKING-STORAGE, pois essas variáveis precisam ter seus valores mantidos
memorizados a cada chamada.
Bem, neste tópico e no anterior a ele foram introduzidas duas novas formas de encerramento de execução de progra-
mas, sendo EXIT PROGRAM (saída do programa) e GOBACK (retorne), além da forma STOP RUN (pare a execução)
exaustivamente aplicada nos programas até então produzidos. Essas três instruções efetuam a mesma ação, ou seja,
encerram a execução de determinado programa. É possível usá-las como substitutas uma das outras em programas
convencionais (programas principais), mas quando usadas em sub-rotinas a coisa muda de figura. Cada uma dessas
instruções muda a forma do encerramento do programa na memória: se o programa ficará em seu estado de execução
inicial, no último estado usado ou então para onde retornar, dependerá da forma de encerramento definida.
A instrução STOP RUN quando aplicada sobre um programa convencional, ou usada em um programa principal, retor-
na o controle de execução do programa ao sistema operacional e procede seu encerramento, mas quando aplicada
sobre um programa de sub-rotina efetua a finalização da sub-rotina e o encerramento do programa chamador. Por esta
razão, esta instrução é adequada para uso em programas convencionais que eventualmente chamam uma sub-rotina,
mas não devem ser usadas nas sub-rotinas.
A instrução EXIT PROGRAM quando aplicada sobre um programa convencional apenas o finaliza não realizando ne-
nhuma outra ação, mas quando aplicada sobre um programa de sub-rotina efetua o retorno da sub-rotina ao programa
chamador sem finalizar a execução completa do programa. Por esta razão, esta instrução é adequada para uso em
sub-rotinas. Caso haja o encadeamento de chamadas de sub-rotinas, o encadeamento será encerrado, mas não finali-
zado, a menos que o programa em execução seja o mais antigo nas chamadas sucessivas.
A instrução GOBACK se aplicada sobre um programa convencional assemelhar-se-á a instrução STOP RUN, se apli-
cada sobre uma sub-rotina assemelhar-se-á a instrução EXIT PROGRAM, mas apesar dessas características não deve
MO D ULA RI ZA ÇÃ O 187

ser usada como substituta genérica as outras instruções. Use GOBACK apenas para o encerramento de programas
recursivos.
É importante considerar que geralmente quando uma sub-rotina for encerrada a partir das instruções GOBACK ou EXIT
PROGRAM seu último estado de comportamento usado permanecerá inalterado. Se a sub-rotina for executada nova-
mente ela encontrará na memória os últimos valores exatamente como deixados. Há algumas exceções dentro do que
já foi exposto: uso de sub-rotinas chamadas pelo comando PERFORM, sub-rotinas chamadas dinamicamente e poste-
riormente canceladas e itens de dados definidos na seção LOCAL-STORAGE são redefinidos ao estado inicial de me-
mória.

5.8 AÇÕES COMPLEMENTARES


A partir de uma visão geral sobre a concepção e uso essencial das ações básicas de produção de programas estrutu-
rados cabe ampliar um pouco mais este conceito com o entendimento de algumas operações que auxiliam esta tarefa
apesar de não estarem diretamente ligadas a essas ações.

5.8.1 Dados renomeados


Há um tema que pode não estar vinculado diretamente a filosofia da programação estruturada, mas com certeza auxilia-
rá na definição adequada de estruturas de dados. Foi visto até aqui o uso e definição de diversos dados nas mais vari-
adas formas, foi visto o uso de alguns recursos, como por exemplo o copybooks que pode ser definido por você ou por
terceiros.
Quando uma estrutura é definida por terceiros em um copybook fica complicado fazer alteração de seus nomes para
melhor acomodar certas situações particulares, por ser um recurso que pode estar sendo compartilhado com outras
pessoas. É neste sentido que se pode lançar mão de um recurso em COBOL que permite redefinir os nomes dos dados
de estruturas padronizadas, que não podem ou não devem ser alterados. Pode ocorrer que você queira ajustar um a
partir de um conjunto de campos e tratá-los como um único campo e muito mais. Para estes casos há para o auxílio a
cláusula RENAMES que para ser usada necessita ser definida com o código de nível 66, o qual permite atribuir apelido
como nome alternativo a um campo ou grupo. Este recurso não adiciona um novo campo ao registro, apenas atribui um
nome alternativo a um campo existente. Desta forma, este recurso não ocupa espaço extra de memória.
A cláusula RENAMES é usada para a formatação de itens elementares pertencentes a um determinado item de grupo.
Sua forma sintática de uso corresponde a:

66 <nome1> RENAMES <nome2> [THROUGH/THRU <nomeN>]

Em que nome1 é a definição de um nome de referência de redefinição ao nome indicado em nome2 que poderá se
entender com o uso das cláusulas THROUGH ou THRU até o nomeN.
O item indicado sob o nível 66 deve obrigatoriamente ser declarado logo após ao item de grupo ao qual fará referência
para, assim, poder ser associado aos seus itens elementares. Jamais use o código de nível 66 como referência a dados
qualificados com os níveis 01, 77 e 88, a variáveis compostas (listas ou tabelas) ou mesmo a outro nível 66, somente
use essa técnica com dados identificados com níveis de 02 a 49.
Se usada a forma 66 <nome1> RENAMES <nome2> ocorrerá que nome1 será sinônimo de referência ao nome2, mas
se for usada a forma 66 <nome1> RENAMES <nome2> THRU <nomeN> ocorrerá que nome1 será uma referência
similar a um item de grupo. Observe esses detalhes.

01 LOCALIZACAO.
05 VIA PIC X(40).
05 NUM PIC 9(05).
05 COMPLMT PIC X(20).
66 ENDERECO RENAMES VIA THRU NUM.
66 COMPLEMENTO RENAMES COMPLMT.
188 PRO G RA MA Ç ÃO CO B OL

Veja que o item COMPLMT é renomeado simplesmente como item elementar COMPLEMENTO e o item ENDERECO é
renomeado como um item de grupo abrangendo do item VIA até (THRU) ao item NUM. Note na sequência uma estrutu-
ra mais complexa.

01 IDENTIFICACAO-PESSOAL.
05 NOME-I PIC X(35).
05 NOME-U PIC X(15).
66 NOME-COMPLETO RENAMES NOME-I THRU NOME-U.
01 LOCALIZACAO.
05 VIA PIC X(40).
05 NUM PIC 9(05).
05 COMPLMT PIC X(20).
05 BAIRRO PIC X(20).
05 CIDADE PIC X(25).
05 ESTADO PIC A(02).
05 CEP PIC 9(08).
66 ENDERECO RENAMES VIA THRU NUM.
66 COMPLEMENTO RENAMES COMPLMT.
66 CIDADE-ESTADO RENAMES CIDADE THRU ESTADO.
66 ENDERECO-COMPLETO RENAMES VIA THRU CEP.

Observe que o item NOME-COMPLETO só pode ser definido imediatamente abaixo do item de grupo a ele vinculado,
ou seja, o único local que esse elemento pode ser definido é imediatamente abaixo de IDENTIFICACAO-PESSOAL.
Outro detalhe é a definição do item ENDERECO-COMPLETO sendo associado a faixa de VIA até CEP. Não tente fazer
a definição de um nível 66 com outros itens de nível 66, pois o compilador não aceita pelo este tipo de definição. Assim
sendo, não tende usar END-COMPLETO RENAMES ENDERECO-COMPLETO.
O recurso de nomeação é uma estratégia que visa economizar espaço em memória. Útil quando há a necessidade de
se trabalhar com dados distintos, mas que tenham alguma proximidade lógica. Imagine a definição de uma estrutura de
registro para acomodar os dados de clientes, tanto para pessoa física como pessoa jurídica. Nesses dois tipos de clien-
te há dados que são comuns e dados que são específicos, os dados comuns poderão ser renomeados para atender a
uma especificidade, observe.

01 CLIENTE.
05 DESEGNACAO PIC X(50).
05 ID-FEDERAL PIC X(18).
05 ENDERECO PIC X(40).

66 PF-NOME RENAMES DESEGNACAO.


66 PF-CPF RENAMES ID-FEDERAL.

66 PJ-NOME RENAMES DESEGNACAO.


66 PF-CNPJ RENAMES ID-FEDERAL.

Veja que a estrutura CLIENTE possui definido genericamente um conjunto de campos, dos quais dois são redesigna-
dos para representar clientes pessoa física e pessoa jurídica aproveitando-se de um único espaço de memória, uma
vez que jamais haverá um cliente que seja de escopo físico e escopo jurídico ao mesmo tempo.
Observe em seguida o trecho de programa que opera esses dados de forma particularizada.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.

MOVE "JOAO PEDRO" TO PF-NOME.


MOVE "123.456.789-00" TO PF-CPF.
MOVE "R. ALFA, 123" TO ENDERECO.
MO D ULA RI ZA ÇÃ O 189

DISPLAY "Dados PESSOA FISICA"


DISPLAY "Nome ......: " PF-NOME.
DISPLAY "Endereco ..: " ENDERECO.
DISPLAY "CPF .......: " PF-CPF.

MOVE "JOAO PEDRO - ME" TO PF-NOME.


MOVE "12.345.678/0001-99" TO PF-CNPJ.
MOVE "R. BETA, 456" TO ENDERECO.

DISPLAY "Dados PESSOA FISICA"


DISPLAY "Nome ......: " PF-NOME.
DISPLAY "Endereco ..: " ENDERECO.
DISPLAY "CPF .......: " PF-CPF.

Perceba no trecho anterior do código o uso transparente dos campos redesignados como se fossem campos totalmente
independentes. Veja que a vantagem dessa estratégia de programação é usar área de memórias de forma genérica a
representação de dados variados.

5.8.2 Acesso externo


Dentre as diversas ações que podem ser realizadas com a linguagem COBOL está a de se fazer comunicação externa
com a máquina a partir de chamadas realizadas a rotinas externas direcionadas ao processador da máquina ou ao
sistema operacional. O acesso a rotinas externas é efetuado com os conhecidos comandos CALL/USING, tendo como
diferencial o uso do nome da rotina externa a ser utilizada e não de uma sub-rotina (interna). Há no GnuCOBOL algu-
mas rotinas externas que podem ser usadas. Aqui são apresentadas apenas duas rotinas, para saber mais a respeito
deste recurso consulte o manual GnuCOBOL: Programmer’s Guide, tópico 8.3, Builtin System Subroutines.
Uma função importante em uma linhagem de programação é por incrível que pareça uma que efetue atrasos no proces-
samento. Há vezes que é necessário imputar atraso no processamento em curso para aguardar outra tarefa que esteja
sendo realizada ser concluída apara que o programa em curso possa dar continuidade.
Para esta situação pode-se usar a rotina C$SLEEP operada a partir da sintaxe.

CALL "C$SLEEP" USING <tempo>

Em que tempo é a definição de um valor numérico decimal positivo que especifica a quantidade do tempo em segun-
dos a ser dado como pausa. Se forem usados valores inteiros, basta imediatamente a cláusula USING definir o valor
desejado de forma numérica, mas se o valor a ser usado for decimal este precisa para o compilador GnuCOBOL estar
grafado entre aspas inglesas como um valor alfanumérico.
No trecho de código seguinte é demonstrado o uso da rotina C$SLEEP com os tempos de 1, 1.5 e 2.3 segundos para
apresentar as mensagens "ALO, MUNDO 1!" "ALO, MUNDO 2!", "ALO, MUNDO 3!" e "ALO, MUNDO 4!".

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY "ALO, MUNDO 1!".
CALL "C$SLEEP" USING 1.
DISPLAY "ALO, MUNDO 2!".
CALL "C$SLEEP" USING "1.5".
DISPLAY "ALO, MUNDO 3!".
CALL "C$SLEEP" USING "2.3".
DISPLAY "ALO, MUNDO 4!".

Veja o detalhamento de uso de tempos inteiros na forma numérica e de tempos decimais na forma alfanumérica. Os
valores inteiros também podem ser definidos entre aspas inglesas.
Um detalhe importante a ser considerado é que a precisão do tempo de pausa poderá variar para mais ou para menos
que os segundos estabelecidos, dependendo do nível de processamento sendo executado pela máquina.
190 PRO G RA MA Ç ÃO CO B OL

Além de executar rotinas externas identificadas com o prefixo “C$” é possível efetuar chamadas as funções executadas
exclusivamente pelo sistema operacional a partir do uso da rotina SYSTEM que opera segundo a sintaxe.

CALL "SYSTEM" USING <"comando"> [RETURNING <valor>].

Em que comando é a definição de uma ação a ser executada pelo sistema operacional sendo representada por uma
sequência de caracteres alfanuméricos delimitados entre aspas inglesas. A cláusula RETURNING é opcional e pode ser
usada para retornar em valor o código de execução da operação efetuada, sendo 0 quando ação for bem sucedida e
diferente de 0 quando ocorrer algum erro na ação solicitada.
O comando passado a rotina SYSTEM é interpretado como se fosse um comando escrito pelo próprio usuário na linha
de comando do modo console/terminal, tendo-se que tomar cuidado com o tamanho do comando usado que pode vari-
ar entre os sistemas operacionais. No caso do Windows a quantidade máxima é de 128 bytes.
A rotina SYSTEM coloca o terminal em operação na sua forma padrão antes do comando enviado ser executado e o
restabelece após a conclusão da ação enviada.
Veja dois exemplos de uso a rotina SYSTEM em sistemas operacionais Windows e LINUX para a realização da apre-
sentação dos arquivos existente no diretório de trabalho do usuário.

CALL "SYSTEM" USING "ls /usr"


CALL "SYSTEM" USING "dir \users\manzano"

Veja a seguir um trecho de programa que apresenta a listagem do conteúdo do diretório da área de trabalho do usuário
a partir da execução do comando CALL.

LOCAL-STORAGE SECTION.
77 LS-RET PIC S9.
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
CALL "SYSTEM" USING "DIR \USERS\MANZANO" RETURNING LS-RET.
DISPLAY X"0D0D"
IF LS-RET = 0
DISPLAY "Acao bem sucedida."
ELSE
DISPLAY "Ocorreu erro."
END-IF.

Observe no trecho indicado a execução do comando de sistema operacional “DIR \USERS\MANZANO” e do retorno do
valor da execução junto a variável LS-RET que se estiver com valor 0 indicará que a ação foi bem sucedida.
A partir dessa proposta pode-se fazer agora o uso de um recurso paliativo para proceder a limpeza da tela do console
de saída. Veja as chamadas para limpar a tela no Windows e LINUX.

CALL "SYSTEM" USING "clear"


CALL "SYSTEM" USING "cls"

Essa forma de efetuar limpeza de tela não é a mais elegante, aliás é tosca. No entanto, ela atende a forma de apresen-
tação mais simplista que a linguagem faz uso a partir do uso do modo texto operado pelo console ou terminal. Há outra
forma mais elegante de se efetuar esta ação no compilador GnuCOBOL com a instrução CALL X"E4". No entanto,
para fazer uso deste recurso é necessário habilitar a seção SCREEN, a ser apresentada mais adiante neste trabalho.
Até lá a tela será limpa com a instrução CALL "SYSTEM" USING "cls".
MO D ULA RI ZA ÇÃ O 191

5.8.3 Funções definidas


Ao longo dos capítulos anteriores foram apresentadas algumas funções internas da linguagem, chamada funções in-
trínsecas. Além dessas funções há a possibilidade de se definir funções próprias. Função é um estilo de sub-rotina que
tem por finalidade retornar um valor como resposta de sua ação.
Antes de demonstrar este recurso é importante esclarecer que o compilador GnuCOBOL apesar de permitir o desenvol-
vimento de funções personalizadas não efetua sua total validação interna. Devido a isto apresenta mensagem de adver-
tência “no definition/prototype seen for function 'função'” quando da indicação de uso deste recurso. Este efeito
ocorre pelo fato de as ações de definição e prototipagem internas não estarem completamente implementadas no com-
pilador. Como o compilador está em desenvolvimento é uma questão de tempo até que esse problema seja devidamen-
te resolvido. No entanto, ele não atrapalha o uso do recurso, apenas incomoda com a apresentação da mensagem.
Para a criação de funções usa-se no programa (que deverá ser escrito separadamente do programa que usará a fun-
ção) o parágrafo FUNCTION-ID semelhantemente ao uso do parágrafo PROGRAM-ID e junto a divisão de procedimen-
to usa-se além de USING BY VALUE a cláusula RETURNING para que a função retorne sua resposta de operação.
O uso de BY VALUE junto a cláusula USING garante que a passagem de parâmetro é efetivamente por valor. Assim,
qualquer valor alfanumérico será tratado como numérico. No entanto, o uso de BY VALUE gera uma mensagem de
advertência avisando que a manipulação dos parâmetros passados por BY VALUE na versão em uso está inacabada e
provavelmente sofrerá alguma alteração posterior “handling of parameters passed BY VALUE is unfinished; imple-
mentation is likely to be changed”. Neste caso, pode-se até omitir BY VALUE, mas aí os parâmetros serão passados
por referência. A passagem de parâmetro em funções pode ser feita apenas por valor (BY VALUE) e referência (BY
REFERENCE), em sub-rotinas pode ser feita por valor (BY VALUE), por conteúdo (BY CONTENT) e por referência (BY
REFERENCE)
Por ser uma função uma sub-rotina, está deve ser encerrada de maneira adequada. Neste sentido, deve-se encerrar o
código da sub-rotina obrigatoriamente com as instruções EXIT FUNCTION e END FUNCTION.
No sentido de demonstrar essa aplicação considere como exemplo o desenvolvimento de uma função que retorna o
resultado da raiz enésima de uma base qualquer. Assim sendo, crie um projeto vazio, atribuindo o nome rzenesi a partir
da extensão “.cbl” na subpasta COBOL da pasta Documentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. RZENESI.
3 DATA DIVISION.
4 LINKAGE SECTION.
5 77 LK-BAS PIC 9(3)V9(5).
6 77 LK-IND PIC 9(3)V9(5).
7 77 LK-EXP PIC 9(3)V9(5).
8 77 LK-RST PIC 9(7)V9(5).
9 PROCEDURE DIVISION USING BY VALUE LK-BAS, LK-IND, LK-EXP
10 RETURNING LK-RST.
11 PROG-PRINCIPAL-PARA.
12 COMPUTE LK-RST = LK-BAS ** (LK-EXP / LK-IND).
13 EXIT FUNCTION.
14 END FUNCTION RZENESI.
------ ------------------------------------------------------------------------

Observe em vermelho a identificação obrigatória do nome da função definido tanto na linha 2 (FUNCTION-ID) como na
linha 13 (END FUNCTION) e na cor verde a identificação de uso das cláusulas USING e RETURNING as nas linhas 9 e
10. Em rosa, na linha 9, é indicado o uso de BY VALUE lembrando de sua condição de advertência no GnuCOBOL
192 PRO G RA MA Ç ÃO CO B OL

Na sequência é preciso criar o programa que efetua a chamada da função RZENESI. Neste caso, abra um projeto va-
zio, atribuindo o nome calcraiz a partir da extensão “.cob” na subpasta COBOL da pasta Documentos e informe o
código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CALCRAIZ.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION RZENESI.
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 77 WS-BAS PIC 9(3)V9(5) VALUE 2.
10 77 WS-IND PIC 9(3)V9(5) VALUE 3.
11 77 WS-EXP PIC 9(3)V9(5) VALUE 4.
12 77 WS-RST PIC 9(7)V9(5).
13 77 WS-RES PIC Z(6)9.9(5).
14 PROCEDURE DIVISION.
15 PROG-PRINCIPAL-PARA.
16 MOVE RZENESI(WS-BAS, WS-IND, WS-EXP) TO WS-RES.
17 DISPLAY FUNCTION TRIM(WS-RES).
18 STOP RUN.
19 END PROGRAM CALCRAIZ.
------ ------------------------------------------------------------------------

O resultado apresentado corresponde a raiz cubica de dois elevado a quatro. Observe junto ao programa principal o
uso da instrução END PROGRAM na linha 19 indicando a finalização do programa. A instrução END PROGRAM é
opcional e por esta razão, por vezes, omitida. A instrução END PROGRAM foi usada até então, neste livro, uma vez no
primeiro exemplo do primeiro capítulo e passará a ser usada com mais frequência nos próximos capítulos. No entanto,
no programa da sub-rotina de função o uso da instrução END FUNCTION é obrigatório. Veja que um código de função
é encerrado com a instrução EXIT FUCTION, enquanto que um programa convencional continua sendo encerrado com
a boa e velha instrução STOP RUN.
O uso do parágrafo REPOSITORY na linha 5 é obrigatório, uma vez que é neste trecho do código que se cria o vínculo
entre o programa chamador e a função chamada e coloca a função a disposição do programa. Funções definidas pelo
usuário não são como as funções intrínsecas que para serem usadas basta serem indicadas com o comando FUNC-
TION quando não são instanciadas na definição do REPOSITORY com a instrução FUNCTION ALL INTRINSIC.
Um detalhe importante no código da sub-rotina de função RZENESI é a indicação da instrução PROCEDURE DIVISION
USING BY VALUE LK-BAS, LK-IND, LK-EXP RETURNING LK-RST, em que são definidos os argumentos dos parâ-
metros de entrada LK-BAS, LK-IND e LK-EXP passados por valor e a indicação do parâmetro de saída LK-RST após a
definição obrigatória da cláusula RETURNING.

5.8.4 Funções recursivas


Anteriormente foi apresentado o conceito de utilização de sub-rotina recursiva, que para ser operada, exige que o nome
do programa no parágrafo PROGRAM-ID seja acompanhado opcionalmente do verbo IS e obrigatoriamente dá cláusula
RECURSIVE e encerrado com o comando GOBACK.
A explicação dada para sub-rotinas recursivas se aplica perfeitamente a funções recursivas, sem por ou tirar uma vírgu-
la, exceto em que escrever funções recursivas é, em média, mais simples que escrever sub-rotinas recursivas apesar
do aparente trabalho a mais que se tem para elaborá-las.
MO D ULA RI ZA ÇÃ O 193

A diferença existente entre uma sub-rotina recursiva e uma função recursiva está na forma de citação deste recurso no
programa em uso. A sub-rotina é aplicada na própria sub-rotina exigindo o uso da cláusula RECURSIVE diferentemente
de uma função que é declarada em separado do programa que a chama sem fazer uso da cláusula RECURSIVE junto
a definição de seu nome
Cabe aqui breve observação a respeito da característica de funcionamento do compilador GnuCOBOL que trata o re-
torno de valores de uma função recursiva como valores alfanuméricos, mesmo que o valor em uso seja numérico. Este
efeito de retorno cria problemas no uso de funções recursivas. Para sanar esta ocorrência usa-se a função intrínseca
NUMVAL que tem por finalidade converter em formato numérico um valor alfanumérico. Isto faz com que o código de
funções recursivas definidas pelo usuário no compilador GnuCOBOL sejam um pouco diferentes do mesmo código
escrito para outros compiladores COBOL. No entanto, a função NUMVAL deve ser utilizada uma única vez dentro da
função definida pelo usuário. Caso ocorra o uso da função NUMVAL mais de uma vez, há com certeza indícios de pro-
blemas de ajuste nas máscaras dos dados numéricos em uso.
Tomando por base o tradicional exemplo de cálculo de fatorial abra um projeto vazio, atribuindo o nome fat4 a partir da
extensão “.cbl” na subpasta COBOL da pasta Documentos e informe o código seguinte. Observe o trecho marcado em
vermelho indicando a função NUMVAL que pode ser omitida em outros compiladores que não sejam o GnuCOBOL. Em
verde está a indicação do uso recursivo da função, marcado na cor rosa está a definição BY VALUE.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FAT4.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 LOCAL-STORAGE SECTION.
9 77 LS-NUM PIC 9(2).
10 LINKAGE SECTION.
11 77 LK-NUM PIC 9(2).
12 77 LK-FAT PIC 9(38).
13 PROCEDURE DIVISION USING BY VALUE LK-NUM RETURNING LK-FAT.
14 PROG-PRINCIPAL-PARA.
15 IF LK-NUM = 0
16 COMPUTE LK-FAT = 1
17 ELSE
18 COMPUTE LS-NUM = LK-NUM - 1
19 COMPUTE LK-FAT = LK-NUM * NUMVAL(FAT4(LS-NUM))
20 END-IF
21 GOBACK.
22 END FUNCTION FAT4.
------ ------------------------------------------------------------------------

Observe que a função chama a si mesma na linha 19 sem o uso da cláusula RECURSIVE junto a declaração do nome
da função após FUNCTION-ID na linha 2. No entanto, é feito uso do comando GOBACK na linha 21 que efetua o retor-
no da função a si mesma, como feito em um programa de sub-rotina recursiva. Outro detalhe importante é que o uso da
cláusula RETURNING na linha 13 é obrigatória em uma função definida pelo usuário, pois toda a operação deve reali-
zada pela função deve retornar um resultado numérico como resposta a sua chamada. Veja que a primeira providencia
do programa é verificar se o valor da variável LK-NUM passada como argumento é zero e sendo o argumento de retor-
no representado pela variável LK-FAT é atribuído a 1. Caso contrário, a variável LS-NUM é atribuída ao valor da variá-
vel LK-NUM menos 1 para ir decrementado este argumento a cada chamada da função. Vale salientar que a instrução
COMPUTE LS-NUM = LK-NUM – 1 na linha 18 é necessária no GnuCOBOL pelo fato deste não aceitar como argu-
mento uma expressão aritmética como FAT4(LK-NUM – 1). Em seguida, efetua-se a multiplicação do valor da variável
194 PRO G RA MA Ç ÃO CO B OL

LK-NUM com o retorno da função FAT4. Observe que para usar a função dentro dela mesma é aplicado o uso da fun-
ção NUMVAL.
Para fazer uso da função recursiva abra um projeto vazio com o nome cap05ap04 com extensão “.cob” na subpasta
COBOL da pasta Documentos e informe o código a seguir.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP04.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION FAT4
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 WORKING-STORAGE SECTION.
10 77 WS-NUM PIC 9(2).
11 77 WS-FAT PIC Z(38).
12 PROCEDURE DIVISION.
13 PROG-PRINCIPAL-PARA.
14 ACCEPT WS-NUM.
15 MOVE FAT4(WS-NUM) TO WS-FAT
16 DISPLAY TRIM(WS-FAT).
17 STOP RUN.
18 END PROGRAM CAP05AP04.
------ ------------------------------------------------------------------------

Veja o parágrafo REPOSITORY definido na linha 5 na cor rosa indicando o vínculo do programa com a função FAT4
indicada na cor laranja. Na cor verde está a indicação da citação de uso de todas as funções intrínsecas sem o uso
obrigatório da cláusula FUNCTION antes do nome da função, neste caso TRIM
No código anterior o parágrafo REPOSITORY indica o uso de duas sentenças relacionadas as funções em uso no pro-
grama, sendo que essas sentenças estão descritas linha a linha de modo que há apenas um ponto final na última linha
das sentenças indicadas. Nos demais detalhes o código deste programa segue o padrão já usado e conhecido, dispen-
sando outros comentários. A sentença FUNCTION FATORIAL coloca em uso a função FATORIAL no programa e a
sentença FUNCTION ALL INTRINSIC coloca em uso as funções internas sem o uso da cláusula FUNCTION.
As funções recursivas possuem sua estrutura de código mais elegante que a estrutura de código das sub-rotinas recur-
sivas. Recursividade é um estilo de programação muito elegante e comum de uso no paradigma de programação funci-
onal. No entanto, se não for bem planejado poderá se tornar um grave problema de consumo de memória.
É comum encontrar críticas a respeito ao uso de funções recursivas. Seus críticos dizem que é uma forma de progra-
mação a ser evitada apesar de “bonitinha”, uma vez que devido ao efeito de empilhamento que faz na memória pelas
sucessivas chamadas a si mesma torna seu uso inconveniente e por esta razão a ser evitado, o que de certa forma até
é, parcialmente, verdade. O problema é que as críticas param a discussão neste ponto e não avançam mostrando o uso
do efeito de recursividade em cauda que não efetua empilhamentos na memória e é tão rápida quanto laços iterativos.
Veja na sequência o conjunto de códigos para aplicação do efeito de recursividade em cauda para o cálculo de uma
fatorial. Para esta situação são necessários três programas: um para a base do cálculo, contendo a lógica de ação;
outro para a interface de execução da base de cálculo; e por último, o programa principal que a partir do uso da interfa-
ce obtém o resultado desejado. Atente para o fato de que o programa está capacitado a operar cálculos apenas na
faixa de valores entre 0 e 33 retornando, como resposta, valor de até 38 dígitos.
Abra um projeto vazio, atribuindo o nome fatbase a partir da extensão “.clb” na subpasta COBOL da pasta Documen-
tos e informe o código seguinte.
MO D ULA RI ZA ÇÃ O 195

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FATBASE.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 LOCAL-STORAGE SECTION.
9 77 LS-NUM PIC 99.
10 77 LS-PAR PIC 9(38).
11 LINKAGE SECTION.
12 77 LK-NUM PIC 99.
13 77 LK-PAR PIC 9(38).
14 77 LK-FAT PIC 9(38).
15 PROCEDURE DIVISION USING BY VALUE LK-NUM, LK-PAR
16 RETURNING LK-FAT.
17 PROG-PRINCIPAL-PARA.
18 IF LK-NUM = 0
19 COMPUTE LK-FAT = LK-PAR
20 ELSE
21 COMPUTE LS-NUM = LK-NUM - 1
22 COMPUTE LS-PAR = LK-NUM * LK-PAR
23 COMPUTE LK-FAT = NUMVAL(FATBASE(LS-NUM, LS-PAR))
24 END-IF
25 GOBACK.
26 END FUNCTION FATBASE.
------ ------------------------------------------------------------------------

Veja que a recursividade em cauda é uma técnica que garante menor consumo de memória possível por não ser ne-
cessário guardar a posição da chamada da função, ou seja, nenhum processamento adicional após o encerramento da
função é realizado. Na prática, o resultado final é o resultado da própria função antes de seu retorno. A função recursiva
em cauda FATBASE recebe dois parâmetros que evoluem seus valores a cada chamada da função. O primeiro parâ-
metro representado por LK-NUM diminui um a um e o segundo parâmetro representado por LK-PAR (valor parcial)
possuindo o último valor calculado. Isto faz com que o resultado do cálculo não seja empilhado na memória.
Funções com recursividade simples e recursividade em cauda ocupam a memória de maneiras diferentes. Consideran-
do a função recursiva simples FAT4(3) e a função em cauda FATBASE(3,1) observe junto a figura 5.7 como cada fun-
ção se comporta na memória.
196 PRO G RA MA Ç ÃO CO B OL

Figura 5.7 – Comparativo entre função recursiva simples e em cauda

Abra um projeto vazio, atribuindo o nome fat5 a partir da extensão “.clb” na subpasta COBOL da pasta Documentos e
informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FAT5.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION FATBASE
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 LOCAL-STORAGE SECTION.
10 77 LS-NUM PIC 99.
11 77 LS-PAR PIC 9(38).
12 LINKAGE SECTION.
13 77 LK-NUM PIC 99.
14 77 LK-FAT PIC 9(38).
15 PROCEDURE DIVISION USING LK-NUM RETURNING LK-FAT.
16 PROG-PRINCIPAL-PARA.
17 MOVE LK-NUM TO LS-NUM
18 MOVE 1 TO LS-PAR
19 COMPUTE LK-FAT = NUMVAL(FATBASE(LS-NUM, LS-PAR))
20 GOBACK.
21 END FUNCTION FAT5.
------ ------------------------------------------------------------------------

A função FAT5 funciona como uma interface intermediária de acesso a função recursiva em cauda passando apenas o
parâmetro principal que é o valor para o cálculo da fatorial. Veja que FAT5 recebe um parâmetro LK-NUM e o transfere
para o parâmetro LS-NUM ajustando nessa movimentação o tipo de dado alfanumérico para numérico deixando como
para o parâmetro LS-PAR a definição do valor 1.
MO D ULA RI ZA ÇÃ O 197

Abra um projeto vazio, atribuindo o nome cap05ap05 a partir da extensão “.cob” na subpasta COBOL da pasta Docu-
mentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP05.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION FAT5
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 WORKING-STORAGE SECTION.
10 77 WS-NUM PIC 9(2).
11 77 WS-FAT PIC Z(38).
12 PROCEDURE DIVISION.
13 PROG-PRINCIPAL-PARA.
14 ACCEPT WS-NUM.
15 MOVE FAT5(WS-NUM) TO WS-FAT.
16 DISPLAY TRIM(WS-FAT).
17 STOP RUN.
18 END PROGRAM CAP05AP05.
------ ------------------------------------------------------------------------

O programa principal chama a função FAT5 que coleta o valor fornecido e o transfere para a função FATBASE, a qual
efetua o cálculo do resultado da fatorial do valor indicado.
Quando se trabalha com funções como fatorial que chamam a si mesmas apenas uma instância por vez a percepção
do quanto o estilo simples consome memória em relação ao estilo cauda é praticamente imperceptível. No entanto, uma
situação em seja apresentado o valor do termo da série de Fibonacci é diferente.
A série de Fibonacci é conhecida pela sequência numérica 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 e assim por diante, ten-
dendo ao infinito. Uma função Fibonacci efetua a cada iteração a chamada de duas instâncias de si mesma. A primeira
iteração chama duas instâncias, que ao ser executada chama quatro instâncias e assim por diante tornando o proces-
samento bastante lento e inadequado. Desta forma, considere a seguir um programa que exemplifique o uso de uma
função com recursividade simples para apresentar o valor do termo de Fibonacci.
Abra um projeto vazio, atribuindo o nome fib1 a partir da extensão “.clb” na subpasta COBOL da pasta Documentos e
informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FIB1.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 LOCAL-STORAGE SECTION.
9 77 LS-NF1 PIC 9(3).
10 77 LS-NF2 PIC 9(3).
------ ------------------------------------------------------------------------
198 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
11 77 LS-NUM PIC 9(38).
12 LINKAGE SECTION.
13 77 LK-NUM PIC 9(3).
14 77 LK-FIB PIC 9(38).
15 PROCEDURE DIVISION USING BY VALUE LK-NUM RETURNING LK-FIB.
16 PROG-PRINCIPAL-PARA.
17 MOVE LK-NUM TO LS-NUM.
18 EVALUATE LS-NUM
19 WHEN 0
20 COMPUTE LK-FIB = 0
21 WHEN 1
22 COMPUTE LK-FIB = 1
23 WHEN 2
24 COMPUTE LK-FIB = 1
25 WHEN OTHER
26 COMPUTE LS-NF1 = LS-NUM - 1
27 COMPUTE LS-NF2 = LS-NUM - 2
28 COMPUTE LK-FIB = NUMVAL(FIB1(LS-NF1)) +
29 NUMVAL(FIB1(LS-NF2))
30 END-EVALUATE.
31 GOBACK.
32 END FUNCTION FIB1.
------ ------------------------------------------------------------------------

Abra um projeto vazio, atribuindo o nome cap05ap06 a partir da extensão “.cob” na subpasta COBOL da pasta Docu-
mentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
3 IDENTIFICATION DIVISION.
4 PROGRAM-ID. CAP05AP06.
5 ENVIRONMENT DIVISION.
6 CONFIGURATION SECTION.
7 REPOSITORY.
8 FUNCTION FIB1
9 FUNCTION ALL INTRINSIC.
10 DATA DIVISION.
11 WORKING-STORAGE SECTION.
12 77 WS-NUM PIC 9(3).
13 77 WS-FIB PIC Z(37)9.
14 PROCEDURE DIVISION.
15 PROG-PRINCIPAL-PARA.
16 ACCEPT WS-NUM.
17 MOVE FIB1(WS-NUM) TO WS-FIB.
18 DISPLAY TRIM(WS-FIB).
19 STOP RUN.
20 END PROGRAM CAP05AP06.
------ ------------------------------------------------------------------------

Ao ser executado o programa você perceberá que até a entrada de apresentação do vigésimo terceiro termo o tempo
de espera para obter a resposta é quase que imperceptível chegando próximo a meio segundo de espera. No entanto,
MO D ULA RI ZA ÇÃ O 199

valores a partir de 23 começarão a demonstrar o custo do processamento e cobrar um preço alto. O programa conse-
gue apresentar termos com até 38 dígitos, isto posto, os valores aceitos pelo programa ficam entre 0 e 183.
A tabela 5.1 apresenta a indicação de alguns valores de termos e o tempo médio em segundos que poderá ocorrer para
que a resposta seja retornada. Veja que o tempo médio é mais ou menos proporcional aos próprios valores de forma-
ção da série.

Tabela 5.1 – Tempo médio de execução Fibonnaci recursivo simples

Termo Tempo médio (em segundos)

24 1s

25 2s

26 3s

27 5s

28 8s

29 13s

30 21s

31 34s

O código fib1 retorna o valor do termo da série de Fibonacci a partir do termo fornecido no código testefib. O programa
apresenta adequadamente os dados 0, 1, 1, 2, 3, 5, 8, 13, ..., 785.69.350.599.398.894.027.251.472.817.058.687.522,
obtidos a partir da faixa de valores fornecidos entre 0 e 183.
A título de ilustração observe em seguida versão do programa Fibonacci a partir do uso de recursão por cauda. Atente
para as definições das funcionalidades fibbase e fib2.
Abra um projeto vazio, atribuindo o nome fibbase a partir da extensão “.clb” na subpasta COBOL da pasta Documen-
tos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FIBBASE.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 LOCAL-STORAGE SECTION.
9 77 LS-NUM PIC 9(38).
10 77 LS-ATU PIC 9(38).
11 77 LS-PRX PIC 9(38).
12 LINKAGE SECTION.
13 77 LK-NUM PIC 9(38).
14 77 LK-ANT PIC 9(38).
15 77 LK-ATU PIC 9(38).
16 77 LK-FIB PIC 9(38).
------ ------------------------------------------------------------------------
200 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
17 PROCEDURE DIVISION USING BY VALUE LK-NUM, LK-ANT, LK-ATU
18 RETURNING LK-FIB.
19 PROG-PRINCIPAL-PARA.
20 EVALUATE LK-NUM
21 WHEN 0
22 COMPUTE LK-FIB = LK-ANT
23 WHEN 1
24 COMPUTE LK-FIB = LK-ATU
25 WHEN 2
26 COMPUTE LS-PRX = LK-ANT + LK-ATU
27 COMPUTE LK-FIB = LS-PRX
28 WHEN OTHER
29 MOVE LK-ATU TO LS-ATU
30 COMPUTE LS-NUM = LK-NUM - 1
31 COMPUTE LS-PRX = LK-ANT + LK-ATU
32 COMPUTE LK-FIB =
33 NUMVAL(FIBBASE(LS-NUM, LS-ATU, LS-PRX))
34 END-EVALUATE.
35 GOBACK.
36 END FUNCTION FIBBASE.
------ ------------------------------------------------------------------------

Abra um projeto vazio, atribuindo o nome fib2 a partir da extensão “.clb” na subpasta COBOL da pasta Documentos e
informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. FIB2.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION FIBBASE
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 LOCAL-STORAGE SECTION.
10 77 LS-ANT PIC 9(38).
11 77 LS-ATU PIC 9(38).
12 77 LS-NUM PIC 9(38).
13 LINKAGE SECTION.
14 77 LK-NUM PIC 9(3).
15 77 LK-FIB PIC 9(38).
16 PROCEDURE DIVISION USING BY VALUE LK-NUM RETURNING LK-FIB.
17 PROG-PRINCIPAL-PARA.
18 MOVE 0 TO LS-ANT.
19 MOVE 1 TO LS-ATU.
20 MOVE LK-NUM TO LS-NUM.
21 COMPUTE LK-FIB = NUMVAL(FIBBASE(LS-NUM, LS-ANT, LS-ATU)).
22 GOBACK.
23 END FUNCTION FIB2.
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 201

Abra um projeto vazio, atribuindo o nome cap05ap07 a partir da extensão “.cob” na subpasta COBOL da pasta Docu-
mentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP05AP07.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION FIB2
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 WORKING-STORAGE SECTION.
10 77 WS-NUM PIC 9(3).
11 77 WS-FIB PIC Z(38)9.
12 PROCEDURE DIVISION.
13 PROG-PRINCIPAL-PARA.
14 ACCEPT WS-NUM.
15 MOVE FIB2(WS-NUM) TO WS-FIB.
16 DISPLAY TRIM(WS-FIB).
17 STOP RUN.
18 END PROGRAM CAP05AP07.
------ ------------------------------------------------------------------------

Em cada um dos códigos para o cálculo do termo da série de Fibonacci com função recursiva de cauda são estabeleci-
dos alguns dados. Observe atentamente as máscaras definidas. Agora entre os valores indicados na tabela 5.1 e ob-
serve que o resultado é imediato, sem latência de espera para o processamento.
Entre sub-rotinas recursivas e funções recursivas, particularmente, as funções recursivas são mais elegantes em sua
forma de expressão e acabam sendo menos poluídas do ponto de vista sintático. E ao decidir usar recursividade sem-
pre opte pela recursão em cauda. A recursão simples é um evento interessante mas inadequado ao uso servindo ape-
nas como elemento didático.

5.9 HORA DE PROGRAMAR


Agora é o momento de colocar em prática parte dos recursos apresentados neste capítulo. Os próximos programas
completos mostram como fazer uso sub-rotinas internas e externas; passagens de parâmetro; copybook e recursivida-
de. Mantenha sua atenção, pois coisas novas são apresentadas nesta etapa do estudo.

CALCULADORA COM DEFINIÇÃO DE SEÇÃO


Elaborar programa de computador que simule uma calculadora simples que a partir da leitura de dois valores numéricos
decimais positivos ou negativos com duas casas decimais e limite de expoente com unidade, dezena, centena e unida-
de de milhar apresente o resultado da operação matemática escolhida indicando os símbolos de positivo ou negativo
sem o uso da máscara para esta condição, mas se o resultado for zero o valor de resposta deve ser neutro (sem os
símbolos de positivo ou negativo). O programa deve apresentar um menu contendo as opções de acesso que informe
erro se uma opção diferente das estabelecidas seja informada. Se fornecido valor zero para o divisor de uma divisão o
programa deve apresentar uma mensagem de erro informando essa ocorrência. O programa deve para gerenciar suas
operações fazer uso seções customizadas ao estilo sub-rotinas internas.
Para o desenvolvimento deste programa é considerada uma máscara de entrada definida com o formato S9(4)V99 e
para a saída a máscara definida com o formato Z(8)9.99.
202 PRO G RA MA Ç ÃO CO B OL

Selecione e defina um projeto do programa vazio com o nome c05ex01.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C05EX01 AS "Capitulo 5 – Exemplo 1".
3 *
4 DATA DIVISION.
5 LOCAL-STORAGE SECTION.
6 77 LS-VLR-1 PIC S9(4)V99.
7 77 LS-VLR-2 PIC S9(4)V99.
8 77 LS-C-RST PIC S9(8)V99.
9 77 LS-S-RST PIC Z(8)9.99.
10 77 LS-OPCAO PIC 9.
11 77 LS-ENTER PIC X.
12 78 CR VALUE X"0D".
13 *
14 PROCEDURE DIVISION.
15 PROG-PRINCIPAL-PARA.
16 PERFORM 100-MENU.
17 PERFORM 500-FIM.
18 ******************************************************************
19 * APRESENTACAO DO MENU DE OPCOES DO PROGRAMA *
20 ******************************************************************
21 100-MENU SECTION.
22 PERFORM FOREVER
23 CALL "SYSTEM" USING "cls"
24 DISPLAY "--------------------"
25 DISPLAY "Programa Calculadora"
26 DISPLAY " Menu Principal "
27 DISPLAY "--------------------"
28 DISPLAY CR
29 DISPLAY "[1] - Adicao"
30 DISPLAY "[2] - Subtracao"
31 DISPLAY "[3] - Multiplicacao"
32 DISPLAY "[4] - Divisao"
33 DISPLAY "[5] - Fim de programa"
34 DISPLAY CR
35 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
36 ACCEPT LS-OPCAO
37 IF LS-OPCAO NOT = 5
38 EVALUATE LS-OPCAO
39 WHEN 1
40 PERFORM 110-CALCULO-ADC
41 WHEN 2
42 PERFORM 120-CALCULO-SUB
43 WHEN 3
44 PERFORM 130-CALCULO-MUL
45 WHEN 4
46 PERFORM 140-CALCULO-DIV
47 WHEN OTHER
48 DISPLAY "Opcao invalida." WITH NO ADVANCING
49 PERFORM 400-PAUSA
50 END-EVALUATE
51 ELSE
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 203

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
52 EXIT PERFORM
53 END-IF
54 END-PERFORM.
55 EXIT.
56 ******************************************************************
57 * ROTINA PARA CALCULO DA ADICAO *
58 ******************************************************************
59 110-CALCULO-ADC SECTION.
60 CALL "SYSTEM" USING "cls"
61 DISPLAY "----------------"
62 DISPLAY "Rotina de Adicao"
63 DISPLAY "----------------"
64 PERFORM 200-ENTRADA
65 COMPUTE LS-C-RST = LS-VLR-1 + LS-VLR-2.
66 PERFORM 300-SAIDA
67 EXIT.
68 ******************************************************************
69 * ROTINA PARA CALCULO DA SUBTRACAO *
70 ******************************************************************
71 120-CALCULO-SUB SECTION.
72 CALL "SYSTEM" USING "cls"
73 DISPLAY "-------------------"
74 DISPLAY "Rotina de Subtracao"
75 DISPLAY "-------------------"
76 PERFORM 200-ENTRADA
77 COMPUTE LS-C-RST = LS-VLR-1 - LS-VLR-2
78 PERFORM 300-SAIDA
79 EXIT.
80 ******************************************************************
81 * ROTINA PARA CALCULO DA MULTIPLICAO *
82 ******************************************************************
83 130-CALCULO-MUL SECTION.
84 CALL "SYSTEM" USING "cls"
85 DISPLAY "-----------------------"
86 DISPLAY "Rotina de Multiplicacao"
87 DISPLAY "-----------------------"
87 PERFORM 200-ENTRADA
88 COMPUTE LS-C-RST = LS-VLR-1 * LS-VLR-2.
89 PERFORM 300-SAIDA
90 EXIT.
91 ******************************************************************
92 * ROTINA PARA CALCULO DA DIVISAO *
93 ******************************************************************
94 140-CALCULO-DIV SECTION.
95 CALL "SYSTEM" USING "cls"
96 DISPLAY "-----------------"
97 DISPLAY "Rotina de Divisao"
98 DISPLAY "-----------------"
99 PERFORM 200-ENTRADA
100 IF LS-VLR-2 = 0
101 DISPLAY CR
102 DISPLAY "Resultado = ERRO"
103 PERFORM 400-PAUSA
------ ------------------------------------------------------------------------
204 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
104 ELSE
105 COMPUTE LS-C-RST = LS-VLR-1 / LS-VLR-2.
106 PERFORM 300-SAIDA
107 END-IF
108 EXIT.
109 ******************************************************************
110 * ROTINA PARA A ENTRADA DE DADOS NA CALCULADORA *
111 ******************************************************************
112 200-ENTRADA SECTION.
113 DISPLAY CR
114 DISPLAY "Entre valor 1: " WITH NO ADVANCING
115 ACCEPT LS-VLR-1
116 DISPLAY "Entre valor 2: " WITH NO ADVANCING
117 ACCEPT LS-VLR-2
118 EXIT.
119 ******************************************************************
120 * ROTINA DE SAIDA DE DADOS DA CALCULADORA *
121 ******************************************************************
122 300-SAIDA SECTION.
123 MOVE LS-C-RST TO LS-S-RST
124 DISPLAY CR
125 IF LS-C-RST = 0
126 DISPLAY "Resultado = " FUNCTION TRIM(LS-S-RST)
127 ELSE
128 IF LS-C-RST < 0
129 DISPLAY "Resultado = -" FUNCTION TRIM(LS-S-RST)
130 ELSE
131 DISPLAY "Resultado = +" FUNCTION TRIM(LS-S-RST)
132 END-IF
133 END-IF
134 PERFORM 400-PAUSA
135 EXIT.
136 ******************************************************************
137 * EXECUCAO DA SECAO DE PAUSA PARA PARADA DE TELA *
138 ******************************************************************
139 400-PAUSA SECTION.
140 DISPLAY CR
141 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING
142 ACCEPT LS-ENTER.
143 EXIT.
144 ******************************************************************
145 * ENCERRAMENTO DA EXECUCAO DO PROGRAMA CALCULADORA *
146 ******************************************************************
147 500-FIM SECTION.
148 STOP RUN.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa teste todas as
possibilidades de cálculo e opções de menu. Atente para os detalhes escritos em cada linha de instrução do código.
Este é o código mais longo até o presente momento deste estudo. Veja que entre as linhas 4 e 12 estão definidas as
variáveis de operação do programa agora na seção LOCAL-STORAGE.
MO D ULA RI ZA ÇÃ O 205

Na divisão de procedimento, linha 14 encontra-se as instruções de acesso de todo o programa. A linha 15 faz a chama-
da do menu que controla todas as funcionalidades do programa. Na linha 16 é definida a seção que faz o encerramento
do programa e que será executada quando a ação da linha 15 for concluída. Na linha 16 poderia ter sido mantida a
instrução de saída STOP RUN, mas deixar o encerramento do programa no meio do código não é uma ação muito
elegante. Por isso o encerramento efetivo do programa é executado na seção 500-FIM que está definida nas linhas 147
e 148.
A seção de menu encontra-se definida entre as linhas 20 e 54. A apresentação do menu é controlado por um laço infini-
to PERFORM FOREVER que somente é encerrado quando a opção 5 é fornecida pelo usuário e o fluxo operacional do
programa passa pela linha 51 que encerra a execução da seção de menu colocando o programa na linha 16 que vai a
linha 147 e 148 e faz o encerramento da execução.
A entrada da opção de acesso as funcionalidades do programa são realizadas na linha 35. Qualquer valor fornecido é
validado primeiro na linha 36, pois se o valor for 5 o programa é encerrado. Não sendo 5 é verificado entre as linhas 37
e 49 se a opção fornecida está entre 1 e 4, sendo um desses valores verdadeiros serão executadas as chamadas de
seções nas linhas 39, 41, 43 ou 45. Se o valor fornecido não for nenhum dos valores válidos é executa a ação da linha
47.
As linhas de 58 até 66 (adição), de 70 até 78 (subtração), de 82 até 90 (multiplicação) e de 94 até 108 (divisão) especi-
ficam as seções para a realização de cada um dos cálculos indicados no menu. Essas seções são idênticas exceto a de
divisão que efetua a validação do valor do divisor entre as linhas 100 e 107, Cada uma dessas seções faz a chamada
das seções de entrada definida entre as linhas de 112 até 118 e de saída definida entre as linhas 122 e 135.
A rotina de entrada efetua a recepção dos valores para o cálculo da calculadora demonstrada nas linhas 115 e 117.
A seção de saída de dados efetua entre as linhas 125 e 133 o tratamento da apresentação das respostas como solici-
tado no problema, mostra quando zero um resultado sem a simbologia de positivo ou negativo e com a simbologia
quando o valor do resultado não for igual 0.
Para auxiliar a apresentação do resultado e pausa de ação nas seções do programa, principalmente nas ações de cál-
culo são definidas duas seções operacionais. Entre as linhas 139 e 143 há a indicação de uma mensagem de pausa
que aguarda o acionamento da tecla <Enter> e nas linhas 147 e 148 encontra-se a seção de finalização do programa.

CALCULADORA COM DEFINIÇÃO DE SUB-ROTINAS


Elaborar programa de computador que simule uma calculadora simples que a partir da leitura de dois valores numéricos
decimais positivos ou negativos com duas casas decimais e limite de expoente com unidade, dezena, centena e unida-
de de milhar apresente o resultado da operação matemática escolhida indicando os símbolos de positivo ou negativo
sem o uso da máscara para esta condição, mas se o resultado for zero o valor de resposta deve ser neutro (sem os
símbolos de positivo ou negativo). O programa deve apresentar um menu contendo as opções de acesso que informe
erro se uma opção diferente das estabelecidas seja informada. Se fornecido valor zero para o divisor de uma divisão o
programa deve apresentar uma mensagem de erro informando essa ocorrência. O programa deve para gerenciar suas
operações fazer uso de sub-rotinas externas, em que cada uma das operações esteja separada em módulos de pro-
gramas externos. Deixe as variáveis do programa definidas em um copybook.
Para o desenvolvimento deste programa são considerados a escrita das partes componentes separadas uma das ou-
tras na forma de arquivos de código.
O primeiro código definido do programa é a criação do livro de cópia (copybook) contendo a estrutura de dados usada
no programa calculadora. Para tanto, selecione um projeto de programa vazio a partir do nome c05ex02.cpy na pasta
COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 77 LS-VLR-1 PIC S9(4)V99.
2 77 LS-VLR-2 PIC S9(4)V99.
------ ------------------------------------------------------------------------
206 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
3 77 LS-C-RST PIC S9(8)V99.
4 77 LS-S-RST PIC Z(8)9.99.
------ ------------------------------------------------------------------------

No trecho anterior encontra-se as definições das variáveis usadas no programa calculadora. São definidos no copybook
as variáveis auxiliares as operações de entrada, processamento e saída de dados em algumas das sub-rotinas do pro-
grama.
O segundo código do programa é a definição da sub-rotina que efetua a pausa quando solicitada. Para tanto, selecione
um projeto de programa vazio com o nome c0502psa.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502PSA.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 77 LS-ENTER PIC X.
6 78 CR VALUE X"0D".
7 LINKAGE SECTION.
8 77 LK-ENTER PIC X.
9 PROCEDURE DIVISION USING LK-ENTER.
10 PROG-PRINCIPAL-PARA.
11 DISPLAY CR.
12 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
13 ACCEPT LS-ENTER.
14 EXIT.
------ ------------------------------------------------------------------------

No trecho anterior encontra-se a definição da sub-rotina de execução de pausa apresentada após a execução dos cál-
culos do programa e da execução de mensagem de erro do menu. Nesta rotina encontra-se definida na linha 6 a variá-
vel local LS-ENTER, a constante de salto de linha CR é definida na linha 7 e a variável de vínculo LK-ENTER definida
na linha 10. Variáveis de vínculo precisam ser definidas para determinar uma das características de sub-rotinas, mesmo
que essas variáveis não sejam usadas.
O terceiro código do programa é a definição da sub-rotina que efetua a entrada dos valores numéricos. Para tanto,
selecione um projeto de programa vazio com o nome c0502ent.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502ENT.
3 DATA DIVISION.
4 LINKAGE SECTION.
5 77 LK-VLR-1 PIC S9(4)V99.
6 77 LK-VLR-2 PIC S9(4)V99.
7 PROCEDURE DIVISION USING LK-VLR-1, LK-VLR-2.
8 PROG-PRINCIPAL-PARA.
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 207

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
9 DISPLAY "Entre valor 1: " WITH NO ADVANCING.
10 ACCEPT LK-VLR-1.
11 DISPLAY "Entre valor 2: " WITH NO ADVANCING.
12 ACCEPT LK-VLR-2.
13 EXIT.
------ ------------------------------------------------------------------------

No trecho anterior encontra-se a definição da sub-rotina que auxilia a entrada de dados nas demais sub-rotinas de cál-
culo do programa. Observe que neste trecho está sendo utilizado diretamente as variáveis de vínculo para a recepção
das entradas definidas nas linhas 6 e 7. Veja que isto é possível de ocorrer quando o programa chamador passa para a
sub-rotina passagem de parâmetro por referência. A definição de referência é usada quando se deseja que o parâmetro
tenha a capacidade de operar leituras e escritas nesta posição. Neste caso, a sub-rotina c0502ent faz a leitura forneci-
da pelo usuário e por passagem de parâmetro por referência transfere para o programa chamador esses valores.
As variáveis de vínculo LK-VLR-1 e LK-VLR-2 são as representantes do parâmetro passada pelo programa chamador
a sub-rotina. Neste caso, a sub-rotina opera na linha 9 a entrada dos valores passados como parâmetro pelo programa
chamador, mas não tem a definição se o parâmetro é por conteúdo ou referência, pois esta informação é passada pelo
programa chamador e a partir desta informação efetua sua ação interna devolvendo ou não uma resposta a passagem
de parâmetro.
O quarto código do programa é a definição da sub-rotina que efetua a saída do resultado de cada operação. Para tanto,
selecione um projeto de programa vazio com o nome c0502sai.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502SAI.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 COPY "c05ex02.cpy".
6 LINKAGE SECTION.
7 77 LK-C-RST PIC S9(8)V99.
8 PROCEDURE DIVISION USING LK-C-RST.
9 PROG-PRINCIPAL-PARA.
10 MOVE LK-C-RST TO LS-S-RST.
11 IF LK-C-RST = 0
12 DISPLAY "Resultado = " FUNCTION TRIM(LS-S-RST)
13 ELSE
14 IF LK-C-RST < 0
15 DISPLAY "Resultado = -" FUNCTION TRIM(LS-S-RST)
16 ELSE
17 DISPLAY "Resultado = +" FUNCTION TRIM(LS-S-RST)
18 END-IF
19 END-IF
20 CALL "C0502PSA".
21 EXIT.
------ ------------------------------------------------------------------------

No trecho anterior encontra-se a definição da sub-rotina que efetua a saída do resultado após a efetivação de cada um
dos cálculos do programa. Veja que nesta sub-rotina é efetuada na linha 6 a chamada do copybook que possui as defi-
nições das variáveis usadas pelo programa e neste caso a definição da variável LS-S-RST.
208 PRO G RA MA Ç ÃO CO B OL

A linha 22 faz uso do verbo CALL sem o uso da cláusula USING, uma vez que não a necessidade de passar parâmetro
deste programa a sub-rotina c0502psa, que apresenta apenas a mensagem de pausa para algumas ações do progra-
ma.
O quinto código do programa é a definição da sub-rotina que efetua a operação de adição. Para tanto, selecione um
projeto de programa vazio com o nome c0502adc.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502ADC.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 78 CR VALUE X"0D".
6 COPY "c05ex02.cpy".
7 LINKAGE SECTION.
8 77 LK-VLR-1 PIC S9(4)V99.
9 77 LK-VLR-2 PIC S9(4)V99.
10 77 LK-C-RST PIC S9(8)V99.
11 PROCEDURE DIVISION USING LK-VLR-1, LK-VLR-2, LK-C-RST.
12 PROG-PRINCIPAL-PARA.
13 CALL "SYSTEM" USING "cls".
14 DISPLAY "----------------".
15 DISPLAY "Rotina de Adicao".
16 DISPLAY "----------------".
17 DISPLAY CR.
18 CALL "C0502ENT" USING BY REFERENCE LS-VLR-1, LS-VLR-2.
19 COMPUTE LS-C-RST = LS-VLR-1 + LS-VLR-2.
20 DISPLAY CR.
21 CALL "C0502SAI" USING BY CONTENT LS-C-RST.
22 EXIT.
------ ------------------------------------------------------------------------

A sub-rotina de adição c0502adc para sua ação faz uso do copybook como indicado na linha 7. Desta forma, as variá-
veis comuns ao programa são copiadas para este código no momento da compilação. Atente nesta sub-rotina para a
linha 20 que faz uso de passagem de parâmetro por referência junto a sub-rotina c0502ent que é chamada para fazer a
entrada e devolver a c0502adc os valores fornecidos para a realização do cálculo junto a linha 21. Após a efetivação do
cálculo é chamada a sub-rotina c0502sai que tem por responsabilidade apresentar o resultado do cálculo passado por
conteúdo.
O sexto código do programa é a definição da sub-rotina que efetua a operação de subtração, semelhante a sub-rotina
de adição. Para tanto, selecione um projeto de programa vazio com o nome c0502sub.cbl na pasta COBOL da pasta
Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502SUB.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 78 CR VALUE X"0D".
6 COPY "c05ex02.cpy".
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 209

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
7 LINKAGE SECTION.
8 77 LK-VLR-1 PIC S9(4)V99.
9 77 LK-VLR-2 PIC S9(4)V99.
10 77 LK-C-RST PIC S9(8)V99.
11 PROCEDURE DIVISION USING LK-VLR-1, LK-VLR-2, LK-C-RST.
12 PROG-PRINCIPAL-PARA.
13 CALL "SYSTEM" USING "cls".
14 DISPLAY "-------------------".
15 DISPLAY "Rotina de Subtracao".
16 DISPLAY "-------------------".
17 DISPLAY CR.
18 CALL "C0502ENT" USING BY REFERENCE LS-VLR-1, LS-VLR-2.
19 COMPUTE LS-C-RST = LS-VLR-1 - LS-VLR-2.
20 DISPLAY CR.
21 CALL "C0502SAI" USING BY CONTENT LS-C-RST.
22 EXIT.
------ ------------------------------------------------------------------------

A sub-rotina de subtração c0502sub é idêntica a sub-rotina de adição c0502adc dispensando maiores observações.
O sétimo código do programa é a definição da sub-rotina que efetua a operação de multiplicação. Para tanto, selecione
um projeto de programa vazio com o nome c0502mul.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502MUL.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 78 CR VALUE X"0D".
6 COPY "c05ex02.cpy".
7 LINKAGE SECTION.
8 77 LK-VLR-1 PIC S9(4)V99.
9 77 LK-VLR-2 PIC S9(4)V99.
10 77 LK-C-RST PIC S9(8)V99.
11 PROCEDURE DIVISION USING LK-VLR-1, LK-VLR-2, LK-C-RST.
12 PROG-PRINCIPAL-PARA.
13 CALL "SYSTEM" USING "cls".
14 DISPLAY "-----------------------".
15 DISPLAY "Rotina de Multiplicacao".
16 DISPLAY "-----------------------".
17 DISPLAY CR.
18 CALL "C0502ENT" USING BY REFERENCE LS-VLR-1, LS-VLR-2.
19 COMPUTE LS-C-RST = LS-VLR-1 * LS-VLR-2.
20 DISPLAY CR.
21 CALL "C0502SAI" USING BY CONTENT LS-C-RST.
22 EXIT.
------ ------------------------------------------------------------------------

A sub-rotina de multiplicação c0502mul é idêntica as sub-rotinas de adição c0502adc e de subtração c0502sub dis-
pensando maiores observações.
210 PRO G RA MA Ç ÃO CO B OL

O oitavo código do programa é a definição da sub-rotina que efetua a operação de divisão. Para tanto, selecione um
projeto de programa vazio com o nome c0502div.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502DIV.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 78 CR VALUE X"0D".
6 COPY "c05ex02.cpy".
7 LINKAGE SECTION.
8 77 LK-VLR-1 PIC S9(4)V99.
9 77 LK-VLR-2 PIC S9(4)V99.
10 77 LK-C-RST PIC S9(8)V99.
11 77 LK-ENTER PIC X.
12 PROCEDURE DIVISION USING LK-VLR-1, LK-VLR-2, LK-C-RST.
13 PROG-PRINCIPAL-PARA.
14 CALL "SYSTEM" USING "cls".
15 DISPLAY "-----------------".
16 DISPLAY "Rotina de Divisao".
17 DISPLAY "-----------------".
18 DISPLAY CR.
19 CALL "C0502ENT" USING BY REFERENCE LS-VLR-1, LS-VLR-2.
20 IF LS-VLR-2 = 0
21 DISPLAY CR
22 DISPLAY "Resultado = ERRO"
23 CALL "C0502PSA"
24 ELSE
25 DISPLAY CR
26 COMPUTE LS-C-RST = LS-VLR-1 / LS-VLR-2
27 CALL "C0502SAI" USING BY CONTENT LS-C-RST
28 END-IF
29 EXIT.
------ ------------------------------------------------------------------------

A sub-rotina de divisão c0502div difere-se um pouco das demais devido a sua característica de validar a recepção do
valor de divisor diferente de 0 como indicado entre as linhas 22 e 30. Os demais detalhes são idênticos aos das sub-
rotinas anteriores.
Concluída a montagem das sub-rotinas responsáveis pelos cálculos do programa passe-se para o desenvolvimento da
sub-rotina de apresentação do menu. Assim sendo, para o nono código selecione um projeto vazio, atribua o nome
c0502men.cbl na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0502MEN.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 77 LS-OPCAO PIC 9.
6 78 CR VALUE X"0D".
------ ------------------------------------------------------------------------
MO D ULA RI ZA ÇÃ O 211

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
7 LINKAGE SECTION.
8 77 LK-OPCAO PIC 9.
9 PROCEDURE DIVISION USING LK-OPCAO.
10 PROG-PRINCIPAL-PARA.
11 PERFORM FOREVER
12 CALL "SYSTEM" USING "cls"
13 DISPLAY "--------------------"
14 DISPLAY "Programa Calculadora"
15 DISPLAY " Menu Principal "
16 DISPLAY "--------------------"
17 DISPLAY CR
18 DISPLAY "[1] - Adicao"
19 DISPLAY "[2] - Subtracao"
20 DISPLAY "[3] - Multiplicacao"
21 DISPLAY "[4] - Divisao"
22 DISPLAY "[5] - Fim de programa"
23 DISPLAY CR
24 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
25 ACCEPT LS-OPCAO
26 IF LS-OPCAO NOT = 5
27 EVALUATE LS-OPCAO
28 WHEN 1
29 CALL "C0502ADC"
30 WHEN 2
31 CALL "C0502SUB"
32 WHEN 3
33 CALL "C0502MUL"
34 WHEN 4
35 CALL "C0502DIV"
36 WHEN OTHER
37 DISPLAY "Opcao invalida." WITH NO ADVANCING
38 CALL "C0502PSA"
39 END-EVALUATE
40 ELSE
41 EXIT PERFORM
42 END-IF
43 END-PERFORM.
44 EXIT.
------ ------------------------------------------------------------------------

A sub-rotina c0502men efetua a apresentação do menu. Neste corpo de código é definida na linha 6 a variável de
acesso a seleção de opções LS-OPCAO e na linha 7 a definição da constante CR, também definidas em outras sub-
rotinas deste programa. Observe que no trecho entre as linhas 29 e 45 é realizado o controle e validação das entradas
efetivadas como opções de acesso. Veja que nas linhas 32, 34, 36 e 38 são efetivadas as chamadas de cada sub-rotina
de cálculo.
O décimo código do programa é a definição do programa principal. Para tanto, selecione um projeto de programa vazio
com o nome c05ex02.cob na pasta COBOL da pasta Documentos.
212 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C05EX02 AS "Capitulo 5 – Exemplo 2".
3 PROCEDURE DIVISION.
4 PROG-PRINCIPAL-PARA.
5 CALL "C0502MEN".
6 STOP RUN.
------ ------------------------------------------------------------------------

Perceba que o programa principal acaba sendo o que possui o menor número de linhas uma vez que precisa apenas
disparar a sub-rotina c0502men para que o restante do programa entre em operação. Quando a sub-rotina de apresen-
tação do menu é encerrada o fluxo de processamento do programa é devolvido para a linha 6 que efetiva o encerra-
mento total da aplicação.
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 213

6
MANIPULAÇÃO DE CADEIAS DE CARACTERES

Nos capítulos anteriores a atenção foi dada aos dados numéricos, pouco se falou sobre o uso de dados alfa-
numéricos, assim este capítulo dá atenção em separado a este tema. Uma cadeia de caracteres (string) ca-
racteriza-se por ser um conjunto de dados delimitados entre aspas simples ou aspas inglesas. Neste capítulo
são apresentados de maneira simplista os recursos que permitem executar a manipulação de caracteres com
ações de concatenação, decomposição, inspeção e outros recursos associados a este tipo de dado.

6.1 CONCATENAÇÃO DE TEXTOS


É comum haver a necessidade de ter que organizar dados diversos fornecidos pelo usuário ou advindos de outras fon-
tes para o devido tratamento no programa, principalmente para a apresentação legível destes dados em telas ou relató-
rios, principalmente impressos. Neste sentido, uma das ações importantes a serem consideradas é a concatenação de
textos ou caracteres. Concatenar significa unir partes separadas. Esta ação pode ser produzida em GnuCOBOL com o
uso do comando STRING ou da função intrínseca CONCATENATE.
O comando STRING em sua forma mais simplista pode ser considerado a partir da estrutura sintática:

STRING <dado1>/<cadeia1> DELIMITED [BY] <dado2>/<cadeia2>/SIZE ... INTO <dado3>

Onde, dado1 ou cadeia1 é a indicação do conteúdo a ser unido a certo delimitador DELIMITED em dado2 ou cadeia2,
podendo-se especificar uma lista de dados a serem unidos ao campo receptor dado3 a partir da cláusula INTO. A pala-
vra BY é opcional e sua ausência ou uso não afeta em absoluto o uso da instrução.
A função CONCATENATE, exclusiva do GnuCOBOL baseia-se na estrutura sintática:

CONCATENATE(<cadeia1> [, <cadeia2>] ...)

Em que cadeia1 e o dado a ser anexado a cadeia2 ou a lista de cadeias especificadas como parâmetros da função.
A função CONCATENATE é um recurso de concatenação mais simples que o comando STRING, o qual oferece outras
funcionalidades operacionais nas ações de concatenação. O resultado da função CONCATENATE deve ser atribuído a
uma variável com auxílio do comando MOVE.
Atente ao trecho de código seguinte que demonstra o uso da função CONCATENATE fazendo a junção de dois textos
distintos em um terceiro texto.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 WS-TEXTO-1 PIC X(10) VALUE "LIVRO: ===".
77 WS-TEXTO-2 PIC X(20) VALUE " PROGRAMACAO COBOL".
77 WS-TEXTO-3 PIC X(30).
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
214 PRO G RA MA Ç ÃO CO B OL

DISPLAY "Texto 1 .......................: " WS-TEXTO-1.


DISPLAY "Texto 2 .......................: " WS-TEXTO-2.
MOVE FUNCTION CONCATENATE(WS-TEXTO-1, WS-TEXTO-2) TO WS-TEXTO-3
DISPLAY "Texto concatenado com funcao ..: " WS-TEXTO-3.

Observe que as variáveis WS-TEXTO-1 e WS-TEXTO-2 possuem a definição de suas cadeias dentro dos limites esta-
belecidos nas máscaras de sua definição. Assim como a variável WS-TEXTO-3. A execução do trecho de código resul-
tará na apresentação de uma saída semelhante a indicada, em relação apenas os textos operados.

|LIVRO: ===|
| PROGRAMACAO COBOL|
|LIVRO: === PROGRAMACAO COBOL|

Veja na terceira linha, a apresentação da saída concatenada que mostra a junção de todos os caracteres, sendo espa-
ços em branco, símbolos de igualdade, pontuação e os caracteres alfabéticos. A remoção do excesso de espaços em
branco pode ser manipulada com o uso da função TRIM apresentada em capítulos anteriores.
Apesar da função CONCATENATE realizar bem sua tarefa, ela é muito limitada por fazer sua operação de uma manei-
ra muito simples. Por esta razão pode não ser muito adequada para operações de concatenação sofisticadas. Neste
sentido, o comando STRING poderá ser a opção mais vantajosa.
Para demonstrar o uso do comando STRING considere a seguinte estrutura de dado:

01 NOME-COMPLETO.
02 PRIMEIRO-NOME PIC X(15).
02 NOME-MEIO PIC X(15).
02 SOBRENOME PIC X(10).

A partir da estrutura proposta para composição do nome completo de uma pessoa deseja-se mostrar o nome no forma-
to “SOBRENOME, PRIMEIRO-NOME NOME-MEIO”. Considerando o nome “JOSE AUGUSTO MANZANO” este deve
ser escrito como “MANZANO, JOSE AUGUSTO”. Para tanto, observe a composição da figura 6.1.

PRIMEIRO-NOME
1 1 1 1 1 1
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
J O S E

NOME-MEIO
1 1 1 1 1 1
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
A U G U S T O

SOBRENOME
1
1 2 3 4 5 6 7 8 9 0
M A N Z A N O
Figura 6.1 – Estrutura de dados para formação de nome completo

Se a partir da estrutura de dado NOME-COMPLETO indicada na figura 6.1 fosse usada a função CONCATENATE o
resultado seria algo semelhante a:

CONCATENATE(SOBRENOME, ", " PRIMEIRO-NOME, NOME-MEIO)


| MANZANO , JOSE AUGUSTO |
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 215

Mesmo usando a função TRIM para tirar o excesso de espaços em branco a estrutura de escrita ficará complexa tor-
nando-se confusa. Note que os espaços em branco são também concatenados.
O controle de remoção dos espaços em branco é mais fácil se executado com o comando STRING. Assim, veja a se-
guir um trecho de código com um exemplo simples que não atenderá plenamente o desejado, mas chegará bem perto.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 NOME-COMPLETO.
02 PRIMEIRO-NOME PIC X(15) VALUE "JOSE".
02 NOME-MEIO PIC X(15) VALUE "AUGUSTO".
02 SOBRENOME PIC X(10) VALUE "MANZANO".
77 NOME PIC X(40).
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
STRING SOBRENOME DELIMITED BY " "
", " DELIMITED BY " "
PRIMEIRO-NOME DELIMITED BY " "
NOME-MEIO DELIMITED BY " "
INTO NOME.
DISPLAY NOME.

Ao ser executado o trecho de código anterior será apresentado o nome completo como uma sequência de dados com
todos os espaços embranco retirados.

|MANZANO,JOSEAUGUSTO|

Não sendo bem isso o que se deseja ver é necessário pedir o que se deseja de forma correta, pois a forma usada pede
para retirar todo os espaços em branco. O uso da cláusula DELIMITED BY " " retira todos os espaços e ao ser retirado
esses espaços pode-se pedir para que alguns desses espaços sejam mantidos. Observe no trecho seguinte as marca-
ções em vermelho.

STRING SOBRENOME DELIMITED BY " "


", " DELIMITED BY " " " " DELIMITED BY SIZE
PRIMEIRO-NOME DELIMITED BY " " " " DELIMITED BY SIZE
NOME-MEIO DELIMITED BY " "
INTO NOME.

Neste trecho o campo receptor NOME é o resultado da concatenação do SOBRENOME sem os espaços em branco, da
vírgula com espaço em branco, do PRIMEIRO-NOME com espaço em branco e do NOME-MEIO sem espaços em
branco. A cláusula DELIMITED BY SIZE coloca um espaço após o campo per ela indicado. O espaço em branco inseri-
do pela cláusula DELIMITED BY SIZE é definido a sua frente, gerando o resultado.

|MANZANO, JOSE AUGUSTO|

É pertinente salientar que aqui está sendo realizada uma ação com os espaços em branco. No entanto, esse recurso
pode ser aplicado a qualquer caractere de uma cadeia.
O comando STRING efetua sempre a concatenação de dados em um campo receptor tenha este ou não o tamanho
adequado para a recepção dos dados. Por exemplo, se o campo NOME estivesse configurado para o tamanho 10 seri-
am concatenados os dez primeiros caracteres que fossem possíveis de serem inseridos e os demais caracteres seriam
automaticamente desprezados. Veja esta ocorrência, sinalizada em vermelho.

LOCAL-STORAGE SECTION.
01 NOME-COMPLETO.
02 PRIMEIRO-NOME PIC X(15) VALUE "JOSE".
02 NOME-MEIO PIC X(15) VALUE "AUGUSTO".
02 SOBRENOME PIC X(10) VALUE "MANZANO".
77 NOME PIC X(10).
216 PRO G RA MA Ç ÃO CO B OL

Ao ser executado o programa com o trecho anterior ter-se-á como saída a indicação.

|MANZANO, J|

No entanto, ao ocorrer este efeito há internamente uma sinalização de ação bem ou mal sucedida. Além das cláusulas
usadas o comando STRING possui como cláusula auxiliar o evento [NOT] ON OVERFLOW a ser definido após o uso
de INTO que pode ser usado para indicar uma ocorrência de erro quando um programa recebe dados incompatível com
o tamanho necessário ao seu tratamento.
Mantendo o campo NOME configurado para o tamanho 10 observe a baixo o trecho marcado em vermelho com o uso
da cláusula ON OVERFLOW.

STRING SOBRENOME DELIMITED BY " "


", " DELIMITED BY " " " " DELIMITED BY SIZE
PRIMEIRO-NOME DELIMITED BY " " " " DELIMITED BY SIZE
NOME-MEIO DELIMITED BY " "
INTO NOME
ON OVERFLOW DISPLAY "ERRO! - Tamanho excedido".

Ao ser executado o programa é apresentado o resultado.

ERRO! - Tamanho excedido


MANZANO, J

Veja que após ON OVERFLOW pode-se colocar qualquer ação, como por exemplo a execução de uma sub-rotina,
interna ou externa a fim de apresentar alguma mensagem de alerta ao usuário para que o suporte técnico possa provi-
denciar a correção do código ou então outra necessidade que se faça necessária.
A cláusula ON OVERFLOW pode ser negada com o uso de NOT e apresentar mensagem ou executar alguma ação
caso a ação seja bem sucedida. Observe o trecho seguinte com indicações em vermelho e verde para execução de
ações mal ou bem sucedidas.

01 NOME-COMPLETO.
02 PRIMEIRO-NOME PIC X(15) VALUE "JOSE".
02 NOME-MEIO PIC X(15) VALUE "AUGUSTO".
02 SOBRENOME PIC X(10) VALUE "MANZANO".
77 NOME PIC X(10).

PROCEDURE DIVISION.
STRING SOBRENOME DELIMITED BY " "
", " DELIMITED BY " " " " DELIMITED BY SIZE
PRIMEIRO-NOME DELIMITED BY " " " " DELIMITED BY SIZE
NOME-MEIO DELIMITED BY " "
INTO NOME
ON OVERFLOW DISPLAY "ERRO! - Tamanho excedido"
NOT ON OVERFLOW DISPLAY "OK! - Acao bem sucedida".

Ao ser executado o trecho anterior ocorrerá a apresentação da saída.

OK! - Acao bem sucedida


MANZANO, JOSE AUGUSTO

O campo receptor de uma ação executada pelo comando STRING deve ser sempre um item elementar do tipo alfabéti-
co ou alfanumérico, bem como, todos os demais campos a serem usados.
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 217

6.2 DECOMPOSIÇÃO DE TEXTOS


A ação de concatenação refere-se a fazer a junção de textos separados em um só texto e ação de decomposição faz o
inverso da concatenação, ou seja, faz a disjunção de textos em partes menores. Essas operações são úteis quando se
recebe dados de outras fontes como, pôr exemplo, arquivos com dados gravados em formato CVS (Comma Separated
Values) que usam um caractere de identificação que marca a separação dos dados de um registro. Para operar decom-
posições de textos usa-se o comando UNSTRING que possui a forma sintática simplificada definida como:

UNSTRING <dado1>/<cadeia1> [DELIMITED [BY] <cadeia2>] INTO <dado3> ...

Em que, dado1 ou cadeia1 é a indicação do conteúdo a ser desunido (campo remetente) a partir da indicação do dado
apontado na cláusula de delimitação DELIMITED como cadeia2, podendo-se especificar uma lista de dados a serem
separados em dado3 após a cláusula INTO. A palavra BY é opcional e sua ausência ou uso não afeta em absoluto o
uso da instrução.
Como exemplo considere um programa que a partir de uma cadeia de caracteres definida como uma sequência CVS
contendo sobrenome, primeiro nome e nome do meio (MANZANO;JOSE;AUGUSTO) separados com pontos-e-vírgulas
sejam decompostas em três campos distintos.

DATA DIVISION.
LOCAL-STORAGE SECTION.
77 NOME PIC X(40) VALUE "MANZANO;JOSE;AUGUSTO".
01 NOME-COMPLETO.
02 PRIMEIRO-NOME PIC X(15).
02 NOME-MEIO PIC X(15).
02 SOBRENOME PIC X(10).

A partir da estrutura de dado definida basta executar a instrução.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
UNSTRING NOME DELIMITED BY ";"
INTO SOBRENOME
NOME-MEIO
PRIMEIRO-NOME.
DISPLAY SOBRENOME.
DISPLAY NOME-MEIO.
DISPLAY PRIMEIRO-NOME.

Ao ser executado o trecho de código anterior os dados são apresentados separadamente.

|MANZANO |
|JOSE |
|AUGUSTO |

Observe que as barras laterais indicadas são meros balizadores para dar a ideia de onde os espaços em branco do
espaço encontram-se definidos como por exemplo:
Um detalhe que pode ser usado com o comando UNSTRING é operá-lo com mais de um caractere delimitador de sepa-
ração. Imagine que o conjunto de dados recebido esteja usando como separadores, ao invés de ponto-vírgula, símbolos
de ponto final e vírgula, como segue.

77 NOME PIC X(40) VALUE "MANZANO,JOSE.AUGUSTO".

Para efetuar a separação dos dados com esses símbolos delimitadores deve-se fazer uso do operador OR junto a cláu-
sula DELIMITED como segue.
218 PRO G RA MA Ç ÃO CO B OL

UNSTRING NOME DELIMITED BY "." OR ","


INTO SOBRENOME
NOME-MEIO
PRIMEIRO-NOME.

Assim como STRING o comando UNSTRING também pode fazer uso da cláusula ON OVERFLOW com ou sem o ope-
rador NOT e um detalhe importantíssimo para usar UNSTRING o campo remetente deve ser alfabético ou alfanumérico.

6.3 INSPEÇÃO DE TEXTOS


Além das possibilidades de realizar a junção e disjunção de caracteres há outro importante recurso que pode ser usado
para inspecionar e realizar ações sobre sequências de caracteres. A ação de inspeção pode ser usada para realizar
três operações distintas, como: contar o número de ocorrências de determinado caractere ou sequência de caracteres
sobre determinada variável ou campo de registro; realizar ações de busca e troca de caracteres; e efetuar a conversão
de dados.
Veja a forma de definição do comando INSPECT para a realização da ação de contagem de ocorrências de caracteres.

INSPECT <dado1> TALLYING <dado2>


FOR CHARACTERS / ALL <dado3/literal1> / LEADING <dado4/literal2>
[BEFORE INITIAL / AFTER INITIAL <dado5/literal3>]

Onde, dado1 refere-se ao conteúdo a ser contado e dado2 refere-se ao espaço de armazenamento da contagem reali-
zada. A cláusula FOR indica qual caractere de dado1 deve ser usado na contagem de dado2 em que CHARACTERS
fornece um registro do número de caracteres existentes em dado1, ALL atribui em dado2 o registro das ocorrências de
todos os caracteres especificados em dado3 ou literal1 e LEADING atribui em dado2 o registro das ocorrências de
todos os caracteres especificados que antecedem a primeira ocorrência de qualquer outro caractere indicado em dado4
ou literal2. Os complementos BEFORE INITIAL e AFTER INITIAL referem-se à possibilidade de determinar em dado4
ou literal2 de que ponto ou até que ponto a contagem de dado2 deve ser realizada.
Como exemplo considere a estrutura de dado “MANZANO, JOSE AUGUSTO” como cadeia de caracteres a ser inspe-
cionada e a variável CONTAGEM para armazenamento da contagem de ocorrências.

DATA DIVISION.
LOCAL-STORAGE SECTION.
77 NOME PIC X(21) VALUE "MANZANO, JOSE AUGUSTO".
77 CONTAGEM PIC 99.

A partir da estrutura de dado definida basta executar a instrução.

PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
MOVE ZERO TO CONTAGEM.
INSPECT NOME TALLYING CONTAGEM FOR ALL "A".
DISPLAY CONTAGEM.

Ao ser executado o trecho de código anterior o programa apresenta o valor 3 que é o número de caracteres “A” existen-
te na cadeia indicada em NOME. É ideal sempre zeras a variável que guardará a contagem de caracteres para o co-
mando INSPECT.
Observe a seguir o indicativo de algumas ações que podem ser realizadas.

INSPECT NOME TALLYING CONTAGEM FOR ALL SPACES.

Mostra a quantidade de ocorrências de espaços em branco existentes, neste caso apresenta o valor 2.

INSPECT NOME TALLYING CONTAGEM FOR ALL "AN".


MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 219

Mostra a quantidade de ocorrências da existência dos caracteres AN, neste caso apresenta o valor 2.

INSPECT NOME TALLYING CONTAGEM FOR ALL "O"


BEFORE INITIAL ",".

Mostra a quantidade de ocorrências da existência dos caracteres O antes da vírgula, neste caso apresenta o valor 1.

INSPECT NOME TALLYING CONTAGEM FOR ALL "O"


AFTER INITIAL ",".

Mostra a quantidade de ocorrências da existência dos caracteres O depois da vírgula, neste caso apresenta o valor 2.

INSPECT NOME TALLYING CONTAGEM FOR CHARACTERS.

Mostra a quantidade de caracteres existentes, neste caso apresenta o valor 21.

INSPECT NOME TALLYING CONTAGEM FOR CHARACTERS


AFTER INITIAL "JOSE".

Mostra a quantidade de caracteres depois da palavra JOSE, neste caso apresenta o valor 8 (contando a existência de
espaços em branco).

INSPECT NOME TALLYING CONTAGEM FOR CHARACTERS


BEFORE INITIAL "JOSE".

Mostra a quantidade de caracteres antes da palavra JOSE, neste caso apresenta o valor 9.

INSPECT "AAA MANZANO" TALLYING CONTAGEM FOR LEADING "A".

Mostra a quantidade de ocorrências sucessivas do caractere “A”, existentes antes da primeira ocorrência isolada de “A”
em “MANZANO”, neste caso apresenta o valor 3.
Há momentos em que é necessário fazer a substituição de caracteres dentro dos dados de uma estrutura por diversos
motivos. Um exemplo, pode ser a substituição de caracteres acentuados por caractere sem acento para homogeneida-
de n armazenamento dos dados. Neste sentido, pode-se fazer uso do comando INSPECT para a realização da ação de
busca e troca caracteres, a partir da estrutura sintática.

INSPECT <dado1> REPLACING


CHARACTERS / [ALL / LEADING / FIRST <dado2/literal1>]
BY <dado3/literal2> BEFORE INITIAL / AFTER INITIAL <dado4/literal3>]

Onde, dado1 refere-se ao conteúdo a ser substituído por REPLACING. As cláusulas CHARACTERS, ALL, LEADING,
BEFORE INITIAL e AFTER INITIAL possuem o mesmo significado apresentado para TALLYING. A cláusula FIRST
quando em uso efetua a substituição do conteúdo da literal1 pelo conteúdo da literal2.
Observe alguns exemplos para o efeito de troca e substituição de caracteres a partir da estrutura de dados.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(04) VALUE "JOSÉ".
77 DATACAL PIC X(10) VALUE "26-04-1965".
77 TELEFONE PIC X(09) VALUE "1234 5678".
77 CODIGO PIC X(16) VALUE "COD: AC-ZZY-3367".
77 REFERENCIA PIC X(10) VALUE "5552597855".

A partir da estrutura indicada proceda a execução das instruções a seguir para visualizar alguns exemplos de ocorrên-
cias de substituição de conteúdo.

INSPECT DATACAL REPLACING ALL "-" BY "/".


220 PRO G RA MA Ç ÃO CO B OL

Mostra a data indicada em DATACAL como sendo “26/04/1965” retirando da data os traços usados como separação e
inserindo em seu lugar símbolos de barras.

INSPECT TELEFONE REPLACING ALL SPACES BY "-".

Mostra o número de telefone indicado em TELEFONE como sendo “1234-5678” retirando os espaços em branco exis-
tentes e substituindo pelo símbolo traço.

INSPECT CODIGO REPLACING FIRST "Z" BY "X".

Mostra o número do código de produto CODIGO como sendo “COD: AC-XZY-3367” retirando a primeira ocorrência do
caractere “Z” existente e substituindo-o pelo caractere “X”.

INSPECT REFERENCIA REPLACING LEADING "5" BY "7".

Mostra o número do código de referência do campo REFERENCIA como sendo “7772597855” substituindo os valores
sucessivos de “5” antes da primeira ocorrência isolada de “5” pelo valor “7”.

INSPECT NOME REPLACING ALL "É" BY "E".

Mostra o conteúdo do campo NOME como “JOSE” retirando o caractere acentuado e deixando o sem aceto.
Após conhecer os procedimentos de contagens de caracteres, busca e substituições de caracteres torna-se importante
saber como lidar com conversões de dados. Neste sentido, a uma terceira forma de se fazer uso do comando INSPECT
a partir da estrutura sintática.

INSPECT <dado1> CONVERTING <dado2/literal1> TO <dado3/literal2>


BEFORE INITIAL / AFTER INITIAL <dado4/literal3>]

Onde os dados indicados em dado2 ou literal1 serão convertidos pelos dados indicados em dado3 ou literal2. Os
demais detalhes usados no comando já são conhecidos.
Uma das ações mais comuns de conversão é fazer a alteração de eventuais dados alfabéticos minúsculos em formato
maiúsculo. Assim sendo, considere como exemplo a definição da seguinte estrutura de dados.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(12) VALUE "Jose AUGustO".
77 MINUSC PIC X(26) VALUE "abcdefghijklmnoprstuvwxyz".
77 MAIUSC PIC X(26) VALUE "ABCDEFGHIJKLMNOPRSTUVWXYZ".

Veja que são definidas duas sequências de caracteres contendo o abecedário minúsculo para MINUSC e abecedário
maiúsculo para MAIUSC. Na sequência observe a instrução.

INSPECT NOME CONVERTING MINUSC TO MAIUSC.

Veja que o nome é apresentado totalmente formatado em caractere maiúsculos. Note que esse evento permitiu que
fosse definida uma ação de correção para a composição dos dados.
O comando INSPECT tem grande importância no tratamento da conformidade dos dados fornecidos de forma textual,
pois permite, como visto, realizar uma série de operações de tratamento desde a contabilização de ocorrências de ca-
racteres, passando pelas ações de substituição e conversão de dados.

6.4 FUNÇÕES PARA CARACTERES


Operações de manipulação e tratamento de caracteres são uma das mais importantes ações de processamento em
qualquer linguagem de programação, mais precisamente em linguagens voltadas a aplicações comerciais, como é o
caso de COBOL. Para auxiliar essas tarefas há um conjunto de funções internas que podem ser utilizadas.
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 221

Neste sentido destacam-se as principais funções intrínsecas para este tipo de ação, sendo: CHAR, LENGTH, LOWER-
CASE, ORD, REVERSE, SUBSTITUTE e UPPER-CASE e excepcionalmente a extração de sub cadeias.
A função CHAR(inteiro) retorna o caractere ASCII (American Standard Code for Information Interchange) correspon-
dente ao valor ordinal indicado como argumento inteiro.
O valor inteiro deve estar situado na faixa de 1 até 256 para representar valores internos dos caracteres entre 0 e 255.
Isto posto, significa que o caractere maiúsculo correspondente a letra “A” retorna o valor 66 (sexagésimo sexto) carac-
tere na tabela ASCII que corresponde ao valor 65.
Contrário ao funcionamento da função CHAR existe a função ORD(caractere) que retorna o valor numérico ordinal do
caractere definido entre aspas e informado junto ao argumento caractere.
O trecho de código seguinte demonstra a apresentação dos caracteres ASCII e seus valores ordinais e cardinais a
partir da demonstração de uso das funções CHAR e ORD marcadas em vermelho e verde para os caracteres imprimí-
veis ASCII de 32 até 127.

CONFIGURATION SECTION.
REPOSITORY.
FUNCTION CHAR INTRINSIC
FUNCTION ORD INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 AC-CI PIC 9(3).
77 WS-ORD PIC 9(3).
77 WS-CAR PIC 9(3).
77 WS-S-O PIC Z(3).
77 WS-S-C PIC Z(3).
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY "ORD CAR ASCII".
DISPLAY "-----------------".
PERFORM VARYING AC-CI FROM 33 BY 1 UNTIL AC-CI > 127
MOVE AC-CI TO WS-ORD
COMPUTE WS-CAR = WS-ORD - 1
MOVE ORD(CHAR(WS-ORD)) TO WS-S-O
MOVE WS-CAR TO WS-S-C
DISPLAY WS-S-O "o. - " WS-S-C " - " CHAR(WS-S-O)

No trecho anterior além do uso das funções CHAR ORD observe no parágrafo REPOSITORY a indicação de uso ape-
nas das funções especificas. Esta forma deixa apenas essas funções disponíveis para uso sem a necessidade de utili-
zar o comando FUNCTION.
A função LENGTH(cadeia) efetua o retorno da quantidade de caracteres que uma cadeia passada como argumento
possui. Esta é uma forma rápida de obter a mesma informação retornada pelo comando INSPECT com a cláusula
TALLYING.
O trecho de código seguinte demonstra a apresentação do número de caractere de uma cadeia a partir do uso da fun-
ção LENGTH.

CONFIGURATION SECTION.
REPOSITORY.
FUNCTION ALL INTRINSIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(20) VALUE "AUGUSTO MANZANO".
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY LENGTH(TRIM(NOME)).
222 PRO G RA MA Ç ÃO CO B OL

Ao ser executado o programa é apresentado o resultado 15 sendo este o tamanho da cadeia após a remoção dos es-
paços em branco existentes. Observe que o campo NOME é definido a partir de 20 bytes. A função TRIM faz a remoção
dos espaços excedentes e a função LENGTH retorna a quantidade de caracteres.
Outro recurso que pode ser usado com funções em substituição a INSPECT com a cláusula CONVERTING são os usos
das funções LOWER-CASE(cadeia) e UPPER-CASE(cadeia) que respectivamente retornam suas cadeias nos forma-
tos minúsculo e maiúsculo.
O trecho de código seguinte demonstra a apresentação de uma sequência de caracteres definida com caracteres mi-
núsculos e maiúsculos a partir do uso das funções LOWER-CASE e UPPER-CASE.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(12) VALUE "Jose AUGustO".
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY FUNCTION LOWER-CASE(NOME).
DISPLAY FUNCTION UPPER-CASE(NOME).

Outra manipulação que pode ser necessária em algum momento é a reversão de uma cadeia de caracteres definida. A
reversão de uma cadeia pode ser executada com auxílio da função REVERSE(cadeia).
O trecho de código seguinte demonstra a apresentação de uma sequência de caracteres definida em sua forma inversa
a partir do uso da função REVERSE.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(15) VALUE "AUGUSTO MANZANO".
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY FUNCTION REVERSE(NOME).

Outra função que pode ser usada em substituição ao comando INSPECT com a cláusula REPLACING de forma simpli-
ficada e a função REVERSE(cadeia, fonter1, destino1 [, fonteN, destinoN]) que efetua a troca de caracteres dentro
de uma cadeia.
O trecho de código seguinte demonstra a apresentação da troca dos caracteres a partir da cadeia de caracteres “AU-
GUSTO MANZANO”. A primeira ação efetua a troca do caractere “O” pelo caractere “X”, a segunda ação efetua a troca
do caractere “N” pelo caractere “W” e do caractere “A” pelo caractere “Y” e por último efetua-se a troca do caractere “U”
pelo caractere “A” e do caractere “A” pelo caractere “T”.

DATA DIVISION.
WORKING-STORAGE SECTION.
77 NOME PIC X(15) VALUE "AUGUSTO MANZANO".
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY FUNCTION SUBSTITUTE(NOME, "O", "X").
DISPLAY FUNCTION SUBSTITUTE(NOME, "N", "W", "A" "Y").
DISPLAY FUNCTION SUBSTITUTE(NOME, "U", "A", "A" "T").

Este tópico apresentas principais funções internas de tratamento de caracteres e de cadeias de caracteres. Existem
outras que com uma boa consulta nos guias de referência podem ser estudas e experimentadas.
Na linguagem COBOL especificamente faltam funções que operem com sub cadeias de modo que seja possível extrair
partes de uma cadeia maior. No entanto, esta ação pode ser realizada de uma maneira alterativa, pois uma cadeia de
caracteres é por sua natureza uma lista de dados alfabéticos ou alfanuméricos. Desta forma, por ser uma lista possui a
definição de índices que podem ser acessados a partir do uso de modificadores de referência.
O trecho de código seguinte apresenta de forma decomposta a palavra COMPUTADOR dividida nas partes COM, PU-
TA e DOR.
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 223

DATA DIVISION.
WORKING-STORAGE SECTION.
77 SUB-CADEIA PIC X(10) VALUE "COMPUTADOR".
PROCEDURE DIVISION.
PROG-PRINCIPAL-PARA.
DISPLAY SUB-CADEIA(1:3).
DISPLAY SUB-CADEIA(4:4).
DISPLAY SUB-CADEIA(8:3).

Observe que a indicação (1:3) diz que é para ser pegos da variável SUB-CADEIA a partir do primeiro caractere pulan-
do-se 3, a indicação (4:4) diz que a partir do quatro caractere é para ser pego os 4 próximos e por último a indicação
(8:3) diz que a partir do oitavo caractere deve-se pegar o 4 próximos. Veja que para realizar esta ação não é necessá-
ria.

6.5 DÍGITO VERIFICADOR


Algumas das operações apresentadas nos tópicos anteriores neste capítulo podem parecer etéreas para algumas pes-
soas. No sentido de mostrar de maneira mais prática o uso de algumas das operações apresentadas considere neste
tópico o uso do recurso de definição e validação de dígito verificador.
Na computação há duas formas de se trabalhar com itens numéricos, uma como dados numéricos propriamente dito e
outra como dados alfanuméricos. Os dados definidos como numéricos estão diretamente relacionados a valores asso-
ciados a realização de processamento matemático e os dados alfanuméricos estão relacionados diretamente a repre-
sentação de valores de identificação de itens (produtos, documentos, contas correntes e etc) que eventualmente podem
estar associados a realização de cálculos matemáticos, sendo a validação de dígitos verificadores, ação realizada so-
bre dados alfanuméricos.
O dígito verificador é um valor de identificação calculado a partir de um algoritmo matemático especifico que visa garan-
tir a integridade e autenticidade de um código de identificação. Para a geração de dígitos verificadores existem diversos
algoritmos que podem ser utilizados, sendo muito populares os algoritmos de módulo 10 e 11.
Para conhecer os algoritmos de módulos 10 e 11, além da possibilidade de geração de dígito verificador para códigos
alfanuméricos contendo letras e números sugere-se consulta ao manual HP Data Entry and Forms Management Sys-
tem (VPLUS): Reference Manual – HP 3000 MPE/iX Computer System indicado na bibliografia desta obra.
O algoritmo de módulo 10 é aplicado a partir das seguintes considerações:
 as posições intermediárias das unidades que compõem o número básico a partir da última posição de duas em duas
posições da direita para a esquerda são multiplicadas por 2;
 o resultado obtido da multiplicação do dígito por 2 quando maior que 9 deve ser ajustado para um valor de um dígi-
to. Neste caso faz-se a soma dos dígitos componentes do valor para ter-se um resultado de apenas um dígito. Por
exemplo, se o resultado após a multiplicação for o valor 16, este deve ser considerado 7 (1 + 6). Outra forma de fa-
zer esta operação é usar o conceito “nove fora”, onde se subtrai 9. Neste caso 16 – 9 resulta em 7;
 os dígitos multiplicados por dois e após ajuste quando maior que 9 são adicionados aos dígitos das demais posições
que não foram multiplicados;
 o somatório dos valores ajustados dos dígitos deve ser subtraído do maior valor terminado em zero a partir do resul-
tado deste somatório, obtendo-se assim o dígito verificador.
Para demonstrar o uso do algoritmo de geração de dígito verificador módulo 10 considere o algoritmo descrito na tabela
6.1 para se obter o dígito verificador do código 987.654. Após a aplicação do algoritmo passa-se a ter como dígito veri-
ficador o valor 1 e pode assim ser representado 987.654-1.
224 PRO G RA MA Ç ÃO CO B OL

Tabela 6.1 – Algoritmo Modulo 10


Código numérico 9 8 7 6 5 4

Peso multiplicador - x 2 - x 2 - x 2

Resultado parcial 9 16 7 12 5 8

Ajuste quando >= 10 9 16 - 9 7 12 - 9 5 8

Resultado final 9 7 7 3 5 8

Soma do resultado final 39

Maior número seguinte terminado em 0 (*) 40

DV = 40 – 39 1

(*) O maior número seguinte terminado em zero (próximo múltiplo de 10, variável PM) a partir do valor da
soma do resultado final é conseguido com a expressão aritmética:
PM = INTEIRO((SOMA / 10) + 1) * 10

Para demonstrar o uso de dígito verificador considere a definição do código de identificação de um produto a partir da
máscara 999.999-9, onde os seis números, antes do traço, são o código do produto separados por um ponto em dois
grupos numéricos de três dígitos cada um. O último valor, após o traço, é o dígito verificador do código do produto.
Nesta proposta são definidos dois programas: um para gerar o dígito verificador e o outro para validar se o dígito verifi-
cador informado é correto.
Ambos os programas devem aceitar na entrada do código do produto a formatação da máscara em uso como definida.
O tratamento do ponto e traço fornecidos deverá ser tratado pelo programa. Isto significa que o usuário deverá fornecer
no programa de geração do dígito verificador o formato de código 999.999 e no programa de validação o formato de
código 999.999-9. Os pontos e eventualmente o traço deverá ser administrado no programa.
Para realizar o cálculo de dígito verificador é necessário que o programa retire da entrada do usuário o caractere que
não represente um valor numérico natural, sendo o ponto e/ou o traço. A linguagem COBOL não possui uma função
que faça a retirada de determinado caractere de uma cadeia. Isso faz com que o próprio programador venha a resolver
o problema, desenvolvendo uma função para esta ação. Para tanto, crie um projeto vazio, atribuindo o nome rmvchar a
partir da extensão “.clb” na subpasta COBOL da pasta Documentos e codifique o programa seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 FUNCTION-ID. RMVCHAR.
3 DATA DIVISION.
4 LOCAL-STORAGE SECTION.
5 77 LS-PTR PIC 9(3).
6 77 LS-IND PIC 9(3).
7 77 LS-CTR PIC 9(3).
8 77 LS-CAD-ENT PIC X(256).
9 LINKAGE SECTION.
10 77 LK-CAD-ENT PIC X(256).
11 77 LK-TAM PIC 9(3).
12 77 LK-CARACTR PIC X.
13 77 LK-CAD-SAI PIC X(256).
14 PROCEDURE DIVISION USING BY VALUE LK-CAD-ENT, LK-TAM, LK-CARACTR
15 RETURNING LK-CAD-SAI.
16 PROG-PRINCIPAL-PARA.
17 MOVE LK-CAD-ENT TO LS-CAD-ENT
18 INSPECT LS-CAD-ENT CONVERTING LK-CARACTR TO LOW-VALUE
19 MOVE 1 TO LS-PTR LS-IND
------ ------------------------------------------------------------------------
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 225

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
20 PERFORM UNTIL LS-PTR > LK-TAM
21 UNSTRING LS-CAD-ENT DELIMITED ALL LOW-VALUE
22 INTO LK-CAD-SAI(LS-IND:) COUNT IN LS-CTR
23 WITH POINTER LS-PTR
24 ADD LS-CTR TO LS-IND
25 END-PERFORM.
26 END FUNCTION RMVCHAR.
------ ------------------------------------------------------------------------

O código apresentado possui o uso de recursos conhecidos e parcialmente conhecidos. Observe os detalhes comenta-
dos a seguir.
Na seção LOCAL-STORAGE (linha 4) são definidas as variáveis que auxiliam a localização do caractere a ser retirado
da cadeia fornecida. As variáveis WS-PTR (linha 5) e WS-IND (linha 6) são responsáveis pelo deslocamento e posicio-
namento do índice da cadeia. A variável WS-CTR (linha 7) armazena a contagem da inspeção realizada com o coman-
do INSPECT definido na linha 18. A variável WS-CAD-ENT (linha 13) é usada para armazenar e preservar o valor do
parâmetro LK-CAD-ENT com a instrução MOVE LK-CAD-ENT TO WS-CAD-ENT na linha 17 antes de efetuar o pro-
cessamento, lembrando que esta ação é necessária no compilador GnuCOBOL devido ao fato de não estar implemen-
tado adequadamente o recurso BY VALUE na divisão de procedimento de uma função.
Na seção LINKAGE SECTION (linha 9) são definidas as variáveis de ligação entre a função rmvchar e o programa
chamador. Veja que a função recebe três argumentos representados pelos parâmetros LK-CAD-ENT (linhas 10 e 14),
LK-TAM (linhas 11 e 14), LK-CARACTR (linhas 12 e 14) e devolve como resposta a saída LK-CAD-SAI (linhas 13 e
15). Os parâmetros LK-CAD-ENT, LK-TAM e LK-CARACTR são respectivamente as indicações da cadeia entrada, do
tamanho da cadeia entrada e o caractere a ser removido da cadeia entrada.
O resultado LK-CAD-SAI é a devolução da cadeia entrada sem o caractere indicado em LK-CARACTR. As variáveis
LK-CAD-ENT e LK-CAD-SAI estão configuradas para operar com códigos de até 256 dígitos e a variável LK-TAM
ajustada para até três dígitos de tamanho (unidade, dezena e centena), suficiente para administra o tamanho das variá-
veis LK-CAD-ENT e LK-CAD-SAI.
Para realizar a remoção de um caractere de uma cadeia é necessário definir este caractere como de baixo valor. Isso é
feito com a instrução INSPECT LK-CAD-ENT CONVERTING LK-CARACTR TO LOW-VALUE na linha 18 que inspeci-
ona a cadeia LK-CAD-ENT e converte o caractere indicado em LK-CARACTR para baixo valor (LOW-VALUE). No
capítulo 2 foram feitos comentários sobre o uso de constantes figurativas destacando-se LOW-VALUE e LOW-VALUES
usadas nesta oportunidade.
A partir da identificação do caractere de baixa ordem na cadeia, faz-se a remoção deste mantendo-se os demais carac-
teres. Para proceder a remoção do caractere de baixa ordem é necessário percorrer a cadeia LK-CAD-ENT. Para que
isso seja possível é executada a instrução MOVE 1 TO WS-PTR WS-IND na linha 19 que atribui as variáveis WS-PTR e
WS-IND o valor 1, ou seja, coloca essas variáveis apontadas para o primeiro índice da lista LK-CAD-ENT.
O laço PERFORM definido entre as linhas 20 e 25 faz sua iteração até que o valor do índice WS-PTR seja maior que o
valor do tamanho LK-TAM, sendo o valor de WS-PTR incrementado em uma posição a partir da execução do trecho
WITH POINTER WS-PTR definido junto ao comando UNSTRING.
A instrução do comando UNSTRING (linha 21) pega da cadeia LK-CAD-ENT o caractere de baixa ordem LOW-VALUE
(sinalizado anteriormente), desconsidera-o e passa os demais caracteres para a cadeia LK-CAD-SAI. A cada inserção
de caractere válido a variável WS-CTR é contabilizada em 1 e é feito o deslocamento de uma posição de WS-PTR a
frente na cadeia LK-CAD-ENT, desta forma, WS-PTR terá seu valor aumentado em uma posição, sendo validado a
partir da verificação da condição WS-PTR > LK-TAM. A cada iteração valida de UNSTRING ocorre a atualização do
valor da variável WS-IND como o valor contabilizado de WS-CTR a partir da execução da instrução ADD WS-CTR TO
WS-IND na linha 24.
226 PRO G RA MA Ç ÃO CO B OL

A frase opcional WITH POINTER (linha 23) definida em UNSTRING é também encontrada no comando STRING. Este
recurso tem por finalidade determinar a posição do ponteiro (POINTER) de acesso a cada caractere da cadeia de ori-
gem, neste caso, LK-CAD-ENT e auxiliar a inserção deste caractere na cadeia de destino, neste caso, LK-CAD-SAI.
Um detalhe importante na linha 21 é o uso do conceito de sub cadeia no índice da variável LK-CAD-SAI indicado como
(WS-IND:). Veja que nesta aplicação está definido o índice de posicionamento na lista, mas não está se colocando a
quantidade de caracteres a ser retornado. Neste caso, considera-se todos os caracteres à direita da posição marcada
com “WS-IND:”. O segundo índice está indiretamente subentendido no uso da variável WS-PTR.
A partir do preparado da função rmvchar que vai auxiliar os programas de geração e validação de dígitos verificares
passa-se a escrita desses programas.
O programa seguinte demonstra a aplicação do algoritmo de módulo 10 para a geração de um dígito verificador para
um código fornecido sob o formato de máscara 999.999 e apresentado sob o formato de máscara 999.999-9. Assim
sendo, crie um projeto vazio, atribuindo o nome cap06ap01 a partir da extensão “.cob” na subpasta COBOL da pasta
Documentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP06AP01.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION RMVCHAR
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 WORKING-STORAGE SECTION.
10 77 WS-TAM PIC 9(3).
11 77 AC-CI PIC 9(3).
12 77 WS-SOMA PIC 9(4) VALUE ZERO.
13 77 WS-DV PIC 9.
14 77 WS-POS PIC 9.
15 77 WS-COD-CPTO PIC X(7).
16 77 WS-COD-SPTO PIC X(6).
17 PROCEDURE DIVISION.
18 PROG-PRINCIPAL-PARA.
19 DISPLAY "Entre codigo (999.999): " WITH NO ADVANCING.
20 ACCEPT WS-COD-CPTO.
21 * >>> Calculo do DV (inicio) **********************************
22 COMPUTE WS-TAM = LENGTH(WS-COD-CPTO).
23 MOVE RMVCHAR(WS-COD-CPTO, WS-TAM, ".") TO WS-COD-SPTO.
24 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-TAM - 1
25 MOVE WS-COD-SPTO(AC-CI:1) TO WS-POS
26 IF REM(AC-CI, 2) = 0 AND WS-POS * 2 > 9
27 COMPUTE WS-SOMA = WS-SOMA + WS-POS * 2 - 9
28 ELSE
29 IF REM(AC-CI, 2) = 0 AND WS-POS * 2 <= 9
30 COMPUTE WS-SOMA = WS-SOMA + WS-POS * 2
31 END-IF
32 END-IF
33 IF REM(AC-CI, 2) NOT = 0
34 COMPUTE WS-SOMA = WS-SOMA + WS-POS
35 END-IF
36 END-PERFORM.
------ ------------------------------------------------------------------------
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 227

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
37 COMPUTE WS-DV = INTEGER(WS-SOMA / 10 + 1) * 10 - WS-SOMA.
38 * >>> Calculo do DV (fim) *************************************
39 DISPLAY "Matricula com DV = " WS-COD-CPTO "-" WS-DV.
40 STOP RUN.
41 END PROGRAM CAP06AP01.
------ ------------------------------------------------------------------------

Ao executar o programa, forneça para teste o código 987.654. Observe a apresentação do resultado 987.654-1 com o
dígito verificador cálculado de acordo com o algoritmo apresentado.
O laço PERFORM entre as linhas 24 e 36 percorre a cadeia que possui apenas os números sem o ponto informado na
entrada, por esta razão esta cadeia é menor em uma posição que a cadeia usada para a entrada do valor do código.
Daí o uso da condição de encerramento com WS-TAM – 1.
Dentro do laço na linha 25 ocorre a decomposição de cada slot da lista WS-COD-SPTO(AC-CI:1) para a variável WS-
POS a fim de se obter separadamente cada um dos dígitos do conjunto de valores. O valor de WS-POS é verificado
nas condições IF. Observe que é verificado se o valor do dígito é par e se multiplicado por 2 está acima de 9, realizando
os ajustes necessários de acordo com o que está apresentado na tabela 6.1. Ao término do laço é feito o cálculo do
dígito verificador com a instrução COMPUTE WS-DV = INTEGER(WS-SOMA / 10 + 1) * 10 - WS-SOMA executada na
linha 37.
O programa seguinte demonstra a aplicação do algoritmo de módulo 10 para a validação de um dígito verificador para
um código fornecido sob o formato de máscara 999.999-9. Assim sendo, crie um projeto vazio com o nome cap06ap02
a partir da extensão “.cob” na subpasta COBOL da pasta Documentos e informe o código seguinte.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP06AP02.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION RMVCHAR
7 FUNCTION ALL INTRINSIC.
8 DATA DIVISION.
9 WORKING-STORAGE SECTION.
10 77 WS-TAM PIC 9(3).
11 77 AC-CI PIC 9(3).
12 77 WS-SOMA PIC 9(4) VALUE ZERO.
13 77 WS-DVC PIC 9.
14 77 WS-DVE PIC 9.
15 77 WS-POS PIC 9.
16 77 WS-COD-CPTO PIC X(9).
17 77 WS-COD-SPTO PIC X(8).
18 77 WS-COD-STRC PIC X(7).
19 PROCEDURE DIVISION.
50 PROG-PRINCIPAL-PARA.
21 DISPLAY "Entre codigo (999.999-9): " WITH NO ADVANCING.
22 ACCEPT WS-COD-CPTO.
23 * >>> VALIDACAO DE DV
24 COMPUTE WS-TAM = LENGTH(WS-COD-CPTO). *> EXTRAI O PONTO
------ ------------------------------------------------------------------------
228 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
25 MOVE RMVCHAR(WS-COD-CPTO, WS-TAM, ".") TO WS-COD-SPTO.
26 COMPUTE WS-TAM = LENGTH(WS-COD-SPTO). *> EXTRAI O TRACO
27 MOVE RMVCHAR(WS-COD-SPTO, WS-TAM, "-") TO WS-COD-STRC.
28 PERFORM VARYING AC-CI FROM 1 BY 1 UNTIL AC-CI > WS-TAM - 2
29 MOVE WS-COD-STRC(AC-CI:1) TO WS-POS
30 IF REM(AC-CI, 2) = 0 AND WS-POS * 2 > 9
31 COMPUTE WS-SOMA = WS-SOMA + WS-POS * 2 - 9
32 ELSE
33 IF REM(AC-CI, 2) = 0 AND WS-POS * 2 <= 9
34 COMPUTE WS-SOMA = WS-SOMA + WS-POS * 2
35 END-IF
36 END-IF
37 IF REM(AC-CI, 2) NOT = 0
38 COMPUTE WS-SOMA = WS-SOMA + WS-POS
39 END-IF
40 END-PERFORM.
41 COMPUTE WS-DVC = INTEGER(WS-SOMA / 10 + 1) * 10 - WS-SOMA.
42 MOVE WS-COD-STRC(7:1) TO WS-DVE.
43 IF WS-DVC = WS-DVE
44 DISPLAY "Numero de codigo valido."
45 ELSE
46 DISPLAY "Numero de codigo invalido."
47 END-IF.
48 STOP RUN.
49 END PROGRAM CAP06AP02.
------ ------------------------------------------------------------------------

Ao executar o programa, entre o código 987.654-1 para ver a mensagem de validade apresentada. Depois entre outro
valor e veja o que ocorre, por exemplo, entre o código 987.654-8.
Em linhas gerais, o programa cap06ap02 é semelhante ao programa cap06ap01, tendo diferenças sutis, como a defini-
ção das variáveis WS-DVC (dígito verificador calculado - linha 13) e WS-DVE (dígito verificado entrado - linha 14), além
do laço PERFORM fazer uso de um limite de iteração menor com WS-TAM - 2 (linha 28) devido a duas movimentações
de retirada de caracteres: um ponto e um traço. Os trechos em vermelho mostram como aplicar comentários de linhas
no código.

6.6 HORA DE PROGRAMAR


A partir dos comentários apresentados neste capítulo sobre manipulação de cadeias de caracteres e eventual tratamen-
to de dados alfanuméricos como numéricos observe a seguir alguns exemplos desses e outros recursos mostrados em
capítulos anteriores. Observe que muitas vezes o uso da manipulação de caracteres ocorre de forma indireta.
Nem sempre no tratamento de caractere se usa obrigatoriamente os comandos STRING, UNSTRING e ISNSPECT,
grande parte das vezes é necessário utilizar-se das funções intrínsecas para esta ação. É importante perceber quando
uma ou outra estratégia deve ou pode ser usada.

DIA DA SEMANA DE UMA DATA FORNECIDA


Elaborar programa de computador que a partir da entrada de uma data no formato DD/MM/AAAA apresente a data
informada, o dia, o mês, o ano, a data informada em formato ANSI (AAAAMMDD) e respectivo dia da semana de forma
reduzida como Seg, Ter, Qua, Qui, Sex, Sab ou Dom. Usar no programa a filosofia de programação estruturada.
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 229

Para o desenvolvimento deste programa são consideradas algumas variáveis diretas para o controle das ações de
entrada, processamento e saída ação e outras indiretas para o apoio exclusivo as operações de processamento. Atente
para cada detalhe apresentado.
Selecione e defina um projeto do programa vazio com o nome c06ex01.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C06EX01 AS "Capitulo 6 – Exemplo 1".
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 * Variaveis diretas de acao do programa
10 01 WS-ENTRA-DATA.
11 05 DIA PIC XX.
12 05 FILLER PIC X VALUE "/".
13 05 MES PIC XX.
14 05 FILLER PIC X VALUE "/".
15 05 ANO PIC X(4).
16 77 WS-DIA-SEMANA PIC X(21) VALUE "DomSegTerQuaQuiSexSab".
17 77 WS-DIA-NUMERO PIC 9(1) value 0.
18 77 WS-DATA-ANSI PIC X(8).
19 77 WS-DT-ANSI-N PIC 9(8).
20 * Variaveis indiretas de apoio ao programa
21 77 WS-SOMA PIC 99 VALUE ZERO.
22 77 WS-DESLOC PIC 99.
23 77 AC-CI PIC 9.
24 *
25 PROCEDURE DIVISION.
26 PROG-PRINCIPAL-PARA.
27 PERFORM 100-ENTRADA THRU 100-ENTRADA-FIM.
28 PERFORM 200-PROCESSAMENTO THRU 200-PROCESSAMENTO-FIM.
29 PERFORM 300-SAIDA THRU 300-SAIDA-FIM.
30 STOP RUN.
31 * Entrada de dado (data formato DD/MM/AAAA)
32 100-ENTRADA SECTION.
33 DISPLAY "Entre data DD/MM/AAAA: " WITH NO ADVANCING.
34 ACCEPT WS-ENTRA-DATA.
35 EXIT.
36 100-ENTRADA-FIM SECTION.
37 * Processamento da data
38 200-PROCESSAMENTO SECTION.
39 * Transforma data (DD/MM/AAAA) em data ANSI (AAAAMMDD)
40 STRING ANO DELIMITED BY " " MES DELIMITED BY " " DIA INTO
41 WS-DATA-ANSI.
42 MOVE WS-DATA-ANSI TO WS-DT-ANSI-N.
43 * Calcula o dia da semana a partir da data ANSI
44 COMPUTE
45 WS-DIA-NUMERO = MOD(INTEGER-OF-DATE(WS-DT-ANSI-N), 7) + 1.
46 * Prepara indice de localização do nome do dia da semana
47 PERFORM VARYING AC-CI FROM 0 BY 2 UNTIL AC-CI > WS-DIA-NUMERO
------ ------------------------------------------------------------------------
230 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
48 COMPUTE WS-SOMA = WS-SOMA + AC-CI
49 END-PERFORM.
50 COMPUTE WS-DESLOC = WS-SOMA + WS-DIA-NUMERO.
51 EXIT.
52 200-PROCESSAMENTO-FIM SECTION.
53 * Apresentacao dos dados a partir da entrada da data DD/MM/AAAA
54 300-SAIDA SECTION.
55 DISPLAY "Data informada ......: " WS-ENTRA-DATA.
56 DISPLAY "Dia da data .........: " DIA.
57 DISPLAY "Mes da data .........: " MES.
58 DISPLAY "Ano da data .........: " ANO.
59 DISPLAY "Data modo ANSI ......: " WS-DATA-ANSI.
60 DISPLAY "Dia da semana (#) ...: " WS-DIA-NUMERO.
61 DISPLAY "Dia da semana (ext) .: " WS-DIA-SEMANA(WS-DESLOC:3).
62 EXIT.
63 300-SAIDA-FIM SECTION.
64 *
65 END PROGRAM C06EX01.
------ ------------------------------------------------------------------------

Observe atentamente cada linha do código do programa apresentado. Ao ser executado o programa informe a data no
formato indicado e veja as informações apresentadas.
Parte do que está em uso no programa é conhecida. Há alguns detalhes em uso a respeito do uso da filosofia estrutu-
rada de programação que não foram apresentados anteriormente como é o caso de uso do comando THRU nas linhas
de 27 a 29. O comando opcional THRU estabelece até onde considerar a ação do comando PERFORM. Veja que neste
exemplo as seções definidas como sub-rotinas possuem um ponto de início marcado com o comando PERFORM e um
ponto de saída definido após o comando THRU. Esta é uma ação que visa deixar o programa sintaticamente com apa-
rência estruturada mais elegante.
As linhas de 10 a 19 estabelecem as variáveis de apoio as operações de entrada, processamento e saída que serão de
alguma forma apresentadas no trecho de código entre as linhas 55 e 61. Entre as linhas 21 e 23 estão definidas as
variáveis de apoio ao processamento realizado no trecho entre as linhas 39 e 51.
Para a entrada da data é estabelecido na linha 10 o registro do dado chamado WS-ENTRADA-DATA formado pelos
campos DIA (linha 11), MÊS (linha 13) e ANO (linha 15). As linhas 12 e 14 estabelecem os campos anônimos represen-
tantes apenas da barra de separação do conjunto de dados.
Na linha 16 é definida uma lista interna chamada WS-DIA-SEMANA contendo uma cadeia com os nomes resumidos
dos dias da semana. Esta variável é manipulada na linha 61 com apoio das ações de processamento realizadas no
trecho de processamento do programa.
As demais variáveis apoiam a execução do programa atentando especialmente a variável WS-DATA-ANSI da linha 18
que tem por finalidade armazenar a data no formato AAAAMMDD, conhecido como formato ANSI. Este formato é ne-
cessário as operações das funções intrínsecas de manipulação de data da linguagem.
O trecho de entrada entre as linhas 32 e 36 realiza a recepção da data sem nenhuma ação de validação ou tratamento.
Assim sendo, entre a data como solicitado.
Entre as linhas 38 e 52 está o trecho de processamento em que a primeira ação executada nas linhas 40 e 42 é o ajus-
te da data informada no formato ANSI, observe que a data fornecida na linha 37 é aqui concatenada no formato ade-
quado as operações do programa. Na linha 42 faz-se a conversão da data ANSI do formato cadeia para o formato nu-
mérico com o uso da instrução MOVE WS-DATA-ANSI TO WS-DT-ANSI-N. Uma vez formatada a data para o formato
numérico é realizado nas linhas 44 e 45 o cálculo do dia da semana a partir da data. Veja que para esta operação basta
pegar a data no formato ANSI, dividi-la por 7 e olhar o resto da divisão que é um valor cardinal, daí fazer-se a soma de
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 231

mais 1 para olhar o valor de forma ordinal de modo que 1 seja domingo, 2 seja segunda-feira, e assim por diante até 7
sendo sábado.
O próximo passo do programa é encontrar entre as linhas 47 e 50 o valor adequado para obter o nome resumido do dia
da semana existente na lista WS-DIA-SEMANA como descreve a figura 6.2.

WS-DIA-SEMANA
1 1 1 1 1 1 1 1 1 1 2 2
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
D o m S e g T e r Q u a Q u i S e x S a b
1 2 3 4 5 6 7
Figura 6.2 – Estrutura para os dias da semana

A variável WS-DIA-NUMERO tem após seu cálculo na linha 45 o valor da terceira linha da figura 6.2. Mas observe que,
por exemplo, para pegar o dia de sábado com WS-DIA-NUMERO em 7 é necessário posicionar-se na variável WS-DIA-
SEMANA com o uso de modificador de referência na posição 19 e entender 3 posições.
Veja que há uma relação de valores curiosos na figura 6.2. Observando a terceira e a primeira linha tem-se a sequência
de valores 1 (1, 2, 3), 2 (4, 5, 6), 3 (7, 8, 9), 4 (10, 11, 12), 5 (13, 14, 15), 6 (16, 17, 18) e 7 (19, 20, 21) que indica a
informação do que é necessário ser feito. Note que há certo padrão nos valores indicados.
Tome os valores da terceira linha e observe a relação deste com os primeiros valores de cada três células da primeira
linha. Veja que o valor 1 da terceira linha marca a posição 1 da primeira linha, o valor 2 da terceira linha marca a posi-
ção 4 da primeira linha e assim sucessivamente. Veja o que está exposto na figura 6.3.

WS-DIA-SEMANA
1 1 1 1 1 1 1 1 1 1 2 2
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
D o m S e g T e r Q u a Q u i S e x S a b
1 2 3 4 5 6 7
Figura 6.3 – Pontos de indexação importantes

Observe que há certa evolução de valores entre os pontos marcados na figura 6.3. Fazendo-se a subtração dos valores
marcados na figura 6.3 entre a primeira e terceira linhas tem-se as diferenças desses valores que são a base para o
cálculo da variável WS-SOMA e do trecho deste processamento entre as linhas 47 e 49. Observe a figura 6.4 mostran-
do na quarta linha os resultados de 1 – 1 = 0, 4 – 2 = 2, 7 – 3 = 4, 10 – 4 = 6, 13 – 5 = 8, 16 – 6 = 10 e 19 – 7 = 12.

WS-DIA-SEMANA
1 1 1 1 1 1 1 1 1 1 2 2
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
D o m S e g T e r Q u a Q u i S e x S a b
1 2 3 4 5 6 7
0 2 4 6 8 10 12
Figura 6.4 – Cálculo dos valores de ajustes

Para a obtenção dos valores de ajustes posicionais de 0 até 12 de 2 em 2 define-se o trecho de código entre as linhas
47 e 49, em que é realizada enquanto o valor do contador AC-CI iniciado em 0 permanece menor ou igual que o valor
do dia da semanada obtido (WS-DIA-NUMERO). Veja que a cada dia percorrido soma-se 2 a variável WS-SOMA ob-
tendo-se os valores de ajustes da quarta linha na figura 6.4.
A partir da obtenção do valor do dia da semana (WS-DIA-NUMERO) e do deslocamento na lista WS-DIA-SEMANA
obtido com a variável WS-SOMA, basta somar esses dois valores para obter o deslocamento correto na lista como
efetuado na linha 50 usado posteriormente na linha 61 como WS-DIA-SEMANA(WS-DESLOC:3).
232 PRO G RA MA Ç ÃO CO B OL

VALIDAÇÃO DOS LIMITES DE DATAS DO CALENDÁRIO


Elaborar programa de computador que a partir da entrada de uma data no formato DD/MM/AAAA apresente a data se
esta for válida. Caso a data informada não seja válida deve apresentar a saída com o detalhe **/**/****. O programa
deve ser capaz de não aceitar datas com mais de 30 dias para os meses 4, 6, 9 e 11; com mais de 31 dias para os
meses 1, 3, 5, 7, 8, 10 e 12 e limitar o mês 2 com 29 dias para anos bissextos e 28 dias para anos não bissextos.
Para o desenvolvimento deste programa são realizadas algumas verificações não suportadas na linguagem. É impor-
tante ressaltar que em sua maioria as linguagens de programação comerciais fornecem funções para o tratamento de
datas. No entanto, essas funções não validam a consistência da data informada como, por exemplo, 30/02/2021, fican-
do esta tarefa a cargo do profissional de desenvolvimento. Neste sentido, segue então o programa que faz a validação
da entrada de certa data. Primeiro é descrito o código de sub-rotina e depois o código do programa chamador.
Selecione e defina um projeto do programa vazio com o nome c0602dat.clb na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C0602DAT.
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 REPOSITORY.
6 FUNCTION ALL INTRINSIC.
7 DATA DIVISION.
8 LOCAL-STORAGE SECTION.
9 01 TB-DATA.
10 05 TB-DATA-DIA PIC 99.
11 05 TB-DATA-MES PIC 99.
12 05 TB-DATA-ANO PIC 9(5).
13 05 TB-ULTIMO-DIA PIC 99.
14 05 TB-DATA-BISXT PIC 9.
15 88 TB-DT-BISX VALUE 0 1. *> 0 = Falso | 1 = Verdadeiro
16 05 TB-DATA-OK PIC 9.
17 88 TB-DT-OK VALUE 0 1. *> 0 = Falso | 1 = Verdadeiro
18 78 FEVEREIRO VALUE 2.
19 78 JULHO VALUE 7.
20 77 LS-DATA-ANSI PIC X(8).
21 77 LS-RESTO PIC 9(4).
22 77 LS-QUOCT PIC 9(4).
23 LINKAGE SECTION.
24 77 LK-ENTRA-DATA PIC X(10).
25 77 LK-SAIDA-DATA PIC X(10).
26 PROCEDURE DIVISION USING LK-ENTRA-DATA, LK-SAIDA-DATA.
27 PROG-PRINCIPAL-PARA.
28 MOVE LK-ENTRA-DATA(1:2) TO TB-DATA-DIA.
29 MOVE LK-ENTRA-DATA(4:2) TO TB-DATA-MES.
30 MOVE LK-ENTRA-DATA(7:4) TO TB-DATA-ANO.
31 * Checa ano bissexto
32 MOVE 0 TO TB-DATA-BISXT.
33 COMPUTE LS-RESTO = REM(TB-DATA-ANO, 400).
34 IF LS-RESTO = 0
35 MOVE 1 TO TB-DATA-BISXT
36 ELSE
37 COMPUTE LS-RESTO = REM(TB-DATA-ANO, 100)
38 IF LS-RESTO NOT = 0
------ ------------------------------------------------------------------------
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 233

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
39 COMPUTE LS-RESTO = REM(TB-DATA-ANO, 4)
40 IF LS-RESTO = 0
41 MOVE 1 TO TB-DATA-BISXT
42 END-IF
43 END-IF
44 END-IF.
45 * Detecta ultimo dia do MES
46 IF TB-DATA-MES = FEVEREIRO
47 IF TB-DATA-BISXT = 1
48 MOVE 29 TO TB-ULTIMO-DIA
49 ELSE
50 MOVE 28 TO TB-ULTIMO-DIA
51 END-IF
52 ELSE
53 IF TB-DATA-MES <= JULHO
54 COMPUTE LS-RESTO = REM(TB-DATA-MES, 2)
55 IF LS-RESTO = 0
56 MOVE 30 TO TB-ULTIMO-DIA
57 ELSE
58 MOVE 31 TO TB-ULTIMO-DIA
59 END-IF
60 ELSE
61 COMPUTE LS-RESTO = REM(TB-DATA-MES, 2)
62 IF LS-RESTO = 0
63 MOVE 31 TO TB-ULTIMO-DIA
64 ELSE
65 MOVE 30 TO TB-ULTIMO-DIA
66 END-IF
67 END-IF
68 END-IF.
69 * Validacao da DATA
70 MOVE 0 TO TB-DATA-OK.
71 IF TB-DATA-ANO >= 1601 AND
72 TB-DATA-ANO <= 9999 AND
73 TB-DATA-MES >= 1 AND
74 TB-DATA-MES <= 12 AND
75 TB-DATA-DIA >= 1 AND
76 TB-DATA-DIA <= TB-ULTIMO-DIA
77 MOVE 1 TO TB-DATA-OK
78 END-IF.
79 * Validacao do retorno para apresentacao de data
80 IF TB-DATA-OK = 1
81 MOVE LK-ENTRA-DATA TO LK-SAIDA-DATA
82 ELSE
83 MOVE "**/**/****" TO LK-SAIDA-DATA
84 END-IF.
85 EXIT PROGRAM.
86 END PROGRAM C0602DAT.
------ ------------------------------------------------------------------------

O código de programa apresentado pode ser compilado, mas não pode ser executado uma vez que por ser o código de
sub-rotina necessita da definição de outro programa que faça sua chamada.
234 PRO G RA MA Ç ÃO CO B OL

Entre as linhas 9 e 19 é definida a estrutura de dados TB-DATA para armazenamento e controle de uma data de calen-
dário fornecida. Observe as definições dos campos para o dia (linhas 10), mês (linha 11) e ano (linha 12), além desses
campos encontra-se a definição do campo para armazenar o valor do último dia do mês (linha 13), a validação lógica se
o ano é ou não bissexto (linhas 14 e 15) e um campo especial para marcação do status da data informada sendo corre-
ta ou incorreta (linhas 16 e 17). Além desses campos a estrutura possui definida duas constantes para validação dos
meses de FEVEREIRO e JULHO. Esses dois meses possuem características que determinam o alinhamento do calen-
dário.
Um detalhe importante no programa é a definição dos pontos de vínculo para a entrada de uma data e sua saída vali-
dada ou não indicados nas linhas 24 e 25.
Entre as linhas 28 e 30 são realizadas as operações de manipulação de cadeia com a extração dos componentes dias
(TB-DATA-DIA), mês (TB-DATA-MES) e ano (TB-DATA-ANO) da data informada para uso nas operações de proces-
samento do programa.
O trecho de código entre as linhas 32 e 44 verificam se dado certo ano (TB-DATA-ANO) é ou não bissexto. Para saber
se um ano é bissexto, basta verificar se é divisível por 400 ou divisível por 4, mas não por 100. O trecho é inicializado
com a definição de valor falso (0) para o campo TB-DATA-BISXT, sendo as condições do trecho validas para um ano
bissexto o campo TB-DATA-BISXT é atualizado em 1 indicando que a operação é verdadeira.
Na sequência o programa detecta entre as linhas 46 e 68 a quantidade de dias validas para determinado mês. Veja que
a primeira ação é verificar se o campo TB-DATA-MES equivale a FEVEREIRO (linha 46) e sendo esta condição verda-
deira o programa na linha 47 detecta se o ano da data é bissexto, sendo bissexto determina para o campo TB-ULTIMO-
DIA a quantidade de 29 dias (linha 48). Senão deixa este campo com a quantidade de 28 dias (linha 50).
Se a condição de verificação do mês de fevereiro não for cumprida, o fluxo do programa é desviado para a linha 53 que
detecta se o campo TB-DATA-MÊS possui seu valor menor ou igual a JULHO. Se esta condição for verdadeira estabe-
lece que os meses pares possuem 30 dias e os meses ímpares possuem 32 dias. No entanto fora desta condição os
meses pares possuem 31 dias e os meses impares possuem 30 dias. Observe detalhadamente as linhas do trecho de
53 até 67.
Validado o ano bissexto e os limites máximos de dias permitidos para cada mês é realizada a validação da data entre
as linhas 70 e 77. O programa está concentrado na faixa de datas que as funções intrínsecas para estes eventos ope-
ram, mas pode ser ajustado para outros limites, desde que outras verificações necessárias para a manipulação de da-
tas sejam programadas. Neste trecho se a data informada estiver dentro das conformidades esperadas o campo TB-
DATA-OK é configurado em 1 indicando data validada.
A última ação do programa entre as linhas 80 e 84 é fazer o retorno da informação da data validada ou não. Observe
que se a data estiver correta ela é movimentada para o argumento LK-SAIDA-DATA, mas se for incorreta é movimen-
tado para o campo a informação **/**/****.
Selecione e defina um projeto do programa vazio com o nome c06ex02.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C06EX02 AS "Capitulo 6 – Exemplo 2".
3 DATA DIVISION.
4 WORKING-STORAGE SECTION.
5 01 WS-ENTRA-DATA.
6 05 DIA PIC XX.
7 05 FILLER PIC X VALUE "/".
8 05 MES PIC XX.
9 05 FILLER PIC X VALUE "/".
10 05 ANO PIC X(4).
11 66 WS-SAIDA-DATA RENAMES DIA THRU ANO.
12 PROCEDURE DIVISION.
------ ------------------------------------------------------------------------
MA NIP UL A ÇÃ O DE C ADE IA S DE CA R A CTE RE S 235

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
13 PROG-PRINCIPAL-PARA.
14 DISPLAY "Entre data DD/MM/AAAA: " WITH NO ADVANCING.
15 ACCEPT WS-ENTRA-DATA.
16 CALL "C0602DAT" USING BY CONTENT WS-ENTRA-DATA,
17 BY REFERENCE WS-SAIDA-DATA.
18 DISPLAY "Data informada: " WS-SAIDA-DATA.
19 STOP RUN.
20 END PROGRAM C06EX02.
------ ------------------------------------------------------------------------

Execute o programa e forneça algumas datas, seguindo a máscara indicada. Atente para a forma como o programa se
comporta, entre a data 30/02/2021 e veja o que ocorre. Aproveite execute novamente o programa c06ex01 e observe o
que ocorre quando a data 30/02/2021 é fornecida. Observe a diferença operacional entre os dois códigos. Neste pro-
grama é declarado entre as linhas 5 e 10 a estrutura de dados para a recepção da data informada. A linha 11 utiliza um
campo nomeado a partir do código 66 aproveitando-se a estrutura definida entre as linhas 7 e 11.
Assim que a entrada é definida junto a linha 15 o programa faz na linha 16 e 17 a chamada da sub-rotina passando
como parâmetro a data informada em WS-ENTRA-DATA. A sub-rotina faz as validações dos limites de data e consis-
tência devolvendo o resultado no parâmetro WS-SAIDA-DATA, para sua apresentação na linha 18.

VALIDAÇÃO DA ENTRADA DE UMA DATA DO CALENDÁRIO


Elaborar programa de computador que impossibilite a entrada de uma data de calendário caso não seja a data forneci-
da de acordo com a máscara MM/DD/AAAA. Qualquer tentativa de entrada diferente do esperado deve ser negada.
Este programa deve receber como entrada de dados os símbolos numéricos e a barra como caractere de separação.
Basicamente este programa é semelhante ao programa anterior, tendo como diferencial o trecho responsável por vali-
dar a entrada do usuário em não deixar que as entradas inconsistentes sejam aceitas. Selecione e defina um projeto do
programa vazio com o nome c06ex03.cob na pasta COBOL da pasta Documentos.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. C06EX03 AS "Capitulo 6 – Exemplo 3".
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 SPECIAL-NAMES.
6 CLASS CARACTERE IS "0" THRU "9" "/".
7 REPOSITORY.
8 FUNCTION LENGTH INTRINSIC
9 FUNCTION TRIM INTRINSIC.
10 DATA DIVISION.
11 LOCAL-STORAGE SECTION.
12 01 LS-ENTRA-DATA.
13 05 DIA PIC XX.
14 05 FILLER PIC X VALUE "/".
15 05 MES PIC XX.
16 05 FILLER PIC X VALUE "/".
17 05 ANO PIC X(4).
18 66 LS-SAIDA-DATA RENAMES DIA THRU ANO.
------ ------------------------------------------------------------------------
236 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
19 PROCEDURE DIVISION.
20 PROG-PRINCIPAL-PARA.
21 PERFORM UNTIL EXIT
22 DISPLAY "Entre data DD/MM/AAAA: " WITH NO ADVANCING
23 ACCEPT LS-ENTRA-DATA
24 IF LENGTH(TRIM(LS-ENTRA-DATA)) < 10 OR
25 LS-ENTRA-DATA NOT CARACTERE OR
26 LS-ENTRA-DATA(3:1) NOT = "/" OR
27 LS-ENTRA-DATA(6:1) NOT = "/"
28 DISPLAY "Erro na entrada: " WITH NO ADVANCING
29 ELSE
30 EXIT PERFORM
31 END-IF
32 END-PERFORM.
33 CALL "C0602DAT"
34 USING BY CONTENT LS-ENTRA-DATA, BY REFERENCE LS-SAIDA-DATA.
35 DISPLAY "Data informada: " LS-SAIDA-DATA.
36 STOP RUN.
37 END PROGRAM C06EX03.
------ ------------------------------------------------------------------------

Execute o programa e faça tentativas de entradas que sejam absurdas, tente usar letras e símbolos que não sejam os
caracteres esperados. Entre dados que sejam menores ou maiores que dez caracteres. Observe que o programa so-
mente aceita os caracteres numéricos e a barra, desde que esteja na posição correta.
Para estabelecer a validação do que pode ou não ser aceito no programa é necessário configurar o ambiente operacio-
nal do programa. Isto é feito na ENVIRONMENT DIVISION definida entre as linhas 3 e 9.
A CONFIGURATION SECTION está sendo definida com dois parágrafos, um conhecido entre as linhas 7 e 9 e o outro
definido nas linhas 5 e 6.
É importante considerar que o parágrafo SPECIAL-NAMES deve vir antes do parágrafo REPOSITORY. Veja que na
linha 6 há a definição da instrução CLASS CARACTERE IS "0" THRU "9" "/" que especifica os caracteres a serem
aceitos na entrada controlada do programa, sendo valores de 0 até 9 e a barra de separação. A cláusula CLASS de-
terminada uma palavra, neste caso, CARACTERE que contém os caracteres indicados. Esta instrução poderia estar
definida como CLASS CARACTERE IS "0123456789/". Apesar de não comentado no capítulo a cláusula CLASS é
mais um componente de auxilio a tarefa de manipulação de cadeias de caracteres.
O trecho mais importante do programa é o da entrada controlada definida entre as linhas 23 e 31. Observe que após a
efetivação da entrada entre encontra-se a decisão que valida a entrada ou não da sequencia de dados informada. As
condições definidas após o comando IF entre as linhas 25 e 27 evitam que entradas incorretas sejam aceitas. Veja que
entradas menores que dez caracteres (LENGTH(TRIM(LS-ENTRA-DATA)) < 10), entradas que não possuam os carac-
teres esperados e definidos na linha 7 (LS-ENTRA-DATA NOT CARACTERE), entradas que não possuem nas posi-
ções 3 (LS-ENTRA-DATA(3:1) NOT = "/") e 6 (LS-ENTRA-DATA(6:1) NOT = "/") os símbolos de barra são negadas e
nova entrada é solicitada com a apresentação de mensagem de erro.
A entrada estando correta o programa segue seu fluxo, chama a sub-rotina que avalia se os valores da data indicados
são consistentes com os limites operacionais e apresenta a data informada ou a indicação de seu erro **/**/****.
UT ILI ZA ÇÃ O D E A RQ U IV OS 237

7
UTILIZAÇÃO DE ARQUIVOS

Anteriormente, foram apresentados o uso de conjuntos de dados manipulados em memória principal na forma
de listas e tabelas. Este capítulo descreve a utilização e manipulação de dados em memória secundária na
forma de arquivos. São apresentados arquivos sequenciais, indexados e relativos, bem como, as operações
de manipulação de dados.

7.1 ARQUIVO, REGISTRO E CAMPO


Um arquivo, resumidamente falando, é um conjunto de registros que por sua vez é formado por um conjunto de campos
que é formado por um conjunto de dados que representam o valor intrínseco de certa informação definida a uma aplica-
ção. Um arquivo visa representar elementos informacionais de certo ente. Estes entes podem ser clientes, fornecedo-
res, itens de estoque, movimentos financeiros entre diversas outras possibilidades.
Há de se tomar cuidado quando se define arquivo do ponto de vista COBOL e mesmo em relação a outras linguagens
de programação. Note que a definição de arquivo dada se parece com o conceito de tabela usadas nos SGBDs (Siste-
mas de Gerenciamento de Banco de Dados). Um banco de dados armazena dentro de um arquivo físico (arquivo gra-
vado em mídia de memória secundária), o banco propriamente dito, tabelas que são as coleções de registros. Em CO-
BOL essas tabelas não existem, pois são representadas diretamente a partir dos arquivos nativos, a menos que se faça
uso de algum gerenciador de banco de dados.
Outro cuidado a ser tomado é que em outras linguagens de programação é comum ter-se dois tipos de arquivos: texto e
binário (principalmente na baixa plataforma). Em COBOL esse conceito não é usado, arquivo é arquivo e não importa o
formato dos dados armazenados (na forma de bytes ou bits), sendo possível manipular acessos a registros armazena-
dos em modo sequencial, indexado ou relativa. O acesso sequencial pode ser realizado por linha, por registro, relativo
ou indexado. Quando a organização do arquivo for sequencial linear, sequencial por registro ou relativo é o que se terá,
grosso modo, mais próximo de um arquivo texto nas linguagens da baixa plataforma. Já o acesso sequencial indexado;
randômico relativo, randômico indexado, dinâmico relativo e dinâmico indexado podem de certa forma se aproximar ao
uso de arquivos binários.
O uso de arquivos em COBOL exige a compreensão de conceitos bastante simples, mas extremamente importantes a
manipulação de dados, como: campo, registro, registro físico, registro lógico e arquivo.
O campo é um componente de armazenamento que representa um valor único pertencente a um elemento componen-
te de um registro. O campo pode ser usado para armazenar diferentes domínios de dados. Um campo pode guardar um
dado de chave primária, chave secundária ou descrição. A chave primária se refere a um dado único usado para iden-
tificar o registro de forma inequívoca, a chave secundária se refere ou não a um dado único podendo ser usado como
complemento a chave primária para a efetivação de ações de relacionamentos de dados e o campo descrição se refe-
re aos elementos que identificam o conjunto de conteúdo de um registro.
O registro por sua vez é o conjunto de campos relacionados a identificação dos dados armazenados, também chama-
do entidade. Um registro pode ser formado com um único campo, sendo esta configuração mais rara. Os registros em
238 PRO G RA MA Ç ÃO CO B OL

média, mais simples, possuem dois campos, sendo um para a chave primária e outro para descrição que contém o
valor de posicionamento relativo de registro de outro arquivo. O comum é possuir registros com mais de dois campos.
O registro físico caracteriza-se pelo conjunto de dados efetivamente gravados externamente ao computador em me-
mória secundária como, por exemplo, uma unidade de disco ou outra forma de armazenamento.
O registro lógico caracteriza-se pelo conjunto de dados processado na memória primária do computador, ou seja, são
os dados de um registro usados pelo programa em tempo de execução definidos em variáveis simples ou compostas na
forma de listas ou tabelas.
O arquivo é por sua vez o conjunto de registros físicos relacionados a uma aplicação em curso. O arquivo permite a
guarda “permanente” de registros nas unidades físicas de armazenamento. O termo permanente está destacado para
lembrar que a permanência de registros em um arquivo físico pode ser temporária, mas mantida mesmo com o compu-
tador desligado ou fora do ar.
A figura 7.1 mostra os detalhes da definição de um arquivo CADFUN (cadastro de funcionário) contendo os registros
formados pelos campos CODFUN (chave primária), NOME, DEPTO, FUNCAO e SALARIO.

Figura 7.1 – Estrutura de dados para tabela e arquivo (sugestão)

A partir da visão geral sobre os detalhes que caracterizam um arquivo, é importante levar em consideração que a forma
do arquivo ser operacionalizado depende da organização interna (ORGANIZATION IS) de seus registros, podendo esta
ordem ser sequencial (SEQUENTIAL), indexada (INDEXED) ou relativa (RELATIVE).
Um arquivo de organização sequencial realiza operações de acesso aos registros sequencialmente sem uso de índi-
ces para localização, sendo necessário para acessar certo registro percorrer todos os registros que o antecedem. As
inserções de novos registros ocorrem no final do arquivo. Cada registro, exceto o primeiro, possui um registro prede-
cessor exclusivo, e cada registro, exceto o último, possui um registro sucessor exclusivo. Arquivos sequenciais podem
ser acessados de modo sequencial, indexado e relativo. Há uma variação chamada arquivo sequencial linear usada
no armazenamento de sequências de caracteres tendo apenas como forma de acesso ao modo sequencial.
Um arquivo de organização relativa realiza as operações de acesso aos registros de forma sequencial e/ou direta. Os
registros deste arquivo são dispostos a partir de um índice ordinal de posicionamento, sendo acessados a partir da
especificação do número da posição do registro no arquivo, onde o primeiro registro é o registro 1, o segundo registro é
o registro 2 e assim por diante. Este tipo de arquivo pode ser acessado na forma sequencial, randômica ou dinâmica.
Um arquivo de organização indexada realiza as operações de acesso aos registros de forma sequencial e/ou indexa-
da. Os registros deste arquivo são dispostos a partir da definição de um ou mais campos chave, sendo acessados a
partir da especificação de um campo de chave que pode ser uma chave primária ou uma chave alternativa. Este tipo de
arquivo pode ser acessado na forma sequencial, randômica ou dinâmica.
A forma de definição de um arquivo não altera o formato em si o conjunto de registros e dados armazenados. O que
muda é a maneira como o tratamento de acesso aos registros é realizada.
UT ILI ZA ÇÃ O D E A RQ U IV OS 239

7.2 PREPARAÇÃO PARA USO DE ARQUIVOS


Os arquivos para serem usados necessitam ser indicados dentro do ambiente operacional da linguagem. Assim sendo,
é necessário fazer uso de seções e parágrafos específicos para este tratamento nas divisões ENVIRONMENT e DATA,
além de algumas definições, obrigatoriamente, realizadas na seção WORKING-STORAGE.
Na ENVIRONMENT DIVISION é necessário especificar a seção INPUT-OUTPUT que fornece informações de acesso a
respeito dos dispositivos usados com os arquivos manipulados pelo programa estabelecendo o vínculo entre o nome
lógico do arquivo (nome usado dentro do programa) com o nome real do arquivo externo gravado na memória secundá-
ria. Dentro da INPUT-OUTPUT SECTION é estabelecido o parágrafo FILE-CONTROL que efetua o controle de acesso
aos arquivos usados no programa. A estrutura sintática para esta definição segue o estilo:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.

A partir da definição do parágrafo FILE-CONTROL faz-se o estabelecimento da relação de arquivos a serem usados no
programa com auxílio do comando SELECT que por finalidade estabelecer o vínculo do nome interno (arquivo lógico)
com o nome do arquivo externo (arquivo gravado em mídia de memória secundária) a partir da estrutura sintática simpli-
ficada:

SELECT <arquivo> ASSIGN TO <"arquivo-externo">


ORGANIZATION IS <forma-de-acesso>
ACCESS MODE IS <modo-de-acesso>
[RECORD KEY IS <chave1> [OF <arquivo>]]
[ALTERNATE RECORD KEY IS <chave2> [OF <arquivo>] [WITH DUPLICATES]]
[RELATIVE KEY IS <chave3>]
[FILE STATUS IS <código-erro>].

Onde, arquivo refere-se ao rótulo de referência interna de um arquivo lógico referenciado a um arquivo físico externo
definido como arquivo-externo; forma-do-arquivo refere-se a forma de organização de acesso ao arquivo, podendo
ser sequencial (SEQUENTIAL), indexado (INDEXED) ou relativo (RELATIVE); modo-de-acesso refere-se a ação de
escrita e/ou leitura de registros no arquivo, podendo ser sequencial (SEQUENTIAL), aleatório (RANDOM) ou dinâmico
(DYNAMIC); chave1 refere-se ao uso de um campo chave definido no arquivo como chave primária; chave2 refere-se
a definição de chave complementar a ser usada na gravação alternativa de algum registro que poderá ou não ser dupli-
cada; chave3 refere-se a definição de chave para acesso a um arquivo relativo e por último código-erro que refere-se
a detecção de códigos de erro que podem ocorrer no tratamento das operações sobre arquivos. Caso a cláusula AC-
CESS MODE IS seja omitida o comando SELECT assume como padrão o modo de organização sequencial para o
arquivo em uso.
As chave1 e chave2 são usadas para definir os pontos de localização em arquivos relativos ou indexados. Em arquivos
relativos usa-se a cláusula RELATIVE KEY IS e em arquivos indexados usam-se as cláusulas RECORD KEY IS e/ou
ALTERNATE RECORD KEY IS que podem ou não serem acompanhadas da cláusula OF <arquivo>.
Do conjunto de cláusulas indicadas para uso com o comando SELECT nem todas serão utilizadas juntas. A combina-
ção de uso das cláusulas de acesso e tratamento de operações sobre arquivos dependerá do tipo de organização e do
modo de acesso pretendidos. Cada arquivo vinculado no comando SELECT deve ser especificado junto a seção FILE
da DATA DIVISION em parágrafos específicos que contenham a descrição dos arquivos em uso. Observe a forma de
estrutura geral da utilização do comando SELECT definido junto ao parágrafo FILE-CONTROL:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <ação>.

Quando um arquivo é associado com o comando SELECT poderá ocorrer, a partir de seu uso, por algum motivo não
intencional erros de acesso. Esses erros devem ser interceptados e tratados, evitando-se a interrupção de execução do
programa. Para auxiliar esta tarefa o comando SELECT pode fazer o uso opcional da cláusula FILE STATUS que tem
240 PRO G RA MA Ç ÃO CO B OL

por finalidade o papel de monitorar as ações de acesso de leitura e/ou escrita dos arquivos e capturar o código de erro
que poderá ser tratado no programa. A estrutura sintática de FILE STATUS segue o estilo:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <ação>
FILE STATUS IS <código>.

Onde, código é a representação de um valor numérico de dois dígitos referentes a eventual ocorrência de erro no
acesso a um arquivo. A tabela 7.1 apresenta alguns dos códigos regimentados a partir da norma ISO 1989:1985.

Tabela 7.1 Códigos de erro para operações mal sucedidas de arquivos

Código Descrição do erro Em que operação


00 Sucesso (completo) Para todas as operações
01 Não é uma chave de status de arquivo válida -x-
02 Duplicidade em chave alternativa READ, RE/WRITE
03 Não é um código de status de arquivo válido -x-
04 Tamanho do registro inconsistente READ
05 Arquivo opcional não encontrado OPEN
06 Tentativa de escrita em arquivo aberto para leitura WRITE
07 Sucesso (arquivo não abre ou fecha) OPEN, CLOSE
08 Tentativa de leitura em arquivo aberto para escrita READ
09 Diretório ou pasta inexistente -x-
10 Fim de arquivo encontrado (arquivo sequencial) READ
12 Tentativa de abrir arquivo já aberto OPEN
13 Não há próximo registro lógico (fim de arquivo) READ
14 Chave fora de faixa (arquivo relativo) READ
15 Tentativa de primeira leitura em arquivo não presente READ
21 Chave inválida READ, REWRITE, DELETE
22 Registro existente no arquivo WRITE
23 Registro não encontrado (arquivo indexado e relativo) RE/WRITE, START, DELETE
24 Disco cheio WRITE
25 Inicialização ou leitura em arquivo não presente READ, START
30 Erro permanente de I/O (problema de hardware) Para todas as operações
31 Nome de arquivo inconsistente OPEN
34 Violação de limite WRITE, SORT
35 Arquivo não encontrado OPEN, SORT
37 Operação não permitida OPEN
38 Arquivo fechado com trava OPEN
39 Arquivo difere do declarado no programa OPEN
41 Arquivo está aberto OPEN
42 Arquivo está fechado CLOSE
UT ILI ZA ÇÃ O D E A RQ U IV OS 241

Código Descrição do erro Em que operação


43 Leitura não realizada antecipadamente REWRITE, DELETE
44 Tamanho do registro excedido RE/WRITE
46 Erro de leitura READ, START
47 Leitura de arquivo aberto para escrita READ, START
48 Escrita de arquivo aberto para leitura WRITE
49 Atualização de arquivo aberto para leitura REWRITE, DELETE
51 Registro bloqueado READ, WRITE, DELETE
52 Fim de página -x-
57 Informações específicas de linhas inválidas -x-
61 Falha no compartilhamento do arquivo -x-
91 Arquivo não disponível OPEN
93 Arquivo bloqueado por outro usuário OPEN
99 Registro bloqueado por outro processo READ, RE/WRITE, DELETE, SORT, MERGE

A tabela 7.1 apresenta os principais erros que podem ocorrer com o uso de ações sobre arquivos. A definição da coluna
“em que operação” dá uma ideia de como determinadas ações de acesso a arquivos podem incorrer em erros.
É muito importante sempre testar o retorno do valor de uma variável associada a cláusula FILE STATUS para saber se
ocorreu ou não algum erro de acesso ao arquivo. Não desrespeite esta regra, pois muitos problemas no uso de dados
podem ser facilmente evitados com esta simples ação. Uma coisa é perder um dado transitório na memória principal,
outra completamente diferente é perder dados “permanentemente” em memória secundária, pior ainda é perder efeti-
vamente o acesso ao arquivo de dados.
A cláusula FILE STATUS para ser usada necessita ser mencionada, como apresentada, junto ao comando SELECT,
devendo possuir um ponto de vínculo na seção WORKING-STORAGE (apesar de possível, não use o espaço de me-
mória da seção LOCAL-STORAGE) a partir da definição de uma variável com tamanho de dois caracteres alfanuméri-
cos que será usada para armazenar o código de erro quando ocorrido para posterior tratamento. A estrutura sintática de
FILE STATUS e seu vínculo na WORKING-STORAGE SECTION segue o estilo:

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <ação>
[<cláusulas>]
FILE STATUS IS <código>.

WORKING-STORAGE SECTION.
77 <código> PIC XX.

Após definir em FILE-STATUS IS a varável de código que armazenará o código de ocorrência de erro e tê-la definida
junto a seção de armazenamento WORKING-STORAGE SECTION basta fazer seu uso com alguma instrução de deci-
são. Observe um trecho desta sugestão:

IF <código> NOT = "00"


<ocorreu algum erro que necessita ser interceptado>
ELSE
<está tudo OK, basta realizar as operações normais com o arquivo>
END-IF.

É ideal que um programa que acesse arquivos possua a definição de uma sub-rotina de validação de acesso que infor-
me o código de erro para o usuário de modo que este tenha condições de informar a ocorrência ao suporte para as
242 PRO G RA MA Ç ÃO CO B OL

devidas correções. É importante na ocorrência de erro garantir que os dados até o momento em uso estejam preserva-
dos.
A partir do estabelecimento e ambientação dos arquivos no programa é necessário descrever a estrutura de dados a
ser usada, o formato dos registros existentes no(s) arquivo(s) a partir da seção FILE em DATA DIVISION e o vínculo
entre essas duas instâncias.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <ação>
[<cláusulas>]
FILE STATUS IS código.

DATA DIVISION.
FILE SECTION.

Na FILE SECTION são especificados os formatos das estruturas de dados da memória principal vinculadas aos arqui-
vos (memória secundária). Essas estruturas devem ser definidas a partir do mesmo formato usado no arquivo a fim de
evitar inconsistências.
É possível definir estruturas de dados vinculados aos arquivos em uso com a cláusula FD (File Description) que mapeia
a estrutura de dados de um arquivo com a estrutura definida na memória principal e SD (Sort file Description) que ma-
peia a estrutura de dados para operações de classificação e junção. Em FD e SD são definidos os campos de um regis-
tro, bem como suas características de conteúdo.

DATA DIVISION.
FILE SECTION.
FD / SD <nome-arquivo>

Onde, nome-arquivo refere-se ao rótulo de referência interna de um arquivo lógico associado a um arquivo externo a
partir do uso do comando SELECT.
As cláusulas FD e SD representam o mais alto nível de organização dos dados na FILE-SECTION.

7.3 MODOS DE ACESSO E FORMAS DE ORGANIZAÇÃO


Após observar o que vem a ser um arquivo e de como esse componente pode ser qualificado é importante conhecer os
modos de acesso a registros que podem ser imputados sobre arquivos, seja sequencial, indexado ou relativo. Muito
cuidado em não confundir tipos de arquivos com tipos de acesso a arquivos.
O modo de acesso sobre registros estabelece a maneira pela qual o programa gerencia esses dados, podendo realizar
acessos em modo: sequencial, aleatório e dinâmico.
A tabela 7.2 apresenta a relação existente entre as formas de organização dos arquivos e o modo de acesso aos seus
registros.
UT ILI ZA ÇÃ O D E A RQ U IV OS 243

Tabela 7.2 Modos de acesso versus formas de organização de arquivos

Formas de organização de arquivos Modos de acesso


SEQUENCIAL
RELATIVO SEQUENCIAL
INDEXADO

RELATIVO
RANDÔMICO
INDEXADO

RELATIVO
DINÂMICO
INDEXADO

No modo de acesso sequencial pode ser adotado no uso de arquivos sequenciais, indexados ou relativos, sendo que o
modo de acesso aos registros muda de acordo com o tipo de organização em uso. A desvantagem no modo sequencial
é sua lentidão no acesso aos registros, pois as operações são realizadas a partir do início do arquivo.
No acesso sequencial em arquivo de organização sequencial o registro é obtido na mesma ordem em que foi cadas-
trado a partir do primeiro registro até o último registro existente. Observe a estrutura sintática de uso do modo de aces-
so sequencial em arquivo sequencial.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS {LINE / [RECORD | BINARY]} SEQUENTIAL
ACCESS MODE IS SEQUENTIAL
FILE STATUS IS <código-erro>.

No acesso sequencial em arquivo de organização indexada o registro do arquivo de dados é obtido a partir da locali-
zação sequencial da posição da chave de registro no arquivo, podendo-se usar um índice alternativo. Observe a estru-
tura sintática de uso do modo de acesso sequencial em arquivo indexado.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS INDEXED
ACCESS MODE IS [RECORD | BINARY] SEQUENTIAL
RECORD KEY IS <chave-primária>
ALTERNATE RECORD KEY IS <chave-alternativa> [WITH DUPLICATES]
FILE STATUS IS <código-erro>.

No acesso sequencial em arquivo de organização relativa o registro é obtido a partir da ordem de gravação, posição
ordinal do registro no arquivo. Observe a estrutura sintática de uso do modo de acesso sequencial em arquivo relativo.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS RELATIVE
ACCESS MODE IS [RECORD | BINARY] SEQUENTIAL
[RELATIVE KEY IS <chave-relativa>]
FILE STATUS IS <código-erro>.
244 PRO G RA MA Ç ÃO CO B OL

O modo de acesso aleatório (acesso randômico) pode ser adotado no uso de arquivos indexados ou relativos a partir de
uma chave fornecida como elemento de busca de registro no arquivo indexado ou um valor ordinal de posição no arqui-
vo relativo. O acesso aleatório permite que se efetue o posicionamento de forma direta em qualquer registro do arquivo.
No acesso aleatório em arquivo de organização relativa o registro do arquivo de dados é obtido a partir do valor es-
pecificado no campo de chave de registro do arquivo relativo. Observe a estrutura sintática de uso do modo de acesso
aleatório em arquivo relativo.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS RELATIVE
ACCESS MODE IS RANDOM
RELATIVE KEY IS <chave-relativa>
FILE STATUS IS <código-erro>.

No acesso aleatório em arquivo de organização indexada o registro do arquivo de dados é obtido a partir do valor
especificado no campo chave de registro do arquivo indexado. O valor da chave pode ser um campo primário, alternati-
vo ou relativo, podendo-se usar mais de um índice alternativo. Observe a estrutura sintática de uso do modo de acesso
aleatório em arquivo indexado.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS <chave-primária>
[ALTERNATE RECORD KEY IS <chave-alternativa> [WITH DUPLICATES]]
FILE STATUS IS <código-erro>.

O modo de acesso dinâmico pode ser adotado com arquivos indexados e relativos. O modo dinâmico combina em um
só programa os modos de acesso indexado e relativo. Desta forma, é possível mudar no programa a maneira como os
registros são acessados, alguns registros podem ser acessados sequencialmente e outros podem ser acessados alea-
toriamente.
No acesso dinâmico em arquivo de organização relativa o registro do arquivo de dados pode ser obtido a partir do
valor especificado no campo de chave de registro do arquivo relativo ou por intermédio da chave indicada. Observe a
estrutura sintática de uso do modo de acesso aleatório em arquivo relativo.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS RELATIVE
ACCESS MODE IS DYNAMIC
RELATIVE KEY IS <chave-relativa>
FILE STATUS IS <código-erro>.

No acesso dinâmico em arquivo de organização indexada o registro do arquivo de dados pode ser obtido a partir do
valor especificado no campo de chave de registro do arquivo relativo ou por intermédio da chave indicada. Observe a
estrutura sintática de uso do modo de acesso aleatório em arquivo relativo.
UT ILI ZA ÇÃ O D E A RQ U IV OS 245

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <nome-arquivo> ASSIGN TO <"arquivo-externo">
ORGANIZATION IS INDEXED
ACCESS MODE IS DYNAMIC
RECORD KEY IS <chave-primária>
[ALTERNATE RECORD KEY IS <chave-alternativa> [WITH DUPLICATES]]
FILE STATUS IS <código-erro>.

Não importando a forma de acesso realizada sobre um arquivo é pertinente salientar que basicamente as únicas duas
operações realizadas em arquivos são: leitura e escrita de dados. No entanto, para realizar essas operações é neces-
sário que o arquivo seja aberto, bem como deve ser fechado ao final de seu uso no encerramento do programa. Nunca
deixe um arquivo aberto. A forma de organização de um arquivo determina como a leitura e escrita de dados nos regis-
tros deve ocorrer.

7.4 AÇÕES OPERACIONAIS


A partir do conhecimento da forma como um arquivo pode ser definido e como poderão seus dados serem acessados é
necessário conhecer as ações que podem ser efetuadas sobre os arquivos representadas por alguns verbos da lingua-
gem. É importante ressaltar que dependendo da forma de organização usada em um arquivo determinado verbo poderá
não ser aplicado. Neste sentido, são indicados os verbos que efetuam operações de abertura de arquivos, fechamento
de arquivos, leitura de registro, escrita de registro, atualização de registro e exclusão de registro.
A primeira operação a ser executada em arquivos após sua definição no ambiente da linguagem é sua abertura com o
verbo OPEN que tem como forma sintática a escrita:

OPEN <modo> <arquivo>.

Onde, modo estabelece a operação a ser executada, compatibilizada com a forma de organização e acesso do arquivo
e arquivo a indicação lógica de acesso ao arquivo externo mapeado. As variáveis definidas na estrutura de arquivo
somente ficam operacionais enquanto o arquivo associado estiver aberto. A tabela 7.3 mostra os modos de operação
utilizados na abertura de um arquivo.

Tabela 7.3 – Modos de acesso a arquivos

Modo de operação Descrição operacional

INPUT Definição do modo de leitura não sendo permitido a realização de escrita de dados.

Definição do modo de escrita não sendo permitido a realização de leitura de dados. Quando em
uso reescreve os dados nas mesmas posições
OUTPUT

Definição do modo de escrita a ser usado em arquivos sequenciais não sendo permitido a reali-
zação de leitura de dados. Quando usado acrescenta dados no arquivo (estende).
EXTEND

Definição dos modos simultâneos de leitura e escrita a ser usado em qualquer modo de organi-
zação de arquivos.
I-O

O modo de operação saída (OUTPUT) é adequado para criar novos arquivos, devendo ser evitado sobre arquivos que
contenham registros, pois estes serão sempre apagados. O modo de operação estendido (EXTEND) permite estender a
ação de escrita permitindo anexar novos registros, podendo ser usado com arquivos sequenciais somente se os novos
registros forem escritos de forma crescente. O modo de operação entrada (INPUT) permite a definição de ações de
entrada de dados em qualquer forma de organização de arquivos. O modo entrada e saída (I-O) permite a definição de
operações de entrada e saída a arquivos atribuídos a dispositivos de acesso direto, não podendo ser utilizados com
arquivos sequenciais de linha.
246 PRO G RA MA Ç ÃO CO B OL

O comando OPEN abre o arquivo e disponibiliza a área de registro associada ao programa para uso dependendo obvi-
amente do modo de acesso, possibilitando o uso de operações de leitura e escrita.
A tabela 7.4 mostra os comandos que podem ser usados em arquivos sequenciais para registros de acordo com o mo-
do sequencial. As ações permitidas em arquivos sequenciais são dentro de seu escopo bastante amplas.

Tabela 7.4 – Ações operacionais para arquivo sequencial de registro com acesso sequencial

Modo de acesso Comando INPUT OUTPUT I-O EXTEND

SEQUENCIAL READ X - X -
em organização WRITE - X - X
SEQUENCIAL DE REGISTRO REWRITE - - X -

A tabela 7.5 mostra os comandos que podem ser usados em arquivos sequenciais lineares de acordo com o modo
sequencial. Veja que neste tipo de arquivo as ações permitidas são as mínimas possíveis e as mais essenciais.

Tabela 7.5 – Ações operacionais para arquivo sequencial linear com acesso sequencial

Modo de acesso Comando INPUT OUTPUT I-O EXTEND

SEQUENCIAL READ X - - -
em organização WRITE - X - X
SEQUENCIAL LINEAR REWRITE - - - -

A tabela 7.6 apresenta os comandos que podem ser usados em arquivos indexado e relativo de acordo com o modo de
operação estabelecido. Nestes tipos de arquivos se tem as maiores possibilidades de operação.
A execução de OPEN pode ocasionar os erros de FILE STATUS com código 05, 07, 12, 30, 31, 35, 37, 38, 39, 41, 91 e
93.
A última operação a ser executada em arquivos após seu uso é seu fechamento com o verbo CLOSE que tem como
forma sintática a escrita:

CLOSE <arquivo>.

Onde, arquivo é a indicação lógica de acesso ao arquivo anteriormente aberto. Após o fechamento do arquivo em uso
as variáveis da estrutura de arquivos que estavam ativas se tornam inacessíveis. Qualquer arquivo em uso deve ser
fechado antes do encerramento total do programa. A execução de CLOSE pode ocasionar os erros de FILE STATUS
com código 07, 30 e 42.
Assim que um arquivo é aberto este pode ser colocado em modo de operação de escrita ou leitura. No modo de escrita
é possível efetuar a gravação de um registro que está na memória principal na memória secundária, representada pelo
arquivo em uso. Já, no modo de leitura será realizada a transferência do registro que está na memória secundária para
a memória principal.
O verbo READ é responsável por efetuar a leitura de um registro por vez no arquivo e transferir o conteúdo lido para a
memória principal. Para realizar operações de leitura abra arquivos nos modos I-O ou INPUT. A ação de leitura de ar-
quivo difere-se quando em operação arquivos sequenciais ou aleatórios. A cláusula END-READ é opcional e será utili-
zada quando usado a cláusula [NOT] AT END.
UT ILI ZA ÇÃ O D E A RQ U IV OS 247

Tabela 7.6 – Ações operacionais para arquivos com acesso relativo/indexado

Modo de acesso Comando INPUT OUTPUT I-O EXTEND


READ X - X -

RELATIVO / INDEXADO WRITE - X - X


em organização REWRITE - - X -
SEQUENCIAL DE REGISTRO START X - X -
DELETE - - X -
READ X - X -

RELATIVO / INDEXADO WRITE - X - -


em organização REWRITE - - X -
- - - -
RANDÔMICA (ALEATÓRIA) START
DELETE - - X -
READ X - X -

RELATIVO / INDEXADO WRITE - X X -


em organização REWRITE - - X -
DINÂMICA START X - X -
DELETE - - X -

Para a leitura de registros em arquivo sequencial use a forma sintática:

READ <arquivo> [{NEXT / PREVIOUS} RECORD] INTO <recepção>


[[NOT] AT END <ação>]
END-READ.

Onde, arquivo é a indicação lógica de acesso ao arquivo anteriormente aberto, recepção e a estrutura de dado usada
para a recepção do registro lido do arquivo e ação é a especificação de uma operação iterativa quando ocorrer erro de
acesso com o comando READ.
As cláusulas NEXT e PREVIOUS com RECORD são usadas respectivamente para definir a leitura do próximo ou ante-
rior registro. Ao se fazer uso da cláusula PREVIOUS e nenhum registro anterior for encontrado a ação de READ será
mal sucedida e a condição AT END ocorrerá.
Para a leitura de registros em arquivo aleatório (randômico) use a forma sintática:

MOVE <chave-informadas> TO <chave-arquivo>


READ <arquivo> [{NEXT / PREVIOUS} RECORD] INTO <recepção> KEY IS <chave>
[[NOT] INVALID KEY <ação>]
END-READ.

Onde, chave-informada é a definição de uma chave fornecida pelo usuário que definida em chave-arquivo indique
para MOVE qual chave de pesquisa será usada pelo verbo READ, arquivo é a indicação lógica de acesso ao arquivo
anteriormente aberto, recepção e a estrutura de dado usada para a recepção do registro lido do arquivo, chave é a
especificação de uma chave de registro associada apenas com arquivo indexado e ação é a especificação de uma
operação iterativa quando ocorrer erro de acesso à chave indicada. A execução de READ pode ocasionar os erros de
FILE STATUS com código 02, 04, 08, 10, 13, 14, 15, 21, 25, 30, 46, 47, 51 e 99.
A cláusula KEY com o verbo IS é aplicada apenas a arquivos randômicos e as cláusulas INVALID e KEY são dispara-
das quando alguma situação de erro de acesso ao arquivo ocorre como ocorrência de uma condição de chave inválida.
A condição de chave inválida pode ocorrer com o uso dos comandos READ, WRITE, REWRITE, DELETE ou START.
248 PRO G RA MA Ç ÃO CO B OL

O verbo WRITE é responsável por efetuar a escrita de um registro por vez no arquivo transferindo o conteúdo da me-
mória principal para a memória secundária. A cláusula END-WRITE é opcional e será mantida nos programas deste
capítulo quando a cláusula [NOT] INVALID KEY for usada. Para realizar operações de escrita abra arquivos nos modos
I-O, EXTEND ou OUTPUT, que tem como forma sintática a escrita:

WRITE <arquivo> FROM <expedição>


[[NOT] INVALID KEY <ação>]
END- WRITE.

Onde, arquivo é a indicação lógica de acesso ao arquivo anteriormente aberto, expedição e a estrutura de dado usada
para o envio do registro a ser escrito no arquivo e ação é a especificação de uma operação iterativa quando ocorrer
erro de acesso à chave indicada. A execução de WRITE pode ocasionar os erros de FILE STATUS com código 02, 06,
22, 23, 24, 30, 34, 44, 48, 51 e 99.
O verbo REWRITE é responsável por efetuar a reescrita do último registro lido em um arquivo de acesso direto, ou seja,
realiza a atualização de um registro que fora anteriormente lido transferindo o conteúdo da memória principal para a
memória secundária. A cláusula END-REWRITE é opcional e será mantida nos programas deste capítulo quando a
cláusula [NOT] INVALID KEY for usada. Para realizar operações de reescrita abra arquivos apenas no modo I-O, que
tem como forma sintática a escrita:

REWRITE <arquivo> FROM <expedição>


[[NOT] INVALID KEY <ação>]
END- REWRITE.

Onde, arquivo é a indicação lógica do nome de acesso de uma entrada FD (a ser visto) da divisão de dados, expedi-
ção e a estrutura de dado usada para o envio do registro a ser escrito no arquivo e ação é a especificação de uma
operação iterativa quando ocorrer erro de acesso à chave indicada. A execução de REWRITE pode ocasionar os erros
de FILE STATUS com código 02, 21, 23, 30, 43, 44, 49 e 99.
O verbo DELETE é responsável por efetuar a remoção do último registro lido em arquivos relativos e indexados ou a
remoção de arquivos aleatórios desde que seja antecipadamente definida a chave de acesso ao registro a ser excluído.
A cláusula END-DELETE é opcional e será mantida nos programas deste capítulo quando a cláusula [NOT] INVALID
KEY for usada. Para realizar operações de remoção abra arquivos apenas no modo I-O, que tem como forma sintática
a escrita:

DELETE <arquivo> RECORD


[[NOT] INVALID KEY <ação>]
END- DELETE.

Onde, arquivo é a indicação lógica de acesso ao arquivo anteriormente aberto e ação é a especificação de uma opera-
ção iterativa quando ocorrer erro de acesso à chave indicada. A execução de DELETE pode ocasionar os erros de FILE
STATUS com código 21, 23, 30, 43, 49, 51 e 99.
O verbo START é responsável por efetuar o posicionamento do ponteiro do arquivo em um registro específico de arqui-
vos indexados e relativos com modo de acesso definido como sequencial ou dinâmico. A cláusula END- START é opci-
onal e será mantida nos programas deste capítulo quando a cláusula [NOT] INVALID KEY for usada. Para realizar
operações de apontamento abra arquivos nos modos I-O ou INPUT, tendo como forma sintática a escrita:

START <arquivo> KEY IS {=, >, <, NOT, <=, >=} <posição>
[[NOT] INVALID KEY <ação>]
END-START.

Onde, arquivo é a indicação lógica de acesso ao arquivo anteriormente aberto, posição refere-se ao local de acesso
no arquivo e ação é a especificação de uma operação iterativa quando ocorrer erro de acesso à chave indicada. A
execução de START pode ocasionar os erros de FILE STATUS com código 23, 25, 30, 46 e 47.
O verbo SORT (já conhecido da classificação de listas e tabelas) é usado no contexto de arquivos para realizar opera-
ções de classificação de registros em um ou mais arquivos, tendo como forma sintática a escrita:
UT ILI ZA ÇÃ O D E A RQ U IV OS 249

SORT <arquivo-de-trabalho> ON ASCENDING KEY <chave1> [ON DESCENDING KEY <chave2>]


USING <arquivo-de-entrada> GIVING <arquivo-de-saída>.

Onde, arquivo-de-trabalho é a indicação lógica do arquivo definido na seção de arquivo e usado para manter os regis-
tros durante a operação de classificação, arquivo-de-entrada é a indicação lógica do arquivo que será classificado na
ordem indicada, arquivo-de-saída é a definição lógica do arquivo que será o resultado da classificação e chave1 e
chave2 são as definições dos campos usados como pivôs da classificação. O arquivo de trabalho deve ser aberto no
modo I-O, o arquivo de entrada deve ser aberto no modo INPUT e o arquivo de saída deve ser aberto no modo OU-
TPUT. A execução de SORT pode ocasionar os erros de FILE STATUS com código 30, 34, 35 e 99.
O verbo MERGE é usado para juntar em um só arquivo outros arquivos, sejam de entrada, de trabalho ou de saída,
tendo como forma sintática a escrita:

MERGE <arquivo-de-trabalho> ON ASCENDING KEY <chave1> [ON DESCENDING KEY <chave2>]


USING <arquivo-de-entrada1>, <arquivo-de-entrada2>, ... GIVING <arquivo-de-saída>.

Onde, arquivo-de-trabalho é a indicação lógica do arquivo definido na seção de arquivo e usado para manter os regis-
tros mesclados, arquivo-de-entrada1 (ou arquivo-de-entrada2) é a indicação lógica do(s) arquivo(s) que serão fundi-
dos de acordo com a indicada, arquivo-de-saída é a definição lógica do arquivo que será o resultado da junção entre
os arquivos de entrada e chave1 e chave2 são as definições dos campos usados como pivôs da junção. O arquivo de
trabalho deve ser aberto no modo I-O, o arquivo de entrada deve ser aberto no modo INPUT e o arquivo de saída deve
ser aberto no modo OUTPUT. A execução de MERGE pode ocasionar os erros de FILE STATUS com código 30 e 99.
A partir do conjunto de informações sobre definição de arquivos e seu modo de organização operacional, dos modos de
acesso e das ferramentas para as ações operacionais já é possível começar a escrever pequenos programas com a
finalidade de gerenciar, mesmo que de forma simplista, arquivos de dados.

7.5 CONTROLE DE ACESSO


Para a realização de testes com o uso de arquivos é necessário antes mesmo de cria-los estabelecer algumas rotinas
operacionais de controle ao acesso com detecção e tratamento de erros. Assim sendo, são apresentados para a detec-
ção de erros um arquivo de copybook e para auxiliar o tratamento da ocorrência de erros a definição de uma sub-rotina
que apresenta de forma customizada qual a ocorrência de erro gerada.

7.5.1 Detecção de erro no acesso a arquivos


Para auxiliar as tarefas de detecção de erro é definido um arquivo de copybook que contém a estrutura de dados de um
grupo elementar chamado de CODIGO-ERRO com a definição de campos lógicos associados aos valores de cada erro
que pode ocorrer. O código indicado é uma adaptação de um código similar apresentado por John Ellis publicado no
documento GnuCOBOL FAQ (https://open-cobol.sourceforge.io/faq/gcfaq.html#gnucobol-file-status-codes) para
compatibilizá-lo com os detalhes mostrados na tabela 7.1. Assim sendo, abra um novo projeto vazio chamado fscoderr
(file status code error) com a indicação da extensão “.cpy” na subpasta COBOL da pasta Documentos e escreva a
partir da sétima coluna as instruções indicadas a seguir.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 01 CODIGO-ERRO PIC X(2) VALUE SPACES.
2 88 SUCCESS VALUE "00".
3 88 SUCCESS-DUPLICATE VALUE "02".
4 88 NOT-CODE-STATUS VALUE "03".
5 88 SUCCESS-INCOMPLETE VALUE "04".
6 88 SUCCESS-OPTIONAL VALUE "05".
------ ------------------------------------------------------------------------
250 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
7 88 WRITE-OPEN-INPUT VALUE "06".
8 88 SUCCESS-NO-UNIT VALUE "07".
9 88 INPUT-OPEN-WRITE VALUE "08".
10 88 DIRECTORY-NOT-EXIST VALUE "09".
11 88 END-OF-FILE VALUE "10".
12 88 OPEN-FILE-IS-OPEN VALUE "12".
13 88 NEXT-RECORD-NOT-EXIST VALUE "13".
14 88 OUT-OF-KEY-RANGE VALUE "14".
15 88 READ-FILE-NOT-PRESENT VALUE "15".
16 88 KEY-INVALID VALUE "21".
17 88 KEY-EXISTS VALUE "22".
18 88 KEY-NOT-EXISTS VALUE "23".
19 88 DISK-FULL VALUE "24".
20 88 ACCESS-FILE-NOT-PRESENT VALUE "25".
21 88 PERMANENT-ERROR VALUE "30".
22 88 INCONSISTENT-FILENAME VALUE "31".
23 88 BOUNDARY-VIOLATION VALUE "34".
24 88 NOT-EXISTS VALUE "35".
25 88 PERMISSION-DENIED VALUE "37".
26 88 CLOSED-WITH-LOCK VALUE "38".
27 88 CONFLICT-ATTRIBUTE VALUE "39".
28 88 ALREADY-OPEN VALUE "41".
29 88 NOT-OPEN VALUE "42".
30 88 READ-NOT-DONE VALUE "43".
31 88 RECORD-OVERFLOW VALUE "44".
32 88 READ-ERROR VALUE "46".
33 88 INPUT-DENIED VALUE "47".
34 88 OUTPUT-DENIED VALUE "48".
35 88 I-O-DENIED VALUE "49".
36 88 RECORD-LOCKED VALUE "51".
37 88 END-PAGE VALUE "52".
38 88 I-O-LINAGE VALUE "57".
39 88 FILE-SHARING VALUE "61".
40 88 FILE-NOT-AVAILABLE VALUE "91".
41 88 FILE-LOCK-USER VALUE "93".
42 88 RECORD-LOCK-PROCESS VALUE "99".
------ ------------------------------------------------------------------------

Para a realização de um teste de funcionalidade com acesso ao uso da definição dos códigos de erro intermediados por
um copybook chamado fscoderr.cpy considere um programa simplista que tenta manipular um arquivo que tem por
finalidade armazenar uma linha de texto com 80 caracteres. Assim sendo, abra um projeto vazio chamado cap07ap01
com a extensão “.cob” na subpasta COBOL da pasta Documentos e escreva o código indicado a seguir, ressaltando
que o programa tenta realizar uma operação de leitura em um arquivo não existente. O programa ao ser executado
apresenta de forma simplista uma mensagem de erro com a indicação do valor do código ocorrido sem fazer a interrup-
ção abrupta do programa. Observe atentamente os trechos colorizados e as relações definidas com cada cor:

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP01 AS "Capitulo 7 – Aplicacao 1".
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 251

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 *
7 FILE-CONTROL.
8 SELECT ARQ-SEQ ASSIGN TO "DADOS.SEQ"
9 ORGANIZATION IS LINE SEQUENTIAL
10 ACCESS MODE IS SEQUENTIAL
11 FILE STATUS IS WS-PEGA-ERRO.
12 *
13 DATA DIVISION.
14 FILE SECTION.
15 FD ARQ-SEQ.
16 01 LINHA PIC X(80).
17 *
18 WORKING-STORAGE SECTION.
19 COPY "FSCODERR.CPY".
20 77 WS-PEGA-ERRO PIC XX.
21 77 WS-ENTER PIC X.
22 *
23 PROCEDURE DIVISION.
24 PROG-PRINCIPAL-PARA.
25 *
26 OPEN INPUT ARQ-SEQ.
27 DISPLAY "DETECCAO DE ERRO CONTROLADO EM ARQUIVO".
28 DISPLAY "--------------------------------------".
29 DISPLAY X"0D".
30 IF WS-PEGA-ERRO = "00"
31 DISPLAY "Arquivo existe em disco"
32 ELSE
33 DISPLAY "Erro de acesso: " WS-PEGA-ERRO
34 DISPLAY "Contacte o suporte tecnico."
35 END-IF.
36 CLOSE ARQ-SEQ.
37 *
38 DISPLAY X"0D".
39 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
40 ACCEPT WS-ENTER.
41 STOP RUN.
42 END PROGRAM CAP07AP01.
------ ------------------------------------------------------------------------

Ao ser executado o programa será apresentada a mensagem "Erro de acesso: 35", uma vez que não foi possível abrir
o arquivo ARQ-SEQ com a instrução OPEN INPUT ARQ-SEQ por este não existir em disco.
Ao se fazer a tentativa de abertura de um arquivo inexistente na linha 26 um erro operacional (erro de estado de arqui-
vo) é gerado sendo este interceptado pela cláusula FILE STATUS IS na definição do arquivo ARQ-SEQ indicado na
linha 11 e armazenando o valor da ocorrência de erro na variável WS-PEGA-ERRO definida na WORKING-STORAGE
SECTION como indicado na linha 20. Após a chamada do arquivo de copybook na linha 19 que carrega para a memória
a estrutura CODIGO-ERRO. A detecção da possibilidade de erro ocorre com a instrução IF WS-PEGA-ERRO = "00" da
linha 30, que sendo diferente de 00 indica um erro, mostrando o código do erro e indicando a mensagem para o usuário
definidos nas linhas 33 e 34 para que o usuário entre em contato com o suporte técnico responsável pelo programa.
252 PRO G RA MA Ç ÃO CO B OL

Para verificar a ocorrência de erro de acesso a um arquivo para escrita sem nenhuma forma de tratamento operacional
abra um novo projeto vazio chamado cap07ap02 com a extensão “.cob” na subpasta COBOL da pasta Documentos
que tentará realizar uma operação de leitura em um arquivo não existente.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP02 AS "Capitulo 7 – Aplicacao 2".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT ARQ-SEQ ASSIGN TO "DADOS.SEQ"
8 ACCESS MODE IS SEQUENTIAL
9 ORGANIZATION IS LINE SEQUENTIAL.
10 *
11 DATA DIVISION.
12 FILE SECTION.
13 FD ARQ-SEQ.
14 01 LINHA PIC X(80).
15 *
16 WORKING-STORAGE SECTION.
17 77 WS-ENTER PIC X.
18 *
19 PROCEDURE DIVISION.
20 PROG-PRINCIPAL-PARA.
21 OPEN INPUT ARQ-SEQ.
22 DISPLAY "OCORRENCIA DE ERRO EM ARQUIVO SEM TRATAMENTO"
23 DISPLAY "--------------------------------------------"
24 DISPLAY X"0D"
25 DISPLAY "Arquivo existe em disco".
26 CLOSE ARQ-SEQ.
27 DISPLAY X"0D".
28 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
29 ACCEPT WS-ENTER.
30 STOP RUN.
31 END PROGRAM CAP07AP02.
------ ------------------------------------------------------------------------

Os programas cap07ap01.cob e cap07ap02.cob são idênticos com a diferença de que no programa cap07ap02.cob
não se faz o tratamento da ocorrência de erro de acesso e por esta razão quando executado faz com que a tentativa de
abertura do arquivo na linha 21 inexistente gere um erro que interrompe a execução do programa apresentado a men-
sagem:

libcob: cap07ap02.cob:21: error: file does not exist (status = 35) for file ARQ-
SEQ ('DADOS.SEQ') on OPEN

A mensagem apresentada indica a ocorrência de erro com código status = 35 na linha 21 do programa cap07ap02.cob
ocorrida sobre a tentativa de abertura do arquivo DADOS.SEQ. A parte da mensagem indicando "file does not exist"
deixa claro que o arquivo solicitado para abertura não existe na mídia de gravação. Veja que após a apresentação des-
sa mensagem o programa é encerrado abruptamente (abortado). É por esta razão que os programas de acesso a ar-
quivos necessitam de uma rotina customizada de interceptação e tratamento da ocorrência de erros vinculados as ope-
rações de acesso a arquivos.
UT ILI ZA ÇÃ O D E A RQ U IV OS 253

Observe na execução do programa cap07ap02.cob que o erro ocorre na linha 21 do programa exatamente no momen-
to em que se pede a abertura do arquivo com a instrução OPEN INPUT ARQ-SEQ. Veja que se quer a linha 22 é exe-
cutada para a apresentação da mensagem "Arquivo existe em disco" na linha 25.

7.5.2 Tratamento das mensagens de erro


Uma ação que pode ser implementada em um programa além da detecção de erros sobre acessos a arquivos é a cria-
ção de uma sub-rotina que devolve uma mensagem customizada referente a problemas de ocorrência de erros nos
acessos realizados sobre arquivos e suas operações.
O programa que se segue está baseado na indicação dos elementos da tabela 7.1. Para tanto, abra um novo projeto
vazio e definia o programa mensgerr (mensagens de erro) com a extensão “.cbl” na subpasta COBOL da pasta Do-
cumentos, escrevendo as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. MENSGERR.
3 *
4 DATA DIVISION.
5 LOCAL-STORAGE SECTION.
6 77 LS-MENSAG-ERRO PIC X(48).
7 *
8 LINKAGE SECTION.
9 77 LK-CODIGO-ERRO PIC X(02).
10 *
11 PROCEDURE DIVISION USING LK-CODIGO-ERRO.
12 PROG-PRINCIPAL-PARA.
13 EVALUATE LK-CODIGO-ERRO
14 WHEN "01"
15 MOVE "Chave de status do arquivo invalida"
16 TO LS-MENSAG-ERRO
17 WHEN "02"
18 MOVE "Duplicidade de chave na escrita"
19 TO LS-MENSAG-ERRO
20 WHEN "03"
21 MOVE "Codigo de status do arquivo nao valido"
22 TO LS-MENSAG-ERRO
23 WHEN "04"
24 MOVE "Tamanho do registro inconsistente"
25 TO LS-MENSAG-ERRO
26 WHEN "05"
27 MOVE "Arquivo opcionalmente nao encontrado"
28 TO LS-MENSAG-ERRO
29 WHEN "07"
30 MOVE "Arquivo nao abre ou fecha"
31 TO LS-MENSAG-ERRO
32 WHEN "08"
33 MOVE "Tentativa de leitura em arquivo de escrita"
34 TO LS-MENSAG-ERRO
35 WHEN "09"
36 MOVE "Diretorio ou pasta inexistente"
37 TO LS-MENSAG-ERRO
------ ------------------------------------------------------------------------
254 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
38 WHEN "10"
39 MOVE "Fim de arquivo encontrado"
40 TO LS-MENSAG-ERRO
41 WHEN "12"
42 MOVE "Tentativa de abrir arquivo que esta aberto"
43 TO LS-MENSAG-ERRO
44 WHEN "13"
45 MOVE "Nao ha proximo registro logico"
46 TO LS-MENSAG-ERRO
47 WHEN "14"
48 MOVE "Chave fora da faixa"
49 TO LS-MENSAG-ERRO
50 WHEN "15"
51 MOVE "Tentativa de leitura em arquivo nao presente"
52 TO LS-MENSAG-ERRO
53 WHEN "21"
54 MOVE "Chave invalida"
55 TO LS-MENSAG-ERRO
56 WHEN "22"
57 MOVE "Registro existente no arquivo"
58 TO LS-MENSAG-ERRO
59 WHEN "23"
60 MOVE "Registro nao encontrado"
61 TO LS-MENSAG-ERRO
62 WHEN "24"
63 MOVE "Disco cheio"
64 TO LS-MENSAG-ERRO
65 WHEN "25"
66 MOVE "Inicializacao ou leitura em arquivo nao presente"
67 TO LS-MENSAG-ERRO
68 WHEN "30"
69 MOVE "Erro permanente de I/O"
70 TO LS-MENSAG-ERRO
71 WHEN "31"
72 MOVE "Nome do arquivo inconsistente"
73 TO LS-MENSAG-ERRO
74 WHEN "34"
75 MOVE "Violacao de limite"
76 TO LS-MENSAG-ERRO
77 WHEN "35"
78 MOVE "Arquivo nao encontrado"
79 TO LS-MENSAG-ERRO
80 WHEN "37"
81 MOVE "Operacao nao permitida"
82 TO LS-MENSAG-ERRO
83 WHEN "38"
84 MOVE "Arquivo travado"
85 TO LS-MENSAG-ERRO
86 WHEN "39"
87 MOVE "Arquivo difere do declarado no programa"
88 TO LS-MENSAG-ERRO
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 255

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
89 WHEN "41"
90 MOVE "Arquivo esta aberto"
91 TO LS-MENSAG-ERRO
92 WHEN "42"
93 MOVE "Arquivo esta fechado"
94 TO LS-MENSAG-ERRO
95 WHEN "43"
96 MOVE "Leitura nao realizada antecipadamente"
97 TO LS-MENSAG-ERRO
98 WHEN "44"
99 MOVE "Tamanho do registro excedido"
100 TO LS-MENSAG-ERRO
101 WHEN "46"
102 MOVE "Erro de leitura"
103 TO LS-MENSAG-ERRO
104 WHEN "47"
105 MOVE "Leitura de arquivo aberto para escrita"
106 TO LS-MENSAG-ERRO
107 WHEN "48"
108 MOVE "Escrita de arquivo aberto para leitura"
109 TO LS-MENSAG-ERRO
110 WHEN "49"
111 MOVE "Atualizacao de arquivo aberto para leitura"
112 TO LS-MENSAG-ERRO
113 WHEN "51"
114 MOVE "Registro bloqueado"
115 TO LS-MENSAG-ERRO
116 WHEN "52"
117 MOVE "Fim de pagina"
118 TO LS-MENSAG-ERRO
119 WHEN "57"
120 MOVE "Informacoes especificas de linhas invalidas"
121 TO LS-MENSAG-ERRO
122 WHEN "61"
123 MOVE "Falha no compartilhamento do arquivo"
124 TO LS-MENSAG-ERRO
125 WHEN "91"
126 MOVE "Arquivo nao disponivel"
127 TO LS-MENSAG-ERRO
128 WHEN "93"
129 MOVE "Arquivo bloqueado por outro usuario"
130 TO LS-MENSAG-ERRO
131 WHEN "99"
132 MOVE "Registro bloqueado por outro processo"
133 TO LS-MENSAG-ERRO
134 END-EVALUATE.
135 DISPLAY X"0D".
136 DISPLAY "Erro de acesso: " LK-CODIGO-ERRO WITH NO ADVANCING.
137 DISPLAY " (" FUNCTION TRIM(LS-MENSAG-ERRO) ")".
138 DISPLAY "Contacte o suporte tecnico."
139 GOBACK.
140 END PROGRAM MENSGERR.
------ ------------------------------------------------------------------------
256 PRO G RA MA Ç ÃO CO B OL

A partir do preparo da sub-rotina que informa de forma customizada mensagens da ocorrência de erros sobre as opera-
ções em arquivos e do copybook que faz a detecção da ocorrência de erro em si, basta escrever um programa que faça
a utilização integrada desses dois recursos. Assim sendo, abra um projeto vazio com o nome cap07ap03 e extensão
“.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes e observe as partes colorizadas
indicando suas relações dentro do código.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP03 AS "Capitulo 7 – Aplicacao 3".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT ARQ-SEQ ASSIGN TO "DADOS.SEQ"
8 ORGANIZATION IS LINE SEQUENTIAL
9 ACCESS MODE IS SEQUENTIAL
10 FILE STATUS IS WS-PEGA-ERRO.
11 *
12 DATA DIVISION.
13 FILE SECTION.
14 FD ARQ-SEQ.
15 01 LINHA PIC X(80).
16 *
17 WORKING-STORAGE SECTION.
18 COPY "FSCODERR.CPY".
19 77 WS-PEGA-ERRO PIC XX.
20 77 WS-ENTER PIC X.
21 *
22 PROCEDURE DIVISION.
23 PROG-PRINCIPAL-PARA.
24 OPEN INPUT ARQ-SEQ.
25 DISPLAY "DETECCAO DE ACESSO A ARQUIVO COM ERRO CONTROLADO".
26 DISPLAY "------------------------------------------------".
27 IF WS-PEGA-ERRO = "00"
28 DISPLAY X"0D"
29 DISPLAY "Arquivo existe em disco"
30 ELSE
31 CALL "MENSGERR" USING WS-PEGA-ERRO
32 END-IF.
33 CLOSE ARQ-SEQ.
34 DISPLAY X"0D".
35 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
36 ACCEPT WS-ENTER.
37 STOP RUN.
38 END PROGRAM CAP07AP03.
------ ------------------------------------------------------------------------

Ao ser executado o programa uma mensagem, agora personalizada, é apresentada para indicar a ocorrência de erro no
acesso a arquivos, evitando que o programa seja abortado e consequentemente interrompido abruptamente.
A partir deste ponto todos os códigos de programas escritos para a manipulação de arquivos fazem uso do copybook
para a detecção controlada dos códigos de erro e da sub-rotina de informação para a apresentação das mensagens
customizadas sobre ocorrência de erro aos acessos e operações em arquivos.
UT ILI ZA ÇÃ O D E A RQ U IV OS 257

7.6 MANIPULAÇÃO BÁSICA DE ARQUIVOS


A partir do que foi exposto até este momento torna-se mais fácil e compreensível criar e usar arquivos. Neste tópico são
abordados a criação e manipulação básica de arquivos de maneira simplista sem grandes preocupações técnicas em
relação a aplicação profissional destes e uso da filosofia estruturada na programação, servindo este tópico como ele-
mento de ilustração.
Para fazer uso de arquivo é necessário primeiramente cria-los ou tê-los já criado. A partir da existência de um arquivo é
possível realizar duas operações muito básicas sobre eles: a escrita e leitura de registros como coleção de dados. Para
que essas operações ocorram é importante sempre realizar duas ações: abrir os arquivos e após seu uso fechá-los. Os
subtópicos seguintes mostram, cada um, três eventos em programas separados para: a criação; abertura e fechamento
de arquivos nas operações de escrita e leitura de registros.
Para os exemplos deste tópico considere uma estrutura de dados que descreva uma entidade de registro composta a
partir dos campos codfun, nome, depto (departamento), funcao (função) e salario (salário) como apresentado na figura
7.2 que descreve o estilo da estrutura de dados usada nos programas deste tópico.

Figura 7.2 – Estrutura de dados para operacionalização dos programas

Os arquivos devem ser estabelecidos a partir da organização interna que se deseja para os registros. A forma de orga-
nização permite ou não fazer certas operações de acesso. No sentido de simplificar esta observação, veja na tabela 7.7
as formas de organização e quais modos de acesso estão presentes para cada organização de arquivo escolhida e na
tabela 7.8 as principais características operacionais de cada forma de organização que pode ser usada em um arquivo.

Tabela 7.7 – Modos de acesso versus formas de organização

Modo de acesso Formas de organização Disposição dos registros Remoções Atualizações

SEQUENCIAL LINEAR ORDEM DE ENTRADA NÃO NÃO

SEQUENCIAL
SEQUENCIAL DE REGISTRO ORDEM DE ENTRADA NÃO SIM
RELATIVO NÚMERO DO REGISTRO SIM SIM
INDEXADO CAMPO CHAVE SIM SIM

RELATIVO NÚMERO DO REGISTRO SIM SIM


RANDÔMICO
INDEXADO CAMPO CHAVE SIM SIM

RELATIVO NÚMERO DO REGISTRO SIM SIM


DINÂMICO
INDEXADO CAMPO CHAVE SIM SIM

Veja na tabela 7.7 que os modos de acesso relativo e indexado podem ser aplicados a arquivos com organização de
registros sequencial, randômico e dinâmico. O modo de acesso sequencial aplica-se a arquivos com organização se-
quencial linear ou de registro. Quando usado arquivo sequencial de registro as remoções não podem ser realizadas,
mas o espaço de um registro pode ser usado para gravar um novo registro que seja do mesmo tamanho.
258 PRO G RA MA Ç ÃO CO B OL

Tabela 7.8 – Detalhes operacionais das formas de organização de arquivos

Arquivo sequencial Arquivo relativo Arquivo indexado

Os registros são inseridos na


Os registries são inseridos na Os registros são inseridos na
ordem especificada pelo número
ordem em que a entrada é rea- relativo de registro, conheci- ordem indicada junto ao campo
lizada. chave.
do como RRN.

São permitidos a existência de Não são permitidos a existên- Não são permitidos a existên-
registros duplicados. cia de registros duplicados. cia de registros duplicados.

Os registros são classificados


Os registros são dispostos sem Os registros são classificados
prévia classificação. com base no número relativo de com base no campo chave.
registro.

Os registros não podem ser Os registros podem ser excluí- Os registros podem ser excluí-
excluídos. dos. dos.

O acesso aos registros é mais


O acesso aos registros é bas- O acesso aos registros é mais
tante lento. rápido que o acesso indexado. rápido que o acesso sequen-
cial.

Os registros são armazenados


Os registros são armazenados Os registros são armazenados
em disco ou fita (quando dis- apenas em disco. apenas em disco.
ponível).

Não possui a definição de cha- Possui chave fora da estrutura Possui chave como elemento
ve para direcionar operações de registro, sendo controlado integrante da estrutura do
de acesso ao arquivo. automaticamente pelo sistema. registro, sendo definida pelo
usuário.

Como comentado, o uso de arquivo requer a definição da descrição de arquivo lógico na DATA DIVISION junto a FILE
SECTION e vinculado ao arquivo físico com o comando SELECT mencionado no parágrafo FILE-CONTROL definido
junto a INPUT-OUTPUT SECTION na ENVIRONMENT DIVISION. Observe atentamente cada código e também os
pontos colorizados que indicam as relações entre variáveis, campos e arquivos. Devido as características operacionais
no uso de arquivos os programas de gerenciamento e acesso a registros tendem a ser maiores que outros já apresen-
tados nesta obra.

7.6.1 Arquivo sequencial linear para acesso sequencial


Um arquivo de organização sequencial linear com acesso sequencial é uma forma de organização onde cada registro
de tamanho variável é escrito linearmente a partir de um conjunto de caracteres finalizados com uma marca de finaliza-
ção não imprimível. Nos sistemas operacionais DOS, Windows, OS/2 essa marca é estabelecida com os caracteres
X"0D" (carriege return) e X"0A" (new line) e no UNIX essa marca é estabelecida apenas com o caractere X"0A". Es-
ses arquivos são suportados como arquivos de textos simples, podendo ser enviado a uma impressora ou unidade
física de armazenamento sendo usados como dados de exibição. A tabela 7.9 mostra as operações possíveis ações de
serem realizadas em arquivos sequenciais lineares de acordo com o modo de operação permitido para o arquivo.
UT ILI ZA ÇÃ O D E A RQ U IV OS 259

Tabela 7.9 – Ações permitidas para arquivo sequencial linear com acesso sequencial

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - - -
Acesso sequencial WRITE - X - X
para arquivo START - - - -
sequencial linear REWRITE - - - -
DELETE - - - -

A organização sequencial linear de um arquivo pode ser operada apenas pelo modo de acesso sequencial. Neste sen-
tido, a primeira ação a ser definida é a criação do arquivo sequencial linear ARQSEQLN.SEQ para escrita e leitura de
um único registro no arquivo. Abra um projeto vazio com o nome cap07ap04 e extensão “.cob” na subpasta COBOL da
pasta Documentos e codifique as instruções seguintes. Atente aos pontos colorizados e suas relações no código do
programa, mas especialmente as indicações LINE SEQUENTIAL e SEQUENTIAL.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP04 AS "Capitulo 7 – Aplicacao 4".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SEQ"
8 ORGANIZATION IS LINE SEQUENTIAL
9 ACCESS MODE IS SEQUENTIAL
10 FILE STATUS IS WS-PEGA-ERRO.
11 *
12 DATA DIVISION.
13 FILE SECTION.
14 FD FD-VIRTUAL.
15 01 FS-CADFUN.
16 05 F001-CODFUN PIC X(09).
17 05 F001-NOME PIC X(40).
18 05 F001-DEPTO PIC 99.
19 05 F001-FUNCAO PIC X(20).
20 05 F001-SALARIO PIC 9(10)V99.
21 *
22 WORKING-STORAGE SECTION.
23 COPY "FSCODERR.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 77 WS-ENTER PIC X.
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN OUTPUT FD-VIRTUAL.
30 DISPLAY "CRIACAO DE ARQUIVO SEQUENCIAL LINEAR".
31 DISPLAY "------------------------------------".
32 DISPLAY X"0D".
33 IF WS-PEGA-ERRO = "00"
34 WRITE FS-CADFUN
35 DISPLAY "Arquivo criado."
36 ELSE
------ ------------------------------------------------------------------------
260 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
37 CALL "MENSGERR" USING WS-PEGA-ERRO
38 END-IF.
39 CLOSE FD-VIRTUAL.
40 DISPLAY X"0D".
41 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
42 ACCEPT WS-ENTER.
43 STOP RUN.
44 END PROGRAM CAP07AP04.
------ ------------------------------------------------------------------------

Ao ser executado o programa a mensagem “Arquivo criado.” é apresentada indicando que o arquivo vinculado a defi-
nição de arquivo FD-VIRTUAL com a instrução OPEN OUTPUT FD-VIRTUAL indicado na linha 29 foi criado. O modo
de operação OUTPUT sempre cria o arquivo, sendo exclusivo para uso com o comando WRITE (não use o comando
READ no modo de operação OUTPUT). Se já existir um arquivo com registros com o mesmo nome este será recriado e
os dados anteriormente armazenados são sumariamente perdidos. Mais adiante esta questão será abordada para que
seja possível evitar a ocorrência de perda de dados em arquivos a partir do uso do modo de operação EXTEND.
Observe a definição da descrição do arquivo chamada FD-VIRTUAL na linha 14 com a definição na linha 15 do registro
FS-CADFUN formado pelos campos F001-CODFUN, F001-NOME, F001-DEPTO, F001-FUNCAO e F001-SALARIO.
Veja que os campos estão sendo indicados por F001. Esta técnica não é obrigatória, mas auxilia no uso da aplicação
da filosofia estruturada de programação. O prefixo F001 refere-se a dizer que está sendo definido um campo especifi-
camente associado ao primeiro arquivo em uso. Desta forma se for necessário fazer uso de mais arquivos em um pro-
grama com a mesma estrutura fica fácil saber por esta referência a que arquivo certo campo se relaciona.
A gravação de um registro ocorre efetivamente com o comando WRITE na linha 34 que tem por finalidade escrever o
conteúdo da memória principal (representada pela estrutura da dedados FS-CADFUN) dentro do arquivo aberto e re-
presentado pela definição de arquivo FD-VIRTUAL sinalizada em memória pelo comando OPEN em modo OUTPUT.
Após a realização da criação do arquivo e a escrita de absolutamente nada, tem-se um arquivo criado vazio. Na se-
quência o arquivo é fechado com a instrução CLOSE FD-VIRTUAL executada pela linha 39.
A próxima ação definida é a criação do programa que fará a gravação de um único registro no arquivo operacionaliza-
do, neste caso, ARQSEQLN.SEQ. Assim sendo, abra um projeto vazio com o nome cap07ap05 e extensão “.cob” na
subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP05 AS "Capitulo 7 – Aplicacao 5".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SEQ"
8 ORGANIZATION IS LINE SEQUENTIAL
9 ACCESS MODE IS SEQUENTIAL
10 FILE STATUS IS WS-PEGA-ERRO.
11 *
12 DATA DIVISION.
13 FILE SECTION.
14 FD FD-VIRTUAL.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 261

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
15 01 FS-CADFUN.
16 05 F001-CODFUN PIC X(09).
17 05 F001-NOME PIC X(40).
18 05 F001-DEPTO PIC 99.
19 05 F001-FUNCAO PIC X(20).
20 05 F001-SALARIO PIC 9(10)V99.
21 *
22 WORKING-STORAGE SECTION.
23 COPY "FSCODERR.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 01 TB-VIRTUAL.
26 05 TB-CADFUN.
27 10 TB-CODFUN PIC X(09).
28 10 TB-NOME PIC X(40).
29 10 TB-DEPTO PIC 99.
30 10 TB-FUNCAO PIC X(20).
31 10 TB-SALARIO PIC 9(10)V99.
32 77 WS-ENTER PIC X.
33 *
34 PROCEDURE DIVISION.
35 PROG-PRINCIPAL-PARA.
36 OPEN OUTPUT FD-VIRTUAL.
37 IF WS-PEGA-ERRO = "00"
38 DISPLAY "CADASTRO DE FUNCIONARIO"
39 DISPLAY "GRAVACAO DE REGISTRO"
40 DISPLAY "-----------------------"
41 DISPLAY X"0D"
42 DISPLAY "Codigo ........: " WITH NO ADVANCING
43 ACCEPT TB-CODFUN
44 DISPLAY "Nome ..........: " WITH NO ADVANCING
45 ACCEPT TB-NOME
46 DISPLAY "Departamento ..: " WITH NO ADVANCING
47 ACCEPT TB-DEPTO
48 DISPLAY "Funcao ........: " WITH NO ADVANCING
49 ACCEPT TB-FUNCAO
50 DISPLAY "Salario .......: " WITH NO ADVANCING
51 ACCEPT TB-SALARIO
52 WRITE FS-CADFUN FROM TB-CADFUN
53 DISPLAY X"0D"
54 DISPLAY "Registro gravado no arquivo."
55 ELSE
56 CALL "MENSGERR" USING WS-PEGA-ERRO
57 END-IF.
58 CLOSE FD-VIRTUAL.
59 DISPLAY X"0D".
60 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
61 ACCEPT WS-ENTER.
62 STOP RUN.
63 END PROGRAM CAP07AP05.
------ ------------------------------------------------------------------------

Ao ser executado o programa é solicitado a entrada dos dados para composição do registro de um único funcionário,
observe que a instrução WRITE FS-CADFUN FROM TB-CADFUN definida na linha 52 escreve o conteúdo informado
para a estrutura de dados TB-CADFUN indicada na linha 26 na estrutura de arquivo FS-CADFUN definida na linha 15.
262 PRO G RA MA Ç ÃO CO B OL

Veja que após o uso, antes de encerrar o programa é realizado o fechamento do arquivo junto a linha 58, nunca deixe
por conta do sistema operacional a tarefa de fechar seus arquivos, tenha sempre o controle sobre suas ações.
Agora é a vez do programa que efetua a leitura do único registro existente no arquivo ARQSEQLN.SEQ. Assim sendo,
abra um projeto vazio com o nome cap07ap06 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifi-
que as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP06 AS "Capitulo 7 – Aplicacao 6".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SEQ"
8 ORGANIZATION IS LINE SEQUENTIAL
9 ACCESS MODE IS SEQUENTIAL
10 FILE STATUS IS WS-PEGA-ERRO.
11 *
12 DATA DIVISION.
13 FILE SECTION.
14 FD FD-VIRTUAL.
15 01 FS-CADFUN.
16 05 F001-CODFUN PIC X(09).
17 05 F001-NOME PIC X(40).
18 05 F001-DEPTO PIC 99.
19 05 F001-FUNCAO PIC X(20).
20 05 F001-SALARIO PIC 9(10)V99.
21
22 WORKING-STORAGE SECTION.
23 COPY "FSCODERR.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 01 TB-VIRTUAL.
26 05 TB-CADFUN.
27 10 TB-CODFUN PIC X(09).
28 10 TB-NOME PIC X(40).
29 10 TB-DEPTO PIC 99.
30 10 TB-FUNCAO PIC X(20).
31 10 TB-SALARIO PIC 9(10)V99.
32 77 WS-ENTER PIC X.
33 *
34 PROCEDURE DIVISION.
35 PROG-PRINCIPAL-PARA.
36 OPEN INPUT FD-VIRTUAL.
37 IF WS-PEGA-ERRO = "00"
38 READ FD-VIRTUAL INTO TB-CADFUN
39 DISPLAY "CADASTRO DE FUNCIONARIO"
40 DISPLAY "LEITURA DE REGISTRO"
41 DISPLAY "-----------------------"
42 DISPLAY X"0D"
43 DISPLAY "Codigo ........: " TB-CODFUN
44 DISPLAY "Nome ..........: " TB-NOME
45 DISPLAY "Departamento ..: " TB-DEPTO
46 DISPLAY "Funcao ........: " TB-FUNCAO
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 263

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
47 DISPLAY "Salario .......: " TB-SALARIO
48 DISPLAY X"0D"
49 DISPLAY "Registro lido do arquivo."
50 ELSE
51 CALL "MENSGERR" USING WS-PEGA-ERRO
52 END-IF.
53 CLOSE FD-VIRTUAL.
54 DISPLAY X"0D".
55 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
56 ACCEPT WS-ENTER.
57 STOP RUN.
58 END PROGRAM CAP07AP06.
------ ------------------------------------------------------------------------

Ao ser executado o programa é apresentado os dados cadastrados no arquivo ARQSEQLN.SEQ. Note que a instrução
READ FD-VIRTUAL INTO TB-CADFUN da linha 38 efetua a leitura do conteúdo do arquivo aberto no modo INPUT
representado pela definição de arquivo FD-VIRTUAL da linha 14 e transfere os dados para a estrutura de dados TB-
CADFUN definida na linha 26 que é então apresentada. Veja que nos dois últimos programas a gravação é feita dos
dados fornecidos na estrutura de dados TB-CADFUN para a estrutura de arquivo FS-CADFUN e a leitura ocorre senti-
do contrário, pois faz-se a leitura do registro no arquivo representado pela definição de arquivo FD-VIRTUAL e transfe-
re-se os dados para a estrutura de dados TB-CADFUN a partir da instrução READ FD-VIRTUAL INTO TB-CADFUN.
Os programas de manipulação de arquivos deste tópico usarão a descrição de arquivo indicada na figura 7.2. Assim
sendo, é conveniente criar um copybook que tenha a descrição do arquivo definido a fim de tornar os programas mais
compactados. Assim sendo, abra um novo projeto vazio chamado fdvirtual com a indicação da extensão “.cpy” na
subpasta COBOL da pasta Documentos e escreva a partir da sétima coluna as instruções indicadas a seguir.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 FD FD-VIRTUAL.
2 01 FS-CADFUN.
3 05 F001-CODFUN PIC X(09).
4 05 F001-NOME PIC X(40).
5 05 F001-DEPTO PIC 99.
6 05 F001-FUNCAO PIC X(20).
7 05 F001-SALARIO PIC 9(10)V99.
------ ------------------------------------------------------------------------

Além da descrição do arquivo FD-VIRTUAL é usado maciçamente a definição da estrutura de dados TB-VIRTUAL.
Assim sendo, é conveniente criar um copybook que tenha a descrição do arquivo definido a fim de tornar os programas
mais compactados. Assim sendo, abra um novo projeto vazio chamado tbvirtual com a indicação da extensão “.cpy” na
subpasta COBOL da pasta Documentos e escreva a partir da sétima coluna as instruções indicadas a seguir.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 01 TB-VIRTUAL.
2 05 TB-CADFUN.
------ ------------------------------------------------------------------------
264 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
3 10 TB-CODFUN PIC X(09).
4 10 TB-NOME PIC X(40).
5 10 TB-DEPTO PIC 99.
6 10 TB-FUNCAO PIC X(20).
7 10 TB-SALARIO PIC 9(10)V99.
------ ------------------------------------------------------------------------

Os próximos programas realizam a escrita e leitura de registros em arquivos lineares com o efeito de anexação de re-
gistros, ou seja, quando o arquivo existir este não será recriado, será colocado em modo de extensão (anexação de
registros). Desta forma, os registros existentes são preservados e os próximos registros são anexados ao final do arqui-
vo. Mas antes de proceder ao uso de registros anexados considere um programa que escreva em um arquivo sequen-
cial linear mais de um registro. O programa deve usa o arquivo ARQSEQLN.SST. Assim sendo, abra um projeto vazio
com o nome cap07ap07 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções se-
guintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP07 AS "Capitulo 7 – Aplicacao 7".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SST"
11 ORGANIZATION IS LINE SEQUENTIAL
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 WS-RESP PIC A VALUE "S".
25 *
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 OPEN OUTPUT FD-VIRTUAL.
29 DISPLAY "CADASTRO DE FUNCIONARIOS".
30 DISPLAY "GRAVACAO DE REGISTROS".
31 DISPLAY "------------------------".
32 IF WS-PEGA-ERRO = "00"
33 PERFORM FOREVER
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 265

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
34 DISPLAY X"0D"
35 DISPLAY "Codigo ........: " WITH NO ADVANCING
36 ACCEPT TB-CODFUN
37 DISPLAY "Nome ..........: " WITH NO ADVANCING
38 ACCEPT TB-NOME
39 DISPLAY "Departamento ..: " WITH NO ADVANCING
40 ACCEPT TB-DEPTO
41 DISPLAY "Funcao ........: " WITH NO ADVANCING
42 ACCEPT TB-FUNCAO
43 DISPLAY "Salario .......: " WITH NO ADVANCING
44 ACCEPT TB-SALARIO
45 WRITE FS-CADFUN FROM TB-CADFUN
46 DISPLAY X"0D"
47 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
48 DISPLAY "- qualquer outra letra para NAO: "
49 WITH NO ADVANCING
50 ACCEPT WS-RESP
51 IF UPPER-CASE(WS-RESP) NOT = "S"
52 EXIT PERFORM
53 END-IF
54 END-PERFORM
55 ELSE
56 CALL "MENSGERR" USING WS-PEGA-ERRO
57 END-IF.
58 CLOSE FD-VIRTUAL.
59 DISPLAY X"0D".
60 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
61 ACCEPT WS-ENTER.
62 STOP RUN.
63 END PROGRAM CAP07AP07.
------ ------------------------------------------------------------------------

Execute o programa e informe alguns registros para que cada um seja colocado um após o outro. Veja que quase nada
é diferente ao programa cap07ap05.cob. A diferença está no uso do laço PERFORM FOREVER na linha 33 dentro da
validação da operação de acesso ao arquivo realizada pela instrução IF WS-PEGA-ERRO = "00" da linha 32. Veja que
a saída deste laço ocorre na verificação condicional entre as linhas 51 e 53. Observe em especial as linhas 17 e 21 com
a chamada dos copybooks que possuem as descrições dos campos do arquivo e a definição da estrutura de dados a
ser usada no programa.
O programa seguinte efetua a leitura dos registros armazenados no arquivo linear ARQSEQLN.SST. Assim sendo, abra
um projeto vazio com o nome cap07ap08 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as
instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP08 AS "Capitulo 7 – Aplicacao 8".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
------ ------------------------------------------------------------------------
266 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SST"
11 ORGANIZATION IS LINE SEQUENTIAL
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 *
25 PROCEDURE DIVISION.
26 PROG-PRINCIPAL-PARA.
27 OPEN INPUT FD-VIRTUAL.
28 DISPLAY "CADASTRO DE FUNCIONARIOS".
29 DISPLAY "LEITURA DE REGISTROS"
30 DISPLAY "------------------------".
31 IF WS-PEGA-ERRO = "00"
32 PERFORM FOREVER
33 READ FD-VIRTUAL INTO TB-CADFUN
34 IF WS-PEGA-ERRO = "10"
35 EXIT PERFORM
36 END-IF
37 DISPLAY X"0D"
38 DISPLAY "Codigo ........: " TB-CODFUN
39 DISPLAY "Nome ..........: " TB-NOME
40 DISPLAY "Departamento ..: " TB-DEPTO
41 DISPLAY "Funcao ........: " TB-FUNCAO
42 DISPLAY "Salario .......: " TB-SALARIO
43 END-PERFORM
44 ELSE
45 CALL "MENSGERR" USING WS-PEGA-ERRO
46 END-IF.
47 CLOSE FD-VIRTUAL.
48 DISPLAY X"0D".
49 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
50 ACCEPT WS-ENTER.
51 STOP RUN.
52 END PROGRAM CAP07AP08.
------ ------------------------------------------------------------------------

Ao ser executado o programa serão apresentados os registros anteriormente informados. Neste programa é necessário
identificar o final do arquivo entre as linhas 34 e 36 a partir do código 10 para que a ação do laço PERFORM FOREVER
seja interrompido. Esta operação é realizada com a instrução IF WS-PEGA-ERRO = "10", em que o código 10 refere-
se ao encontro do final do arquivo em uso. Quando esta condição for verdadeira a instrução EXIT PERFORM da linha
35 é executada e o laço é então encerrado. Um detalhe importante é estabelecer esta condição de verificação de final
UT ILI ZA ÇÃ O D E A RQ U IV OS 267

de arquivo imediatamente após a realização da ação de leitura do arquivo com a instrução READ FD-VIRTUAL INTO
TB-CADFUN na linha 33.
A partir dos dois últimos programas possui-se um conjunto de programas que gerenciam o uso de um arquivo linear
com linhas de registro. No entanto, se for executado o programa cap07ap07.cob o arquivo ARQSEQLN.SST será
recriado e os registros existentes serão perdidos.
Para melhorar este comportamento o próximo programa faz uso do modo de abertura EXTEND. Desta forma, o arquivo
poderá ser aberto sem que os registros sejam apagados. O modo de operação EXTEND abre um arquivo e posicionar o
ponteiro de acesso após o último registro antes da marcação de fim de arquivo. No entanto, este modo de operação
possui diferenças em outras implementações COBOL. Aqui segue o estilo, particular, do compilador GnuCOBOL.
Abra um projeto vazio com o nome cap07ap09 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifi-
que as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP09 AS "Capitulo 7 – Aplicacao 9".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQLN.SST"
11 ORGANIZATION IS LINE SEQUENTIAL
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 WS-RESP PIC A VALUE "S".
25 *
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 OPEN EXTEND FD-VIRTUAL.
29 IF WS-PEGA-ERRO = "35"
30 OPEN OUTPUT FD-VIRTUAL
31 END-IF
32 DISPLAY "CADASTRO DE FUNCIONARIOS"
33 DISPLAY "ANEXACAO DE REGISTROS"
34 DISPLAY "------------------------"
35 IF WS-PEGA-ERRO = "00"
36 PERFORM FOREVER
37 DISPLAY X"0D"
38 DISPLAY "Codigo ........: " WITH NO ADVANCING
------ ------------------------------------------------------------------------
268 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
39 ACCEPT TB-CODFUN
40 DISPLAY "Nome ..........: " WITH NO ADVANCING
41 ACCEPT TB-NOME
42 DISPLAY "Departamento ..: " WITH NO ADVANCING
43 ACCEPT TB-DEPTO
44 DISPLAY "Funcao ........: " WITH NO ADVANCING
45 ACCEPT TB-FUNCAO
46 DISPLAY "Salario .......: " WITH NO ADVANCING
47 ACCEPT TB-SALARIO
48 WRITE FS-CADFUN FROM TB-CADFUN
49 DISPLAY X"0D"
50 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
51 DISPLAY "- qualquer outra letra para NAO: "
52 WITH NO ADVANCING
53 ACCEPT WS-RESP
54 IF UPPER-CASE(WS-RESP) NOT = "S"
55 EXIT PERFORM
56 END-IF
57 END-PERFORM
58 ELSE
59 CALL "MENSGERR" USING WS-PEGA-ERRO
60 END-IF.
61 CLOSE FD-VIRTUAL.
62 DISPLAY X"0D".
63 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
64 ACCEPT WS-ENTER.
65 STOP RUN.
66 END PROGRAM CAP07AP09.
------ ------------------------------------------------------------------------

Ao ser executado o programa entre alguns outros registros e na sequência execute o programa cap07ap08.cob para
ver o conjunto de registros anexados ao arquivo ARQSEQLN.SST.
No GnuCOBOL o uso do modo EXTEND pode ocasionar o surgimento do erro 35, referente a não localização do arqui-
vo indicado, ou seja, a tentativa de abrir um arquivo inexistente. Neste caso, ocorrendo este erro o programa deve antes
criar o arquivo com a instrução OPEN OUTPUT FD-VIRTUAL. Daí o uso do trecho de código definido entre as linhas 28
e 31.
Se na execução da instrução OPEN EXTEND FD-VIRTUAL não ocorrer erro o arquivo é aberto em modo de extensão,
permitindo ser acrescentado novas registros no final do arquivo. É pertinente informar que em outras implementações
da linguagem o uso da instrução IF WS-PEGA-ERRO = "35" não é aplicado, bastando apenas e diretamente usar a
instrução OPEN EXTEND FD-VIRTUAL para anexar registros a um arquivo ou criar um arquivo para anexação. Há
implementações que necessitam para o modo EXTEND do uso da cláusula OPTIONAL junto ao comando SELECT.

7.6.2 Arquivo sequencial de registro para acesso sequencial


Um arquivo de organização sequencial de registro com acesso sequencial é uma forma de organização onde cada
registro de tamanho variável ou não é escrito sequencialmente um após o outro, sendo acessível para leitura na mesma
ordem em que foram inseridos. Neste tipo de arquivo os registros podem ser lidos e/ou escritos sequencialmente. Em
arquivos sequenciais não é possível excluir registros, mas é possível atualizá-los. Este tipo de arquivo é útil em situa-
ções em que a ordem dos registros não é importante, sendo útil o seu uso na impressão de relatórios desde que os
registros sejam dispostos previamente de forma classificada. A tabela 7.10 mostra as operações possíveis de serem
realizadas em arquivos sequenciais de acordo com o modo de operação permitido para o arquivo.
UT ILI ZA ÇÃ O D E A RQ U IV OS 269

Tabela 7.10 – Ações permitidas para arquivo sequencial de registro com acesso sequencial

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso sequencial WRITE - X - X
para arquivo START - - - -
sequencial de registro REWRITE - - X -
DELETE - - - -

O programa a seguir, se não existir, cria o arquivo sequencial ARQSEQBT.SEQ colocando-o em modo de extensão
para que aceite sempre novos registros ao arquivo. Assim sendo, abra um projeto vazio com o nome cap07ap10 e
extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP10 AS "Capitulo 7 – Aplicacao 10".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQBT.SEQ"
11 ORGANIZATION IS RECORD BINARY SEQUENTIAL
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 WS-RESP PIC A VALUE "S".
25 *
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 OPEN EXTEND FD-VIRTUAL.
29 IF WS-PEGA-ERRO = "35"
30 OPEN OUTPUT FD-VIRTUAL
31 END-IF
32 DISPLAY "CADASTRO DE FUNCIONARIOS"
33 DISPLAY "ENTRADA ANEXADA"
34 DISPLAY "------------------------"
35 IF WS-PEGA-ERRO = "00"
36 PERFORM FOREVER
37 DISPLAY X"0D"
38 DISPLAY "Codigo ........: " WITH NO ADVANCING
------ ------------------------------------------------------------------------
270 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
39 ACCEPT TB-CODFUN
40 DISPLAY "Nome ..........: " WITH NO ADVANCING
41 ACCEPT TB-NOME
42 DISPLAY "Departamento ..: " WITH NO ADVANCING
43 ACCEPT TB-DEPTO
44 DISPLAY "Funcao ........: " WITH NO ADVANCING
45 ACCEPT TB-FUNCAO
46 DISPLAY "Salario .......: " WITH NO ADVANCING
47 ACCEPT TB-SALARIO
48 WRITE FS-CADFUN FROM TB-CADFUN
49 DISPLAY X"0D"
50 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
51 DISPLAY "- qualquer outra letra para NAO: "
52 WITH NO ADVANCING
53 ACCEPT WS-RESP
54 IF UPPER-CASE(WS-RESP) NOT = "S"
55 EXIT PERFORM
56 END-IF
57 END-PERFORM
58 ELSE
59 CALL "MENSGERR" USING WS-PEGA-ERRO
60 END-IF.
61 CLOSE FD-VIRTUAL.
62 DISPLAY X"0D".
63 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
64 ACCEPT WS-ENTER.
65 STOP RUN.
66 END PROGRAM CAP07AP10.
------ ------------------------------------------------------------------------

Ao ser executado o programa entre alguns registros. Veja que, basicamente a única diferença no programa está no uso
da organização RECORD BINARY SEQUENTIAL em ORGANIZATION IS, antes definida como LINE SEQUENTIAL.
Essa diferença faz com que ao ser criado o arquivo os registros sejam colocados uns após os outros sem a ocorrência
de mudança de linha após o último campo do registro.
As cláusulas ORGANIZATION IS RECORD BINARY SEQUENTIAL (linha 11), bem como a cláusula ACCESS MODE
IS SEQUENTIAL (linha 12) podem ser omitidas, uma vez que o padrão automático da linguagem é operar com arquivos
sequenciais.
A citação RECORD BINARY SEQUENTIAL pode ser escrita como RECORD SEQUENTIAL, BINARY SEQUENTIAL
ou simplesmente SEQUENTIAL. Um jeito elegante para deixar bem diferenciado do modo LINE SEQUENTIAL e man-
ter o uso do estilo RECORD SEQUENTIAL.
A leitura de um arquivo sequencial de registro é similar a leitura realizada em um arquivo sequencial linear, tendo como
diferencial o uso da cláusula SEQUENTIAL em ORGANIZATION IS. Assim sendo, abra um projeto vazio com o nome
cap07ap11 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP11 AS "Capitulo 7 – Aplicacao 11".
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 271

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 *
10 FILE-CONTROL.
11 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQBT.SEQ"
12 ORGANIZATION IS RECORD SEQUENTIAL
13 ACCESS MODE IS SEQUENTIAL
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 OPEN INPUT FD-VIRTUAL.
29 DISPLAY "CADASTRO DE FUNCIONARIOS"
30 DISPLAY "APRESENTA REGISTROS"
31 DISPLAY "------------------------"
32 IF WS-PEGA-ERRO = "00"
33 PERFORM FOREVER
34 READ FD-VIRTUAL INTO TB-CADFUN
35 IF WS-PEGA-ERRO = "10"
36 EXIT PERFORM
37 END-IF
38 DISPLAY X"0D"
39 DISPLAY "Codigo ........: " TB-CODFUN
40 DISPLAY "Nome ..........: " TB-NOME
41 DISPLAY "Departamento ..: " TB-DEPTO
42 DISPLAY "Funcao ........: " TB-FUNCAO
43 DISPLAY "Salario .......: " TB-SALARIO
44 END-PERFORM
45 ELSE
46 CALL "MENSGERR" USING WS-PEGA-ERRO
47 END-IF.
48 CLOSE FD-VIRTUAL.
49 DISPLAY X"0D".
50 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
51 ACCEPT WS-ENTER.
52 STOP RUN.
53 END PROGRAM CAP07AP11.
------ ------------------------------------------------------------------------
272 PRO G RA MA Ç ÃO CO B OL

Ao ser executado o programa serão apresentados os registros anteriormente informados. Observe que o uso de arqui-
vos sequenciais convencional e lineares são muito parecidos, guardando-se as diferenças já mencionadas. A utilização
do código 10 em IF WS-PEGA-ERRO = "10" da linha 35 ocorre quando a ação de leitura do arquivo ultrapassa seu
final. Como visto um arquivo sequencial é aquele em que os registros só podem ser acessados sequencialmente e na
mesma ordem em que foram originalmente gravados. Novos registros podem ser adicionados ao arquivo se a cláusula
EXTEND estiver em uso no momento da gravação.
Uma operação que pode ser realizada em arquivos sequenciais de registros é a reescrita de dados em registros exis-
tentes desde que o novo registro tenha exatamente o mesmo tamanho do registro original. Para efetivar esta ação usa-
se o comando REWRITE com o arquivo aberto em modo I-O sem o uso da cláusula [NOT] INVALID KEY após a exe-
cução do comando READ que seja bem sucedido.
O próximo exemplo de programa efetua a leitura do arquivo ARQSEQBT.SEQ, mostra o registro corrente e pergunta se
deseja alteração. Se a resposta for positiva é solicitado a entrada do novo conjunto de dados do registro a ser alterado.
Assim sendo, abra um projeto vazio com o nome cap07ap12 e extensão “.cob” na subpasta COBOL da pasta Docu-
mentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP12 AS "Capitulo 7 – Aplicacao 12".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQBT.SEQ"
11 ORGANIZATION IS SEQUENTIAL
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 WS-RESP PIC A VALUE "S".
25 77 WS-CI PIC 9(3) VALUE 1.
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN I-O FD-VIRTUAL.
30 DISPLAY "CADASTRO DE FUNCIONARIOS"
31 DISPLAY "ALTERACAO DE RESGISTRO"
32 DISPLAY "------------------------"
33 IF WS-PEGA-ERRO = "00"
34 PERFORM FOREVER
35 READ FD-VIRTUAL INTO TB-CADFUN
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 273

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
36 IF WS-PEGA-ERRO = "10"
37 EXIT PERFORM
38 END-IF
39 DISPLAY X"0D"
40 DISPLAY "Registro ......: " WS-CI
41 DISPLAY "Codigo ........: " TB-CODFUN
42 DISPLAY "Nome ..........: " TB-NOME
43 DISPLAY "Departamento ..: " TB-DEPTO
44 DISPLAY "Funcao ........: " TB-FUNCAO
45 DISPLAY "Salario .......: " TB-SALARIO
46 DISPLAY X"0D"
47 DISPLAY "Alterar registro? (S/N): " WITH NO ADVANCING
48 ACCEPT WS-RESP
49 IF UPPER-CASE(WS-RESP) = "S"
50 DISPLAY X"0D"
51 DISPLAY "Entre os novos dados:"
52 DISPLAY X"0D"
53 DISPLAY "Codigo ........: " TB-CODFUN
54 DISPLAY "Nome ..........: " WITH NO ADVANCING
55 ACCEPT TB-NOME
56 DISPLAY "Departamento ..: " WITH NO ADVANCING
57 ACCEPT TB-DEPTO
58 DISPLAY "Funcao ........: " WITH NO ADVANCING
59 ACCEPT TB-FUNCAO
60 DISPLAY "Salario .......: " WITH NO ADVANCING
61 ACCEPT TB-SALARIO
62 REWRITE FS-CADFUN FROM TB-CADFUN
63 DISPLAY X"0D"
64 DISPLAY "Registro alterado."
65 DISPLAY X"0D"
66 DISPLAY "Tecle <ENTER> para prosseguir... "
67 WITH NO ADVANCING
68 ACCEPT WS-ENTER
69 END-IF
70 ADD 1 TO WS-CI
71 END-PERFORM
72 ELSE
73 CALL "MENSGERR" USING WS-PEGA-ERRO
74 END-IF.
75 CLOSE FD-VIRTUAL.
76 DISPLAY X"0D".
77 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
78 ACCEPT WS-ENTER.
79 STOP RUN.
80 END PROGRAM CAP07AP12.
------ ------------------------------------------------------------------------

Ao ser executado o programa o primeiro registro é apresentado e é perguntado se há o desejo de alterá-lo. Se a res-
posta for positiva é aberta a área de entrada de dados entre as linhas 50 e 68 que permite alterar os dados do registro
apresentado, exceto o código de identificação do funcionário. Caso a resposta a alteração seja negativa o programa
apresenta o próximo registro. Isso será realizado para cada registro do arquivo apresentado.
274 PRO G RA MA Ç ÃO CO B OL

7.6.3 Arquivo relativo para acesso sequencial


Um arquivo de organização relativa com acesso sequencial é uma forma de organização onde cada registro é identifi-
cado a partir da posição ordinal que ocupa dentro do arquivo sempre com tamanho fixo, tendo tempo de acesso mais
rápido de todos os tipos de arquivos usados em COBOL. Os registros de um arquivo relativo são seguidos por um mar-
cador de dois bytes X"0D0A", o primeiro byte se refere ao sinal (carriege return) e o segundo byte se refere ao sinal
(new line). A tabela 7.11 mostra as operações possíveis de serem realizadas em arquivos sequenciais relativos de
acordo com o modo de operação permitido para o arquivo.

Tabela 7.11 – Ações permitidas para arquivo relativo com acesso sequencial

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso sequencial WRITE - X - X
para arquivo START X - X -
relativo REWRITE - - X -
DELETE - - X -

No caso, específico, de um arquivo sequencial relativo as operações de leitura e escrita são realizadas normalmente
com os comandos WRITE e READ da forma mesma forma como usada nas operações com arquivos sequencias linea-
res e de registros. Para a escrita de registros define-se a organização do arquivo como relativa e o modo de acesso
como sequencial e para a saída fazem-se as mesmas ações acrescentando-se a definição de um campo de chave
relativa para ser usado nas operações de busca e o uso do comando START para direcionar a forma de leitura tanto
para reescrita de registro (REWRITE) ou remoção (DELETE).
O programa a seguir, se não existir, cria o arquivo sequencial relativo ARQSEQBT.SEQ colocando-o em modo de ex-
tensão para receber sempre novos registros ao arquivo. Assim sendo, abra um projeto vazio com o nome cap07ap13 e
extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP13 AS "Capitulo 7 – Aplicacao 13".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQRL.SEQ"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS SEQUENTIAL
13 FILE STATUS IS WS-PEGA-ERRO.
14 *
15 DATA DIVISION.
16 FILE SECTION.
17 COPY "FDVIRTUAL.CPY".
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 275

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
23 77 WS-ENTER PIC X.
24 77 WS-RESP PIC A VALUE "S".
25 *
26 PROCEDURE DIVISION.
27 PROG-PRINCIPAL-PARA.
28 OPEN EXTEND FD-VIRTUAL.
29 IF WS-PEGA-ERRO = "35"
30 OPEN OUTPUT FD-VIRTUAL
31 END-IF
32 DISPLAY "CADASTRO DE FUNCIONARIOS"
33 DISPLAY "INSERCAO DE REGISTROS"
34 DISPLAY "------------------------"
35 IF WS-PEGA-ERRO = "00"
36 PERFORM FOREVER
37 DISPLAY X"0D"
38 DISPLAY "Codigo ........: " WITH NO ADVANCING
39 ACCEPT TB-CODFUN
40 DISPLAY "Nome ..........: " WITH NO ADVANCING
41 ACCEPT TB-NOME
42 DISPLAY "Departamento ..: " WITH NO ADVANCING
43 ACCEPT TB-DEPTO
44 DISPLAY "Funcao ........: " WITH NO ADVANCING
45 ACCEPT TB-FUNCAO
46 DISPLAY "Salario .......: " WITH NO ADVANCING
47 ACCEPT TB-SALARIO
48 WRITE FS-CADFUN FROM TB-CADFUN
49 DISPLAY X"0D"
50 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
51 DISPLAY "- qualquer outra letra para NAO: "
52 WITH NO ADVANCING
53 ACCEPT WS-RESP
54 IF UPPER-CASE(WS-RESP) NOT = "S"
55 EXIT PERFORM
56 END-IF
57 END-PERFORM
58 ELSE
59 CALL "MENSGERR" USING WS-PEGA-ERRO
60 END-IF.
61 CLOSE FD-VIRTUAL.
62 DISPLAY X"0D".
63 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
64 ACCEPT WS-ENTER.
65 STOP RUN.
66 END PROGRAM CAP07AP13.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe alguns registros como feito anteriormente. Observe que o código do programa é
similar aos programas anteriores que realizaram operações semelhantes, a diferença está na definição da organização
do arquivo como RELATIVE indicado na linha 11. Esta forma de organização define no arquivo sequencial uma marca
que permite acessar os registros a partir de suas posições ordinais.
O próximo programa faz a consulta dos registros no arquivo ARQSEQBT.SEQ e mostra o registro se o valor do posici-
onamento informado for válido. Não sendo válido a mensagem “Registro inexistente.” será apresentada. Assim sendo,
276 PRO G RA MA Ç ÃO CO B OL

abra um projeto vazio com o nome cap07ap14 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifi-
que as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP14 AS "Capitulo 7 – Aplicacao 14".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 *
10 FILE-CONTROL.
11 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQRL.SEQ"
12 ORGANIZATION IS RELATIVE
13 ACCESS MODE IS SEQUENTIAL
14 RELATIVE KEY IS TB-NUM-REG
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 *
21 WORKING-STORAGE SECTION.
22 COPY "FSCODERR.CPY".
23 COPY "TBVIRTUAL.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 77 WS-ENTER PIC X.
26 77 WS-RESP PIC A VALUE "S".
27 77 TB-NUM-REG PIC 9(4). *> DE 0001 ATE 9999 REGISTROS
28 *
29 PROCEDURE DIVISION.
30 PROG-PRINCIPAL-PARA.
31 OPEN INPUT FD-VIRTUAL.
32 DISPLAY "CADASTRO DE FUNCIONARIOS"
33 DISPLAY "CONSULTA DE REGISTROS"
34 DISPLAY "------------------------"
35 IF WS-PEGA-ERRO = "00"
36 PERFORM FOREVER
37 DISPLAY X"0D"
38 DISPLAY "Qual registro: " WITH NO ADVANCING
39 ACCEPT TB-NUM-REG
40 START FD-VIRTUAL KEY IS = TB-NUM-REG *> "=" OU "EQUAL"
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
46 NOT INVALID KEY
47 READ FD-VIRTUAL INTO TB-CADFUN
48 DISPLAY X"0D"
49 DISPLAY "Codigo ........: " TB-CODFUN
50 DISPLAY "Nome ..........: " TB-NOME
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 277

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
51 DISPLAY "Departamento ..: " TB-DEPTO
52 DISPLAY "Funcao ........: " TB-FUNCAO
53 DISPLAY "Salario .......: " TB-SALARIO
54 DISPLAY X"0D"
55 PERFORM 900-MENSAGEM
56 END-START
57 IF UPPER-CASE(WS-RESP) NOT = "S"
58 EXIT PERFORM
59 END-IF
60 END-PERFORM
61 ELSE
62 CALL "MENSGERR" USING WS-PEGA-ERRO
63 END-IF.
64 CLOSE FD-VIRTUAL.
65 DISPLAY X"0D".
66 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
67 ACCEPT WS-ENTER.
68 STOP RUN.
69 900-MENSAGEM SECTION.
70 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING
71 DISPLAY "- qualquer outra letra para NAO: " WITH NO ADVANCING
72 ACCEPT WS-RESP
73 EXIT.
74 END PROGRAM CAP07AP14.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe os registros ordinais, como 1 para o primeiro, 2 para o segundo e assim por dian-
te. Quando o registro existir no arquivo este será apresentado. Caso não exista a mensagem informando a inexistência
do registro é apresentada.
Observe atentamente a definição da variável TB-NUM-REG na linha 27 associada a cláusula RELATIVE KEY IS (que
opera apenas com valores numéricos inteiros positivos) na linha 14 para uso como coletora do valor do registro posicio-
nal para a pesquisa. Veja a relação da variável TB-NUM-REG com a estrutura de arquivo FD-VIRTUAL a partir da ins-
trução START FD-VIRTUAL KEY IS = TB-NUM-REG na linha 40 que direciona ações de apresentação de dados quando a
operação é bem sucedida (NOT INVALID KEY) ou mal sucedida (INVALID KEY). Quando bem sucedida efetua-se a
leitura da estrutura do arquivo transferindo o registro para a estrutura de dados com o comando READ.
Veja nas linhas 45 e 55 o uso de uma chamada de sub-rotina para a apresentação da mensagem de nova pesquisa. A
sub-rotina indicadas é definida entre as linhas 69 e 73.
O comando START quando em uso faz um apontamento ao registro indicado em TB-NUM-REG localizando o registro e
deixando-o pronto para recuperação com o comando READ da linha 47 que efetua a leitura do registro, então apontado
por START. O comando START não pode ser usado em arquivos de organização sequencial (de linha), mas é adequa-
do para arquivos com organização relativa ou indexada. A indicação KEY IS, além do operador = (EQUAL) pode usar
os operadores > (GREATER), < (LESS), <= (NOT GREATER ou LESS OR EQUAL) e >= (NOT LESS ou GREATER
OR EQUAL), os quais possuem os seguintes significados:
 EQUAL - posiciona na chave escolhida;
 GREATER - posiciona na chave do primeiro registro maior do que o informado;
 LESS - posiciona na chave do primeiro registro menor do que o informado;
 NOT GREATER - posiciona na chave do último menor ou igual do que o informado;
 NOT LESS - posiciona na chave do primeiro registro maior ou igual do que o informado.
278 PRO G RA MA Ç ÃO CO B OL

Quando START não localiza um registro a partir do índice apontado ocorre um erro de condição que pode ser tratado
com a cláusula INVALID KEY.
O próximo programa visa estabelecer uma linha de gerenciamento de registros em arquivo existentes. Neste programa
estará disponível a operação de reescrever um registro pesquisado relativamente em arquivo sequencial. Assim sendo,
abra um projeto vazio com o nome cap07ap15 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifi-
que as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP15 AS "Capitulo 7 – Aplicacao 15".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQRL.SEQ"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS SEQUENTIAL
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL.
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "REESCRITA DE REGISTRO"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual registro: " WITH NO ADVANCING
38 ACCEPT TB-NUM-REG
39 START FD-VIRTUAL KEY IS = TB-NUM-REG
40 INVALID KEY
41 DISPLAY X"0D"
42 DISPLAY "Registro inexistente."
43 DISPLAY X"0D"
44 PERFORM 900-MENSAGEM
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 279

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
45 NOT INVALID KEY
46 READ FD-VIRTUAL INTO TB-CADFUN
47 DISPLAY X"0D"
48 DISPLAY "Codigo ........: " TB-CODFUN
49 DISPLAY "Nome ..........: " TB-NOME
50 DISPLAY "Departamento ..: " TB-DEPTO
51 DISPLAY "Funcao ........: " TB-FUNCAO
52 DISPLAY "Salario .......: " TB-SALARIO
53 DISPLAY X"0D"
54 DISPLAY "Alterar registro? (S/N): "
55 WITH NO ADVANCING
56 ACCEPT WS-RESP
57 IF UPPER-CASE(WS-RESP) = "S"
58 DISPLAY X"0D"
59 DISPLAY "Entre os novos dados:"
60 DISPLAY X"0D"
61 DISPLAY "Codigo ........: " TB-CODFUN
62 DISPLAY "Nome ..........: " WITH NO ADVANCING
63 ACCEPT TB-NOME
64 DISPLAY "Departamento ..: " WITH NO ADVANCING
65 ACCEPT TB-DEPTO
66 DISPLAY "Funcao ........: " WITH NO ADVANCING
67 ACCEPT TB-FUNCAO
68 DISPLAY "Salario .......: " WITH NO ADVANCING
69 ACCEPT TB-SALARIO
70 REWRITE FS-CADFUN FROM TB-CADFUN
71 DISPLAY X"0D"
72 DISPLAY "Registro alterado."
73 DISPLAY X"0D"
74 DISPLAY "Tecle <ENTER> para prosseguir... "
75 WITH NO ADVANCING
76 ACCEPT WS-ENTER
77 END-IF
78 DISPLAY X"0D"
79 PERFORM 900-MENSAGEM
80 END-START
81 IF UPPER-CASE(WS-RESP) NOT = "S"
82 EXIT PERFORM
83 END-IF
84 END-PERFORM
85 ELSE
86 CALL "MENSGERR" USING WS-PEGA-ERRO
87 END-IF.
88 CLOSE FD-VIRTUAL.
89 DISPLAY X"0D".
90 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
91 ACCEPT WS-ENTER.
92 STOP RUN.
93 900-MENSAGEM SECTION.
94 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
95 DISPLAY "- qualquer outra letra para NAO: "
96 WITH NO ADVANCING.
97 ACCEPT WS-RESP.
------ ------------------------------------------------------------------------
280 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
98 EXIT.
99 END PROGRAM CAP07AP15.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe o registro desejado e confirme ou não sua alteração, teste todas as possibilida-
des do programa.
A pesquisa do registro realizada na linha 39 com o comando START quando encontra o registro procurado direciona o
fluxo de ação do programa para o trecho de linhas entre 46 e 79. A linha 46 com a instrução READ FD-VIRTUAL INTO
TB-CADFUN faz a leitura do registro transferindo-o para a memória principal, recebe os novos dados e na linha 70 a
instrução REWRITE FS-CADFUN FROM TB-CADFUN realiza a gravação dos novos dados sobre o registro existente.
Caso a pesquisa não encontre um registro válido é apresentada a mensagem da linha 42 informando que o registro não
existe no arquivo. Veja que para esta operação o arquivo é aberto em modo I-O como indicado na linha 30.
Os registros de um arquivo sequencial relativo podem ser removidos logicamente. A remoção lógica não apaga fisica-
mente o registro do arquivo apenas marca o registro como removido ao colocar no final do registro os bytes X"0D00",
sendo o primeiro byte referente ao sinal CR (carriege return) e o segundo byte referente ao sinal NULL (nulo).
Para definir um programa que permita remover registros com acesso sequencial um arquivo relativo abra um projeto
vazio com o nome cap07ap16 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções
seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP16 AS "Capitulo 7 – Aplicacao 16".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQRL.SEQ"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS SEQUENTIAL
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4).
27 *
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 281

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
27 OPEN I-O FD-VIRTUAL.
28 DISPLAY "CADASTRO DE FUNCIONARIOS"
29 DISPLAY "REMOCAO DE REGISTROS"
30 DISPLAY "------------------------"
31 IF WS-PEGA-ERRO = "00"
32 PERFORM FOREVER
33 DISPLAY X"0D"
34 DISPLAY "Qual registro: " WITH NO ADVANCING
35 ACCEPT TB-NUM-REG
36 START FD-VIRTUAL KEY IS = TB-NUM-REG
37 INVALID KEY
38 DISPLAY X"0D"
39 DISPLAY "Registro inexistente."
40 DISPLAY X"0D"
41 PERFORM 900-MENSAGEM
42 NOT INVALID KEY
43 READ FD-VIRTUAL INTO TB-CADFUN
44 DISPLAY X"0D"
45 DISPLAY "Codigo ........: " TB-CODFUN
46 DISPLAY "Nome ..........: " TB-NOME
47 DISPLAY "Departamento ..: " TB-DEPTO
48 DISPLAY "Funcao ........: " TB-FUNCAO
49 DISPLAY "Salario .......: " TB-SALARIO
50 DISPLAY X"0D"
51 DISPLAY "Remover registro? (S/N): "
52 WITH NO ADVANCING
53 ACCEPT WS-RESP
54 IF UPPER-CASE(WS-RESP) = "S"
55 DELETE FD-VIRTUAL RECORD
56 DISPLAY X"0D"
57 DISPLAY "Registro removido."
58 PERFORM 910-MENSAGEM
59 END-IF
60 DISPLAY X"0D"
61 PERFORM 900-MENSAGEM
62 END-START
63 IF UPPER-CASE(WS-RESP) NOT = "S"
64 EXIT PERFORM
65 END-IF
66 END-PERFORM
67 ELSE
68 CALL "MENSGERR" USING WS-PEGA-ERRO
69 END-IF.
70 CLOSE FD-VIRTUAL.
71 PERFORM 910-MENSAGEM.
72 STOP RUN.
73 900-MENSAGEM SECTION.
74 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
75 DISPLAY "- qualquer outra letra para NAO: "
76 WITH NO ADVANCING.
77 ACCEPT WS-RESP.
------ ------------------------------------------------------------------------
282 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
78 EXIT.
79 910-MENSAGEM SECTION.
80 DISPLAY X"0D".
81 DISPLAY "Tecle <ENTER> para prosseguir... "
82 WITH NO ADVANCING.
83 ACCEPT WS-ENTER.
84 EXIT.
85 END PROGRAM CAP07AP16.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe o registro desejado e confirme ou não sua remoção, teste todas as possibilidades
do programa. Observe que após remover um registro este não é mais acessível, mesmo não sendo removido fisicamen-
te do arquivo.
É importante atentar para o fato de que quando um arquivo relativo é definido como acesso sequencial este precisa ser
previamente lido com o comando READ (linha 43) antes de executar o comando DELETE (linha 55). Caso isso não seja
feito ocorrerá um erro de acesso ao arquivo de código 43 (leitura não realizada antecipadamente).
O arquivo que possui registros removidos logicamente os deixa gravados no arquivo com a indicação de uma marca
que sinaliza que não mais existem. O problema é que o arquivo continua com o registro ocupando espaço em disco.
Uma maneira de mitigar essa ocorrência é fazer um novo cadastro na posição de um registro removido antes de efetuar
a nova entrada de registro ao final do arquivo. Outra alternativa é criar um programa que faça a compactação do arqui-
vo retirando fisicamente os registros removidos e deixando apenas os registros ativos.
O programa a seguir demonstra o uso de dois arquivos no mesmo programa. O primeiro arquivo é o principal e contém
os registros removidos, o segundo arquivo que conterá ao término da execução os registros ativos copiados do primeiro
arquivo. No final da operação o programa apaga o primeiro arquivo e altera o nome do segundo arquivo para que este
assuma o nome do primeiro arquivo. Assim sendo, abra um projeto vazio com o nome cap07ap17 e extensão “.cob” na
subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Atente aos pontos colorizados.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP17 AS "Capitulo 7 – Aplicacao 17".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 *
11 SELECT FD-ARQ1 ASSIGN TO "ARQSEQRL.SEQ" *> EXISTENTE
12 ORGANIZATION IS RELATIVE
13 ACCESS MODE IS SEQUENTIAL
14 RELATIVE KEY IS TB-NUM-REG
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 SELECT FD-ARQ2 ASSIGN TO "COMPACTF.SEQ" *> A SER CRIADO
18 ORGANIZATION IS RELATIVE
19 ACCESS MODE IS SEQUENTIAL.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 283

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
20 *
21 DATA DIVISION.
22 FILE SECTION.
23 *
24 FD FD-ARQ1.
25 01 FS-CADFUN1.
26 05 F001-CODFUN PIC X(09).
27 05 F001-NOME PIC X(40).
28 05 F001-DEPTO PIC 99.
29 05 F001-FUNCAO PIC X(20).
30 05 F001-SALARIO PIC 9(10)V99.
31 *
32 FD FD-ARQ2.
33 01 FS-CADFUN2.
34 05 F002-CODFUN PIC X(09).
35 05 F002-NOME PIC X(40).
36 05 F002-DEPTO PIC 99.
37 05 F002-FUNCAO PIC X(20).
38 05 F002-SALARIO PIC 9(10)V99.
39 *
40 WORKING-STORAGE SECTION.
41 COPY "FSCODERR.CPY".
42 COPY "TBVIRTUAL.CPY".
43 77 WS-PEGA-ERRO PIC XX.
44 77 WS-ENTER PIC X.
45 77 TB-NUM-REG PIC 9(4).
46 77 WS-EOF-FD-ARQ1 PIC X VALUE "F".
47 *
48 PROCEDURE DIVISION.
49 PROG-PRINCIPAL-PARA.
50 OPEN INPUT FD-ARQ1
51 OUTPUT FD-ARQ2.
52 DISPLAY "CADASTRO DE FUNCIONARIOS"
53 DISPLAY "COMPACTACAO DE REGISTROS"
54 DISPLAY "------------------------"
55 IF WS-PEGA-ERRO = "00"
56 PERFORM UNTIL WS-EOF-FD-ARQ1 = "V"
57 ADD 1 TO TB-NUM-REG
58 READ FD-ARQ1 INTO TB-CADFUN
59 AT END
60 MOVE "V" TO WS-EOF-FD-ARQ1
61 NOT AT END
62 WRITE FS-CADFUN2 FROM TB-CADFUN
63 DISPLAY "Registro " TB-NUM-REG " copiado."
64 END-READ
65 END-PERFORM
66 DISPLAY X"0D"
67 DISPLAY "Arquivo compactado."
68 ELSE
69 CALL "MENSGERR" USING WS-PEGA-ERRO
70 END-IF.
71 CLOSE FD-ARQ1 FD-ARQ2.
72 CALL "SYSTEM" USING "DEL ARQSEQRL.SEQ"
------ ------------------------------------------------------------------------
284 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
73 CALL "SYSTEM" USING "REN COMPACTF.SEQ ARQSEQRL.SEQ"
74 DISPLAY X"0D".
75 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
76 ACCEPT WS-ENTER.
77 STOP RUN.
78 END PROGRAM CAP07AP17.
------ ------------------------------------------------------------------------

Ao ser executado o programa é realizada a leitura no primeiro arquivo (FD-ARQ1) com o comando READ na linha 58
agora dinamizado com as cláusulas AT END e NOT AT END. A cada leitura de um registro não removido este é então
escrito com WRITE no segundo arquivo (FD-ARQ2) na linha 62.
A cláusula AT END da linha 59 é executada apenas uma vez quando o ponteiro de posicionamento relativo chega ao
final do arquivo e a cláusula NOT AT END da linha 61 é executada diversas vezes enquanto há registros no arquivo, a
cada execução bem sucedida o programa indica o número de posição do registro do primeiro arquivo ativo copiado
para o segundo arquivo.
A leitura só é processada sobre os registros ativos do arquivo FD-ARQ1, registros removidos logicamente são automa-
ticamente desconsiderados. Note o primeiro arquivo aberto para leitura na linha 50 (INPUT) e o segundo arquivo aberto
para escrita (WRITE) na linha 51. Veja que a cada leitura valida executa pela linha 58 ocorre a gravação dos dados no
segundo arquivo pela linha 62. Neste trecho o programa mostra qual registro foi copiado para o segundo arquivo.
Para detectar o final de um arquivo sequencial em modo sequencial usa-se a verificação do código 10. Mas em arqui-
vos relativos o código 10 não gera efeito o que obriga o uso de outra estratégia. Note a definição da variável de valida-
ção de fim de arquivo WS-EOF-FD-ARQ1 (verifica fim de arquivo do arquivo ARQ1, onde EOF = End Of File) inicializa-
da com valor "F" de falso na linha 46 usada junto ao laço PERFORM UNTIL WS-EOF-FD-ARQ1 = "V" da linha 56. Veja
que o laço será executado até que seu valor seja "V" de verdadeiro. O valor de WS-EOF-FD-ARQ1 muda quando a
cláusula AT END do comando READ for executada. Neste momento o valor de TB-EOF torna-se "V" e o laço é então
encerrado.
Um detalhe neste programa é a abertura e o fechamento de dois arquivos respectivamente com o uso de apenas um
comando OPEN e CLOSE. No modo OPEN atente para indicar antes da abertura do arquivo seu modo de operação.

7.6.4 Arquivo indexado para acesso sequencial


Um arquivo de organização indexada com acesso sequencial é uma forma de organização de registros onde cada re-
gistro é identificado a partir de campos-chave com chave primária ou pela composição de campos como chaves alterna-
tivas podendo-se ter tamanho fixo ou variável. Os campos-chave são um recurso que possibilita identificar exclusiva-
mente um registro e determina a sequência na qual este registro pode ser acessado em relação a outros registros do
arquivo. As chaves alternativas podem ser compostas com dados que sejam repetidos ou não dentro do arquivo, dife-
rentemente da chave primária que não admite dados repetitivos. Neste tipo de arquivo é possível acessar registros
sequencialmente ou diretamente a partir do uso de uma das chaves, desde que a chave de pesquisa seja conhecida.
Este tipo de arquivo é composto de duas partes: os dados contendo os registros em ordem sequencial; e o índice,
sendo uma tabela interna ordenada pela chave primária e a posição relativa do registro junto aos dados. Os registros
em arquivos sequenciais indexados são gravados na ordem ascendente do campo chave. A tabela 7.12 mostra as
operações possíveis de serem realizadas em arquivos sequenciais indexados, sendo estas operações semelhantes as
aplicadas em arquivos sequenciais relativos.
UT ILI ZA ÇÃ O D E A RQ U IV OS 285

Tabela 7.12 – Ações permitidas para arquivo indexado com acesso sequencial

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso sequencial WRITE - X - X
para arquivo START X - X -
indexado REWRITE - - X -
DELETE - - X -

O programa a seguir, se não existir, cria o arquivo sequencial indexado ARQSEQIX.SEQ colocando-o em modo de
extensão para que aceite sempre novos registros ao arquivo. Assim sendo, abra um projeto vazio atribuindo-lhe o nome
cap07ap18 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP18 AS "Capitulo 7 – Aplicacao 18".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIX.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN EXTEND FD-VIRTUAL.
30 IF WS-PEGA-ERRO = "35"
31 OPEN OUTPUT FD-VIRTUAL
32 END-IF
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ENTRADA DE REGISTROS"
35 DISPLAY "------------------------"
36 IF WS-PEGA-ERRO = "00"
37 PERFORM FOREVER
38 DISPLAY X"0D"
------ ------------------------------------------------------------------------
286 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
39 DISPLAY "Codigo ........: " WITH NO ADVANCING
40 ACCEPT TB-CODFUN
41 DISPLAY "Nome ..........: " WITH NO ADVANCING
42 ACCEPT TB-NOME
43 DISPLAY "Departamento ..: " WITH NO ADVANCING
44 ACCEPT TB-DEPTO
45 DISPLAY "Funcao ........: " WITH NO ADVANCING
46 ACCEPT TB-FUNCAO
47 DISPLAY "Salario .......: " WITH NO ADVANCING
48 ACCEPT TB-SALARIO
49 WRITE FS-CADFUN FROM TB-CADFUN
50 INVALID KEY
51 DISPLAY X"0D"
52 DISPLAY " Registro nao cadastrado (existente)."
53 NOT INVALID KEY
54 DISPLAY X"0D"
55 DISPLAY "Registro cadastrado com sucesso."
56 END-WRITE
57 DISPLAY X"0D"
58 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
59 DISPLAY "- qualquer outra letra para NAO: "
60 WITH NO ADVANCING
61 ACCEPT WS-RESP
62 IF UPPER-CASE(WS-RESP) NOT = "S"
63 EXIT PERFORM
64 END-IF
65 END-PERFORM
66 ELSE
67 CALL "MENSGERR" USING WS-PEGA-ERRO
68 END-IF.
69 CLOSE FD-VIRTUAL.
70 DISPLAY X"0D".
71 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
72 ACCEPT WS-ENTER.
73 STOP RUN.
74 END PROGRAM CAP07AP18.
------ ------------------------------------------------------------------------

Ao ser executado o programa entre alguns registros fora da ordem de definição dos códigos de funcionários. Observe o
uso da cláusula RECORD KEY IS junto ao comando SELECT na linha 13 como referência de acesso ao campo de
chave primária F001-CODFUN na definição do arquivo FD-VIRTUAL.
Arquivos sequenciais indexados por gravarem seus dados na forma de bits podem fazer uso do comando WRITE com
nível de controle mais sofisticado que o WRITE usado com arquivos sequenciais lineares, de registro ou relativos. Neste
sentido, é possível fazer das cláusulas INVALID KEY (linha 50) e NOT INVALID KEY (linha 53) detectando se o regis-
tro existe ou não no arquivo. Não é possível com o comando WRITE controlar a apresentação dos dados já gravados e
direcionar os que serão gravados, pois o conjunto de dados do registro precisa estar carregado na estrutura de dados
antes da gravação. Observe atentamente as linhas 51, 52, 54 e 55, as quais indicam a realização ou não da operação
de gravação.
Como apresentado o próximo programa tem por finalidade efetuar a consulta de registros no arquivo. Mas este progra-
ma efetua a pesquisa baseado na informação do campo chave. Assim sendo, abra um projeto vazio atribuindo-lhe o
nome cap07ap19 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.
UT ILI ZA ÇÃ O D E A RQ U IV OS 287

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP19 AS "Capitulo 7 – Aplicacao 19".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIX.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL.
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "CONSULTA POR CODIGO"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual codigo: " WITH NO ADVANCING
38 ACCEPT TB-CHV-CODFUN
39 MOVE TB-CHV-CODFUN TO F001-CODFUN
40 START FD-VIRTUAL KEY IS = F001-CODFUN
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
46 NOT INVALID KEY
47 READ FD-VIRTUAL INTO TB-CADFUN
48 DISPLAY X"0D"
49 DISPLAY "Codigo ........: " TB-CODFUN
50 DISPLAY "Nome ..........: " TB-NOME
51 DISPLAY "Departamento ..: " TB-DEPTO
52 DISPLAY "Funcao ........: " TB-FUNCAO
53 DISPLAY "Salario .......: " TB-SALARIO
------ ------------------------------------------------------------------------
288 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 DISPLAY X"0D"
55 PERFORM 900-MENSAGEM
56 END-START
57 IF UPPER-CASE(WS-RESP) NOT = "S"
58 EXIT PERFORM
59 END-IF
60 END-PERFORM
61 ELSE
62 CALL "MENSGERR" USING WS-PEGA-ERRO
63 END-IF.
64 CLOSE FD-VIRTUAL.
65 DISPLAY X"0D".
66 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
67 ACCEPT WS-ENTER.
68 STOP RUN.
69 900-MENSAGEM SECTION.
70 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
71 DISPLAY "- qualquer outra letra para NAO: "
72 WITH NO ADVANCING.
73 ACCEPT WS-RESP.
74 EXIT.
75 END PROGRAM CAP07AP19.
------ ------------------------------------------------------------------------

Ao ser executado o programa entre os valores dos códigos de funcionário para realizar as pesquisas. Este programa
utiliza recursos já conhecidos, servindo como ponto de ampliação do conhecimento apresentado.
Cabe aqui acrescentar mais uns detalhes ao uso do comando START. Este comando pode ser usado, como demons-
trado, em arquivos de acesso sequencial que estejam organizados de forma indexada. Para seu uso o arquivo deve
estar aberto nos modos INPUT ou I-O. Se a cláusula KEY for omitida o comando START assume como padrão uma
relação de igualdade como KEY IS EQUAL.
O próximo programa ter por finalidade apresentar uma listagem em tela de todos os funcionários cadastrados no arqui-
vo. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap20 e extensão “.cob” na subpasta COBOL da
pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP20 AS "Capitulo 7 – Aplicacao 20".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIX.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 289

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 77 WS-EOF-FD-VIRTUAL PIC X VALUE "F".
28 *
29 PROCEDURE DIVISION.
30 PROG-PRINCIPAL-PARA.
31 OPEN INPUT FD-VIRTUAL.
32 DISPLAY "CADASTRO DE FUNCIONARIOS"
33 DISPLAY "LISTAGEM DE REGISTROS"
34 DISPLAY "------------------------"
35 DISPLAY X"0D".
36 IF WS-PEGA-ERRO = "00"
37 PERFORM UNTIL WS-EOF-FD-VIRTUAL = "V"
38 READ FD-VIRTUAL INTO TB-CADFUN
39 AT END
40 MOVE "V" TO WS-EOF-FD-VIRTUAL
41 NOT AT END
42 DISPLAY TB-CODFUN " - " TB-NOME " - " TB-DEPTO
43 END-READ
44 END-PERFORM
45 ELSE
46 CALL "MENSGERR" USING WS-PEGA-ERRO
47 END-IF.
48 CLOSE FD-VIRTUAL.
49 DISPLAY X"0D".
50 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
51 ACCEPT WS-ENTER.
52 STOP RUN.
53 900-MENSAGEM SECTION.
54 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
55 DISPLAY "- qualquer outra letra para NAO: "
56 WITH NO ADVANCING.
57 ACCEPT WS-RESP.
58 EXIT.
59 END PROGRAM CAP07AP20.
------ ------------------------------------------------------------------------

Execute o programa e veja a listagem apresentada contendo o código do funcionário, seu nome e departamento a que
pertence. Note que o laço PERFORM UNTIL WS-EOF-FD-VIRTUAL = "V" definido entre as linhas 37 e 44 efetua a
execução do arquivo até o final ser detectado pela cláusula AT END (linha 39) do comando READ definido na linha 40.
290 PRO G RA MA Ç ÃO CO B OL

O próximo programa estabelece a operação de atualização de registro permitindo reescrever registros pesquisados por
meio de chave primária em arquivo indexado. Assim sendo, abra um projeto vazio com o nome cap07ap21 e extensão
“.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP21 AS "Capitulo 7 – Aplicacao 21".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIX.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL.
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "ATUALIZACAO POR REGISTRO"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual codigo: " WITH NO ADVANCING
38 ACCEPT TB-CHV-CODFUN
39 MOVE TB-CHV-CODFUN TO F001-CODFUN
40 START FD-VIRTUAL KEY IS = F001-CODFUN
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
46 NOT INVALID KEY
47 READ FD-VIRTUAL INTO TB-CADFUN
48 DISPLAY X"0D"
49 DISPLAY "Codigo ........: " TB-CODFUN
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 291

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
50 DISPLAY "Nome ..........: " TB-NOME
51 DISPLAY "Departamento ..: " TB-DEPTO
52 DISPLAY "Funcao ........: " TB-FUNCAO
53 DISPLAY "Salario .......: " TB-SALARIO
54 DISPLAY X"0D"
55 DISPLAY "Alterar registro? (S/N): "
56 WITH NO ADVANCING
57 ACCEPT WS-RESP
58 IF UPPER-CASE(WS-RESP) = "S"
59 DISPLAY X"0D"
60 DISPLAY "Entre os novos dados:"
61 DISPLAY X"0D"
62 DISPLAY "Codigo ........: " TB-CODFUN
63 DISPLAY "Nome ..........: " WITH NO ADVANCING
64 ACCEPT TB-NOME
65 DISPLAY "Departamento ..: " WITH NO ADVANCING
66 ACCEPT TB-DEPTO
67 DISPLAY "Funcao ........: " WITH NO ADVANCING
68 ACCEPT TB-FUNCAO
69 DISPLAY "Salario .......: " WITH NO ADVANCING
70 ACCEPT TB-SALARIO
71 REWRITE FS-CADFUN FROM TB-CADFUN
72 DISPLAY X"0D"
73 DISPLAY "Registro alterado."
74 DISPLAY X"0D"
75 DISPLAY "Tecle <ENTER> para prosseguir... "
76 WITH NO ADVANCING
77 ACCEPT WS-ENTER
78 END-IF
79 DISPLAY X"0D"
80 PERFORM 900-MENSAGEM
81 END-START
82 IF UPPER-CASE(WS-RESP) NOT = "S"
83 EXIT PERFORM
84 END-IF
85 END-PERFORM
86 ELSE
87 CALL "MENSGERR" USING WS-PEGA-ERRO
88 END-IF.
89 CLOSE FD-VIRTUAL.
90 DISPLAY X"0D".
91 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
92 ACCEPT WS-ENTER.
93 STOP RUN.
94 900-MENSAGEM SECTION.
95 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
96 DISPLAY "- qualquer outra letra para NAO: "
97 WITH NO ADVANCING.
98 ACCEPT WS-RESP.
99 EXIT.
100 END PROGRAM CAP07AP21.
------ ------------------------------------------------------------------------
292 PRO G RA MA Ç ÃO CO B OL

Ao ser executado o programa informe o registro desejado e confirme ou não sua alteração, teste todas as possibilida-
des do programa.
Os registros de um arquivo sequencial indexado podem ser removidos logicamente. Como é sabido a remoção lógica
não apaga fisicamente o registro do arquivo apenas marca este registro como removido. Assim sendo, abra um projeto
vazio com o nome cap07ap22 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções
seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP22 AS "Capitulo 7 – Aplicacao 22".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIX.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL.
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "REMOCAO DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual codigo: " WITH NO ADVANCING
38 ACCEPT TB-CHV-CODFUN
39 MOVE TB-CHV-CODFUN TO F001-CODFUN
40 START FD-VIRTUAL KEY IS = F001-CODFUN
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 293

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
46 NOT INVALID KEY
47 READ FD-VIRTUAL INTO TB-VIRTUAL
48 DISPLAY X"0D"
49 DISPLAY "Codigo ........: " TB-CODFUN
50 DISPLAY "Nome ..........: " TB-NOME
51 DISPLAY "Departamento ..: " TB-DEPTO
52 DISPLAY "Funcao ........: " TB-FUNCAO
53 DISPLAY "Salario .......: " TB-SALARIO
54 DISPLAY X"0D"
55 DISPLAY "Remover registro? (S/N): "
56 WITH NO ADVANCING
57 ACCEPT WS-RESP
58 IF UPPER-CASE(WS-RESP) = "S"
59 DELETE FD-VIRTUAL RECORD
60 NOT INVALID KEY
61 DISPLAY X"0D"
62 DISPLAY "Registro removido."
63 END-DELETE
64 PERFORM 910-MENSAGEM
65 END-IF
66 DISPLAY X"0D"
67 PERFORM 900-MENSAGEM
68 END-START
69 IF UPPER-CASE(WS-RESP) NOT = "S"
70 EXIT PERFORM
71 END-IF
72 END-PERFORM
73 ELSE
74 CALL "MENSGERR" USING WS-PEGA-ERRO
75 END-IF.
76 CLOSE FD-VIRTUAL.
77 DISPLAY X"0D".
78 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
79 ACCEPT WS-ENTER.
80 STOP RUN.
81 900-MENSAGEM SECTION.
82 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
83 DISPLAY "- qualquer outra letra para NAO: "
84 WITH NO ADVANCING.
85 ACCEPT WS-RESP.
86 EXIT.
87 910-MENSAGEM SECTION.
88 DISPLAY X"0D".
89 DISPLAY "Tecle <ENTER> para prosseguir... "
90 WITH NO ADVANCING.
91 ACCEPT WS-ENTER.
92 EXIT.
93 END PROGRAM CAP07AP22.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe o código do funcionário e desejando removê-lo confirme. O programa para remo-
ção de registros cap07ap22.cob para arquivo sequencial indexado e semelhante ao programa com a mesma finalidade
apresentado para arquivo sequencial relativo, executando ação e comportamento similares.
294 PRO G RA MA Ç ÃO CO B OL

Veja que neste programa está sendo utilizada a cláusula NOT INVALID KEY do comando DELETE na linha 60 para
detectar se a chave primária em uso é válida (chave não inválida) e sendo o registro é então removido do arquivo.
Uma das possibilidades com arquivos sequenciais indexados é o uso de chaves alternativas. Podem ser definidas di-
versas chaves alternativas, assim como pode ser feito com chaves primárias. As chaves alternativas podem ser configu-
radas com ou sem repetição de dados. Chaves alternativas sem repetição de dados podem ser adequadas para uso
como chaves secundárias e com repetições de dados são adequadas para composição de chaves complementares.
Por exemplo, o CPF é, por sua natureza, uma chave primária, mas o RG de uma pessoa é uma chave alternativa com
repetições, pois poderá existir mais de um número em mais de um Estado da Federação.
Quando se usa a definição de chave alternativa um segundo arquivo é criado automaticamente junto do arquivo se-
quencial, este arquivo possui o mesmo nome do arquivo principal acrescido de uma extensão suplementar com o indi-
cativo “.1”. Se mais de uma chave alternativa for estabelecida as extensões complementares serão definidas com ex-
tensões “.2”, “.3” e assim por diante.
O programa seguinte demonstra o uso da chave primária como código de identificação do cliente e como chave alterna-
tiva que aceite repetição o nome do cliente junto ao arquivo ARQSEQIA.SEQ. Assim sendo, abra um projeto vazio com
o nome cap07ap23 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP23 AS "Capitulo 7 – Aplicacao 23".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIA.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 ALTERNATE KEY IS F001-NOME WITH DUPLICATES
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 *
21 WORKING-STORAGE SECTION.
22 COPY "FSCODERR.CPY".
23 COPY "TBVIRTUAL.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 77 WS-ENTER PIC X.
26 77 WS-RESP PIC A VALUE "S".
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN EXTEND FD-VIRTUAL.
31 IF WS-PEGA-ERRO = "35"
32 OPEN OUTPUT FD-VIRTUAL
33 END-IF
34 DISPLAY "CADASTRO DE FUNCIONARIOS"
35 DISPLAY "CHV PRIMARIA/ALTERNATIVA"
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 295

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
36 DISPLAY "------------------------"
37 IF WS-PEGA-ERRO = "00"
38 PERFORM FOREVER
39 DISPLAY X"0D"
40 DISPLAY "Codigo ........: " WITH NO ADVANCING
41 ACCEPT TB-CODFUN
42 DISPLAY "Nome ..........: " WITH NO ADVANCING
43 ACCEPT TB-NOME
44 DISPLAY "Departamento ..: " WITH NO ADVANCING
45 ACCEPT TB-DEPTO
46 DISPLAY "Funcao ........: " WITH NO ADVANCING
47 ACCEPT TB-FUNCAO
48 DISPLAY "Salario .......: " WITH NO ADVANCING
49 ACCEPT TB-SALARIO
50 WRITE FS-CADFUN FROM TB-CADFUN
51 INVALID KEY
52 DISPLAY X"0D"
53 DISPLAY "Registro nao cadastrado (existente)."
54 NOT INVALID KEY
55 DISPLAY X"0D"
56 DISPLAY "Registro cadastrado com sucesso."
57 END-WRITE
58 DISPLAY X"0D"
59 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
60 DISPLAY "- qualquer outra letra para NAO: "
61 WITH NO ADVANCING
62 ACCEPT WS-RESP
63 IF UPPER-CASE(WS-RESP) NOT = "S"
64 EXIT PERFORM
65 END-IF
66 END-PERFORM
67 ELSE
68 CALL "MENSGERR" USING WS-PEGA-ERRO
69 END-IF.
70 CLOSE FD-VIRTUAL.
71 DISPLAY X"0D".
72 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
73 ACCEPT WS-ENTER.
74 STOP RUN.
75 END PROGRAM CAP07AP23.
------ ------------------------------------------------------------------------

Observe que exceto a definição do campo F001-NOME na linha 14 como chave alternativa o restante do programa é
semelhante ao que já foi exposto. Execute o programa e entre alguns registros. Efetue a entrada de nomes que sejam
repetidos.
Considere um programa que lhe ofereça a possibilidade de efetuar pesquisas por meio do código ou nome do funcioná-
rio. O código é a chave primária e não pode em hipótese alguma possuir campos repetitivos, mas nomes podem existir
mais de um igual. Neste sentido, o programa quando efetuar a pesquisa por código deve apresentar apenas o registro
referente ao código informado, mas se a pesquisa for executada por nome o programa deve mostrar todos os registros
que sejam idênticos ao nome informado.
296 PRO G RA MA Ç ÃO CO B OL

O programa a seguir a partir da definição de chave alternativa demonstra uso de ações de pesquisa com chave primária
e chave alternativa. Assim sendo, abra um projeto vazio com o nome cap07ap24 e extensão “.cob” na subpasta CO-
BOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP24 AS "Capitulo 7 – Aplicacao 24".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIA.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS F001-CODFUN
14 ALTERNATE KEY IS F001-NOME WITH DUPLICATES
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 *
21 WORKING-STORAGE SECTION.
22 COPY "FSCODERR.CPY".
23 COPY "TBVIRTUAL.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 77 WS-ENTER PIC X.
26 77 WS-RESP PIC A VALUE "S".
27 77 WS-OPCAO PIC 9 VALUE ZERO.
28 77 TB-CHV-CODFUN PIC X(09).
29 77 TB-CHV-NOME PIC X(40).
30 *
31 PROCEDURE DIVISION.
32 PROG-PRINCIPAL-PARA.
33 OPEN INPUT FD-VIRTUAL.
34 DISPLAY "CADASTRO DE FUNCIONARIOS"
35 DISPLAY "CONSULTA COM CHAVES"
36 DISPLAY "------------------------"
37 IF WS-PEGA-ERRO = "00"
38 PERFORM FOREVER
39 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 2
40 DISPLAY X"0D"
41 DISPLAY "Escolha a forma de pesquisa:"
42 DISPLAY X"0D"
43 DISPLAY "1 - Codigo do cliente"
44 DISPLAY "2 - Nome do cliente"
45 DISPLAY X"0D"
46 DISPLAY "==> " WITH NO ADVANCING
47 ACCEPT WS-OPCAO
48 END-PERFORM
49 DISPLAY X"0D"
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 297

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
50 IF WS-OPCAO = 1
51 DISPLAY "Qual codigo: " WITH NO ADVANCING
52 ACCEPT TB-CHV-CODFUN
53 MOVE TB-CHV-CODFUN TO F001-CODFUN
54 START FD-VIRTUAL KEY IS = F001-CODFUN
55 INVALID KEY
56 DISPLAY X"0D"
57 DISPLAY "Registro inexistente."
58 DISPLAY X"0D"
59 PERFORM 900-MENSAGEM
60 NOT INVALID KEY
61 READ FD-VIRTUAL INTO TB-CADFUN
62 PERFORM 100-SAIDA
63 PERFORM 900-MENSAGEM
64 END-START
65 ELSE
66 DISPLAY "Qual nome: " WITH NO ADVANCING
67 ACCEPT TB-CHV-NOME
68 MOVE TB-CHV-NOME TO F001-NOME
69 START FD-VIRTUAL KEY IS = F001-NOME
70 INVALID KEY
71 DISPLAY X"0D"
72 DISPLAY "Registro inexistente."
73 DISPLAY X"0D"
74 PERFORM 900-MENSAGEM
75 NOT INVALID KEY
76 PERFORM FOREVER
77 READ FD-VIRTUAL INTO TB-CADFUN
78 AT END
79 EXIT PERFORM
80 NOT AT END
81 IF TB-CHV-NOME = F001-NOME
82 PERFORM 100-SAIDA
83 END-IF
84 END-READ
85 END-PERFORM
86 PERFORM 900-MENSAGEM
87 END-START
88 END-IF
89 MOVE 0 TO WS-OPCAO
90 IF UPPER-CASE(WS-RESP) NOT = "S"
91 EXIT PERFORM
92 END-IF
93 END-PERFORM
94 ELSE
95 CALL "MENSGERR" USING WS-PEGA-ERRO
96 END-IF.
97 CLOSE FD-VIRTUAL.
98 DISPLAY X"0D".
99 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
100 ACCEPT WS-ENTER.
101 STOP RUN.
------ ------------------------------------------------------------------------
298 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
102 100-SAIDA SECTION.
103 DISPLAY X"0D".
104 DISPLAY "Codigo ........: " TB-CODFUN.
105 DISPLAY "Nome ..........: " TB-NOME.
106 DISPLAY "Departamento ..: " TB-DEPTO.
107 DISPLAY "Funcao ........: " TB-FUNCAO.
108 DISPLAY "Salario .......: " TB-SALARIO.
109 DISPLAY X"0D".
110 EXIT.
111 900-MENSAGEM SECTION.
112 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
113 DISPLAY "- qualquer outra letra para NAO: "
114 WITH NO ADVANCING.
115 ACCEPT WS-RESP.
116 EXIT.
117 END PROGRAM CAP07AP24.
------ ------------------------------------------------------------------------

Ao ser executado o programa é apresentado um pequeno menu onde pode-se escolher se a busca será pelo código ou
pelo nome. A escolha da opção do valor atribuído a variável WS-OPCAO definida na linha 29 é usada no direcionamen-
to do tipo de pesquisa a ser realizada. Assim que qualquer uma das pesquisas é efetivada a variável tem seu conteúdo
zerado para voltar ao menu em condições de uma nova seleção de opção.
Em relação a busca por código não há grande diferença daquilo que já foi usado e apresentado. A diferença maior está
a partir do ponto em que o programa solicita a entrada do nome com a instrução DISPLAY "Qual nome: " WITH NO
ADVANCING a partir da linha 66.
Após a entrada do nome na variável TB-CHV-NOME (LINHA 67) o comando START da linha 69 faz a busca do registro
pelo campo alternativo e encontrando o registro abre um laço PERFORM FOREVER da linha 76 que executa o coman-
do READ da linha 77 com uso das cláusulas AT END e NOT AT END.
A cláusula AT END da linha 78 com a instrução EXIT PERFORM ocorre quando a leitura dos registros do arquivo che-
gar no final do arquivo, lembrando que essa ação é controlada pelo laço PERFORM FOREVER que a antecede. A cada
leitura de registro realizada a instrução IF TB-CHV-NOME = F002-NOME verifica se a chave fornecida TB-CHV-NOME
é igual ao campo de chave alternativa F001-NOME que sendo faz a chamada da sub-rotina PERFORM 100-SAIDA.
O programa anterior faz uso apenas de duas chaves, uma primária e outra alternativa, mas é possível trabalhar com
diversas chaves e isso pode tornar as coisas difíceis de se administrar. Uma técnica que pode ser adotada é descrever
na definição de arquivo (FD) quais são chaves a primária e alternativa com nomes elucidativos. Assim sendo, abra um
projeto vazio com o nome cap07ap25 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as
instruções seguintes e observe os pontos colorizados no programa.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP25 AS "Capitulo 7 – Aplicacao 25".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 299

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIA.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS CHV-PRIMAR
14 ALTERNATE KEY IS CHV-ALTERN WITH DUPLICATES
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 FD FD-VIRTUAL.
20 01 FS-CADFUN.
21 05 CHV-PRIMAR.
22 10 F001-CODFUN PIC X(09).
23 05 CHV-ALTERN.
24 10 F001-NOME PIC X(40).
25 05 F001-DEPTO PIC 99.
26 05 F001-FUNCAO PIC X(20).
27 05 F001-SALARIO PIC 9(10)V99.
28 *
29 WORKING-STORAGE SECTION.
30 COPY "FSCODERR.CPY".
31 COPY "TBVIRTUAL.CPY".
32 77 WS-PEGA-ERRO PIC XX.
33 77 WS-ENTER PIC X.
34 77 WS-RESP PIC A VALUE "S".
35 77 WS-OPCAO PIC 9 VALUE ZERO.
36 77 TB-CHV-CODFUN PIC X(09).
37 77 TB-CHV-NOME PIC X(40).
38 *
39 PROCEDURE DIVISION.
40 PROG-PRINCIPAL-PARA.
41 OPEN INPUT FD-VIRTUAL.
42 DISPLAY "CADASTRO DE FUNCIONARIOS"
43 DISPLAY "CHAVES DESCRITAS"
44 DISPLAY "------------------------"
45 IF WS-PEGA-ERRO = "00"
46 PERFORM FOREVER
47 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 2
48 DISPLAY X"0D"
49 DISPLAY "Escolha a forma de pesquisa:"
50 DISPLAY X"0D"
51 DISPLAY "1 - Codigo do cliente"
52 DISPLAY "2 - Nome do cliente"
53 DISPLAY X"0D"
54 DISPLAY "==> " WITH NO ADVANCING
55 ACCEPT WS-OPCAO
56 END-PERFORM
57 DISPLAY X"0D"
58 IF WS-OPCAO = 1
59 DISPLAY "Qual codigo: " WITH NO ADVANCING
60 ACCEPT TB-CHV-CODFUN
------ ------------------------------------------------------------------------
300 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
61 MOVE TB-CHV-CODFUN TO CHV-PRIMAR
62 START FD-VIRTUAL KEY IS = CHV-PRIMAR
63 INVALID KEY
64 DISPLAY X"0D"
65 DISPLAY "Registro inexistente."
66 DISPLAY X"0D"
67 PERFORM 900-MENSAGEM
68 NOT INVALID KEY
69 READ FD-VIRTUAL INTO TB-VIRTUAL
70 PERFORM 100-SAIDA
71 PERFORM 900-MENSAGEM
72 END-START
73 ELSE
74 DISPLAY "Qual nome: " WITH NO ADVANCING
75 ACCEPT TB-CHV-NOME
76 MOVE TB-CHV-NOME TO CHV-ALTERN
77 START FD-VIRTUAL KEY IS = CHV-ALTERN
78 INVALID KEY
79 DISPLAY X"0D"
80 DISPLAY "Registro inexistente."
81 DISPLAY X"0D"
82 PERFORM 900-MENSAGEM
83 NOT INVALID KEY
84 PERFORM FOREVER
85 READ FD-VIRTUAL INTO TB-CADFUN
86 AT END
87 EXIT PERFORM
88 NOT AT END
89 IF TB-CHV-NOME = CHV-ALTERN
90 PERFORM 100-SAIDA
91 END-IF
92 END-READ
93 END-PERFORM
94 PERFORM 900-MENSAGEM
95 END-START
96 END-IF
97 MOVE 0 TO WS-OPCAO
98 IF UPPER-CASE(WS-RESP) NOT = "S"
99 EXIT PERFORM
100 END-IF
101 END-PERFORM
102 ELSE
103 CALL "MENSGERR" USING WS-PEGA-ERRO
104 END-IF.
105 CLOSE FD-VIRTUAL.
106 DISPLAY X"0D".
107 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
108 ACCEPT WS-ENTER.
109 STOP RUN.
110 100-SAIDA SECTION.
111 DISPLAY X"0D".
112 DISPLAY "Codigo ........: " TB-CODFUN.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 301

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
113 DISPLAY "Nome ..........: " TB-NOME.
114 DISPLAY "Departamento ..: " TB-DEPTO.
115 DISPLAY "Funcao ........: " TB-FUNCAO.
116 DISPLAY "Salario .......: " TB-SALARIO.
117 DISPLAY X"0D".
118 EXIT.
119 900-MENSAGEM SECTION.
120 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
121 DISPLAY "- qualquer outra letra para NAO: "
122 WITH NO ADVANCING.
123 ACCEPT WS-RESP.
124 EXIT.
125 END PROGRAM CAP07AP25.
------ ------------------------------------------------------------------------

Observe que o programa cap07ap25.cob é idêntico ao programa cap07ap24.cob tendo como diferença a maneira pela
qual se faz referência as definições de chaves primária e alternativa. As chaves alternativas podem ser declaradas com
e sem WITH DUPLICATES. Quando usadas a cláusula WITH DUPLICATES o que se tem são chaves duplicadas.
No uso de chaves é possível ter em um arquivo uma chave primária e várias chaves alternativas. A chave primária pode
ser configurada com mais de um campo formando o que se chama de chave composta. Por exemplo, imagine em um
cadastro de funcionários, além do campo de código de identificação normal, usar também o número do CPF. Neste
caso, a estrutura do arquivo seria definida a partir de:

FILE-CONTROL.
SELECT FD-VIRTUAL ASSIGN TO "ARQSEQIA.SEQ"
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS CHV-PRIMAR
ALTERNATE KEY IS F003-NOME WITH DUPLICATES
FILE STATUS IS WS-PEGA-ERRO.

DATA DIVISION.
FILE SECTION.
FD FD-VIRTUAL.
01 FS-CADFUN.
05 CHV-PRIMAR.
10 F001-CODFUN PIC X(09).
10 F001-CPF PIC X(14).
05 F001-NOME PIC X(40).
05 F001-DEPTO PIC 99.
05 F001-FUNCAO PIC X(20).
05 F001-SALARIO PIC 9(10)V99.

No uso do programa a partir da estrutura de dados proposta a entrada é realizada nos campos chave de forma separa-
da, ou seja, faz-se referência a entrada do código do funcionário (F001-CODFUN) e CPF (F001-CPF) separadamente.
Nas operações de pesquisa usa-se o campo chave nomeado CHV-PRIMAR que dará acesso conjunto a chave com-
posta.
Como exemplo considere um programa simples que apresente um menu contendo duas opções: cadastro e consulta. O
programa deve fazer uso de chave composta para realizar as pesquisas dentro do arquivo ARQSEQCP.SEQ. Assim
sendo, abra um projeto vazio com o nome cap07ap26 e extensão “.cob” na subpasta COBOL da pasta Documentos e
codifique as instruções seguintes e observe os pontos colorizados no programa.
302 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP26 AS "Capitulo 7 – Aplicacao 26".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQSEQCP.SEQ"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS SEQUENTIAL
13 RECORD KEY IS CHV-PRIMAR
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 FD FD-VIRTUAL.
19 01 FS-CADFUN.
20 05 CHV-PRIMAR.
21 10 F001-CODFUN PIC X(09).
22 10 F001-CPF PIC X(14).
23 05 F001-NOME PIC X(40).
24 05 F001-DEPTO PIC 99.
25 05 F001-FUNCAO PIC X(20).
26 05 F001-SALARIO PIC 9(10)V99.
27 *
28 WORKING-STORAGE SECTION.
29 COPY "FSCODERR.CPY".
30 01 TB-VIRTUAL.
31 05 TB-CADFUN.
32 10 TB-CODFUN PIC X(09).
33 10 TB-CPF PIC X(14).
34 10 TB-NOME PIC X(40).
35 10 TB-DEPTO PIC 99.
36 10 TB-FUNCAO PIC X(20).
37 10 TB-SALARIO PIC 9(10)V99.
38 77 WS-PEGA-ERRO PIC XX.
39 77 WS-ENTER PIC X.
40 77 WS-RESP PIC A VALUE "S".
41 77 WS-OPCAO PIC 9 VALUE ZERO.
42 77 TB-CHV-CODFUN PIC X(09).
43 77 TB-CHV-CPF PIC X(14).
44 *
45 PROCEDURE DIVISION.
46 PROG-PRINCIPAL-PARA.
47 OPEN EXTEND FD-VIRTUAL.
48 IF WS-PEGA-ERRO = "35"
49 OPEN OUTPUT FD-VIRTUAL
50 END-IF
51 IF WS-PEGA-ERRO = "00"
52 CLOSE FD-VIRTUAL
53 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 3
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 303

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 DISPLAY "CADASTRO DE FUNCIONARIOS"
55 DISPLAY "CHAVE COMPOSTA"
56 DISPLAY "------------------------"
57 DISPLAY X"0D"
58 DISPLAY "1 - Cadastro"
59 DISPLAY "2 - Pesquisa"
60 DISPLAY "3 - Finalizar"
61 DISPLAY X"0D"
62 DISPLAY "Opcao ==> " WITH NO ADVANCING
63 ACCEPT WS-OPCAO
64 EVALUATE WS-OPCAO
65 WHEN 1
66 OPEN EXTEND FD-VIRTUAL
67 DISPLAY X"0D"
68 DISPLAY "CADASTRO DE FUNCIONARIOS"
69 DISPLAY "INSERCAO DE REGISTRO"
70 DISPLAY "------------------------"
71 DISPLAY X"0D"
72 DISPLAY "Codigo ........: " WITH NO ADVANCING
73 ACCEPT TB-CODFUN
74 DISPLAY "CPF ...........: " WITH NO ADVANCING
75 ACCEPT TB-CPF
76 DISPLAY "Nome ..........: " WITH NO ADVANCING
77 ACCEPT TB-NOME
78 DISPLAY "Departamento ..: " WITH NO ADVANCING
79 ACCEPT TB-DEPTO
80 DISPLAY "Funcao ........: " WITH NO ADVANCING
81 ACCEPT TB-FUNCAO
82 DISPLAY "Salario .......: " WITH NO ADVANCING
83 ACCEPT TB-SALARIO
84 WRITE FS-CADFUN FROM TB-CADFUN
85 INVALID KEY
86 DISPLAY X"0D"
87 DISPLAY "Registro existente."
88 NOT INVALID KEY
89 DISPLAY X"0D"
90 DISPLAY "Acao realizada com sucesso."
91 END-WRITE
92 PERFORM 900-MENSAGEM
93 WHEN 2
94 OPEN INPUT FD-VIRTUAL
95 DISPLAY X"0D"
96 DISPLAY "CADASTRO DE FUNCIONARIOS"
97 DISPLAY "PESQUISA DE REGISTRO"
98 DISPLAY "------------------------"
99 DISPLAY X"0D"
100 DISPLAY "Codigo ........: " WITH NO ADVANCING
101 ACCEPT TB-CHV-CODFUN
102 DISPLAY "CPF ...........: " WITH NO ADVANCING
103 ACCEPT TB-CHV-CPF
104 MOVE TB-CHV-CODFUN TO F001-CODFUN
105 MOVE TB-CHV-CPF TO F001-CPF
106 START FD-VIRTUAL KEY IS = CHV-PRIMAR
------ ------------------------------------------------------------------------
304 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
107 INVALID KEY
108 DISPLAY X"0D"
109 DISPLAY "Registro inexistente."
110 PERFORM 900-MENSAGEM
111 NOT INVALID KEY
112 READ FD-VIRTUAL INTO TB-CADFUN
113 DISPLAY "Nome ..........: " TB-NOME
114 DISPLAY "Departamento ..: " TB-DEPTO
115 DISPLAY "Funcao ........: " TB-FUNCAO
116 DISPLAY "Salario .......: " TB-SALARIO
117 PERFORM 900-MENSAGEM
118 END-START
119 WHEN 3
120 EXIT PERFORM
121 CLOSE FD-VIRTUAL
122 END-EVALUATE
123 DISPLAY X"0D"
124 MOVE 0 TO WS-OPCAO
125 END-PERFORM
126 ELSE
127 CALL "MENSGERR" USING WS-PEGA-ERRO
128 END-IF.
129 DISPLAY X"0D".
130 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
131 ACCEPT WS-ENTER.
132 STOP RUN.
133 900-MENSAGEM SECTION.
134 CLOSE FD-VIRTUAL.
135 DISPLAY X"0D".
136 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
137 ACCEPT WS-ENTER.
138 EXIT.
139 END PROGRAM CAP07AP26.
------ ------------------------------------------------------------------------

Ao ser executado o programa, o menu é apresentado. Selecione a opção de cadastro e informe os dados solicitados.
Entre alguns registros. Depois efetue as pesquisas desses registros.
Observe o funcionamento do programa e busque uma relação das ações executadas com o código apresentado, veja
que o mesmo arquivo é submetido as operações de escrita e leitura, hora escrevendo e hora lendo registros. Note que
para essas ações serem bem sucedidas é importante o arquivo ser primeiramente fechado para então ser aberto em
um modo diferente do que estava operando.
Atente para cada ponto colorizado, observando as operações de entrada de dados para os registros entre as linhas 72
e 83 e sua gravação no arquivo entre as linhas 84 e 91. Veja nas linhas 101 e 103 a definição das entradas de dados
para as variáveis de apoio TB-CHV-CODFUN e TB-CHV-CPF e como essas variáveis são associadas aos campos que
compõem a chave CHV-PRIMAR quando da execução das instruções MOVE indicadas nas linhas 104 e 105.
Outro detalhe a ser observado é o uso do campo chave CHV-PRIMAR definido na linha 20 englobando de uma única
vez os campos F001-CODFUN (linha 21) e F001-CPF (linha 22). Observe seu uso na linha 106 a partir da execução da
instrução START FD-VIRTUAL KEY IS = CHV-PRIMAR.
UT ILI ZA ÇÃ O D E A RQ U IV OS 305

7.6.5 Arquivo relativo para acesso randômico


Um arquivo de organização relativa com acesso randômico (aleatório ou direto) é uma forma de organização onde cada
registro pode ser acessado por seu valor de posicionamento cardinal de registro. É obrigatório neste tipo de arquivo o
uso da cláusula RELATIVE KEY junto ao comando SELECT. Nas operações de escrita é importante atualizar o valor de
posição do registro do arquivo com uso da instrução ADD 1 TO <chave-relativa> antes da gravação de cada registro
que ocorre de forma sequencial. Para as operações de leitura não se usa o comando START (ação sequencial), o posi-
cionamento do registro é efetivado diretamente com o comando READ a partir da definição de um valor de índice relati-
vo de registro indicado no sentido ordinal junto a variável associada a cláusula RELATIVE KEY. A tabela 7.13 mostra
as operações possíveis de realização em arquivos randômicos relativos.

Tabela 7.13 – Ações permitidas para arquivo relativo com acesso randômico

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso randômico WRITE - X - -
para arquivo START - - - -
relativo REWRITE - - X -
DELETE - - X -

O programa a seguir, se não existir criará um arquivo randômico chamado ARQDINRR.RAN com o modo OUTPUT e se
o arquivo existir este será recriado, portanto atenção no uso de arquivos randômicos relativos. Assim sendo, abra um
projeto vazio atribuindo-lhe o nome cap07ap27 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifi-
que as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP27 AS "Capitulo 7 – Aplicacao 27".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.RAN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS RANDOM
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
------ ------------------------------------------------------------------------
306 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN OUTPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "ENTRADA DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 ADD 1 TO TB-NUM-REG
38 DISPLAY "Registro #: " TB-NUM-REG
39 DISPLAY "Codigo ........: " WITH NO ADVANCING
40 ACCEPT TB-CODFUN
41 DISPLAY "Nome ..........: " WITH NO ADVANCING
42 ACCEPT TB-NOME
43 DISPLAY "Departamento ..: " WITH NO ADVANCING
44 ACCEPT TB-DEPTO
45 DISPLAY "Funcao ........: " WITH NO ADVANCING
46 ACCEPT TB-FUNCAO
47 DISPLAY "Salario .......: " WITH NO ADVANCING
48 ACCEPT TB-SALARIO
49 WRITE FS-CADFUN FROM TB-CADFUN
50 NOT INVALID KEY
51 DISPLAY X"0D"
52 DISPLAY "Registro cadastrado com sucesso."
53 END-WRITE
54 DISPLAY X"0D"
55 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
56 DISPLAY "- qualquer outra letra para NAO: "
57 WITH NO ADVANCING
58 ACCEPT WS-RESP
59 IF UPPER-CASE(WS-RESP) NOT = "S"
60 EXIT PERFORM
61 END-IF
62 END-PERFORM
63 ELSE
64 CALL "MENSGERR" USING WS-PEGA-ERRO
65 END-IF.
66 CLOSE FD-VIRTUAL.
67 DISPLAY X"0D".
68 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
69 ACCEPT WS-ENTER.
70 STOP RUN.
71 END PROGRAM CAP07AP27.
------ ------------------------------------------------------------------------

Ao ser executado este programa e efetivada a entrada de alguns registros não será possível perceber nenhuma dife-
rença em relação a outros programas com ação semelhante já utilizados neste capítulo. Um detalhe importante é o uso
obrigatório da cláusula RELATIVE KEY IS junto ao comando SELECT na linha 13 e sua atualização necessária antes
da realização da escrita do registro no arquivo com a instrução ADD 1 TO TB-NUM-REG na linha 37.
UT ILI ZA ÇÃ O D E A RQ U IV OS 307

Arquivos randômicos com acesso aleatório são arquivos criados sequencialmente e acessados randomicamente. Assim
sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap28 e extensão “.cob” na subpasta COBOL da pasta Do-
cumentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP28 AS "Capitulo 7 – Aplicacao 28".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.RAN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS RANDOM
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "CONSULTA DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual registro: " WITH NO ADVANCING
38 ACCEPT TB-NUM-REG
39 READ FD-VIRTUAL INTO TB-CADFUN
40 INVALID KEY
41 DISPLAY X"0D"
42 DISPLAY "Registro inexistente."
43 DISPLAY X"0D"
44 PERFORM 900-MENSAGEM
45 NOT INVALID KEY
46 DISPLAY X"0D"
47 DISPLAY "Codigo ........: " TB-CODFUN
48 DISPLAY "Nome ..........: " TB-NOME
------ ------------------------------------------------------------------------
308 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
49 DISPLAY "Departamento ..: " TB-DEPTO
50 DISPLAY "Funcao ........: " TB-FUNCAO
51 DISPLAY "Salario .......: " TB-SALARIO
52 DISPLAY X"0D"
53 PERFORM 900-MENSAGEM
54 END-READ
55 IF UPPER-CASE(WS-RESP) NOT = "S"
56 EXIT PERFORM
57 END-IF
58 END-PERFORM
59 ELSE
60 CALL "MENSGERR" USING WS-PEGA-ERRO
61 END-IF.
62 CLOSE FD-VIRTUAL.
63 DISPLAY X"0D".
64 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
65 ACCEPT WS-ENTER.
66 STOP RUN.
67 900-MENSAGEM SECTION.
68 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
69 DISPLAY "- qualquer outra letra para NAO: "
70 WITH NO ADVANCING.
71 ACCEPT WS-RESP.
72 EXIT.
73 END PROGRAM CAP07AP28.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe os valores de posicionamento cardinal de registros. Observe que ao ser estabe-
lecido um valor para a variável TB-NUM-REG o comando READ na linha 39 usa esse valor para fazer a localização
direta do registro no arquivo.
Arquivos randômicos com acesso relativo podem ser abertos no modo de operação I-O para ação de leitura (READ)
com acesso as operações de remoção (DELETE) e atualização de dados (REWRITE). Assim sendo, abra um projeto
vazio atribuindo-lhe o nome cap07ap29 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as
instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP29 AS "Capitulo 7 – Aplicacao 29".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.RAN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS RANDOM
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 309

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 77 WS-OPCAO PIC 9.
28 *
29 PROCEDURE DIVISION.
30 PROG-PRINCIPAL-PARA.
31 OPEN I-O FD-VIRTUAL
32 IF WS-PEGA-ERRO = "00"
33 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 3
34 DISPLAY "CADASTRO DE FUNCIONARIOS"
35 DISPLAY "ADMINISTRAR REGISTROS"
36 DISPLAY "------------------------"
37 DISPLAY X"0D"
38 DISPLAY "1 - Atualizar registro"
39 DISPLAY "2 - Excluir registro"
40 DISPLAY "3 - Finalizar"
41 DISPLAY X"0D"
42 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
43 ACCEPT WS-OPCAO
44 EVALUATE WS-OPCAO
45 WHEN 1
46 PERFORM 100-ENTRADA
47 READ FD-VIRTUAL INTO TB-CADFUN
48 INVALID KEY
49 PERFORM 910-REG-INEXISTENTE
50 PERFORM 900-MENSAGEM
51 NOT INVALID KEY
52 DISPLAY X"0D"
53 PERFORM 200-SAIDA
54 DISPLAY "Entre os novos dados:"
55 DISPLAY X"0D"
56 DISPLAY "Codigo ........: " TB-CODFUN
57 DISPLAY "Nome ..........: "
58 WITH NO ADVANCING
59 ACCEPT TB-NOME
60 DISPLAY "Departamento ..: "
61 WITH NO ADVANCING
62 ACCEPT TB-DEPTO
63 DISPLAY "Funcao ........: "
64 WITH NO ADVANCING
65 ACCEPT TB-FUNCAO
------ ------------------------------------------------------------------------
310 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
66 DISPLAY "Salario .......: "
67 WITH NO ADVANCING
68 ACCEPT TB-SALARIO
69 REWRITE FS-CADFUN FROM TB-CADFUN
70 NOT INVALID KEY
71 DISPLAY X"0D"
72 DISPLAY "Registro atualizado."
73 DISPLAY X"0D"
74 PERFORM 900-MENSAGEM
75 END-REWRITE
76 END-READ
77 WHEN 2
78 PERFORM 100-ENTRADA
79 READ FD-VIRTUAL INTO TB-CADFUN
80 INVALID KEY
81 PERFORM 910-REG-INEXISTENTE
82 PERFORM 900-MENSAGEM
83 NOT INVALID KEY
84 DISPLAY X"0D"
85 PERFORM 200-SAIDA
86 DELETE FD-VIRTUAL RECORD
87 NOT INVALID KEY
88 DISPLAY X"0D"
89 DISPLAY "Registro removido."
90 DISPLAY X"0D"
91 PERFORM 900-MENSAGEM
92 END-DELETE
93 END-READ
94 WHEN 3
95 EXIT PERFORM
96 END-EVALUATE
97 DISPLAY X"0D"
98 MOVE 0 TO WS-OPCAO
99 END-PERFORM
100 ELSE
101 CALL "MENSGERR" USING WS-PEGA-ERRO
102 END-IF.
103 DISPLAY X"0D".
104 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
105 ACCEPT WS-ENTER.
106 CLOSE FD-VIRTUAL
107 STOP RUN.
108 100-ENTRADA SECTION.
109 DISPLAY X"0D".
110 DISPLAY "Qual registro: " WITH NO ADVANCING.
111 ACCEPT TB-NUM-REG.
112 EXIT.
113 200-SAIDA SECTION.
114 DISPLAY "Codigo ........: " TB-CODFUN.
115 DISPLAY "Nome ..........: " TB-NOME.
116 DISPLAY "Departamento ..: " TB-DEPTO.
117 DISPLAY "Funcao ........: " TB-FUNCAO.
118 DISPLAY "Salario .......: " TB-SALARIO.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 311

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
119 EXIT.
120 900-MENSAGEM SECTION.
121 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
122 ACCEPT WS-ENTER.
123 EXIT.
124 910-REG-INEXISTENTE SECTION.
125 DISPLAY X"0D".
126 DISPLAY "Registro inexistente.".
127 DISPLAY X"0D".
128 EXIT.
129 END PROGRAM CAP07AP29.
------ ------------------------------------------------------------------------

Ao ser executado o programa teste as opções de menu, prestando atenção no comportamento das partes. Observe que
no mesmo arquivo são realizadas operações de leitura, remoção e atualização com o uso do modo de operação I-O.
Para a primeira opção é usada apenas a cláusula NOT INVALID KEY do comando REWRITE na linha 69 para indicar
que o registro foi atualizado, uma vez que REWRITE está sendo definido dentro do comando READ que controla e
detecta registros não existentes. O mesmo está sendo realizado com o uso do comando DELETE na linha 86 quando a
segunda opção é escolhida. No entanto, é pertinente salientar que para fazer uso do comando DELETE em arquivos
randômicos com acesso relativo não é necessário fazer antecipadamente a leitura do registro com READ. Para excluir
um registro, basta ter o número cardinal da posição do registro no arquivo e acionar diretamente o comando DELETE.

7.6.6 Arquivo indexado para acesso randômico


Um arquivo de organização indexada com acesso randômico é uma forma de organização onde cada registro pode ser
acessado por seu campo chave de indexação. É obrigatório neste tipo de arquivo o uso da cláusula RECORD KEY
junto ao comando SELECT, podendo-se ainda fazer uso da cláusula ALTERNATE RECORD como demonstrado no
uso de arquivo sequencial indexado. Para as operações de leitura não se usa o comando START (ação sequencial), o
posicionamento do registro é efetivado diretamente com o comando READ a partir da definição de um valor atribuído ao
campo de chave primária. A tabela 7.14 mostra as operações possíveis de realização em arquivos randômicos indexa-
dos.

Tabela 7.14 – Ações permitidas para arquivo randômico com acesso indexado

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso indexado WRITE - X X -
para arquivo START - - - -
randômico REWRITE - - X -
DELETE - - X -

O programa a seguir, se não existir criará um arquivo indexado chamado ARQDINRR.IND com o modo OUTPUT e se o
arquivo existir será aberto no modo I-O. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap30 e exten-
são “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.
312 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP30 AS "Capitulo 7 – Aplicacao 30".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.IND"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS RANDOM
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN I-O FD-VIRTUAL
30 IF WS-PEGA-ERRO = "35"
31 OPEN OUTPUT FD-VIRTUAL
32 END-IF
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ENTRADA DE REGISTROS"
35 DISPLAY "------------------------"
36 IF WS-PEGA-ERRO = "00"
37 PERFORM FOREVER
38 DISPLAY X"0D"
39 DISPLAY "Codigo ........: " WITH NO ADVANCING
40 ACCEPT TB-CODFUN
41 DISPLAY "Nome ..........: " WITH NO ADVANCING
42 ACCEPT TB-NOME
43 DISPLAY "Departamento ..: " WITH NO ADVANCING
44 ACCEPT TB-DEPTO
45 DISPLAY "Funcao ........: " WITH NO ADVANCING
46 ACCEPT TB-FUNCAO
47 DISPLAY "Salario .......: " WITH NO ADVANCING
48 ACCEPT TB-SALARIO
49 WRITE FS-CADFUN FROM TB-CADFUN
50 INVALID KEY
51 DISPLAY X"0D"
52 DISPLAY "Registro existente."
53 NOT INVALID KEY
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 313

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 DISPLAY X"0D"
55 DISPLAY "Registro cadastrado com sucesso."
56 END-WRITE
57 DISPLAY X"0D"
58 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
59 DISPLAY "- qualquer outra letra para NAO: "
60 WITH NO ADVANCING
61 ACCEPT WS-RESP
62 IF UPPER-CASE(WS-RESP) NOT = "S"
63 EXIT PERFORM
64 END-IF
65 END-PERFORM
66 ELSE
67 CALL "MENSGERR" USING WS-PEGA-ERRO
68 END-IF.
69 CLOSE FD-VIRTUAL.
70 DISPLAY X"0D".
71 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
72 ACCEPT WS-ENTER.
73 STOP RUN.
74 END PROGRAM CAP07AP30.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe alguns registros, encerre o programa e volte a fazer alguns novos cadastros.
Observe que arquivos indexados em modo randômico com o uso do modo de operação I-O não necessitam do suporte
do modo EXTEND para acrescentar novos registros no arquivo. Exceto este detalhe o programa possui as mesmas
características de outros códigos similares apresentados anteriormente.
Arquivos randômicos com acesso aleatório são arquivos criados sequencialmente e acessados randomicamente. Assim
sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap31 e extensão “.cob” na subpasta COBOL da pasta Do-
cumentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP31 AS "Capitulo 7 – Aplicacao 31".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.IND"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS RANDOM
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
------ ------------------------------------------------------------------------
314 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "CONSULTA DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual codigo: " WITH NO ADVANCING
38 ACCEPT TB-CHV-CODFUN
39 MOVE TB-CHV-CODFUN TO F001-CODFUN
40 READ FD-VIRTUAL INTO TB-CADFUN
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
46 NOT INVALID KEY
47 DISPLAY X"0D"
48 DISPLAY "Codigo ........: " TB-CODFUN
49 DISPLAY "Nome ..........: " TB-NOME
50 DISPLAY "Departamento ..: " TB-DEPTO
51 DISPLAY "Funcao ........: " TB-FUNCAO
52 DISPLAY "Salario .......: " TB-SALARIO
53 DISPLAY X"0D"
54 PERFORM 900-MENSAGEM
55 END-READ
56 IF UPPER-CASE(WS-RESP) NOT = "S"
57 EXIT PERFORM
58 END-IF
59 END-PERFORM
60 ELSE
61 CALL "MENSGERR" USING WS-PEGA-ERRO
62 END-IF.
63 CLOSE FD-VIRTUAL.
64 DISPLAY X"0D".
65 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
66 ACCEPT WS-ENTER.
67 STOP RUN.
68 900-MENSAGEM SECTION.
69 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 315

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
70 DISPLAY "- qualquer outra letra para NAO: "
71 WITH NO ADVANCING.
72 ACCEPT WS-RESP.
73 EXIT.
74 END PROGRAM CAP07AP31.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe as chaves primárias dos registros a serem pesquisados. Observe que quando se
usa arquivos de acesso randômico a pesquisa no arquivo é realizada diretamente com o uso do comando READ.
O programa a seguir demonstra o uso do modo de operação I-O para ação de leitura (READ) com acesso as operações
de remoção (DELETE) e atualização de dados (REWRITE). Assim sendo, abra um projeto vazio atribuindo-lhe o nome
cap07ap32 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP32 AS "Capitulo 7 – Aplicacao 32".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.IND"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS RANDOM
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-OPCAO PIC 9.
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL
31 IF WS-PEGA-ERRO = "00"
32 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 3
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ADMINISTRAR REGISTROS"
------ ------------------------------------------------------------------------
316 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
35 DISPLAY "------------------------"
36 DISPLAY X"0D"
37 DISPLAY "1 - Atualizar registro"
38 DISPLAY "2 - Excluir registro"
39 DISPLAY "3 - Finalizar"
40 DISPLAY X"0D"
41 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
42 ACCEPT WS-OPCAO
43 EVALUATE WS-OPCAO
44 WHEN 1
45 PERFORM 100-ENTRADA
46 READ FD-VIRTUAL INTO TB-CADFUN
47 INVALID KEY
48 PERFORM 910-REG-INEXISTENTE
49 PERFORM 900-MENSAGEM
50 NOT INVALID KEY
51 DISPLAY X"0D"
52 PERFORM 200-SAIDA
53 DISPLAY "Entre os novos dados:"
54 DISPLAY X"0D"
55 DISPLAY "Codigo ........: " TB-CODFUN
56 DISPLAY "Nome ..........: "
57 WITH NO ADVANCING
58 ACCEPT TB-NOME
59 DISPLAY "Departamento ..: "
60 WITH NO ADVANCING
61 ACCEPT TB-DEPTO
62 DISPLAY "Funcao ........: "
63 WITH NO ADVANCING
64 ACCEPT TB-FUNCAO
65 DISPLAY "Salario .......: "
66 WITH NO ADVANCING
67 ACCEPT TB-SALARIO
68 REWRITE FS-CADFUN FROM TB-CADFUN
69 NOT INVALID KEY
70 DISPLAY X"0D"
71 DISPLAY "Registro atualizado."
72 DISPLAY X"0D"
73 PERFORM 900-MENSAGEM
74 END-REWRITE
75 END-READ
76 WHEN 2
77 PERFORM 100-ENTRADA
78 READ FD-VIRTUAL INTO TB-CADFUN
79 INVALID KEY
80 PERFORM 910-REG-INEXISTENTE
81 PERFORM 900-MENSAGEM
82 NOT INVALID KEY
83 DISPLAY X"0D"
84 PERFORM 200-SAIDA
85 DELETE FD-VIRTUAL RECORD
86 NOT INVALID KEY
87 DISPLAY "Registro removido."
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 317

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
88 DISPLAY X"0D"
89 PERFORM 900-MENSAGEM
90 END-DELETE
91 END-READ
92 WHEN 3
93 EXIT PERFORM
94 END-EVALUATE
95 DISPLAY X"0D"
96 MOVE 0 TO WS-OPCAO
97 END-PERFORM
98 ELSE
99 CALL "MENSGERR" USING WS-PEGA-ERRO
100 END-IF.
101 DISPLAY X"0D".
102 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
103 ACCEPT WS-ENTER.
104 CLOSE FD-VIRTUAL
105 STOP RUN.
106 100-ENTRADA SECTION.
107 DISPLAY X"0D".
108 DISPLAY "Qual codigo: " WITH NO ADVANCING.
109 ACCEPT TB-CHV-CODFUN.
110 MOVE TB-CHV-CODFUN TO F001-CODFUN.
111 EXIT.
112 200-SAIDA SECTION.
113 DISPLAY X"0D".
114 DISPLAY "Codigo ........: " TB-CODFUN.
115 DISPLAY "Nome ..........: " TB-NOME.
116 DISPLAY "Departamento ..: " TB-DEPTO.
117 DISPLAY "Funcao ........: " TB-FUNCAO.
118 DISPLAY "Salario .......: " TB-SALARIO.
119 DISPLAY X"0D".
120 EXIT.
121 900-MENSAGEM SECTION.
122 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
123 ACCEPT WS-ENTER.
124 EXIT.
125 910-REG-INEXISTENTE SECTION.
126 DISPLAY X"0D".
127 DISPLAY "Registro inexistente.".
128 DISPLAY X"0D".
129 EXIT.
130 END PROGRAM CAP07AP32.
------ ------------------------------------------------------------------------

Ao ser executado o programa teste as opções de menu, prestando atenção no comportamento de cada parte do pro-
grama. Observe que comportamento do programa cap07ap32.cob assemelha-se ao programa cap07ap29.cob.

7.6.7 Arquivo relativo para acesso dinâmico


Um arquivo de organização relativa com acesso dinâmico é uma forma de organização onde cada registro pode ser
acessado a partir de sua posição dentro do arquivo ou acessado de forma sequencial. Para as operações de leitura é
318 PRO G RA MA Ç ÃO CO B OL

utilizado como apoio o comando START. A tabela 7.15 mostra as operações possíveis de realização em arquivos dinâ-
micos relativos.

Tabela 7.15 – Ações permitidas para arquivo relativo com acesso dinâmico

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso dinâmico WRITE - X - -
para arquivo START X - X -
relativo REWRITE - - X -
DELETE - - X -

O programa a seguir cria um arquivo randômico chamado ARQDINRR.DYN com o modo OUTPUT. Se o arquivo existir
este será recriado, portanto cuidado no uso deste tipo de arquivo. Na sequência, abra um projeto vazio atribuindo-lhe o
nome cap07ap33 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP33 AS "Capitulo 7 – Aplicacao 33".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.DYN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS DYNAMIC
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN OUTPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "ENTRADA DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 319

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
36 DISPLAY X"0D"
37 ADD 1 TO TB-NUM-REG
38 DISPLAY "Registro #: " TB-NUM-REG
39 DISPLAY "Codigo ........: " WITH NO ADVANCING
40 ACCEPT TB-CODFUN
41 DISPLAY "Nome ..........: " WITH NO ADVANCING
42 ACCEPT TB-NOME
43 DISPLAY "Departamento ..: " WITH NO ADVANCING
44 ACCEPT TB-DEPTO
45 DISPLAY "Funcao ........: " WITH NO ADVANCING
46 ACCEPT TB-FUNCAO
47 DISPLAY "Salario .......: " WITH NO ADVANCING
48 ACCEPT TB-SALARIO
49 WRITE FS-CADFUN FROM TB-CADFUN
50 NOT INVALID KEY
51 DISPLAY X"0D"
52 DISPLAY "Registro cadastrado com sucesso."
53 END-WRITE
54 DISPLAY X"0D"
55 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
56 DISPLAY "- qualquer outra letra para NAO: "
57 WITH NO ADVANCING
58 ACCEPT WS-RESP
59 IF UPPER-CASE(WS-RESP) NOT = "S"
60 EXIT PERFORM
61 END-IF
62 END-PERFORM
63 ELSE
64 CALL "MENSGERR" USING WS-PEGA-ERRO
65 END-IF.
66 CLOSE FD-VIRTUAL.
67 DISPLAY X"0D".
68 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
69 ACCEPT WS-ENTER.
70 STOP RUN.
71 END PROGRAM CAP07AP33.
------ ------------------------------------------------------------------------

Execute o programa e entre alguns registros. Perceba que o comportamento não é diferente dos outros programas que
manipulam arquivos relativos.
O programa a seguir demonstra o uso de acesso dinâmico para arquivo relativo. Atenta para o uso do comando
START. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap34 e extensão “.cob” na subpasta COBOL
da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP34 AS "Capitulo 7 – Aplicacao 34".
3 *
------ ------------------------------------------------------------------------
320 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.DYN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS DYNAMIC
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "CONSULTA DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual registro: " WITH NO ADVANCING
38 ACCEPT TB-NUM-REG
39 START FD-VIRTUAL KEY IS = TB-NUM-REG
40 INVALID KEY
41 DISPLAY X"0D"
42 DISPLAY "Registro inexistente."
43 DISPLAY X"0D"
44 PERFORM 900-MENSAGEM
45 NOT INVALID KEY
46 READ FD-VIRTUAL INTO TB-CADFUN
47 DISPLAY X"0D"
48 DISPLAY "Codigo ........: " TB-CODFUN
49 DISPLAY "Nome ..........: " TB-NOME
50 DISPLAY "Departamento ..: " TB-DEPTO
51 DISPLAY "Funcao ........: " TB-FUNCAO
52 DISPLAY "Salario .......: " TB-SALARIO
53 DISPLAY X"0D"
54 PERFORM 900-MENSAGEM
55 END-START
56 IF UPPER-CASE(WS-RESP) NOT = "S"
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 321

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
57 EXIT PERFORM
58 END-IF
59 END-PERFORM
60 ELSE
61 CALL "MENSGERR" USING WS-PEGA-ERRO
62 END-IF.
63 CLOSE FD-VIRTUAL.
64 DISPLAY X"0D".
65 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
66 ACCEPT WS-ENTER.
67 STOP RUN.
68 900-MENSAGEM SECTION.
69 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
70 DISPLAY "- qualquer outra letra para NAO: "
71 WITH NO ADVANCING.
72 ACCEPT WS-RESP.
73 EXIT.
74 END PROGRAM CAP07AP34.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe os valores relativos de acesso a cada registro. Perceba que o programa operaci-
onalmente não difere de outros já apresentados. O programa cap07ap34.cob faz uso do recurso de pesquisa com o
valor da posição relativa do registro no arquivo e foi comentado que um arquivo com acesso dinâmico permite também
o acesso sequencial. O acesso sequencial pode ocorrer a partir do primeiro registro até o último ou a partir de um regis-
tro especifico até o último. Neste subtópico este efeito não é demonstrado deixando-o para o próximo subtópico.
O programa a seguir demonstra o uso do modo de operação I-O para ação de leitura (READ) com acesso as operações
de remoção (DELETE) e atualização de dados (REWRITE). Assim sendo, abra um projeto vazio atribuindo-lhe o nome
cap07ap35 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP35 AS "Capitulo 7 – Aplicacao 35".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINRR.DYN"
11 ORGANIZATION IS RELATIVE
12 ACCESS MODE IS DYNAMIC
13 RELATIVE KEY IS TB-NUM-REG
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
------ ------------------------------------------------------------------------
322 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-OPCAO PIC 9.
26 77 TB-NUM-REG PIC 9(4) VALUE ZERO.
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL
31 IF WS-PEGA-ERRO = "00"
32 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 3
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ADMINISTRAR REGISTROS"
35 DISPLAY "------------------------"
36 DISPLAY X"0D"
37 DISPLAY "1 - Atualizar registro"
38 DISPLAY "2 - Excluir registro"
39 DISPLAY "3 - Finalizar"
40 DISPLAY X"0D"
41 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
42 ACCEPT WS-OPCAO
43 EVALUATE WS-OPCAO
44 WHEN 1
45 PERFORM 100-ENTRADA
46 READ FD-VIRTUAL INTO TB-CADFUN
47 INVALID KEY
48 PERFORM 910-REG-INEXISTENTE
49 PERFORM 900-MENSAGEM
50 NOT INVALID KEY
51 DISPLAY X"0D"
52 PERFORM 200-SAIDA
53 DISPLAY "Entre os novos dados:"
54 DISPLAY X"0D"
55 DISPLAY "Codigo ........: " TB-CODFUN
56 DISPLAY "Nome ..........: "
57 WITH NO ADVANCING
58 ACCEPT TB-NOME
59 DISPLAY "Departamento ..: "
60 WITH NO ADVANCING
61 ACCEPT TB-DEPTO
62 DISPLAY "Funcao ........: "
63 WITH NO ADVANCING
64 ACCEPT TB-FUNCAO
65 DISPLAY "Salario .......: "
66 WITH NO ADVANCING
67 ACCEPT TB-SALARIO
68 REWRITE FS-CADFUN FROM TB-CADFUN
69 NOT INVALID KEY
70 DISPLAY X"0D"
71 DISPLAY "Registro atualizado."
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 323

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
72 DISPLAY X"0D"
73 PERFORM 900-MENSAGEM
74 END-REWRITE
75 END-READ
76 WHEN 2
77 PERFORM 100-ENTRADA
78 READ FD-VIRTUAL INTO TB-CADFUN
79 INVALID KEY
80 PERFORM 910-REG-INEXISTENTE
81 PERFORM 900-MENSAGEM
82 NOT INVALID KEY
83 PERFORM 200-SAIDA
84 DELETE FD-VIRTUAL RECORD
85 NOT INVALID KEY
86 DISPLAY "Registro removido."
87 DISPLAY X"0D"
88 PERFORM 900-MENSAGEM
89 END-DELETE
90 END-READ
91 WHEN 3
92 EXIT PERFORM
93 END-EVALUATE
94 DISPLAY X"0D"
95 MOVE 0 TO WS-OPCAO
96 END-PERFORM
97 ELSE
98 CALL "MENSGERR" USING WS-PEGA-ERRO
99 END-IF.
100 DISPLAY X"0D".
101 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
102 ACCEPT WS-ENTER.
103 CLOSE FD-VIRTUAL
104 STOP RUN.
105 100-ENTRADA SECTION.
106 DISPLAY X"0D".
107 DISPLAY "Qual registro: " WITH NO ADVANCING.
108 ACCEPT TB-NUM-REG.
109 EXIT.
110 200-SAIDA SECTION.
111 DISPLAY X"0D".
112 DISPLAY "Codigo ........: " TB-CODFUN.
113 DISPLAY "Nome ..........: " TB-NOME.
114 DISPLAY "Departamento ..: " TB-DEPTO.
115 DISPLAY "Funcao ........: " TB-FUNCAO.
116 DISPLAY "Salario .......: " TB-SALARIO.
117 DISPLAY X"0D".
118 EXIT.
119 900-MENSAGEM SECTION.
120 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
121 ACCEPT WS-ENTER.
122 EXIT.
123 910-REG-INEXISTENTE SECTION.
124 DISPLAY X"0D".
------ ------------------------------------------------------------------------
324 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
125 DISPLAY "Registro inexistente.".
126 DISPLAY X"0D".
127 EXIT.
128 END PROGRAM CAP07AP35.
------ ------------------------------------------------------------------------

Ao ser executado o programa teste as opções de menu, prestando atenção no comportamento de cada parte do pro-
grama. Observe que comportamento do programa cap07ap35.cob assemelha-se ao comportamento dos programas
cap07ap29.cob e cap07ap32.cob.

7.6.8 Arquivo indexado para acesso dinâmico


Um arquivo de organização indexada com acesso dinâmico é uma forma de organização onde cada registro pode ser
acessado por seu campo chave de indexação. É obrigatório neste tipo de arquivo o uso da cláusula RECORD KEY
junto ao comando SELECT, podendo-se ainda fazer uso da cláusula ALTERNATE RECORD como demonstrado no
uso de arquivo sequencial indexado. A tabela 7.16 mostra as operações possíveis de realização em arquivos dinâmicos
indexados.

Tabela 7.16 – Ações permitidas para arquivo indexado com acesso dinâmico

Tipo de arquivo Comando INPUT OUTPUT I-O EXTEND


READ X - X -
Acesso dinâmico WRITE - X X -
para arquivo START X - X -
indexado REWRITE - - X -
DELETE - - X -

O programa a seguir cria um arquivo dinâmico chamado ARQDINIX.DYN com o modo OUTPUT. Se o arquivo existir
este será recriado, portanto cuidado no uso deste tipo de arquivo. Na sequência, abra um projeto vazio atribuindo-lhe o
nome cap07ap36 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP36 AS "Capitulo 7 – Aplicacao 36".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 325

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN I-O FD-VIRTUAL
30 IF WS-PEGA-ERRO = "35"
31 OPEN OUTPUT FD-VIRTUAL
32 END-IF
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ENTRADA DE REGISTROS"
35 DISPLAY "------------------------"
36 IF WS-PEGA-ERRO = "00"
37 PERFORM FOREVER
38 DISPLAY X"0D"
39 DISPLAY "Codigo ........: " WITH NO ADVANCING
40 ACCEPT TB-CODFUN
41 DISPLAY "Nome ..........: " WITH NO ADVANCING
42 ACCEPT TB-NOME
43 DISPLAY "Departamento ..: " WITH NO ADVANCING
44 ACCEPT TB-DEPTO
45 DISPLAY "Funcao ........: " WITH NO ADVANCING
46 ACCEPT TB-FUNCAO
47 DISPLAY "Salario .......: " WITH NO ADVANCING
48 ACCEPT TB-SALARIO
49 WRITE FS-CADFUN FROM TB-CADFUN
50 INVALID KEY
51 DISPLAY X"0D"
52 DISPLAY "Registro existente."
53 NOT INVALID KEY
54 DISPLAY X"0D"
55 DISPLAY "Registro cadastrado com sucesso."
56 END-WRITE
57 DISPLAY X"0D"
58 DISPLAY "Mais registro (S) para SIM " WITH NO ADVANCING
59 DISPLAY "- qualquer outra letra para NAO: "
60 WITH NO ADVANCING
61 ACCEPT WS-RESP
62 IF UPPER-CASE(WS-RESP) NOT = "S"
63 EXIT PERFORM
64 END-IF
65 END-PERFORM
66 ELSE
67 CALL "MENSGERR" USING WS-PEGA-ERRO
68 END-IF.
------ ------------------------------------------------------------------------
326 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
69 CLOSE FD-VIRTUAL.
70 DISPLAY X"0D".
71 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
72 ACCEPT WS-ENTER.
73 STOP RUN.
74 END PROGRAM CAP07AP36.
------ ------------------------------------------------------------------------

Execute o programa e entre alguns registros. Perceba que o comportamento não é diferente dos outros programas que
manipulam arquivos indexados. Neste programa se o arquivo não existir este será criado e se existir será aberto para
acréscimos de registros.
O programa a seguir efetuas a apresentação de um registro a partir do fornecimento de seu código a partir da ação
típica de um arquivo com organização indexada. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap37
e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP37 AS "Capitulo 7 – Aplicacao 37".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-RESP PIC A VALUE "S".
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "CONSULTA DE REGISTROS"
33 DISPLAY "------------------------"
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 327

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
34 IF WS-PEGA-ERRO = "00"
35 PERFORM FOREVER
36 DISPLAY X"0D"
37 DISPLAY "Qual codigo: " WITH NO ADVANCING
38 ACCEPT TB-CHV-CODFUN
39 MOVE TB-CHV-CODFUN TO F001-CODFUN
40 READ FD-VIRTUAL INTO TB-CADFUN KEY IS F001-CODFUN
41 INVALID KEY
42 DISPLAY X"0D"
43 DISPLAY "Registro inexistente."
44 DISPLAY X"0D"
45 PERFORM 900-MENSAGEM
46 NOT INVALID KEY
47 DISPLAY X"0D"
48 DISPLAY "Codigo ........: " TB-CODFUN
49 DISPLAY "Nome ..........: " TB-NOME
50 DISPLAY "Departamento ..: " TB-DEPTO
51 DISPLAY "Funcao ........: " TB-FUNCAO
52 DISPLAY "Salario .......: " TB-SALARIO
53 DISPLAY X"0D"
54 PERFORM 900-MENSAGEM
55 END-READ
56 IF UPPER-CASE(WS-RESP) NOT = "S"
57 EXIT PERFORM
58 END-IF
59 END-PERFORM
60 ELSE
61 CALL "MENSGERR" USING WS-PEGA-ERRO
62 END-IF.
63 CLOSE FD-VIRTUAL.
64 DISPLAY X"0D".
65 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
66 ACCEPT WS-ENTER.
67 STOP RUN.
68 900-MENSAGEM SECTION.
69 DISPLAY "Nova pesquisa: (S) para SIM " WITH NO ADVANCING.
70 DISPLAY "- qualquer outra letra para NAO: "
71 WITH NO ADVANCING.
72 ACCEPT WS-RESP.
73 EXIT.
74 END PROGRAM CAP07AP37.
------ ------------------------------------------------------------------------

Ao ser executado o programa informe os códigos de identificação de cada registro. Perceba que o programa operacio-
nalmente não difere de outros já apresentados. O programa cap07ap37.cob faz uso do recurso de pesquisa com o
valor do código do campo chave.
Quando o acesso dinâmico é usado para arquivos indexados pode-se fazer uso do comando READ (linha 40) com ou
sem o uso da cláusula KEY IS. Usar a cláusula KEY IS deixa o código sintaticamente mais claro, mas não é de todo
necessário, tanto que anteriormente pouco foi usado.
Como comentado, arquivos dinâmicos podem ser acessados de forma sequencial. Desta forma, considere um progra-
ma que apresente todos os registros sequencialmente do arquivo ARQDINIX.DYN. Assim sendo, abra um projeto vazio
328 PRO G RA MA Ç ÃO CO B OL

atribuindo-lhe o nome cap07ap38 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instru-
ções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP38 AS "Capitulo 7 – Aplicacao 38".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 *
9 INPUT-OUTPUT SECTION.
10 FILE-CONTROL.
11 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
12 ORGANIZATION IS INDEXED
13 ACCESS MODE IS DYNAMIC
14 RECORD KEY IS F001-CODFUN
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 *
21 WORKING-STORAGE SECTION.
22 COPY "FSCODERR.CPY".
23 COPY "TBVIRTUAL.CPY".
24 77 WS-PEGA-ERRO PIC XX.
25 77 WS-ENTER PIC X.
26 77 TB-EOF PIC X VALUE "F".
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY " LISTAGEM DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 DISPLAY X"0D"
36 PERFORM UNTIL TB-EOF = "V"
37 READ FD-VIRTUAL NEXT RECORD INTO TB-CADFUN
38 AT END
39 MOVE "V" TO TB-EOF
40 NOT AT END
41 DISPLAY TB-CODFUN " - " TB-NOME " - " TB-DEPTO
42 END-READ
43 END-PERFORM
44 ELSE
45 CALL "MENSGERR" USING WS-PEGA-ERRO
46 END-IF.
47 CLOSE FD-VIRTUAL.
48 DISPLAY X"0D".
49 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 329

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
50 ACCEPT WS-ENTER.
51 STOP RUN.
52 END PROGRAM CAP07AP38.
------ ------------------------------------------------------------------------

Ao ser executado o programa uma listagem dos registros existentes é apresentada sequencialmente na tela. Observe o
uso da cláusula opcional NEXT RECORD junto ao comando READ na linha 37 que tem por finalidade indicar a execu-
ção de leitura sequencial do próximo registro a partir da posição atual do ponteiro até que o final do arquivo seja atingi-
do.
Foi comentado que arquivos dinâmicos podem ser acessados de forma direta ou indexada em certo momento e a partir
deste acesso ser acessado sequencialmente. Neste caso, mais há duas ocorrências a serem consideradas: uma sendo
a partir da posição ou chave indicada excluindo-se o dado informado ou incluindo-se o dado informado.
No sentido de visualizar ação de pesquisa a partir de certo ponto do arquivo considere o programa seguinte que apre-
sentará todos os registros a partir do código de identificação funcional informado. Assim sendo, abra um projeto vazio
atribuindo-lhe o nome cap07ap39 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instru-
ções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP39 AS "Capitulo 7 – Aplicacao 39".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 TB-CHV-CODFUN PIC X(09).
26 77 TB-EOF PIC X VALUE "F".
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
------ ------------------------------------------------------------------------
330 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "LISTAGEM DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 DISPLAY X"0D"
36 DISPLAY "A partir do codigo: " WITH NO ADVANCING
37 ACCEPT TB-CHV-CODFUN
38 MOVE TB-CHV-CODFUN TO F001-CODFUN
39 READ FD-VIRTUAL INTO TB-CADFUN KEY IS F001-CODFUN
40 INVALID KEY
41 DISPLAY "Registro inexistente."
42 NOT INVALID KEY
43 PERFORM UNTIL TB-EOF = "V"
44 READ FD-VIRTUAL NEXT RECORD INTO TB-CADFUN
45 AT END
46 MOVE "V" TO TB-EOF
47 NOT AT END
48 DISPLAY TB-CODFUN " - " TB-NOME
49 END-READ
50 END-PERFORM
51 END-READ
52 ELSE
53 CALL "MENSGERR" USING WS-PEGA-ERRO
54 END-IF.
55 CLOSE FD-VIRTUAL.
56 DISPLAY X"0D".
57 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
58 ACCEPT WS-ENTER.
59 STOP RUN.
60 END PROGRAM CAP07AP39.
------ ------------------------------------------------------------------------

Execute o programa e perceba que ao ser fornecido um código de identificação funcional são apresentados sequenci-
almente todos os registros a partir do valor informado sem incluí-lo na listagem. Veja no programa o uso de duas formas
de escrita do comando READ a instrução READ FD-VIRTUAL INTO TB-CADFUN KEY IS F001-CODFUN na linha 39
que faz a pesquisa no arquivo de forma indexada, não encontrando o registro apresenta mensagem informando a con-
dição, mas se o registro existir inicia no laço PERFORM da linha 43 a execução sequencial de leituras com a instrução
READ FD-VIRTUAL NEXT RECORD INTO TB-CADFUN da linha 44. Veja que na ação de leituras sequencias de ar-
quivos dinâmicos o uso da cláusula KEY IS junto ao comando READ é desnecessário uma vez que não é usado pelo
comando READ.
Caso queira um programa que apresente inclusive o registro informado é necessário uma pequena mudança no código
do programa. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap40 e extensão “.cob” na subpasta
COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP40 AS "Capitulo 7 – Aplicacao 40".
3 *
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 331

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 TB-CHV-CODFUN PIC X(09).
26 77 TB-EOF PIC X VALUE "F".
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN INPUT FD-VIRTUAL
31 DISPLAY "CADASTRO DE FUNCIONARIOS"
32 DISPLAY "LISTAGEM DE REGISTROS"
33 DISPLAY "------------------------"
34 IF WS-PEGA-ERRO = "00"
35 DISPLAY X"0D"
36 DISPLAY "Listar do codigo: " WITH NO ADVANCING
37 ACCEPT TB-CHV-CODFUN
38 MOVE TB-CHV-CODFUN TO F001-CODFUN
39 READ FD-VIRTUAL INTO TB-CADFUN KEY IS F001-CODFUN
40 INVALID KEY
41 DISPLAY "Registro inexistente."
42 NOT INVALID KEY
43 READ FD-VIRTUAL PREVIOUS RECORD INTO TB-CADFUN
44 PERFORM UNTIL TB-EOF = "V"
45 READ FD-VIRTUAL NEXT RECORD INTO TB-CADFUN
46 AT END
47 MOVE "V" TO TB-EOF
48 NOT AT END
49 DISPLAY TB-CODFUN " - " TB-NOME
50 END-READ
51 END-PERFORM
52 END-READ
53 ELSE
54 CALL "MENSGERR" USING WS-PEGA-ERRO
55 END-IF.
------ ------------------------------------------------------------------------
332 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
56 CLOSE FD-VIRTUAL.
57 DISPLAY X"0D".
58 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
59 ACCEPT WS-ENTER.
60 STOP RUN.
61 END PROGRAM CAP07AP40.
------ ------------------------------------------------------------------------

Execute o programa e perceba que ao ser fornecido um código de identificação funcional são apresentados sequenci-
almente todos os registros incluindo o registro indicado. Veja no código do programa, na linha 43 a utilização da instru-
ção READ FD-VIRTUAL PREVIOUS RECORD INTO TB-CADFUN onde o uso da cláusula PREVIOUS RECORD faz
com que o ponteiro que avançou após a execução da instrução READ FD-VIRTUAL INTO TB-CADFUN KEY IS F001-
CODFUN da linha 39 retorne uma posição atrás e seja incluído na listagem sequencial.
O programa a seguir demonstra o uso do modo de operação I-O para ação de leitura (READ) com acesso as operações
de remoção (DELETE) e atualização de dados (REWRITE). Assim sendo, abra um projeto vazio atribuindo-lhe o nome
cap07ap41 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP41 AS "Capitulo 7 – Aplicacao 41".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 COPY "TBVIRTUAL.CPY".
23 77 WS-PEGA-ERRO PIC XX.
24 77 WS-ENTER PIC X.
25 77 WS-OPCAO PIC 9.
26 77 TB-CHV-CODFUN PIC X(09).
27 *
28 PROCEDURE DIVISION.
29 PROG-PRINCIPAL-PARA.
30 OPEN I-O FD-VIRTUAL
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 333

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
31 IF WS-PEGA-ERRO = "00"
32 PERFORM UNTIL WS-OPCAO >= 1 AND WS-OPCAO <= 3
33 DISPLAY "CADASTRO DE FUNCIONARIOS"
34 DISPLAY "ADMINISTRAR REGISTROS"
35 DISPLAY "------------------------"
36 DISPLAY X"0D"
37 DISPLAY "1 - Atualizar registro"
38 DISPLAY "2 - Excluir registro"
39 DISPLAY "3 - Finalizar"
40 DISPLAY X"0D"
41 DISPLAY "Escolha uma opcao: " WITH NO ADVANCING
42 ACCEPT WS-OPCAO
43 EVALUATE WS-OPCAO
44 WHEN 1
45 PERFORM 100-ENTRADA
46 READ FD-VIRTUAL INTO TB-CADFUN
47 INVALID KEY
48 PERFORM 910-REG-INEXISTENTE
49 PERFORM 900-MENSAGEM
50 NOT INVALID KEY
51 DISPLAY X"0D"
52 PERFORM 200-SAIDA
53 DISPLAY "Entre os novos dados:"
54 DISPLAY X"0D"
55 DISPLAY "Codigo ........: " TB-CODFUN
56 DISPLAY "Nome ..........: "
57 WITH NO ADVANCING
58 ACCEPT TB-NOME
59 DISPLAY "Departamento ..: "
60 WITH NO ADVANCING
61 ACCEPT TB-DEPTO
62 DISPLAY "Funcao ........: "
63 WITH NO ADVANCING
64 ACCEPT TB-FUNCAO
65 DISPLAY "Salario .......: "
66 WITH NO ADVANCING
67 ACCEPT TB-SALARIO
68 REWRITE FS-CADFUN FROM TB-CADFUN
69 NOT INVALID KEY
70 DISPLAY X"0D"
71 DISPLAY "Registro atualizado."
72 DISPLAY X"0D"
73 PERFORM 900-MENSAGEM
74 END-REWRITE
75 END-READ
76 WHEN 2
77 PERFORM 100-ENTRADA
78 READ FD-VIRTUAL INTO TB-CADFUN
79 INVALID KEY
80 PERFORM 910-REG-INEXISTENTE
81 PERFORM 900-MENSAGEM
82 NOT INVALID KEY
83 PERFORM 200-SAIDA
------ ------------------------------------------------------------------------
334 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
84 DELETE FD-VIRTUAL RECORD
85 NOT INVALID KEY
86 DISPLAY "Registro removido."
87 DISPLAY X"0D"
88 PERFORM 900-MENSAGEM
89 END-DELETE
90 END-READ
91 WHEN 3
92 EXIT PERFORM
93 END-EVALUATE
94 DISPLAY X"0D"
95 MOVE 0 TO WS-OPCAO
96 END-PERFORM
97 ELSE
98 CALL "MENSGERR" USING WS-PEGA-ERRO
99 END-IF.
100 DISPLAY X"0D".
101 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
102 ACCEPT WS-ENTER.
103 CLOSE FD-VIRTUAL
104 STOP RUN.
105 100-ENTRADA SECTION.
106 DISPLAY X"0D".
107 DISPLAY "Qual codigo: " WITH NO ADVANCING.
108 ACCEPT TB-CHV-CODFUN.
109 MOVE TB-CHV-CODFUN TO F001-CODFUN.
110 EXIT.
111 200-SAIDA SECTION.
112 DISPLAY X"0D".
113 DISPLAY "Codigo ........: " TB-CODFUN.
114 DISPLAY "Nome ..........: " TB-NOME.
115 DISPLAY "Departamento ..: " TB-DEPTO.
116 DISPLAY "Funcao ........: " TB-FUNCAO.
117 DISPLAY "Salario .......: " TB-SALARIO.
118 DISPLAY X"0D".
119 EXIT.
120 900-MENSAGEM SECTION.
121 DISPLAY "Tecle <ENTER> para continuar... " WITH NO ADVANCING.
122 ACCEPT WS-ENTER.
123 EXIT.
124 910-REG-INEXISTENTE SECTION.
125 DISPLAY X"0D".
126 DISPLAY "Registro inexistente.".
127 DISPLAY X"0D".
128 EXIT.
129 END PROGRAM CAP07AP41.
------ ------------------------------------------------------------------------

Ao ser executado o programa teste as opções de menu, prestando atenção no comportamento de cada parte do pro-
grama. Observe que comportamento do programa cap07ap41.cob assemelha-se ao comportamento de outros progra-
mas apresentados.
UT ILI ZA ÇÃ O D E A RQ U IV OS 335

7.7 CLASSIFICAÇÃO, AGRUPAMENTO E JUNÇÃO DE REGISTROS


Os registros de um arquivo, normalmente, são gravados na ordem em que são fornecidos. Eventualmente são gravados
sobre registros que tenham sido anteriormente removidos.
Na maioria das vezes essa ordem de gravação não atende as necessidades de apresentação desses dados de forma
organizada seguindo certos critérios de classificação. Neste sentido, faz-se necessário o uso do comando SORT já
conhecido do capítulo 4 quando da apresentação do tema sobre processamento de coleções de dados.
Para usar o comando SORT é necessário que os registros de certo arquivo sejam lidos pelo comando a partir de certa
chave de classificação.
O comando SORT gera internamente um arquivo temporário que contém os dados segundo o critério de classificação
estabelecida e o apaga automaticamente após sua operação. A definição da classificação é descrita na FILE SECTION
a partir da cláusula SD (Sort Description). O arquivo permanente usado para a efetivação da classificação manterá seus
registros inalterados.
A estrutura sintática simplificada do comando SORT para a classificação de registros em arquivos difere da estrutura
sintática usada na manipulação de coleções de dados em memória principal. Assim sendo, observe sua forma sintática
a seguir:

SORT <arquivo-fd> {[ON] {AS/DE|SCENDING} KEY <campo-chave>} [WITH DUPLICATES IN ORDER]


INPUT PROCEDURE IS <rotina1> [THRU|THROUUGH <rotina2>]
OUTPUT PROCEDURE IS <rotina3> [THRU|THROUUGH <rotina4>].

Onde, arquivo-fd é a indicação do nome do arquivo temporário de trabalho definido junto a descrição de classificação
SD, a qual na FILE SECTION descreve o conjunto de registros a serem usados na classificação a partir da definição de
uma chave; campo-chave é a definição do campo do arquivo a ser usado como ordem de classificação, podendo ser
ascendente (ON ASCENDING KEY) ou descendente (ON DESCENDING KEY).
A cláusula WITH DUPLICATES IN ORDER não tem efeito no GnuCOBOL sendo mantida por questões de compatibili-
dade com outros compiladores da linguagem.
A indicação rotina1 e eventualmente a especificação da rotina2 se refere a definição do procedimento executado junto
a cláusula INPUT PROCEDURE IS com a finalidade de ler o arquivo permanente e criar o arquivo temporário. O mesmo
se aplica as rotinas rotina3 e rotina4 em OUTPUT PROCEDURE IS que efetua a leitura do arquivo temporário e gera a
classificação desejada.
Para auxiliar a operação de leitura da sub-rotina chamada por INPUT PROCEDURE IS usa-se como auxilio o comando
RELEASE que só pode ser implementado após o uso do comando SORT.
O comando RELEASE pode ser escrito de duas maneiras diferentes: uma simplificada e outra completa. A forma de
escrita completa permite eliminar o uso do comando MOVE necessário antes de sua ação. A sintaxe completa do co-
mando RELEASE corresponde a:

RELEASE <estrutura-temporária> [FROM <estrutura-permanente>]

Onde, estrutura-temporária é a indicação da estrutura de dados definida após a descrição da classificação em uso e
estrutura-permanente após a cláusula FROM é a indicação da estrutura de dados definida após a descrição do arqui-
vo em operação.
Para auxiliar a operação de escrita da sub-rotina chamada por OUTPUT PROCEDURE IS usa-se como auxilio o co-
mando RETURN que tem como forma sintática a estrutura de escrita:

RETURN <arquivo-sd>
[[NOT] AT END <ação>]
END- RETURN.
336 PRO G RA MA Ç ÃO CO B OL

Onde, arquivo-sd refere-se a descrição da classificação usada no arquivo temporário, ação ser refere a alguma opera-
ção a ser executada quando a leitura chegar no final do arquivo com o uso de AT END ou outra ação enquanto o final
do arquivo não é atingido quando em uso NOT AT END.
O comando SORT executa três etapas oper4acinais de trabalho: primeiro faz a leitura do arquivo permanente (repre-
sentado em arquivo) seguindo a ordem indicada para o campo-chave; segundo efetua a gravação do registro ordena-
do em um arquivo temporário direcionado por INPUT PROCEDURE IS e em terceiro efetua a leitura do arquivo tempo-
rário direcionado por OUTPUT PROCEDURE IS.
A ação de classificação de dados não é aplicada em arquivos sequenciais lineares, mas pode ser aplicada nas demais
formas de organização. Esta ação segue a uma determinada ordem interna computacional que dependendo do tipo de
computador em poderá gerar resultados muito diferentes como ocorre entre computadores da alta e baixa plataformas.
É pertinente salientar que os dois padrões principais usados na computação são o padrão EBCDIC (Extended Binary
Coded Decimal Interchange Code) comum nos computadores da lata plataforma e o padrão ASCII (American Standard
Code for Information Interchange) comum nos computadores da baixa plataforma.
Os padrões EBCDIC e ASCII realizam suas classificações de maneiras diferentes como aponta a tabela 7.17. Para
maiores detalhes consulte o apêndice desta obra.

Tabela 7.17 – Ordem de classificação EBCDIC e ASCII

EBCDIC ASCII

Espaço em branco Espaço em branco

Caracteres especiais Caracteres especiais

Letras minúsculas Números

Letras maiúsculas Letras minúsculas

Números Letras maiúsculas

Para fazer uso o mais simples possível do comando SORT é necessário possuir um arquivo que esteja populado com
registros. Neste sentido, considerando o último arquivo criado considere um programa que apresente uma listagem
contendo os nomes dos funcionários, seus códigos de identificação e o setor que trabalham a partir desse arquivo.
Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap42 e extensão “.cob” na subpasta COBOL da pasta
Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP42 AS "Capitulo 7 – Aplicacao 42".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 *
11 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
12 ORGANIZATION IS INDEXED
13 ACCESS MODE IS DYNAMIC
14 RECORD KEY IS F001-CODFUN
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 337

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
15 FILE STATUS IS WS-PEGA-ERRO.
16 *
17 SELECT SD-VIRTUAL ASSIGN TO "ARQDINIX.DYN".
18 *
19 DATA DIVISION.
20 FILE SECTION.
21 FD FD-VIRTUAL.
22 01 FS-CADFUN.
23 05 FS-REGISTRO.
24 10 F001-CODFUN PIC X(09).
25 10 F001-NOME PIC X(40).
26 10 F001-DEPTO PIC 99.
27 10 F001-FUNCAO PIC X(20).
28 10 F001-SALARIO PIC 9(10)V99.
29 *
30 SD SD-VIRTUAL.
31 01 SD-CADFUN.
32 05 SD-REGISTRO.
33 10 S001-CODFUN PIC X(09).
34 10 S001-NOME PIC X(40).
35 10 S001-DEPTO PIC 99.
36 10 S001-FUNCAO PIC X(20).
37 10 S001-SALARIO PIC 9(10)V99.
38 *
39 WORKING-STORAGE SECTION.
40 COPY "FSCODERR.CPY".
41 77 WS-PEGA-ERRO PIC XX.
42 77 WS-ENTER PIC X.
43 77 LS-EOF PIC X.
44 *
45 PROCEDURE DIVISION.
46 PROG-PRINCIPAL-PARA.
47 OPEN INPUT FD-VIRTUAL
48 DISPLAY "CADASTRO DE FUNCIONARIOS"
49 DISPLAY "LISTAGEM CLASSIFICADA"
50 DISPLAY "------------------------"
51 DISPLAY X"0D".
52 SORT SD-VIRTUAL ON ASCENDING KEY S001-NOME
53 INPUT PROCEDURE IS ENT-PROC
54 OUTPUT PROCEDURE IS SAI-PROC.
55 DISPLAY X"0D".
56 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
57 ACCEPT WS-ENTER.
58 CLOSE FD-VIRTUAL.
59 STOP RUN.
60 *
61 ENT-PROC SECTION.
62 MOVE "F" TO LS-EOF
63 PERFORM UNTIL LS-EOF = "V"
64 READ FD-VIRTUAL
65 AT END
66 MOVE "V" TO LS-EOF
67 NOT AT END
------ ------------------------------------------------------------------------
338 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
68 MOVE FS-REGISTRO TO SD-REGISTRO
69 RELEASE SD-CADFUN
70 END-READ
71 END-PERFORM
72 EXIT.
73 *
74 SAI-PROC SECTION.
75 MOVE "F" TO LS-EOF
76 PERFORM UNTIL LS-EOF = "V"
77 RETURN SD-VIRTUAL
78 AT END
79 MOVE "V" TO LS-EOF
80 NOT AT END
81 DISPLAY S001-NOME " - " S001-CODFUN " - " S001-DEPTO
82 END-RETURN
83 END-PERFORM
84 EXIT.
85 *
86 END PROGRAM CAP07AP42.
------ ------------------------------------------------------------------------

Ao ser executado o programa é apresentada uma listagem simples de todos os funcionários em ordem alfabética de
nome.
O primeiro detalhe a ser observado é o uso dos comandos SELECT com a definição dos arquivos FD-VIRTUAL na
linha 11 e SD-VIRTUAL na linha 17. Veja que o arquivo FD-VIRTUAL (arquivo permanente) se caracteriza por ser um
arquivo de organização indexada com acesso dinâmico como já vinha sendo utilizado e o arquivo SD-VIRTUAL (arqui-
vo temporário) é pela omissão de seus detalhes de qualificação um arquivo sequencial de registro com acesso sequen-
cial por padrão.
Na sequência são definidas a descrição de arquivo FD na linha 21 para o arquivo permanente FD-VIRTUAL com estru-
tura de dados FS-CADFUN e a descrição de classificação SD na linha 30 para o arquivo temporário SD-VIRTUAL com
a estrutura de dados SD-CADUN.
Para realizar a classificação dos registros por nome é necessário fazer na PROCEDURE DIVISION a abertura do arqui-
vo permanente em modo INPUT (linha 48) e indicar para o comando SORT (linha 53) o arquivo temporário com menção
do campo a ser classificado e o modo da classificação (SORT SD-VIRTUAL ON ASCENDING KEY S001-NOME). As
indicações das ações INPUT (linha 53) e OUTPUT (linha 54) efetuam as chamadas dos procedimentos ENT-PROC e
SAI-PROC, definidos respectivamente a partir das linhas 61 (até 72) e 74 (até 84).
No procedimento ENT-PROC é realizada a leitura dos registros do arquivo permanente e a transferência de cada regis-
tro do arquivo permanente (FS-REGISTRO) para o registro do arquivo temporário (SD-REGISTRO). A cada movimen-
tação de registro com o comando READ é realizada a gravação do registro lido para o arquivo temporário (RELEASE
SD-CADFUN na linha 69).
Concluída a leitura do arquivo permanente e sua classificação no arquivo temporário, ocorre a execução do procedi-
mento SAI-PROC que por meio do comando RETURN na linha 77 efetua a leitura sequencial de cada registro do arqui-
vo temporário e faz sua apresentação.
O programa cap07ap42.cob faz uso simplificado do comando RELEASE sem uso da cláusula FROM o que faz com
que seja necessário usar o comando MOVE antes de RELEASE. Usar RELEAE de forma completa pode simplificar a
escrita do programa. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap43 e extensão “.cob” na sub-
pasta COBOL da pasta Documentos e codifique as instruções seguintes.
UT ILI ZA ÇÃ O D E A RQ U IV OS 339

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP43 AS "Capitulo 7 – Aplicacao 43".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 SELECT SD-VIRTUAL ASSIGN TO "ARQDINIX.DYN".
16 *
17 DATA DIVISION.
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 SD SD-VIRTUAL.
21 01 SD-CADFUN.
22 05 S001-CODFUN PIC X(09).
23 05 S001-NOME PIC X(40).
24 05 S001-DEPTO PIC 99.
25 05 S001-FUNCAO PIC X(20).
26 05 S001-SALARIO PIC 9(10)V99.
27 *
28 WORKING-STORAGE SECTION.
29 COPY "FSCODERR.CPY".
30 77 WS-PEGA-ERRO PIC XX.
31 77 WS-ENTER PIC X.
32 77 TB-EOF PIC X.
33 *
34 PROCEDURE DIVISION.
35 PROG-PRINCIPAL-PARA.
36 OPEN INPUT FD-VIRTUAL
37 DISPLAY "CADASTRO DE FUNCIONARIOS"
38 DISPLAY "LISTAGEM CLASSIFICADA"
39 DISPLAY "------------------------"
40 DISPLAY X"0D".
41 SORT SD-VIRTUAL ON ASCENDING KEY S001-NOME
42 INPUT PROCEDURE IS ENT-PROC
43 OUTPUT PROCEDURE IS SAI-PROC.
44 DISPLAY X"0D".
45 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
46 ACCEPT WS-ENTER.
47 CLOSE FD-VIRTUAL.
48 STOP RUN.
49 *
50 ENT-PROC SECTION.
51 MOVE "F" TO TB-EOF
52 PERFORM UNTIL TB-EOF = "V"
53 READ FD-VIRTUAL
------ ------------------------------------------------------------------------
340 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 AT END
55 MOVE "V" TO TB-EOF
56 NOT AT END
57 RELEASE SD-CADFUN FROM FS-CADFUN
58 END-READ
59 END-PERFORM
60 EXIT.
61 *
62 SAI-PROC SECTION.
63 MOVE "F" TO TB-EOF
64 PERFORM UNTIL TB-EOF = "V"
65 RETURN SD-VIRTUAL
66 AT END
67 MOVE "V" TO TB-EOF
68 NOT AT END
69 DISPLAY S001-NOME " - " S001-CODFUN " - " S001-DEPTO
70 END-RETURN
71 END-PERFORM
72 EXIT.
73 END PROGRAM CAP07AP43.
------ ------------------------------------------------------------------------

Ao ser executado o programa cap07ap43.cob ter-se-á o mesmo resultado indicado com o programa cap07ap42.cob. A
diferença está no modo de definição das estruturas de dados do arquivo e da classificação e no uso completo da forma
escrita do comando RELEASE na linha 57.
Pensando agora em uma forma de classificação mais elaborada considere apresentar os dados em ordem ascendente
de nomes agrupados por departamento dispostos em ordem descendente. Para tanto, abra um projeto vazio atribuindo-
lhe o nome cap07ap44 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguin-
tes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP44 AS "Capitulo 7 – Aplicacao 44".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
14 FILE STATUS IS WS-PEGA-ERRO.
15 SELECT SD-VIRTUAL ASSIGN TO "ARQDINIX.DYN".
16 *
17 DATA DIVISION.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 341

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
18 FILE SECTION.
19 COPY "FDVIRTUAL.CPY".
20 *
21 SD SD-VIRTUAL.
22 01 SD-CADFUN.
23 05 S001-CODFUN PIC X(09).
24 05 S001-NOME PIC X(40).
25 05 S001-DEPTO PIC 99.
26 05 S001-FUNCAO PIC X(20).
27 05 S001-SALARIO PIC 9(10)V99.
28 *
29 WORKING-STORAGE SECTION.
30 COPY "FSCODERR.CPY".
31 77 WS-PEGA-ERRO PIC XX.
32 77 WS-ENTER PIC X.
33 77 TB-EOF PIC X.
34 77 TB-DEPTO-ATU PIC 99.
35 77 TB-DEPTO-ANT PIC 99.
36 *
37 PROCEDURE DIVISION.
38 PROG-PRINCIPAL-PARA.
39 OPEN INPUT FD-VIRTUAL
40 DISPLAY "CADASTRO DE FUNCIONARIOS"
41 DISPLAY "LISTAGEM CLASSIFICADA"
42 DISPLAY "------------------------"
43 SORT SD-VIRTUAL
44 ON DESCENDING KEY S001-DEPTO
45 ON ASCENDING KEY S001-NOME
46 INPUT PROCEDURE IS ENT-PROC
47 OUTPUT PROCEDURE IS SAI-PROC.
48 DISPLAY X"0D".
49 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
50 ACCEPT WS-ENTER.
51 CLOSE FD-VIRTUAL.
52 STOP RUN.
53 *
54 ENT-PROC SECTION.
55 MOVE "F" TO TB-EOF
56 PERFORM UNTIL TB-EOF = "V"
57 READ FD-VIRTUAL
58 AT END
59 MOVE "V" TO TB-EOF
60 NOT AT END
61 RELEASE SD-CADFUN FROM FS-CADFUN
62 END-READ
63 END-PERFORM
64 EXIT.
65 *
66 SAI-PROC SECTION.
67 MOVE 0 TO TB-DEPTO-ANT
68 MOVE "F" TO TB-EOF
69 PERFORM UNTIL TB-EOF = "V"
70 RETURN SD-VIRTUAL
------ ------------------------------------------------------------------------
342 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
71 AT END
72 MOVE "V" TO TB-EOF
73 NOT AT END
74 MOVE S001-DEPTO TO TB-DEPTO-ATU
75 IF TB-DEPTO-ATU NOT = TB-DEPTO-ANT
76 DISPLAY X"0D"
77 DISPLAY "Departamento: " TB-DEPTO-ATU
78 DISPLAY X"0D"
79 END-IF
80 DISPLAY S001-CODFUN " - " S001-NOME
81 MOVE TB-DEPTO-ATU TO TB-DEPTO-ANT
82 END-RETURN
83 END-PERFORM
84 EXIT.
85 *
86 END PROGRAM CAP07AP44.
------ ------------------------------------------------------------------------

Ao ser executado o programa são apresentados os grupos de departamento em ordem descendente com a apresenta-
ção dos códigos de identificação funcional e nomes em ordem ascendente.
O efeito de agrupamento separando os registros por departamento é processado junto ao procedimento SAI-PROC a
partir do auxílio das variáveis TB-DEPTO-ANT (definida na linha 34) e TB-DEPTO-ATU (definida na linha 35). Veja que
o procedimento é iniciado com a definição do valor 0 para a variável TB-DEPTO-ANT na linha 67 antes de ser iniciada
as operações de leitura dos registros com a instrução RETURN SD-VIRTUAL. Assim que um registro é lido ocorre a
movimentação para a variável TB-DEPTO-ATU do valor existente no campo S001-DEPTO com a execução da instru-
ção MOVE S001-DEPTO TO TB-DEPTO-ATU na linha 74.
Na sequência (linha 75) a instrução IF TB-DEPTO-ATU NOT = TB-DEPTO-ANT verifica se os valores existentes nas
variáveis TB-DEPTO-ANT e TB-DEPTO-ATU são diferentes, sendo ocorre a apresentação do título “Departamento:”
com o valor atual da variável TB-DEPTO-ATU. Se a condição não for verdadeira a instrução DISPLAY S001-CODFUN
" - " S001-NOME é executada e o código funcional e nome são apresentados.
Após os passos anteriores a instrução MOVE TB-DEPTO-ATU TO TB-DEPTO-ANT da linha 81 pega o valor do depar-
tamento atual da variável TB-DEPTO-ATU e o transfere para a variável TB-DEPTO-ANT, repetindo toda ação nova-
mente até chegar ao final do arquivo validados nas linhas 71 e 72. Veja que com este movimento torna-se possível
verificar quando a mudança no valor do departamento ocorre e desta forma impulsionar uma quebra de agrupamento.
O estilo de uso do comando SORT apresentado realiza as operações de classificação de registros com o auxílio opera-
cional dos comandos RELEASE e RTURN. No entanto, há uma maneira de realizar esta operação de forma diferente a
partir da definição de arquivos de entrada com auxílio da cláusula USING e saída com auxílio da cláusula GIVING, a
partir da estrutura sintática:

SORT <arquivo-fd> {[ON] {AS/DE|SCENDING} KEY <campo-chave>} [WITH DUPLICATES IN ORDER]


USING <arquivo-de-entrada>
GIVING <arquivo-de-saída>.

Neste estilo é necessário definir três arquivos, um para o arquivo temporário indicado em arquivo-fd e outros dois ar-
quivos indicados em arquivo-de-entrada e arquivo-de-saída. Neste formato, o comando SORT pega os registros do
arquivo de entrada, faz sua classificação no arquivo temporário (eliminado ao final da ação) e descarrega os registros
classificados no arquivo de saída.
O programa seguinte demonstra o uso do comando SORT com a definição de arquivos de entrada e saída com ordena-
ção dos registros classificados por ordem de nome ascendente. Assim sendo, abra um projeto vazio atribuindo-lhe o
nome cap07ap45 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.
UT ILI ZA ÇÃ O D E A RQ U IV OS 343

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP45 AS "Capitulo 7 – Aplicacao 45".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 * Arquivo de entrada
11 SELECT FD-VIRTENT ASSIGN TO "ARQDINIX.DYN"
12 ORGANIZATION IS INDEXED
13 ACCESS MODE IS DYNAMIC
14 RECORD KEY IS F001-CODFUN
15 FILE STATUS IS WS-PEGA-ERRO.
16 * Arquivo temporário
17 SELECT SD-VIRTEMP ASSIGN TO "ARQDINIX.TMP".
18 * Arquivo de saida
19 SELECT FD-VIRTSAI ASSIGN TO "ARQDINIX.CLF".
20 *
21 DATA DIVISION.
22 FILE SECTION.
23 *
24 FD FD-VIRTENT.
25 01 FS-CADFUN.
26 05 F001-CODFUN PIC X(09).
27 05 F001-NOME PIC X(40).
28 05 F001-DEPTO PIC 99.
29 05 F001-FUNCAO PIC X(20).
30 05 F001-SALARIO PIC 9(10)V99.
31 *
32 SD SD-VIRTEMP.
33 01 SD-CADFUN.
34 05 S001-CODFUN PIC X(09).
35 05 S001-NOME PIC X(40).
36 05 S001-DEPTO PIC 99.
37 05 S001-FUNCAO PIC X(20).
38 05 S001-SALARIO PIC 9(10)V99.
39 *
40 FD FD-VIRTSAI.
41 01 FD-CADFUN-SAI.
42 05 F002-CODFUN PIC X(09).
43 05 F002-NOME PIC X(40).
44 05 F002-DEPTO PIC 99.
45 05 F002-FUNCAO PIC X(20).
46 05 F002-SALARIO PIC 9(10)V99.
47 *
48 WORKING-STORAGE SECTION.
49 COPY "FSCODERR.CPY".
50 77 WS-PEGA-ERRO PIC XX.
51 77 WS-ENTER PIC X.
52 *
53 PROCEDURE DIVISION.
------ ------------------------------------------------------------------------
344 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
54 PROG-PRINCIPAL-PARA.
55 OPEN INPUT FD-VIRTENT
56 DISPLAY "CADASTRO DE FUNCIONARIOS"
57 DISPLAY "ORDENACAO NO ARQUIVO"
58 DISPLAY "------------------------"
59 SORT SD-VIRTEMP
60 ON ASCENDING KEY S001-NOME
61 USING FD-VIRTENT
62 GIVING FD-VIRTSAI.
63 DISPLAY X"0D".
64 DISPLAY "Classificacao processada.".
65 DISPLAY X"0D".
66 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
67 ACCEPT WS-ENTER.
68 CLOSE FD-VIRTENT.
69 STOP RUN.
70 END PROGRAM CAP07AP45.
------ ------------------------------------------------------------------------

Ao ser executado o programa, apenas a mensagem “Classificacao processada.” é apresentada. No entanto, o arquivo
ARQDINIX.CLF contendo os registros classificados é criado e precisará de um programa adicional para lista-lo. Assim
sendo, abra um projeto vazio atribuindo-lhe o nome cap07ap46 e extensão “.cob” na subpasta COBOL da pasta Do-
cumentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP46 AS "Capitulo 7 – Aplicacao 46".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.CLF"
11 FILE STATUS IS WS-PEGA-ERRO.
12 *
13 DATA DIVISION.
14 FILE SECTION.
15 COPY "FDVIRTUAL.CPY".
16 *
17 WORKING-STORAGE SECTION.
18 COPY "FSCODERR.CPY".
19 77 WS-PEGA-ERRO PIC XX.
20 77 WS-ENTER PIC X.
21 77 TB-EOF PIC X.
22 *
23 PROCEDURE DIVISION.
24 PROG-PRINCIPAL-PARA.
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 345

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
25 OPEN INPUT FD-VIRTUAL
26 DISPLAY "CADASTRO DE FUNCIONARIOS"
27 DISPLAY "LISTAGEM CLASSIFICADA"
28 DISPLAY "------------------------"
29 DISPLAY X"0D".
30 MOVE "F" TO TB-EOF
31 PERFORM UNTIL TB-EOF = "V"
32 READ FD-VIRTUAL
33 AT END
34 MOVE "V" TO TB-EOF
35 NOT AT END
36 DISPLAY F001-CODFUN " - " F001-NOME " - " F001-DEPTO
37 END-READ
38 END-PERFORM
39 DISPLAY X"0D".
40 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
41 ACCEPT WS-ENTER.
42 CLOSE FD-VIRTUAL.
43 STOP RUN.
44 END PROGRAM CAP07AP46.
------ ------------------------------------------------------------------------

Ao ser executado o programa o arquivo ARQDINIX.CLF é lido e os registros existente são apresentados dispostos em
ordem alfabética por nome.
Uma operação comum dentro de um ambiente organizacional é a necessidade de fazer junções de registros existentes
em diferentes arquivos. Neste sentido, há duas maneiras de realizar essa ação em COBOL, sendo com o uso do co-
mando SORT ou com o uso do comando MERGE. O comando MERGE é pouco usado, pois para sua operação exige o
cumprimento de alguns detalhes que com o comando SORT não são necessários, como será tratado logo mais. A título
de ilustração considere a sintaxe do comando MERGE:

MERGE <arquivo-fd> {[ON] {AS/DE|SCENDING} KEY <campo-chave>} [WITH DUPLICATES IN ORDER]


OUTPUT PROCEDURE IS <rotina1> [THRU|THROUUGH <rotina2>]
USING <arquivo-de-entrada>
GIVING <arquivo-de-saída>.

Observe que o comando MERGE é semelhante a estrutura sintática do comando SORT exceto pela ausência da indi-
cação do procedimento de entrada INPUT PROCEDURE IS.
Como estrutura de uso considere a necessidade de se fazer a junção de dois arquivos contendo os valores das vendas
de dois semestres de um ano. Para tanto, considere o trecho de código:

DATA DIVISION.
FILE SECTION.

FD FD-ARQUIVO1.
01 FD-REGISTRO-ARQ1.
05 F001-VALOR PIC 9(10)V99.

FD FD-ARQUIVO2.
01 FD-REGISTRO-ARQ2.
05 F001-VALOR PIC 9(10)V99.
346 PRO G RA MA Ç ÃO CO B OL

SD SD-ARQUIVOS-TEMP.
01 FD-REGISTRO-JUNTAS.
05 F001-VALOR PIC 9(10)V99.

FD FD-ARQUIVO-JUNCAO.
01 FD-REGISTRO-JUNTO.
05 F001-VALOR PIC 9(10)V99.

PROCEDURE DIVISION.
MERGE SD-ARQUIVOS-TEMP
ON ASCENDING KEY F001-VALOR
USING FD-ARQUIVO1 FD-ARQUIVO2
GIVING FD-ARQUIVO-JUNCAO.

Para uso do comando MERGE é obrigatório que os arquivos indicados junto as descrições de arquivos FD-ARQUIVO1
e FD-ARQUIVO2 estejam previamente classificados, ou seja, é preciso antes fazer uso do comando SORT. No entanto,
o comando SORT possui uma característica especial, pois além de realizar classificações realiza também junções.
Desta forma, o trecho seguinte escrito com SORT efetua a mesma ação que escrito com MERGE:

SORT SD-ARQUIVOS-TEMP
ON ASCENDING KEY F001-VALOR
USING FD-ARQUIVO1 FD-ARQUIVO2
GIVING FD-ARQUIVO-JUNCAO.

Veja que o comando SORT torna o uso do comando MERGE desnecessário, pois realiza a operação de classificação e
efetua no mesmo processamento a junção dos arquivos envolvidos.

7.8 CONTAGEM DE REGISTROS


Outra operação que pode ser requerida é saber a quantidade de registros de determinado arquivo. Essa é uma opera-
ção em que infelizmente a linguagem COBOL não oferece de forma direta uma maneira de obter tal informação. É
apresentada a maneira mais simples de realizar esta tarefa.
Assim sendo, abra o arquivo desejado em modo de leitura, percorra sequencialmente cada registro e some 1 a uma
variável auxiliar de contagem até chegar ao final do arquivo. Para ver essa ação em uso abra um projeto vazio atribuin-
do-lhe o nome cap07ap47 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções
seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP07AP47 AS "Capitulo 7 – Aplicacao 47".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 REPOSITORY.
7 FUNCTION ALL INTRINSIC.
8 INPUT-OUTPUT SECTION.
9 FILE-CONTROL.
10 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
11 ORGANIZATION IS INDEXED
12 ACCESS MODE IS DYNAMIC
13 RECORD KEY IS F001-CODFUN
------ ------------------------------------------------------------------------
UT ILI ZA ÇÃ O D E A RQ U IV OS 347

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
14 FILE STATUS IS WS-PEGA-ERRO.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 *
20 WORKING-STORAGE SECTION.
21 COPY "FSCODERR.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 TB-EOF PIC X VALUE "F".
25 77 TB-CONTA-REC PIC 9(04) VALUE 0.
26 *
27 PROCEDURE DIVISION.
28 PROG-PRINCIPAL-PARA.
29 OPEN INPUT FD-VIRTUAL
30 DISPLAY "CONTAGEM DE REGISTROS"
31 DISPLAY "---------------------"
32 DISPLAY X"0D"
33 IF WS-PEGA-ERRO = "00"
34 PERFORM UNTIL TB-EOF = "V"
35 READ FD-VIRTUAL
36 AT END
37 MOVE "V" TO TB-EOF
38 NOT AT END
39 ADD 1 TO TB-CONTA-REC
40 END-READ
41 END-PERFORM
42 ELSE
43 CALL "MENSGERR" USING WS-PEGA-ERRO
44 END-IF.
45 CLOSE FD-VIRTUAL.
46 DISPLAY "Quantidade de registros = " TB-CONTA-REC
47 DISPLAY X"0D".
48 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
49 ACCEPT WS-ENTER.
50 STOP RUN.
51 END PROGRAM CAP07AP47.
------ ------------------------------------------------------------------------

Ao ser executado o programa é apresentada a quantidade de registros existentes no arquivo. Observe que o código é
simplificado se comparado com outros programas já indicados, pois não é necessário possuir a estrutura de dados para
leitura e armazenamento dos dados na memória principal, apenas é necessário abrir o arquivo e percorrer seus regis-
tros contabilizando a quantidade existente.
É óbvio que a solução indicada, e normalmente usada, não é a mais conveniente para se obter a quantidade de regis-
tros de um arquivo, pois o tempo de execução de um programa desses poderá ser demorada dependendo do tamanho
do arquivo avaliado.
O que se pode fazer neste sentido é criar uma rotina de programa que administre um pequeno arquivo auxiliar que
tenha um só registro com a quantidade de registros existentes no arquivo principal. Esse arquivo auxiliar deverá ser lido
antes da operação inicial no arquivo principal e ter sua quantidade atualizada de registros com a entrada de novos re-
gistros no arquivo principal forem feitas ou ajustar a quantidade de registros se operações de compactação estiverem
348 PRO G RA MA Ç ÃO CO B OL

em uso. Este exemplo não é apresentado, por ser considerado intermediário e estar fora do escopo e objetivos deste
trabalho.

7.9 MELHORIA NO CONTROLE DE ACESSO AOS REGISTROS DE UM ARQUIVO


Os programas apresentados neste capítulo demonstram acessos de leitura, escrita, atualização, remoção e posiciona-
mento de registros com base no controle operacional da ação a partir do próprio comando. Assim sendo, os comandos:
READ, WRITE, REWRITE, DELETE, START e RETURN possuem como cláusulas auxiliares de validação condicional
de acesso os indicativos [NOT] AT END ou [NOT] INVALID KEY que apesar de serem práticas tornam o controle de
acesso aos erros limitantes, uma vez que não é possível ter controle apurado além do que é oferecido pelas cláusulas.
Desta forma, usar [NOT] AT END ou [NOT] INVALID KEY, principalmente com os comandos READ, WRITE, REWRI-
TE, DELETE ou START pode não ser adequado, exceto ao comando RETURN que necessita apenas validar se sua
ação chegou ao final do arquivo. A melhor alternativa para realizar controle adequado de acesso aos registros é fazer
uso dos comandos READ, WRITE, REWRITE, DELETE ou START em sua forma mais simples e definir ações de con-
trole com os comandos IF e ELSE. No entanto, para que isso seja possível é importante estar atento aos códigos de
retorno de erro no acesso as operações de arquivos como são indicados na tabela 7.1. A tabela 7.18 apresenta os
comandos de acesso a registros de um arquivo e um resumo dos respectivos códigos de erro que cada um desses
comandos pode obter com suas operações, acrescentando-se o comando RETURN.

Tabela 7.18 Códigos de erro por operações de acesso

Comando Códigos de erro


READ 02, 04, 08, 10, 13, 14, 15, 21, 30, 25, 46, 47, 51, 99
WRITE 02, 06, 22, 23, 24, 30, 34, 44, 48, 51, 99
REWRITE 02, 21, 23, 30, 43, 44, 49, 99
DELETE 21, 23, 30, 43, 49, 51, 99
START 23, 25, 30, 46, 47
RETURN 10

Observe na tabela 7.18 que os comandos mais sensíveis são READ e WRITE, que com sensibilidade média tem-se os
comandos RETURN e DELETE e com baixa sensibilidade os comandos START e RETURN. Do conjunto de comandos
apresentados, dois não necessitam de grande preocupação sendo: START e RETURN, pois as cláusulas que possuem
são suficientes para o controle adequado de suas operações. No entanto, para os demais comandos é necessário mai-
or atenção, mas não em todos os códigos de erros, mas nos códigos específicos as operações relacionadas diretamen-
te ao acesso dos registros no arquivo, como indicado na tabela 7.19.

Tabela 7.19 Códigos de erro, ações e comandos relacionados

Código Significado Comandos


10 Fim de arquivo encontrado (arquivo sequencial) READ
13 Não há próximo registro lógico (fim de arquivo) READ
22 Registro existente no arquivo WRITE
23 Registro não encontrado WRITE, REWRITE, DELETE
43 Leitura não realizada antecipadamente REWRITE, DELETE

A partir desta visão fica mais simples criar rotinas de programas que sejam operacionalmente mais adequadas para o
uso comum. A fim de exemplificar o que é exposto considere um programa que permita cadastrar e pesquisar registros
com um nível de controle fora do uso das cláusulas [NOT] AT END ou [NOT] INVALID KEY.
UT ILI ZA ÇÃ O D E A RQ U IV OS 349

O programa a seguir a partir de um pequeno menu apresenta as opções de cadastro e pesquisa de registros com os
controles de acesso realizados com uso dos comandos IF e ELSE. Assim sendo, abra um projeto vazio atribuindo-lhe o
nome cap07ap48 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.
350 PRO G RA MA Ç ÃO CO B OL

Anotações

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________
IN TE R FA C E C O M O U SUÁ R IO 351

INTERFACES COM O USUÁRIO

Neste capítulo são apresentadas as duas maneiras populares de se estabelecer uma interface de comunica-
ção com os usuários por meio de emissão de relatórios e estruturação da parte visual das telas de um pro-
grama ou sistema. A interface de tela é uma interface utilizada diretamente pelo usuário do programa frente
ao computador, mas os relatórios impressos podem estar sendo utilizados por usuários fisicamente mais dis-
tantes. É oportuno esclarecer que a forma de tratamento de tela apresentada neste capítulo refere-se ao uso
da linguagem na baixa plataforma, pois na alta plataforma o tratamento de telas é realizado de maneira dife-
rente.

8.1 UTILIZAÇÃO DE RELATÓRIOS


Um relatório, do ponto de vista computacional, pode ser entendido como sendo
a apresentação descritiva na forma de listagem das características e/ou organi-
zação lógica do conjunto de dados existentes nos registros de um arquivo.
Um relatório é, normalmente, composto por cabeçalho, corpo e opcionalmente
por um rodapé. O cabeçalho é usado para indicar o nome do relatório e a defi-
nição de outras informações de cunho geral a respeito dos dados apresenta-
dos. O corpo é definido a partir da indicação dos dados agrupados linearmente
sob alguma ordem a formar os detalhes que dão sentido contextualizado ao
conjunto de dados relatados no documento. O rodapé quando em uso é apre-
senta informações complementares.
A figura 8.1 mostra de forma esquematizada a configuração típica da estrutura
básica simplificada de um relatório.
Um relatório pode ser impresso fisicamente em papel ou ser gerado logicamen-
te na forma de um arquivo sequencial denominado arquivo de impressão com a
finalidade de ser impresso ou transferido por outros programas a partir de uma Figura 8.1 – Layout básico de relatório
gama de formatos como: ASCII, EBCDIC, CVS, XML, etc.
Um arquivo de impressão caracteriza-se por ser um conjunto de registros dispostos em formato linear formados por um
conjunto indeterminado de caracteres imprimíveis (de 0 a N caracteres) finalizados com o código de controle X"0D"
para retorno de carro que garante que a impressora ou arquivo gerado entendam que ao final de cada registro há a
indicação de movimentação de uma linha a frente.
Em COBOL é possível gravar (enviar) o arquivo de impressão diretamente para uma impressora obtendo-se a impres-
são física dos registros em papel ou por meio de um arquivo de impressão gravado em disco para posterior impressão
ou qualquer outra forma de uso. Para a linguagem COBOL o periférico de impressão (impressora) é naturalmente con-
sidera como sendo um arquivo de organização sequencial linear operado em modo sequencial.
Na definição de relatórios, principalmente os formatos impressos, é importante ter em mente o tamanho deste docu-
mento. Os quatro tamanhos mais populares para a criação de relatórios impressos são 32, 80, 132 e 136 colunas. Isto
352 PRO G RA MA Ç ÃO CO B OL

significa que é possível encontrar formulários padronizados com essas dimensões. No entanto, podem existir impressos
de relatórios com tamanhos diferentes, como por exemplo usar papéis nos tamanhos A3 e A4.
O tamanho de 32 colunas é comum em aplicações de impressão de cupons fiscais, comandas, entre outras aplicações.
Este formulário é vendido na forma de bobina de papel térmico na dimensão de 80mm de largura, que equivale a im-
pressão de até 32 caracteres por linha (utilizando a largura padrão do caractere impresso na impressora) com 40m de
comprimento, que garante a impressão de até 1.564.000 linhas aproximadas (utilizando o comprimento padrão do ca-
ractere impresso por linha) por bobina. Em bobinas de papel térmico somente há a preocupação de manter a impressão
dentro do limite de 32 colunas, a quantidade de linhas por ser variada não requer grande atenção.
O tamanho de 80 colunas é comum em aplicações de impressão de notas fiscais, recibos, guias, relatórios, entre ou-
tros. Este papel é vendido na forma de formulário contínuo destinado a impressoras matriciais na dimensão de 240mm
de largura e 280mm de comprimento o que permite a impressão de até 80 caracteres por linha (utilizando a largura
padrão do caractere impresso na impressora) com até 66 linhas (utilizando o comprimento padrão do caractere impres-
so por linha).
Os tamanhos de 132 e 136 colunas (utilizando a largura padrão do caractere impresso na impressora) possuem respec-
tivamente as dimensões de largura com 375mm e 395mm com comprimento de 280mm (com até 66 linhas, conside-
rando o comprimento padrão de cada caractere impresso por linha). A aplicação mais comum desse tipo de formulário é
a impressão de relatórios em impressoras matriciais.
Além das impressoras térmicas e matriciais é comum o uso de impressoras laser e jatos de tinta que operam mais co-
mumente com papéis nos tamanhos A3 e A4. Estes tipos de papel são usados para diversas finalidades de impressão.
O papel tamanho A3 possui a dimensão de 297mm de largura por 420mm de comprimento que equivale a 164 colunas
com até 70 linhas, considerando o comprimento padrão de cada caractere impresso em modo paisagem e o papel ta-
manho A4 possui a dimensão de 210mm de largura por 297mm de comprimento que equivale a 82 colunas com até 70
linhas impressas, considerando o modo retrato.
O compilador GnuCOBOL a partir da versão 2.2 possui os dois estilos de uso de relatórios. Um estilo comum onde se
especifica detalhadamente os aspectos físicos e lógicos de um relatório e o estilo a partir do uso do recurso do escritor
de relatórios encontrado na maioria dos compiladores, onde o desenvolvimento do relatório segue uma forma simplifi-
cada de definição. Adiante são mostrados de forma básica as duas formas de criação e uso de relatórios baseando-os
em papéis tamanho A4 com 80 colunas e 68 linhas efetivas de texto. A primeira e última de colunas e de linhas não são
usadas, caracterizando-se apenas como margens de apoio ao papel.

8.1.1 Relatório com arquivo de impressão em disco


Um relatório com arquivo sequencial de impressão gravado em disco caracteriza-se por ser o estilo mais simples de
definição de relatórios em COBOL. Neste sentido, será demonstrado um programa que gera um arquivo sequencial com
a listagem dos funcionários cadastrados no arquivo ARQDINIX.DYN.
A partir da visão geral sobre o que é um relatório, do que é um arquivo de impressão e das dimensões que podem ser
adotadas em um relatório cabe considerar que os arquivos de impressão são operacionalizados em modo OUTPUT o
que leva ao uso do comando (verbo) WRITE. No entanto, o comando WRITE usado na geração de arquivos de impres-
são possui configuração diferente da forma até então usada. Observe sua estrutura sintática.

WRITE <registro-impressão> FROM <variável / constante> AFTER / BEFORE


[ADVANCING] <linhas | PAGE>

Onde, registro-impressão é a definição da linha de registro a ser impressa no relatório, a indicação variável ou cons-
tante é a definição do conteúdo a ser movido pela cláusula FROM para dentro do registro-impressão antes de gravar
este conteúdo no arquivo de impressão. As cláusulas AFTER (depois) ou BEFORE (antes) efetuam respectivamente a
ação de registro de salto depois da gravação ou antes da gravação com base na quantidade de linhas ou da execução
de página (PAGE). A cláusula ADVANCING é opcional e por esta razão normalmente omitida.
O relatório exemplificado a seguir é composto pelo conjunto de campos do código funcional, nome do funcionário, de-
partamento em que o funcionário trabalha e pelo salário recebido. Observe na figura 8.2 o layout básico de configura-
ção deste relatório. Para criar layouts de um relatório aconselha-se o uso de papel quadriculado na dimensão do relató-
rio desejado
IN TE R FA C E C O M O U SUÁ R IO 353

Figura 8.2 – Layout básico de formatação do relatório

O cabeçalho da página é composto por seis linhas, sendo a primeira e sexta linhas formada por um tracejado. As linhas
internas ao tracejados apresentam informação contendo o nome da empresa, a data de emissão do relatório, o nome
do relatório, o número da página impressa e a identificação das colunas de informação apresentadas no relatório; o
corpo, parte principal do relatório, é formado pela indicação do número de identificação funcional, do nome do funcioná-
rio, do departamento em que o funcionário se encontra locado e seu respectivo salário e o rodapé do relatório contém a
quantidade de registros existentes no arquivo será apresentado apenas na última página. Mais detalhes sobre a estru-
tura física de um relatório é indicado no próximo subtópico.
As linhas tracejadas indicadas na figura 8.2 possuem exatamente 80 colunas de comprimento e por conseguinte cada
linha do relatório está distribuída entre as 80 colunas possíveis de uso.
Para a definição do arquivo de impressão deve-se fazer uso do comando SELECT associando o relatório a um arquivo
de organização sequencial linear com modo de acesso sequencial a partir da definição no parágrafo FILE-CONTROL
na seção INPUT-OUTPUT da ENVIRONMENT DIVISION. Observe o estilo da definição de um arquivo de impressão.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT <fd-relatório> ASSIGN TO "<arquivo/impressora>"
ORGANIZATION IS LINE SEQUENTIAL
ACCESS MODE IS SEQUENTIAL.

Onde, fd-relatório é a descrição do arquivo de impressão associado a um arquivo físico quando em uso no me de um
arquivo em arquivo/impressora ou a indicação da porta de conexão da impressora no computador.
Após o estabelecimento da associação do relatório ao arquivo de impressão é necessário na FILE SECTION em DATA
DIVISION fazer a descrição do arquivo de impressão com um registro de linha com a definição do tamanho de caracte-
res a ser impresso. Observe esta definição.

DATA DIVISION.
FILE SECTION.
FD <fd-relatório>.
01 <registro-de-impressão> PIC <quantidade-de-caracteres>.

Onde, em registro-de-impressão se define a estrutura de um registro de linha usada para a impressão com a quanti-
dade-de-caracteres definidas indicando quantas colunas são usadas. A indicação FD-relatório refere-se ao mesmo
nome indicado junto ao comando SELECT.
Após definição da estrutura do registro junto ao arquivo de impressão torna-se necessário definir os componentes de
formação do relatório, como: algumas variáveis auxiliares, cabeçalho, corpo e rodapé. A definição de variáveis auxilia-
res deve ser efetuada junto as seções WORKING-STORAGE ou LOCAL-STORAGE na FILE-SECTION. Veja no trecho
354 PRO G RA MA Ç ÃO CO B OL

a seguir as definições das variáveis auxiliares principais para a criação de um arquivo de impressão, ressaltando que
outras variáveis podem ser definidas.

WORKING-STORAGE SECTION | LOCAL-STORAGE SECTION.


77 <página> PIC 9(03) VALUE 0.
77 <linha> PIC 9(02) VALUE <número-máximo-de-linhas-por-página>.

A figura 8.2 mostra a indicação da apresentação da data de impressão, do número da página e da quantidade de regis-
tros do arquivo listado. Para essas operações podem ser definidas as variáveis para obtenção da data corrente do sis-
tema, do número de página, e do contador de registros do arquivo em uso.
Após a definição das variáveis de apoio torna-se necessário definir a estrutura básica do relatório em si. Assim sendo,
observe o trecho de código seguinte, o qual descreve o cabeçalho, o corpo e o rodapé do relatório.

77 TRACO PIC X(80) VALUE ALL "-".


* CABECALHO
01 CAB01.
05 FILLER PIC X(64) VALUE "EMPRESA XPTO".
05 FILLER PIC X(06) VALUE "DATA: ".
05 <datasis> PIC 9(10).
01 CAB02.
05 FILLER PIC X(64) VALUE "RELACAO DE FUNCIONARIOS".
05 FILLER PIC X(07) VALUE "PAGINA:".
05 <página> PIC Z(08)9.
01 CAB03.
05 FILLER PIC X(09) VALUE "CODIGO".
05 FILLER PIC X.
05 FILLER PIC X(40) VALUE "NOME".
05 FILLER PIC X.
05 FILLER PIC X(16) VALUE "DEPTO".
05 FILLER PIC X.
05 FILLER PIC X(12) VALUE "SALARIO (R$)".
* CORPO
01 CORPO.
05 CRP-CODIGO PIC X(09).
05 FILLER PIC X.
05 CRP-NOME PIC X(40).
05 FILLER PIC X.
05 CRP-DEPTO PIC Z(02)99.
05 FILLER PIC X(09).
05 CRP-SALARIO PIC Z,ZZZ,ZZZ,ZZ9.99.
* RODAPE
01 RODAPE.
05 FILLER PIC X(19) VALUE "TOTAL DE REGISTROS:".
05 <conta-reg> PIC Z(04)9.

No trecho indicado, a variável TRACO é definida com o tamanho de 80, sendo a largura máxima de caracteres por linha
a ser considerada para a estrutura do relatório, tendo as suas posições (VALUE ALL) definidas com o símbolo “-“.
A estrutura visual do relatório, propriamente dito, é separada em três grupos identificados com as linhas de comentários
CABECALHO, CORPO e RODAPE, onde em cada grupo é especificado os elementos componentes a serem gerados.
O trecho de identificação do cabeçalho (CABECALHO) para a figura 8.2 é formado por três segmentos representados
pelas variáveis CAB01, CAB02 e CAB03, descritos a seguir:
 Na variável CAB01 (primeira linha do cabeçalho) há a indicação de dois campos indefinidos contendo no primeiro
campo o título com o nome da empresa, neste caso “EMPRESA XPTO” escrito à esquerda do relatório dentro de
um espaço de 64 posições e o segundo campo com o título “DATA:” para indicar a data do sistema escrito a partir
do primeiro título com o espaçamento de 6 posições, perfazendo um total de 70 espaços. O campo definido datasis
com tamanho 10 indica o uso de uma variável associada a obtenção da data do sistema, sendo tratada na PROCE-
IN TE R FA C E C O M O U SUÁ R IO 355

DURE DIVISION. Note que a soma dos espaços dos dois títulos e da data perfazem um total de 80 posições que é
o limite de tamanho da linha do relatório.
 Na variável CAB02 são definidos dois campos indefinidos contendo os títulos da segunda linha do cabeçalho. O
primeiro título a esquerda indica o nome do relatório “RELACAO DE FUNCIONARIOS” utilizando-se de 64 posi-
ções, A partir da sexagésima quarta posição é apresentado o segundo título com o texto “PAGINA:” com 7 posi-
ções. Para a apresentação do número da página usa-se o campo definido página que deverá fazer uso dos espa-
ços restantes até completar 80 posições. Observe que os títulos da segunda linha ocupam respectivamente 64 e 7
posições, perfazendo um total de 71 posições que para 80 indicam faltar 9 posições. O campo página que tem o va-
lor do número da página usa o formato Z(08)9 que indica o espaço restante de nove posições para o estilo
ZZZZZZZZ9.
 A variável CAB03 é usado apenas para apresentar os nomes dos títulos dos campos das colunas a serem impres-
sas na quarta linha do relatório. Veja que todos os seus campos são declarações indefinidas. Para a apresentação
do código funcional na coluna CODIGO é usado 9 espaços mais um espaço indefinido, perfazendo 10 espaços. Pa-
ra o título NOME usa-se 40 espaços mais um espeço indefinido perfazendo 41 espaços. Para o título DEPTO usa-
se 16 espaços mais um indefinido totalizando 17 espaços e por último para o título SALARIO (R$) usa-se 12 espa-
ços. Ao somar os valores 10, 41, 17 e 12 obtém-se o total de 80 posições.
A variável CORPO é a parte mais importante do relatório, pois é ela que forma a linha de registro a ser impressa. Para
sua composição são definidos campos que devem ser posteriormente vinculados aos campos do arquivo de dados em
uso. No trecho indicado, o campo CRP-CODIGO de 9 posições com mais um espaço indefinido (10 espaços) é usado
para representar a apresentação do código funcional, o campo CRP-NOME de 40 posições com mais um espaço inde-
finido (41 espaços) é usado para indicar os nomes do funcionários, o campo CRP-DEPTO usa para sua apresentação o
formato Z(02)99 que define dois espaços em branco antes dos dois dígitos de identificação do departamento perfazen-
do no total 4 espaços sendo seguido de 9 espaços em branco e por último o campo CRP-SALARIO que usa 16 espa-
ços para apresentar o valor do salário de forma formatada. Se forem somados os valores 10, 41, 4, 9, e 16 tem-se o
tamanho de 80 posições para a linha de registro do relatório.
Para o rodapé do relatório por meio da variável RODAPE faz-se uso de um campo indefinido com o objetivo de apre-
sentar o título “TOTAL DE REGISTROS:” e ao seu lado mostrar a quantidade de registros existente no arquivo apre-
sentado no relatório com o campo conta-reg. Esta é a única linha do relatório que não contém 80 posições de uso.
A partir da visão geral do que é e como é composto um relatório é pertinente mostrar um programa que gere este com-
ponente. Assim sendo, abra um projeto vazio atribuindo-lhe o nome cap08ap01 e extensão “.cob” na subpasta COBOL
da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP01 AS "Capitulo 8 – Aplicacao 1".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 *
7 FILE-CONTROL.
8 * Definicao de acesso ao arquivo da base de dados
9 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
10 ORGANIZATION IS INDEXED
11 ACCESS MODE IS DYNAMIC
12 RECORD KEY IS F001-CODFUN
13 FILE STATUS IS WS-PEGA-ERRO.
14 * Definicao de acesso ao arquivo de impressao
15 SELECT FD-REL01 ASSIGN TO "LISTAGEM.LST"
16 ORGANIZATION IS LINE SEQUENTIAL
------ ------------------------------------------------------------------------
356 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
17 ACCESS MODE IS SEQUENTIAL.
18 *
19 DATA DIVISION.
20 FILE SECTION.
21 COPY "FDVIRTUAL.CPY".
22 * Definicao da estrutura do registro do arquivo de impressao
23 FD FD-REL01.
24 01 REL01-REG-IMPRES PIC X(80).
25 *
26 WORKING-STORAGE SECTION.
27 COPY "FSCODERR.CPY".
28 COPY "TBVIRTUAL.CPY".
29 77 WS-PEGA-ERRO PIC XX.
30 * Variaveis de auxilio as operacoes com relatorio
31 77 CONTAREC PIC 9(05) VALUE 0. *> Contador de registros
32 77 PAGINA PIC 9(03) VALUE 0. *> Contador de paginas
33 77 LINHA PIC 9(02) VALUE 99. *> Contador de linhas
34 *> com valor de estouro para
35 *> gerar cabecalho
36 * ESTRUTURA DE MONTAGEM DO RELATORIO
37 77 TRACO PIC X(80) VALUE ALL "-".
38 * Cabecalho
39 01 CAB01.
40 05 FILLER PIC X(64) VALUE "EMPRESA XPTO".
41 05 FILLER PIC X(06) VALUE "DATA: ".
42 05 CAB01-DATA PIC 9(10).
43 01 CAB02.
44 05 FILLER PIC X(64) VALUE "RELACAO DE FUNCIONARIOS".
45 05 FILLER PIC X(08) VALUE "PAGINA: ".
46 05 CAB02-PAGINA PIC Z(07)9.
47 01 CAB03.
48 05 FILLER PIC X(09) VALUE "CODIGO".
49 05 FILLER PIC X.
50 05 FILLER PIC X(40) VALUE "NOME".
51 05 FILLER PIC X.
52 05 FILLER PIC X(16) VALUE "DEPTO".
53 05 FILLER PIC X.
54 05 FILLER PIC X(12) VALUE "SALARIO (R$)".
55 * Corpo
56 01 CORPO.
57 05 CRP-CODIGO PIC X(09).
58 05 FILLER PIC X.
59 05 CRP-NOME PIC X(40).
60 05 FILLER PIC X.
61 05 CRP-DEPTO PIC Z(02)99.
62 05 FILLER PIC X(09).
63 05 CRP-SALARIO PIC Z,ZZZ,ZZZ,ZZ9.99.
64 * Rodape para ultima pagina impressa
65 01 RODAPE.
66 05 FILLER PIC X(20) VALUE "TOTAL DE REGISTROS: ".
67 05 ROD-CONTADOR PIC ZZZZ9.
68 * Variaveis comuns ao controle do programa
69 77 WS-ENTER PIC X.
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 357

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
70 77 TB-EOF PIC X.
71 01 WS-DATA-CORRENTE-SISTEMA.
72 05 WS-DATA-CORRENTE.
73 10 WS-DATA-CORRENTE-ANO PIC 9(04).
74 10 WS-DATA-CORRENTE-MES PIC 9(02).
75 10 WS-DATA-CORRENTE-DIA PIC 9(02).
76 *
77 PROCEDURE DIVISION.
78 PROG-PRINCIPAL-PARA.
79 * Abertura do arquivo de dados e relatorio
80 OPEN INPUT FD-VIRTUAL
81 OUTPUT FD-REL01.
82 * Preparacao da data a ser apresentada no cabecalho
83 MOVE FUNCTION CURRENT-DATE TO WS-DATA-CORRENTE-SISTEMA
84 STRING WS-DATA-CORRENTE-DIA "/" WS-DATA-CORRENTE-MES "/"
85 WS-DATA-CORRENTE-ANO INTO CAB01-DATA.
86 * Leitura do arquivo de dados e preparacao das linhas de
87 * impressao
88 PERFORM UNTIL TB-EOF = "V"
89 READ FD-VIRTUAL
90 AT END
91 MOVE "V" TO TB-EOF *> Quando atingir o final do ar-
92 PERFORM 200-RODAPE *> quivo mostra o rodape
93 END-READ
94 IF LINHA > 67 *> Quantidade maxima de linhas por pagina
95 PERFORM 100-CABECALHO
96 END-IF
97 ADD 1 TO LINHA, CONTAREC
98 MOVE F001-CODFUN TO CRP-CODIGO *> Preparacao dos campos
99 MOVE F001-NOME TO CRP-NOME *> do arquivo de dados
100 MOVE F001-DEPTO TO CRP-DEPTO *> para o arquivo de im-
101 MOVE F001-SALARIO TO CRP-SALARIO *> pressao
102 * Escreve o conteudo do CORPO na linha de registro do arqui-
103 * vo REL01-REG-IMPRES e pede para em seguida saltar uma li-
104 * nha a frente
105 WRITE REL01-REG-IMPRES FROM CORPO AFTER 1
106 END-PERFORM.
107 *
108 100-CABECALHO SECTION.
109 ADD 1 TO PAGINA.
110 MOVE 9 TO LINHA.
111 MOVE PAGINA TO CAB02-PAGINA.
112 IF PAGINA = 1
113 * se for a primeira pagina do relatorio salte uma linha em
114 * branco para depois (AFTER 1) gerar uma linha tracejada na
115 * linha de registro REL01-REG-IMPRES
116 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1
117 ELSE
118 * se nao for a primeira pagina do relatorio gere uma linha
119 * com espaços em branco e depois efetue eject de pagina na
120 * na impressora (AFTER PAGE)
121 WRITE REL01-REG-IMPRES FROM SPACES AFTER PAGE
122 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1
------ ------------------------------------------------------------------------
358 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
123 END-IF.
124 * Mostra o cabecalho do relatorio
125 WRITE REL01-REG-IMPRES FROM CAB01 AFTER 1.
126 WRITE REL01-REG-IMPRES FROM CAB02 AFTER 1.
127 WRITE REL01-REG-IMPRES FROM CAB03 AFTER 2.
128 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1.
129 WRITE REL01-REG-IMPRES FROM SPACES AFTER 1.
130 EXIT.
131 *
132 200-RODAPE SECTION.
133 MOVE CONTAREC TO ROD-CONTADOR.
134 WRITE REL01-REG-IMPRES FROM TRACO AFTER 2.
135 WRITE REL01-REG-IMPRES FROM RODAPE AFTER 1.
136 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1.
137 WRITE REL01-REG-IMPRES FROM SPACES BEFORE PAGE.
138 EXIT.
139 *
140 CLOSE FD-VIRTUAL, FD-REL01.
141 *
142 DISPLAY "RELATORIO: ARQUIVO DE IMPRESSAO EM DISCO".
143 DISPLAY "----------------------------------------".
144 DISPLAY X"0D".
145 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
146 ACCEPT WS-ENTER.
147 STOP RUN.
148 END PROGRAM CAP08AP01.
------ ------------------------------------------------------------------------

Ao ser executado o programa aparentemente nada ocorre, mas vá a pasta ou diretório em que o programa está grava-
do e peça par visualizar o conteúdo do arquivo LISTAGEM.LST, por exemplo, com o programa Bloco de notas ou
qualquer outro editor de textos de sua preferência, veja que o resultado apresentado está compatível com a estrutura
indicada na imagem da figura 8.2.
Parte do código do programa cap08ap01.cob está comentado e descrito com o uso de linhas de comentários (sinaliza-
das em vermelho). Atente cuidadosamente para cada um desses detalhes que são importantes para a adequada com-
preensão do desenvolvimento de relatórios. No entanto, há outros detalhes que precisam ser discutidos. Assim sendo,
atente para os detalhes comentados a seguir.
O trecho de código entre as linhas 9 e 13 define o acesso ao arquivo de dados ARQDINIX.DYN de organização indexa-
da com modo de acesso dinâmico e o trecho entre as linhas 15 e 17 definem o acesso ao arquivo de impressão, neste
caso, sendo o arquivo LISTAGEM.LST de organização sequencial linear em modo sequencial. Os arquivos de impres-
são são sempre definidos como arquivos de organização sequencial linear com acesso sequencial. É pertinente salien-
tar que as indicações ORGANIZATION IS LINE SEQUENTIAL e ACCESS MODE IS SEQUENTIAL podem ser omiti-
das. Veja que o arquivo físico de impressão LISTAGEM.LST é associado na linha 15 ao arquivo virtual FD-REL01 de-
clarado na descrição de arquivo indicado na linha 23. Veja que na linha 24 é definido o tamanho do registro de impres-
são REL01-REG-IMPRES que poderá conter no máximo 80 caracteres sendo este usado na composição da formação
das linhas impressas do relatório, sejam linhas usadas para os títulos ou registros.
Entre as linhas 33 e 25 são declaradas exclusivamente as variáveis de auxilio as operações de geração do relatório. A
variável CONTAREC é usada para contar a quantidade de registros lidos no arquivo, a variável PAGINA é usada para
indicar o número da página gerada e a variável LINHA é usada para controlar a quantidade de linhas geradas ou outras
operações.
As variáveis CONTAREC (linha 31) e PAGINA (linha 32) são iniciadas com valores zero, mas a variável LINHA (linha
33) é iniciada com valor 99. O valor 99 é maior que a quantidade de linhas permitida em papel A4 (máximo de 70 linhas)
IN TE R FA C E C O M O U SUÁ R IO 359

e é estabelecido, desta forma, como uma técnica para a apresentação do cabeçalho do relatório na primeira página
gerada, pois se isto não for feito a primeira página do relatório fica sem a apresentação de um cabeçalho. O controle
desta ação é efetuado entre as linhas 94 e 96 quando é verificado se o valor da LINHA é maior que 67, e neste caso
sendo, ocorre a chamada na linha 96 da sub-rotina 100-CABECALHO definida entre as linhas 108 e 130. Veja que
neste momento a variável PAGINA é acrescida de 1 na linha 109 e o valor da variável LINHA é atualizado para 9. O
valor 9 atribuído a variável LINHA se dá devido ao fato de o cabeçalho impresso ocupar oito linhas de texto, como mos-
tra a figura 8.3, lembrando que a primeira linha é normalmente deixada em branco e a oitava linha é apenas uma sepa-
ração entre o cabeçalho e os registros a serem apresentados.

Figura 8.3 – Layout com indicação das linhas do cabeçalho

No trecho de linhas entre 37 e 67 é estabelecida a estrutura de formatação do relatório de acordo com o que é indicado
na figura 8.1 e sugerido na figura 8.2. O cabeçalho é definido a partir dos campos CAB01 (linha 39), CAB02 (linha 43) e
CAB03 (linha 47). O corpo na linha 56 é definido pelos CRP-CODIGO (linha 57), CRP-NOME (linha 59), CRP-DEPTO
(linha 61) e CRP-SALARIO (linha 63). Por último o rodapé na linha 65 é definido a partir do campo ROD-CONTADOR
na linha 67. Veja que cada linha definida para a estrutura do relatório se usa no máximo 80 posições de cada linha.
Na definição do campo CAB01 entre as linhas 39 e 42 é indicado na linha 42 o campo CAB01-DATA usado para mos-
trar a data extraída do sistema e tratada entre as linhas 83 e 85. Já no campo CAB02 entre as linhas 43 e 46 é definido
na linha 46 e o campo CAB02-PAGINA que será usado para apresentar o valor da página do relatório tratado junto a
sub-rotina 100-CABECALHO na linha 108.
Entre as linhas 69 e 75 são definidas as variáveis de apoio ao programa como um todo. No entanto atente para a variá-
vel WS-DATA-CORRENTE-SISTEMA na linha 71 com os subcampos de acesso ao ano, mês e dia entre as linhas 73 e
75 para o campo WS-DATA-CORRENTE da linha 72. Os subcampos são usados entre as linhas 83 e 85 para gerarem
a informação do campo do relatório CAB01-DATA.
Nas linhas 80 e 81 são abertos os arquivos de trabalho. O arquivo FD-VIRTUAL é aberto em modo leitura e o arquivo
FD-REL01 é aberto em modo escrita, sendo essas ações controladas pelo trecho do programa entre as linhas 88 e 106.
Veja que a leitura é validada entre as linhas 89 e 93 e guando chegar ao final do arquivo a sub-rotina 200-RODAPE
(linha 92) é chamada indicando estar na última página do relatório. Caso não seja o final do arquivo de dados o trecho
entre as linhas 94 e 105 será executado.
Na linha 94 é verificado se a quantidade de linhas contadas para a variável LINHA excede a 67 (quantidade máxima de
linhas a ser impressa no relatório). Se o valor da variável LINHA for maior que 67 ocorre a chamada da sub-rotina de
apresentação do cabeçalho na linha 95 e é dada continuidade a execução do trecho entre as linhas 98 e 106. Se quan-
tidade de linhas é menor ou igual a 67 ocorre a execução do trecho de linhas entre 97 e 105.
A cada execução do trecho entre as linhas 97 e 105 ocorre a atualização na linha 97 dos valores das variáveis LINHA e
CONTAREC, da transferência do conteúdo dos campos do arquivo para os campos do relatório entre as linhas 98 e 101
e da escrita do registro de impressão indicado na linha 106.
Entre as linhas 108 e 130 encontra-se a sub-rotina de criação do cabeçalho que atualizada o número da página impres-
sa (linha 109) e ajusta o contador de linha para a primeira linha livre após a impressão do cabeçalho (linha 110). Isto é
feito, pois o cabeçalho ocupa as oito primeiras linhas da página como mostra a figura 8.3, ficando o restante do relatório
livre para uso após a linha 9. Na linha 112 a sub-rotina verifica se a variável PAGINA é igual a 1, sendo gera uma linha
tracejada após a emissão de uma linha em branco (AFTER 1) na linha 116 e não sendo emite o sinal de salto de página
(AFTER PAGE) na linha 121 após gerar uma linha com espaços em branco e na sequência gera uma linha tracejada
com antecipação de uma linha em branco (linha 122). No trecho de linhas entre 125 e 129 são escritas as linhas que
formam o cabeçalho do relatório.
360 PRO G RA MA Ç ÃO CO B OL

A sub-rotina para geração do rodapé entre as linhas 132 e 138 é executa uma única vez quando o programa se encon-
tra na última página do relatório. Veja que neste trecho são geradas duas linhas tracejadas indicadas nas linhas 134 e
137 com o conteúdo da variável RODAPE na linha 135 apresentado. Veja que na linha 134 usa-se a indicação AFTER
2, isto faz com que além de saltar uma nova linha seja gerada antes uma linha em branco. Outro detalhe é a indicação
na linha 137 do uso de BEFORE PAGE informando que ao final da criação da última linha do rodapé deve ocorrer um
salto de página para liberação do papel (quando o arquivo for direcionado a uma impressora).

8.1.2 Relatório com arquivo de impressão em papel


Direcionar o conteúdo de um arquivo de impressão para uma impressora ao invés de disco é uma operação considera-
da simples, pois basta indicar junto ao comando SELECT de definição do arquivo de impressão o local onde o periférico
de impressão está conectado. Dependendo do compilador em uso essa operação poderá ser definida de vária maneiras
diferentes da aqui retratada, pois nesta obra está sendo concentrado apenas o uso do compilador GnuCOBOL no sis-
tema operacional Windows.
Se você possui uma impressora conectada e devidamente configurada a seu computador sob controle do sistema ope-
racional Windows, basta em qualquer aplicação que tenha a opção de imprimir, solicitar esta operação e pronto você
obtém uma cópia impressa do conteúdo existente no aplicativo. Mas há aqui um detalhe, esse aplicativo é executado
em modo gráfico e como fica o uso de programas mais antigos que são executados apenas em modo texto, na forma
de uso do Prompt de comando?
Normalmente as impressoras conectadas no computador são definidas na porta USB (Universal Serial Bus). Essa porta
opera no sistema operacional Windows normalmente em modo gráfico, mas o mesmo não ocorre no modo do texto do
Prompt de comando. Se a impressora conectada usar uma porta paralela do tipo LPT (Line Terminal Printer) você con-
seguirá facilmente imprimir tanto em modo gráfico como em modo texto. Então o problema ocorre no uso de impresso-
ras do tipo USB em modo texto.
O modo de programação aplicado nesta obra é o modo texto. Desta forma, para conseguir gerar um relatório efetiva-
mente impresso em modo texto a partir de uma impressora USB é necessário fazer o mapeamento da porta USB como
sendo uma porta LPT, pois o sistema operacional Windows não realiza esta operação automaticamente. Assim, tudo o
que for enviado a porta LPT será direcionado a porta USB.
Para mapear a impressora USB como LPT é necessário ter em mãos duas informações: o nome do computador e da
impressora no seu sistema, mas antes disso é importante ter a impressora USB definida em modo de compartilhamen-
to.
Para verificar se a impressora está compartilhada, acione no Windows 10 o botão Iniciar e selecione Configurações e
será apresentada a tela indicada na figura 8.4. Em Configurações selecione a opção Dispositivos e selecione ao lado
esquerdo a opção Impressoras e escanners (figura 8.5).

Figura 8.4 – Tela: Configurações Figura 8.5 – Tela: Configurações


IN TE R FA C E C O M O U SUÁ R IO 361

Figura 8.6 – Tela: Impressoras e escanners Figura 8.7 – Seleção do botão: Gerenciar

Na tela Impressoras e escanners selecione no lado direito a impressora conectada em seu sistema como indica a
figura 8.6 e acione o botão Gerenciar como mostrado na figura 8.7. Selecione na sequência a opção Propriedades da
impressora como indicado na figura 8.8.
Ao ser apresentada a caixa de diálogo Propriedades de <nome da impressora> figura 8.9 selecione a guia Comparti-
lhamento e marque a opção Compartilhar esta impressora acionando em seguida os botões Aplicar e OK. Caso a
opção já esteja marcada acione o botão Cancelar. Após definir essas etapas anote o nome indicado no campo Nome
de compartilhamento e na tela de Configurações com o nome da impressora apresentado acione o botão superior
esquerdo com a imagem de uma seta para à esquerda ao lado do título Configurações por duas vezes de modo que
se tenha novamente a imagem da figura 8.4.

Figura 8.8 – Tela: Configurações Figura 8.9 – Seleção do botão: Gerenciar

Na sequência selecione a opção Sistema e role as opções do lado esquerdo até localizar a opção Sobre como indica a
figura 8.10, selecionando-a para apresentação de algumas informações adicionais do sistema como mostra a figura
8.11.
Em Nome do dispositivo anote o nome indicado a sua frente e feche a tela Configurações. O próximo passo é execu-
tar o modo do Prompt de comando em modo administrador. Ao lado direito do botão Iniciar no campo de pesquisa
informe o nome cmd e quando apresentado o resultado da pesquisa selecione a opção Executar como administra-
dor. Observe os detalhes indicados na figura 8.12.
Ao ser apresentado a tela do programa CMD é necessário para mapear a impressora fazer uso do comando do sistema
NET com a clausula USE indicando o nome da porta paralela e sua relação com o nome do computador e do comparti-
lhamento da impressora. Assim sendo, considere a instrução.

NET USE <unidade> "\\<computador>\<compartilhamento-da-impressora>" /PERSISTENT:YES


362 PRO G RA MA Ç ÃO CO B OL

Figura 8.10 – Tela de configurações com opção Sobre Figura 8.11 – Tela Sobre

Onde, unidade é a indicação, neste caso, da porta de acesso a impressora paralela; computador é o nome do compu-
tador e compartilhamento-da-impressora é o nome do compartilhamento no sistema.
O parâmetro /PERSISTENT:YES indica que este comando necessita ser efetuado uma única vez e manterá esta confi-
guração permanentemente. No entanto, poderá ocorrer situações onde o mapeamento poderá ser perdido por algum
motivo desconhecido, principalmente se ocorrer mudança de conexão da porta USB após o mapeamento.

Figura 8.12 – Execução do prompt de comando como administrador

De acordo com as informações apresentadas nas figuras 8.9 e 8.11 o comando NET pode ser executado a partir da
instrução.

NET USE lpt1: "\\PC-CASA\EPSON XP-400 Series" /PERSISTENT:YES

É pertinente salientar que em seu sistema os nomes do computador e do compartilhamento serão diferentes. O coman-
do NET USE faz o mapeamento da impressora USB indicada na porta paralela LPT1.
A partir deste ponto o sistema está ajustado para efetuar impressões em papel quando um programa enviar um arquivo
de impressão ao dispositivo LPT1. Basicamente a única mudança a ser feita é alterar no comando SELECT a indicação
do nome do arquivo físico de LISTAGEM.LST para LPT1. No entanto, no sentido de aprimorar um pouco mais a emis-
são de relatórios considere um relatório que apresente os códigos funcionais, os nomes em ordem alfabética ascenden-
te e os salários dos funcionários agrupados por departamento em ordem decrescente, mostrando no rodapé o total de
registros existentes no arquivo relatado. A figura 8.13 mostra a estrutura do layout a ser considerado.
IN TE R FA C E C O M O U SUÁ R IO 363

Figura 8.13 – Layout de formatação do relatório com quebras

Para atender a proposta indicada são definidos dois programas. O primeiro código efetua a criação do arquivo classifi-
cado com os departamentos em ordem decrescente e os nomes em ordem ascendente. O segundo programa efetua a
leitura do arquivo classificado e faz a impressão dos registros agrupados por departamento na impressora.
Para fazer uso do primeiro programa abra um projeto vazio e atribua o nome cap08ap02 e extensão “.cob” na subpasta
COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP02 AS "Capitulo 8 – Aplicacao 2".
3 ENVIRONMENT DIVISION.
4 CONFIGURATION SECTION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTENT ASSIGN TO "ARQDINIX.DYN"
8 ORGANIZATION IS INDEXED
9 ACCESS MODE IS DYNAMIC
10 RECORD KEY IS F001-CODFUN
11 FILE STATUS IS WS-PEGA-ERRO.
12 SELECT SD-VIRTEMP ASSIGN TO "ARQDINIX.TMP".
13 SELECT FD-VIRTSAI ASSIGN TO "ARQDINIX.CLF".
14 DATA DIVISION.
15 FILE SECTION.
16 FD FD-VIRTENT.
17 01 FS-CADFUN.
18 05 F001-CODFUN PIC X(09).
19 05 F001-NOME PIC X(40).
20 05 F001-DEPTO PIC 99.
21 05 F001-FUNCAO PIC X(20).
------ ------------------------------------------------------------------------
364 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
22 05 F001-SALARIO PIC 9(10)V99.
23 SD SD-VIRTEMP.
24 01 SD-CADFUN.
25 05 S001-CODFUN PIC X(09).
26 05 S001-NOME PIC X(40).
27 05 S001-DEPTO PIC 99.
28 05 S001-FUNCAO PIC X(20).
29 05 S001-SALARIO PIC 9(10)V99.
30 FD FD-VIRTSAI.
31 01 FD-CADFUN-SAI.
32 05 F002-CODFUN PIC X(09).
33 05 F002-NOME PIC X(40).
34 05 F002-DEPTO PIC 99.
35 05 F002-FUNCAO PIC X(20).
36 05 F002-SALARIO PIC 9(10)V99.
37 WORKING-STORAGE SECTION.
38 COPY "FSCODERR.CPY".
39 77 WS-PEGA-ERRO PIC XX.
40 77 WS-ENTER PIC X.
41 PROCEDURE DIVISION.
42 PROG-PRINCIPAL-PARA.
43 OPEN INPUT FD-VIRTENT
44 DISPLAY "CADASTRO DE FUNCIONARIOS"
45 DISPLAY "ORDENACAO NO ARQUIVO"
46 DISPLAY "------------------------"
47 SORT SD-VIRTEMP
48 ON DESCENDING KEY S001-DEPTO
49 ON ASCENDING KEY S001-NOME
50 USING FD-VIRTENT
51 GIVING FD-VIRTSAI.
52 DISPLAY X"0D".
53 DISPLAY "Classificacao processada.".
54 DISPLAY X"0D".
55 DISPLAY "DEPTO ..: Em ordem decrescente.".
56 DISPLAY "NOME ...: Em ordem ascendente.".
57 DISPLAY X"0D".
58 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
59 ACCEPT WS-ENTER.
60 CLOSE FD-VIRTENT.
61 STOP RUN.
62 END PROGRAM CAP08AP02.
------ ------------------------------------------------------------------------

Ao ser executado o programa ocorre a apresentação de mensagem informando que o arquivo está classificado com os
departamentos em ordem decrescente e os nomes em ordem ascendente. O estilo de código apresentado foi visto no
capítulo anterior. A atenção maior neste código é o trecho entre as linhas 47 e 51. Observe na 48 a solicitação de clas-
sificação do campo S001-DEPTO em ordem decrescente (ON DESCENDING) e na linha 49 a solicitação de classifica-
ção do campo S001-NOME em ordem ascendente (ON ASCENDING).
A execução do trecho de linhas entre 47 e 51 permite criar um arquivo onde seu conteúdo será preparado com a ordem
de definição dos campos de departamento e dentro deste critério a definição da ordem pelo campo dos nomes.
Para fazer uso do segundo programa abra um projeto vazio e atribua o nome cap08ap03 e extensão “.cob” na subpas-
ta COBOL da pasta Documentos e codifique as instruções seguintes.
IN TE R FA C E C O M O U SUÁ R IO 365

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP03 AS "Capitulo 8 – Aplicacao 3".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.CLF"
8 FILE STATUS IS WS-PEGA-ERRO.
9 SELECT FD-REL01 ASSIGN TO " LPT1" *> impressora
10 ORGANIZATION IS LINE SEQUENTIAL
11 ACCESS MODE IS SEQUENTIAL.
12 *
13 DATA DIVISION.
14 FILE SECTION.
15 COPY "FDVIRTUAL.CPY".
16 FD FD-REL01.
17 01 REL01-REG-IMPRES PIC X(80).
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 CONTAREC PIC 9(05) VALUE 0.
24 77 PAGINA PIC 9(03) VALUE 0.
25 77 LINHA PIC 9(02) VALUE 99.
26 77 TRACO PIC X(80) VALUE ALL "-".
27 01 CAB01.
28 05 FILLER PIC X(64) VALUE "EMPRESA XPTO".
29 05 FILLER PIC X(06) VALUE "DATA: ".
30 05 CAB01-DATA PIC 9(10).
31 01 CAB02.
32 05 FILLER PIC X(64) VALUE "RELACAO DE FUNCIONARIOS".
33 05 FILLER PIC X(08) VALUE "PAGINA: ".
34 05 CAB02-PAGINA PIC Z(07)9.
35 01 CAB03.
36 05 FILLER PIC X(09) VALUE "CODIGO".
37 05 FILLER PIC X.
38 05 FILLER PIC X(57) VALUE "NOME".
39 05 FILLER PIC X.
40 05 FILLER PIC X(12) VALUE "SALARIO (R$)".
41 * Definicao do subtitulo da quebra de agrupamento de dados e das
42 * variaveis de apoio ao gerenciamento da quebra
43 01 CORPO01.
44 05 FILLER PIC X(14) VALUE "DEPARTAMENTO: ".
45 05 CORPO01-DEPTO PIC 99.
46 77 WS-DEPTO-ATU PIC 99.
47 77 WS-DEPTO-ANT PIC 99.
48 * Estrutura da composicao para a linha de registro
49 01 CORPO02.
50 05 CRP-CODIGO PIC X(09).
50 05 FILLER PIC X.
52 05 CRP-NOME PIC X(53).
------ ------------------------------------------------------------------------
366 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
53 05 FILLER PIC X.
54 05 CRP-SALARIO PIC Z,ZZZ,ZZZ,ZZ9.99.
55 01 RODAPE.
56 05 FILLER PIC X(19) VALUE "TOTAL DE REGISTROS:".
57 05 ROD-CONTADOR PIC Z(04)9.
58 77 WS-ENTER PIC X.
59 77 TB-EOF PIC X.
60 01 WS-DATA-SISTEMA.
61 05 WS-DT-CORRENTE.
62 10 WS-DT-ANO PIC 9(04).
63 10 WS-DT-MES PIC 9(02).
64 10 WS-DT-DIA PIC 9(02).
65 *
66 PROCEDURE DIVISION.
67 PROG-PRINCIPAL-PARA.
68 OPEN INPUT FD-VIRTUAL
69 OUTPUT FD-REL01.
70 MOVE FUNCTION CURRENT-DATE TO WS-DATA-SISTEMA
71 STRING WS-DT-DIA "/" WS-DT-MES "/" WS-DT-ANO INTO CAB01-DATA.
72 MOVE 0 TO WS-DEPTO-ANT
73 PERFORM UNTIL TB-EOF = "V"
74 READ FD-VIRTUAL
75 AT END
76 MOVE "V" TO TB-EOF
77 PERFORM 300-RODAPE
78 END-READ
79 IF LINHA > 69
80 PERFORM 100-CABECALHO
81 END-IF
82 ADD 1 TO LINHA, CONTAREC
83 MOVE F001-CODFUN TO CRP-CODIGO
84 MOVE F001-NOME TO CRP-NOME
85 MOVE F001-DEPTO TO WS-DEPTO-ATU
86 MOVE F001-SALARIO TO CRP-SALARIO
87 PERFORM 200-QUEBRA
88 WRITE REL01-REG-IMPRES FROM CORPO02 AFTER 1
89 END-PERFORM.
90 *
91 100-CABECALHO SECTION.
92 ADD 1 TO PAGINA.
93 MOVE 9 TO LINHA.
94 MOVE PAGINA TO CAB02-PAGINA.
95 IF PAGINA = 1
96 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1
97 PERFORM 110-CABECALHO-AUXILIAR
98 ELSE
99 WRITE REL01-REG-IMPRES FROM SPACES AFTER PAGE
100 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1
101 PERFORM 110-CABECALHO-AUXILIAR
102 WRITE REL01-REG-IMPRES FROM SPACES AFTER 1
103 END-IF.
104 EXIT.
105 *
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 367

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
106 110-CABECALHO-AUXILIAR SECTION.
107 WRITE REL01-REG-IMPRES FROM CAB01 AFTER 1.
108 WRITE REL01-REG-IMPRES FROM CAB02 AFTER 1.
109 WRITE REL01-REG-IMPRES FROM CAB03 AFTER 2.
110 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1.
111 EXIT.
112 *
113 200-QUEBRA SECTION.
114 MOVE WS-DEPTO-ATU TO CORPO01-DEPTO
115 IF WS-DEPTO-ATU NOT = WS-DEPTO-ANT
116 WRITE REL01-REG-IMPRES FROM CORPO01 AFTER 2
117 WRITE REL01-REG-IMPRES FROM SPACES AFTER 1
118 ADD 3 TO LINHA
119 END-IF
120 MOVE WS-DEPTO-ATU TO WS-DEPTO-ANT
121 EXIT.
122 *
123 300-RODAPE SECTION.
124 MOVE CONTAREC TO ROD-CONTADOR.
125 WRITE REL01-REG-IMPRES FROM TRACO AFTER 2.
126 WRITE REL01-REG-IMPRES FROM RODAPE AFTER 1.
127 WRITE REL01-REG-IMPRES FROM TRACO AFTER 1.
128 WRITE REL01-REG-IMPRES FROM SPACES BEFORE PAGE.
129 EXIT.
130 *
131 CLOSE FD-VIRTUAL, FD-REL01.
132 *
133 DISPLAY "RELATORIO: ARQUIVO DE IMPRESSAO EM PAPEL".
134 DISPLAY "----------------------------------------".
135 DISPLAY X"0D".
136 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
137 ACCEPT WS-ENTER.
138 STOP RUN.
139 END PROGRAM CAP08AP03.
------ ------------------------------------------------------------------------

Ao ser executado o programa ocorre a apresentação dos nomes em ordem alfabética ascendente separado em grupos
de departamento dispostos em ordem numérica decrescente.
O código do programa cap08ap03.cob possui sua estrutura operacional muito próximo a estrutura operacional do códi-
go do programa cap08ap01.cob. No entanto, devido ao uso da quebra de agrupamento de dados seu contexto lógico é
mais complexo.
O principal recurso do programa está concentrado entre as linhas 43 e 47 onde são definidos o subtítulo do agrupamen-
to e a definição das variáveis de validação de grupo WS-DEPTO-ATU e WS-DEPTO-ANT respectivamente nas linhas
46 e 47. Dentro do contexto da estrutura do relatório os demais elementos entre as linhas 24 e 64 são conhecidos.
Antes do programa iniciar a criação do relatório é feita na linha 72 a inicialização da variável WS-DEPTO-ANT com
valor zero e a variável WS-DEPTO-ATU é atribuída com o valor do campo F001-DEPTO na linha 85. Observe na linha
87 a chamada da sub-rotina 200-QUEBRA que se encontra definida entre as linhas 113 e 121. Veja que a técnica de
quebra, conhecida do capítulo anterior, está sendo usada com auxílio da instrução de tomada de decisão definida entre
as linhas 115 e 121. Na linha 116 é indicada a chamada de execução do subtítulo do corpo do relatório indicado no
campo CORPO01 definido entre as linhas 43 e 47 que caracteriza o título da quebra.
368 PRO G RA MA Ç ÃO CO B OL

O controle do cabeçalho é executado entre as linhas 91 e 104 sendo chamado pela execução da linha 80 quando o
valor da variável LINHA for maior que o limite de 69 como aponta a linha 79. Veja que para manter o relatório dentro do
layout indicado na figura 8.13 é necessário o uso da sub-rotina de apoio 110-CABECALHO-AUXILIAR definida entre as
linhas 106 e 111.
Quando se utiliza quebra de grupos de registros é importante computar a quantidade de linhas usadas nessa ação. No
programa para a definição da quebra se usa três linhas. Daí o uso da instrução ADD 3 TO LINHAS na linha 118 além
da instrução ADD 1 TO LINHA, CONTAREC na linha 82.

8.1.3 Introdução ao escritor de relatórios


O estilo de desenvolvimento de relatórios apresentados anteriormente é sem sombra dúvida a forma mais genérica de
criar relatórios em qualquer compilador COBOL. No entanto, dependendo da complexidade que certo relatório venha a
necessitar, o modo apresentado, por seguir o estilo imperativo, torna-se trabalhoso e pode diminuir o nível de produtivi-
dade no desenvolvimento de programas, por ser necessário investir muito tempo no desenvolvimento dos detalhes de
um relatório e escrever mais de uma centena de linhas de código.
Um relatório, do ponto de vista estrutural, é um documento que pode ser dividido em sete itens estruturais como mostra
a figura 8.14. Anteriormente as figuras 8.2 e 8.13 mostraram respectivamente três e quatro itens estruturais. Na figura
8.2 foram usados estruturalmente os itens cabeçalho de página, corpo e rodapé de relatório e na figura 8.13 foram
usados estruturalmente os itens cabeçalho de página, cabeçalho de controle de corpo, corpo e rodapé de relatório.
O escritor de relatórios fornece recursos para tratar facilmente os sete itens de agrupamento. A figura 8.13 apresenta os
sete itens de dados que podem fazer parte de um relatório. Os itens cabeçalho do relatório e rodapé do relatório são
elementos apresentados uma única vez na emissão de um relatório respectivamente no início da primeira página e no
final da última página, os itens cabeçalho de página e rodapé de página são respectivamente apresentados no início
e no final de cada página e o corpo formado pelos itens de registro que compõem o relatório podem ser agrupados em
conjuntos de dados. Os itens do corpo podem possuir títulos intermediários para a indicação de cabeçalhos ou rodapés
apresentados antes ou depois de cada agrupamento definido respectivamente chamados de cabeçalho de controle
do corpo e rodapé de controle do corpo.
A descrição dos detalhes estruturais no escritor de relatório que com-
põem fisicamente a estrutura de um relatório devem ser realizadas
em uma seção chamada REPORT definida junto a divisão DATA
após as seções WORKING-STORAGE ou LOCAL-STORAGE (se
esta estiver em uso).
A descrição da estrutura física de um relatório na REPORT SECTION
deve estar associada a descrição do arquivo de relatório definido na
FILE SECTION, que deve estar por sua vez definido com o comando
SELECT em INPUT-OUTPUT SECTION.
Para fazer uso do modo escritor de relatórios é necessário na descri-
ção do relatório em FILE SECTION junto ao comando FD dizer que o
relatório a ser usado não está associado a uma linha de registro de
arquivo e sim associado a uma descrição de relatório definido na
REPORT SECTION indicado após a seção WORKING-STORAGE ou
LOCAL-STORAGE. Observe os principais detalhes de uso do escritor
Figura 8.14 – Itens que compõem um relatório
de relatório indicados a seguir.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
SELECT <fd-relatório> ASSIGN TO "<arquivo-impressão>".

DATA DIVISION.
FILE SECTION.
IN TE R FA C E C O M O U SUÁ R IO 369

FD <fd-relatório>
REPORT IS <rd-relatório>.

WORKING-STORAGE SECTION.
LOCAL-STORAGE SECTION.

REPORT SECTION.
RD <rd-relatório>
<configuração>.

Onde, fd-relatório é a definição do nome lógico associado com o comando SELECT a um arquivo físico de impressa
para disco ou impressora indicado em arquivo-impressão, rd-relatório é a definição da associação do relatório opera-
cionalizado pelo escritor de relatório definido na FILE SECTION com o relatório lógico definido em FD a partir da cláu-
sula REPORT IS. Em REPORT SECTION faz-se a definição da estrutura de configuração que o relatório possuirá.
O argumento configuração definido na descrição de relatório RD pode ser composto a partir de um conjunto de cláusu-
las de formatação que estabelecem a estrutura de formatação de um relatório e suas páginas. As áreas de formatação
de um relatório são opcionais e podem ser ou não utilizadas e/ou combinadas entre si a partir do recurso do escritor de
relatório chamado RWCS (Report Writer Control System). Observe as cláusulas de formatação que o descritor de rela-
tório RD utiliza.

RD <rd-relatório>
[CONTROL[S] [IS|ARE] {[FINAL] | [REPORT]}]
[PAGE {[LIMIT IS] | [LIMITS ARE]} <opção> [LINES]]
[LINE LIMIT IS <opção>]
[HEADING IS <opção>]
[FIRST DETAIL IS <opção>]
[LAST CONTROL HEADING IS <opção>]
[LAST DETAIL IS <opção>]
[FOOTING IS <opção>].

As cláusulas opcionais COLTROL IS e CONTROLS ARE são sinônimos intercambiáveis tendo o uso dos verbos IS e
ARE como elementos opcionais. Este recurso é destinado ao uso quando da definição de linhas adicionais para a ob-
tenção de totais ou subtotais quando em uso quebras de grupos de dados que podem ser definidos no corpo do relató-
rio (REPORT) ou no final do relatório (FINAL). Essa cláusula deve ser a primeira a ser definida antes das demais que
podem colocadas na ordem em que desejar.
A cláusula PAGE LIMIT disponibiliza uma série de outras cláusulas que permitem definir a estrutura geral das páginas
de um relatório sendo possível configurar o número de colunas, número de linhas, cabeçalhos, rodapés e outros deta-
lhes do corpo do relatório.
A clausula PAGE LIMIT IS ou PAGE LIMITS ARE são intercambiáveis e quando em uso permitem estabelecer a quan-
tidade de linhas imprimíveis por relatório. Para papéis A3 e A4 esse valor fica em 61 e para formulário contínuo de 80 e
132 (ou 136) colunas o valor fica em 66.
A cláusula LINE LIMIT IS da cláusula PAGE LIMIT é usada para especificar a quantidade de colunas a ser impressa
em um relatório. Para papéis A3 e A4 esse valor fica em 132 e 80 e para formulário contínuo o valor será o equivalente
a largura do formulário em número de caracteres (80, 132 ou 136 colunas).
As cláusulas HEADING IS e FOOTING IS da cláusula PAGE LIMIT são usadas para especificar respectivamente a
primeira linha de cabeçalho e a última linha de rodapé a ser usada pelo relatório.
As cláusulas FIRST DETAIL IS e LAST DETAIL IS da cláusula PAGE LIMIT são usadas quando se estabelece ações
para grupos de dados apresentados.
A cláusula LAST CONTROL HEADING IS da cláusula PAGE LIMIT é usada para definir a última linha de posição de
controle pode ser apresentada.
Normalmente o valor mais comum para a cláusula HEADING IS é 2 e para as demais cláusulas é necessário levar em
consideração as dimensões definidas a partir do valor máximo estabelecido para a cláusula PAGE LIMIT. Assim sendo,
é necessário levar em consideração algumas regras de definição de valores:
370 PRO G RA MA Ç ÃO CO B OL

 A clausula HEADING não pode ser maior que o valor da cláusula FIRST DETAIL;
 A clausula FIRST DETAIL não pode ser maior que o valor da cláusula LAST CONTROL HEADING;
 A clausula LAST CONTROL HEADING não pode ser maior que o valor da cláusula LAST DETAIL;
 A clausula LAST DETAIL não pode ser maior que o valor da cláusula FOOTING.
Após a definição do espaço operacional de configuração do relatório se faz necessário definir a estrutura física deste a
partir dos cabeçalhos, corpo e rodapés. Essa ação é produzida a partir da sucessão de uso da cláusula TYPE ou TYPE
IS, usada na definição do conjunto de cláusulas de itens de apresentação e especificação de um relatório que segue
como estilo a estrutura hierárquica seguinte.

CABEÇALHO DE RELATÓRIO | REPORT HEADING | (RH)


CABEÇALHO DE PÁGINA | PAGE HEADING | (PH)
CABEÇALHO DO CORPO | CONTROL HEADING [{[FINAL] / [LINE] [NEXT GROUP]}] | (CH)
CORPO | DETAIL | (DE)
RODAPÉ DO CORPO | CONTROL FOTTING [{[FINAL] / [LINE] [NEXT GROUP]}] | (CF)
RODAPÉ DE PÁGINA | PAGE FOOTING | (PF)
RODAPÉ DE RELATÓRIO | REPORT FOTTING | (RP)

Os elementos de configuração representados pelas cláusulas RH, PH, CH, DE, CF, PF e RP (ou definidas por duas
formas por extenso) são utilizadas especificamente para determinar o formato da estrutura de um relatório após a espe-
cificação da estrutura da página.
A cláusula REPORT HEADING (RH) é usada uma vez na primeira página e a cláusula REPORT FOOTING (RP) é
usada uma vez na última página de um relatório. O papel A4 possui 70 linhas efetivas de uso, sendo que, normalmente,
a primeira e a septuagésima linhas podem ser reservadas ao uso simplificado do cabeçalho e rodapé do relatório. Desta
forma, podem ser usadas livremente o espaço compreendido entre a segunda e sexagésima nova linhas, perfazendo o
total efetivo de 68 linhas. Os demais elementos da estrutura de um relatório PH, CH, DE, CF e PF podem ser usados
livremente dentro do espaço entre as linhas 2 e 60, além do fato dos elementos CH e CF poderem ser usados com um
identificador de agrupamento de dados com ou sem o uso da cláusula FINAL. Os detalhes não comentados dessas
ações são apresentados mais adiante.
As definições dos elementos de composição de um relatório são indicadas a partir do estabelecimento de um item de
grupo com código 01. Dentro de cada item de grupo cria-se um segundo item, um subitem de grupo, normalmente com
código 02, que é usado para manipular o posicionamento de linhas dos elementos de composição do relatório a partir
da cláusula LINE. Dentro do subitem de linha são definidos os campos de composição do relatório a partir da definição
das colunas com a cláusula COLUMN. As cláusulas LINE e COLUMN podem ser definidas como LINE NUMBER IS e
COLUMN NUMBER IS.
A cláusula LINE pode ser escrita a partir de algumas variações de expressão, como é comum a vários outros comandos
COBOL. O importante desta cláusula é que ela pode ser usada de forma absoluta a partir da forma LINE <n>, onde “n”
é a definição de um número de linha específico ou a partir da forma relativa com a indicação LINE PLUS <n> ou LINE +
<n>, onde “n” é a indica da quantidade de linhas a ser usada a partir da última linha efetiva aplicada.
A cláusula COLUMN corresponde a definição do que será apresentado diretamente no relatório. Para seu uso tem-se
como complemento duas cláusulas de apoio, a cláusula VALUE que permite a apresentação de títulos definidos e a
cláusula SOURCE que permite a apresentação de dados relacionados a variáveis ou campos de um arquivo de dados.
Assim como LINE a cláusula COLUMN também opera com efeito relativo de posicionamento utilizando PLUS ou “+”.
De forma geral, cada componente de composição e formatação de um relatório sendo RH, PH, CH, DE, CF, PF ou RP é
pode ser definido genericamente como:

01 TYPE < RH, PH, CH, DE, CF, PF ou RP>.


02 LINE <n>
03 COLUMN <m> PIC <formato> VALUE "título1".
03 COLUMN + 1 PIC <formato> SOURCE <dado1>.
02 LINE + 1
03 COLUMN <m> PIC <formato> VALUE "título2".
03 COLUMN + 1 PIC <formato> SOURCE <dado2>.
IN TE R FA C E C O M O U SUÁ R IO 371

Após especificar a estrutura física de formatação do relatório (dimensão da página e os tipos de itens a serem apresen-
tado) se faz necessário definir a estrutura lógica operacional que permitirá emitir o relatório. Isso é feito no código prin-
cipal do programa junto a divisão PROCEDURE a partir da estrutura sintática indicada a seguir.

PROCEDURE DIVISION.
OPEN INPUT <fd-dados>
OUTPUT <fd-relatório>.
INITIATE <rd-relatório>.
PERFORM UNTIL <verifica-fim-de-arquivo>
GENERATE <registro>
READ <fd-dados>
AT END
<marca-fim-de-arquivo >
END-READ
END-PERFORM.
TERMINATE <rd-relatório>.
CLOSE <fd-dados>, <fd-relatório>.
STOP RUN.

O trecho anterior mostra toda a estrutura da parte lógica a ser usada para a efetiva criação e uso do relatório. Veja que
o escritor de relatório depende apenas da descrição dos detalhes do relatório junto a REPORT SECTION. Observe que
inicialmente é necessário iniciar a geração do relatório com o comando INITIATE, a gravação do conteúdo no relatório é
executada pela instrução GENERATE e o encerramento do relatório é executado pela instrução TERMINATE.
Além dos detalhes indicados neste subtópico, existem outros elementos complementares ao desenvolvimento de relató-
rios que serão apresentados na medida em que se fizerem necessários.

8.1.4 Relatório simples no escritor de relatórios


A partir de uma visão geral do que efetivamente é um relatório e da rápida introdução ao modo escritor de relatórios é
oportuno usar este recurso para o desenvolvimento deste tipo de documento. Por questões econômicas e de consumo
os relatórios aqui apresentados são desenvolvidos na forma de arquivos de impressão em disco, mas desejando vê-los
impressos em papel, bastará direcionar a saída do arquivo para o modo de impressora LPT1 como orientado.
Usar o escritor de relatório proporciona o desenvolvimento de relatórios mais rápidos do que a forma tradicional, bas-
tando seguir algumas regras de definição e realizar algumas configurações especificando o formato do cabeçalho, cor-
po e rodapé pretendidos.
O modo escritor de relatório é um recurso que auxilia no desenvolvimento de relatórios, de modo que escrever um rela-
tório manualmente torna-se desnecessário, a menos que seja essa a intenção real pretendida pela equipe de profissio-
nais de desenvolvimento Assim fica a seu critério escolher a forma e o estilo do desenvolvimento de relatórios.
Assim sendo, considere como exemplo um relatório no estilo do layout da figura 8.2. Desta forma, abra um projeto vazio
e atribua o nome cap08ap04 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções
seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP04 AS "Capitulo 8 – Aplicacao 4".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
------ ------------------------------------------------------------------------
372 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
7 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.DYN"
8 ORGANIZATION IS INDEXED
9 ACCESS MODE IS DYNAMIC
10 RECORD KEY IS F001-CODFUN
11 FILE STATUS IS WS-PEGA-ERRO.
12 SELECT FD-REL01 ASSIGN TO "LISTAGE2.LST"
13 ORGANIZATION IS LINE SEQUENTIAL
14 ACCESS MODE IS SEQUENTIAL.
15 *
16 DATA DIVISION.
17 FILE SECTION.
18 COPY "FDVIRTUAL.CPY".
19 FD FD-REL01
20 REPORT IS RD-REL01.
21 *
22 WORKING-STORAGE SECTION.
23 COPY "FSCODERR.CPY".
24 COPY "TBVIRTUAL.CPY".
25 77 WS-PEGA-ERRO PIC XX.
26 * Variaveis gerais
27 77 WS-ENTER PIC X.
28 77 TB-EOF PIC X.
29 01 WS-DATA-SISTEMA.
30 05 WS-DATA-CORRENTE.
31 10 WS-DT-ANO PIC 9(04).
32 10 WS-DT-MES PIC 9(02).
33 10 WS-DT-DIA PIC 9(02).
34 * PARAMETROS DE CONFIGURACAO PARA O ESCRITOR DE RELATORIO
35 * Variaveis de apoio ao recurso relatorio
36 77 CONTAREC PIC 9(05) VALUE 0.
37 77 CAB01-DATA PIC X(10).
38 77 TRACO PIC X(80) VALUE ALL "-".
39 * Estrutura fisica da pagina do relatório
40 REPORT SECTION.
41 RD RD-REL01
42 PAGE LIMIT IS 68
43 LINE LIMIT IS 80
44 FIRST DETAIL IS 9.
45 * Estrutura fisica dos elementos de formacao do relatorio
46 01 TYPE PAGE HEADING.
47 02 LINE 2.
48 03 COLUMN 1 PIC X(80) SOURCE TRACO.
49 02 LINE 3.
50 03 COLUMN 1 PIC X(12) VALUE "EMPRESA XPTO".
51 03 COLUMN 65 PIC X(05) VALUE "DATA:".
52 03 COLUMN + 2 PIC X(10) SOURCE CAB01-DATA.
53 02 LINE 4.
54 03 COLUMN 1 PIC X(23) VALUE "RELACAO DE FUNCIONARIOS".
55 03 COLUMN 65 PIC X(07) VALUE "PAGINA:".
56 03 COLUMN 73 PIC Z(07)9 SOURCE PAGE-COUNTER.
57 02 LINE + 2.
58 03 COLUMN 1 PIC X(09) VALUE "CODIGO".
59 03 COLUMN 11 PIC X(40) VALUE "NOME".
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 373

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
60 03 COLUMN 52 PIC X(05) VALUE "DEPTO".
61 03 COLUMN 69 PIC X(12) VALUE "SALARIO (R$)".
62 02 LINE 7.
63 03 COLUMN 1 PIC X(80) SOURCE TRACO.
64 01 REL01-REG-IMPRES TYPE DETAIL.
65 02 LINE PLUS 1 ON NEXT PAGE.
66 03 COLUMN 1 PIC X(09) SOURCE F001-CODFUN.
67 03 COLUMN 11 PIC X(40) SOURCE F001-NOME.
68 03 COLUMN 54 PIC X(05) SOURCE F001-DEPTO.
69 03 COLUMN 65 PIC Z,ZZZ,ZZZ,ZZ9.99 SOURCE F001-SALARIO.
70 01 TYPE CONTROL FOOTING FINAL.
71 02 LINE + 2.
72 03 COLUMN 1 PIC X(80) SOURCE TRACO.
73 02 LINE + 1.
74 03 COLUMN 1 PIC X(19) VALUE "TOTAL DE REGISTROS:".
75 03 COLUMN + 2 PIC ZZZZ9 SOURCE CONTAREC.
76 02 LINE + 1 ON NEXT PAGE.
77 03 COLUMN 1 PIC X(80) SOURCE TRACO.
78 *
79 PROCEDURE DIVISION.
80 PROG-PRINCIPAL-PARA.
81 OPEN INPUT FD-VIRTUAL
82 OUTPUT FD-REL01.
83 MOVE FUNCTION CURRENT-DATE TO WS-DATA-SISTEMA
84 STRING WS-DT-DIA "/" WS-DT-MES "/" WS-DT-ANO INTO CAB01-DATA.
85 * >>> CRIACAO DO RELATORIO
86 INITIATE RD-REL01.
87 * Ajustes do cabeçalho, pagina e rodape
88 MOVE "F" TO TB-EOF
89 READ FD-VIRTUAL
90 AT END
91 MOVE "V" TO TB-EOF
92 END-READ
93 * Criacao dos resgistros de impressao
94 PERFORM UNTIL TB-EOF = "V"
95 GENERATE REL01-REG-IMPRES
96 READ FD-VIRTUAL
97 AT END
98 MOVE "V" TO TB-EOF
99 NOT AT END
100 ADD 1 TO CONTAREC
101 END-READ
102 END-PERFORM.
103 TERMINATE RD-REL01.
104 *
105 CLOSE FD-VIRTUAL, FD-REL01.
106 *
170 DISPLAY "RELATORIO: GERADO NO ESCRITOR DE RELATORIOS".
108 DISPLAY "EXEMPLO: RELATORIO SIMPLES".
109 DISPLAY "-------------------------------------------".
110 DISPLAY X"0D".
111 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
112 ACCEPT WS-ENTER.
------ ------------------------------------------------------------------------
374 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
113 STOP RUN.
114 END PROGRAM CAP08AP04.
------ ------------------------------------------------------------------------

Ao ser executado o programa peça par visualizar o conteúdo do arquivo LISTAGE2.LST, veja que o resultado apresen-
tado está semelhante com a estrutura indicada na imagem da figura 8.2. Note que o programa cap08ap04.cob ao ser
executado mostra um relatório semelhante a execução do programa cap08ap01.cob, tendo como diferença a quanti-
dade do número de linhas muito menor.
Entre as linhas 7 e 14 são definidos os relacionamentos dos arquivos físicos com os arquivos lógicos. Note na linha 12
a definição do vínculo entre o arquivo físico LISTAGE2.LST com o arquivo lógico FD-REL01 indicado e configurado
entre as linhas 41 e 77.
Nas linhas 42 e 43 são definidos respectivamente a quantidade de linhas por página (PAGE LIMIT IS), a quantidade de
colunas (caracteres) por página (LINE LIMIT IS) e a partir de qual linha do relatório o corpo com os registros será apre-
sentado (FIRST DETAIL IS) para a definição da estrutura do relatório entre as linhas 64 e 69.
O elemento PAGE HEADING (cabeçalho de página) definido entre as linhas 46 e 63 indica o uso de um pequeno agru-
pamento de informações que são geradas no início de cada página que compõem o relatório, sendo permitido por rela-
tório. Neste trecho são definidas as linhas do cabeçalho do relatório. Veja que nas linhas 48 e 63 são definidas a instru-
ção de escrita da linha tracejada com COLUMN 1 PIC X(80) SOURCE TRACO. Veja que para esta ação no uso da
cláusula COLUMN é definido a cláusula SOURCE. Nas linhas 45 e 62 que antecedem a apresentação da linha traceja
há a definição da cláusula LINE com a indicação do número de linha a ser usado.
Para a terceira linha do cabeçalho (LINE 3) indicada na linha 49 é definida a estrutura da linha que mostra o nome da
empresa e a data do sistema. O mesmo se utiliza junto a linha 50 para a definição do nome do relatório e o número da
página na LINE 4. Veja o uso das clausulas VALUE e SOURCE para a cláusula COLUMN.
A linha 57 indicada por LINE + 2 usa o último valor de LINE, neste caso, 4 e assoma a este valor 2 tendo-se relativa-
mente o valor 6 para os títulos das colunas do relatório. Desta forma a quinta linha do cabeçalho ficará em branco.
O elemento DETAIL definido entre as linhas 64 e 69 indica o uso do grupo de detalhamento dos registros apresentados
a cada execução do comando GENERATE indicado na linha 95 dentro da PROCEDURE DIVISION. O detalhamento do
corpo do relatório é definido entre as linhas 66 e 69. Veja que na linha 65 usa-se a instrução LINE PLUS 1 ON NEXT
PAGE que faz a apresentação relativa de cada registro em uma linha a frente (LINE PLUS 1) e quando atingir o limite
de linhas permitidas efetua um eject de página na impressora (NEXT PAGE).
O trecho entre as linhas 70 e 77 descreve o rodapé a ser impressora apenas na última página devido ao indicativo de
tipo CONTROL FOOTING FINAL. Atente também para a linha 76 que informa o salto de página (NEXT PAGE) caso o
fim da página não tenha sido atingido. O elemento de composição do relatório CONTROL FOOTING indicado na linha
70 define um conjunto de dados produzido ao final do agrupamento de dados como quebra de relatório (a ser demons-
trado) ou ao final de um relatório, uma única vez, quando em uso a cláusula FINAL como é o caso apresentado.
Após a definição da estrutura física do relatório, entre as linhas 86 e 103 efetua-se a apresentação do relatório propria-
mente dito, sendo que o relatório deve ser inicializado na linha 86 (INITIATE), gerado na linha 95 (GENERATE) e finali-
zado na linha 103 (TERMINATE).
Veja que a criação do relatório passa por dois estágios, a partir do uso do comando READ. O primeiro estágio repre-
sentado entre as linhas 88 e 92 é usado para criar a estrutura interna do relatório estruturando o cabeçalho, corpo e o
rodapé. Já o segundo estágio definido entre as linhas 94 e 102 é responsável pelo desenvolvimento do cabeçalho pro-
priamente dito.
IN TE R FA C E C O M O U SUÁ R IO 375

8.1.5 Relatório com quebra simples no escritor de relatórios


Anteriormente foi apresentado e indicado na figura 8.13 a definição de um relatório simples com quebras de agrupa-
mentos de dados separados por departamento em ordem decrescente com os nomes dos funcionários em ordem as-
cendente com um rodapé ao final do relatório. No sentido de demostrar esta ação considere a mesma situação a ser
tratada no modo escritor de relatórios. Assim sendo, abra um projeto vazio e atribua o nome cap08ap05 e extensão
“.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Os detalhes para uso e defini-
ção de quebras em relatório são explanados após a indicação do código do programa.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP05 AS "Capitulo 8 – Aplicacao 5".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.CLF"
8 FILE STATUS IS WS-PEGA-ERRO.
9 SELECT FD-REL01 ASSIGN TO "LISTAGE3.LST"
10 ORGANIZATION IS LINE SEQUENTIAL
11 ACCESS MODE IS SEQUENTIAL.
12 *
13 DATA DIVISION.
14 FILE SECTION.
15 COPY "FDVIRTUAL.CPY".
16 FD FD-REL01
17 REPORT IS RD-REL01.
18 WORKING-STORAGE SECTION.
19 COPY "FSCODERR.CPY".
20 COPY "TBVIRTUAL.CPY".
21 77 WS-PEGA-ERRO PIC XX.
22 * Variaveis de apoio ao programa e relatorio
23 77 WS-ENTER PIC X.
24 77 TB-EOF PIC X.
25 01 WS-DATA-SISTEMA.
26 05 WS-DATA-CORRENTE.
27 10 WS-DT-ANO PIC 9(04).
28 10 WS-DT-MES PIC 9(02).
29 10 WS-DT-DIA PIC 9(02).
30 77 CONTAREC PIC 9(05) VALUE 0.
31 77 CAB01-DATA PIC X(10).
32 77 TRACO PIC X(80) VALUE ALL "-".
33 * ESTRUTURA FISICA DA PAGINA DO RELATORIO
34 REPORT SECTION.
35 RD RD-REL01
36 * Defijnicao do controle de quebra
37 CONTROL IS F001-DEPTO
38 * Definiocao dos limites de pagina
39 PAGE LIMIT IS 68 LINES *> Limite de linhas por pagina
40 LINE LIMIT IS 80 *> Quantidade de colunas por linha
41 HEADING IS 2 *> Posicao inicial do cabecalho
42 FIRST DETAIL IS 9. *> Primeira linha de apresentacao do
43 *> corpo apos definicao do cabecalho
------ ------------------------------------------------------------------------
376 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
44 * ESTRUTURA FISICA DOS ELEMENTOS DE FORMACAO DO RELATORIO
45 * >>> CABECALHO
46 01 TYPE PAGE HEADING.
47 02 LINE 2.
48 03 COLUMN 1 PIC X(80) SOURCE TRACO.
49 02 LINE 3.
50 03 COLUMN 1 PIC X(12) VALUE "EMPRESA XPTO".
51 03 COLUMN 65 PIC X(05) VALUE "DATA:".
52 03 COLUMN + 2 PIC X(10) SOURCE CAB01-DATA.
53 02 LINE 4.
54 03 COLUMN 1 PIC X(23) VALUE "RELACAO DE FUNCIONARIOS".
55 03 COLUMN 65 PIC X(07) VALUE "PAGINA:".
56 03 COLUMN 73 PIC Z(07)9 SOURCE PAGE-COUNTER.
57 02 LINE + 2.
58 03 COLUMN 1 PIC X(09) VALUE "CODIGO".
59 03 COLUMN 11 PIC X(40) VALUE "NOME".
60 03 COLUMN 69 PIC X(12) VALUE "SALARIO (R$)".
61 02 LINE 7.
62 03 COLUMN 1 PIC X(80) SOURCE TRACO.
63 * >>> CORPO
64 * Definicao do titulo de quebra do relatorio
65 01 TYPE CONTROL HEADING F001-DEPTO LINE + 1 NEXT GROUP + 1.
66 03 COLUMN 1 PIC X(13) VALUE "DEPARTAMENTO:".
67 03 COLUMN + 2 PIC X(05) SOURCE F001-DEPTO.
68 * Definicao do registro com dados a ser apresentado por quebra
69 01 REL01-REG-IMPRES TYPE DETAIL.
70 02 LINE PLUS 1 ON NEXT PAGE.
71 03 COLUMN 1 PIC X(09) SOURCE F001-CODFUN.
72 03 COLUMN 11 PIC X(40) SOURCE F001-NOME.
73 03 COLUMN 65 PIC
74 Z,ZZZ,ZZZ,ZZ9.99 SOURCE F001-SALARIO.
75 * Definicao do regsitro sem dados a ser apresentado por quebra
76 01 REL01-REG-IMPRES-LIMPO TYPE DETAIL.
77 02 LINE PLUS 1.
78 03 COLUMN 10 PIC X(80) VALUE SPACES.
79 * >>> RODAPE DA QUEBRA DE DETALHAMENTO NA PAGINA
80 * Definicao de salto de linha em branco apos escrever os
81 * registros na quebra
82 01 TYPE CONTROL FOOTING F001-DEPTO NEXT GROUP + 1.
83 02 COLUMN 1 PIC X(80) VALUE SPACES. *> linha em branco
84 * >>> RODAPE DA PAGINA NO FINAL DO RELATORIO
85 01 TYPE CONTROL FOOTING FINAL.
86 02 LINE + 2.
87 03 COLUMN 1 PIC X(80) SOURCE TRACO.
88 02 LINE + 1.
89 03 COLUMN 1 PIC X(19) VALUE "TOTAL DE REGISTROS:".
90 03 COLUMN + 2 PIC ZZZZ9 SOURCE CONTAREC.
91 02 LINE + 1 ON NEXT PAGE.
92 03 COLUMN 1 PIC X(80) SOURCE TRACO.
93 *
94 PROCEDURE DIVISION.
95 PROG-PRINCIPAL-PARA.
96 OPEN INPUT FD-VIRTUAL
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 377

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
97 OUTPUT FD-REL01.
98 MOVE FUNCTION CURRENT-DATE TO WS-DATA-SISTEMA
99 STRING WS-DT-DIA "/" WS-DT-MES "/" WS-DT-ANO
100 INTO CAB01-DATA.
101 INITIATE RD-REL01.
102 * Ajustes dos cabecalhos do relatorio, da pagina e da quebra
103 MOVE "F" TO TB-EOF
104 READ FD-VIRTUAL
105 AT END
106 MOVE "V" TO TB-EOF
107 GENERATE REL01-REG-IMPRES-LIMPO
108 END-READ
109 * Criacao do relatorio
110 PERFORM UNTIL TB-EOF = "V"
111 GENERATE REL01-REG-IMPRES
112 READ FD-VIRTUAL
113 AT END
114 MOVE "V" TO TB-EOF
115 NOT AT END
116 ADD 1 TO CONTAREC
117 END-READ
118 END-PERFORM.
119 TERMINATE RD-REL01.
120 *
121 CLOSE FD-VIRTUAL, FD-REL01.
122 *
123 DISPLAY "RELATORIO: GERADO NO ESCRITOR DE RELATORIOS".
124 DISPLAY "EXEMPLO: RELATORIO COM QUEBRA SIMPLES".
125 DISPLAY "-------------------------------------------".
126 DISPLAY X"0D".
127 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
128 ACCEPT WS-ENTER.
129 STOP RUN.
130 END PROGRAM CAP08AP05.
------ ------------------------------------------------------------------------

Ao ser executado o programa peça par visualizar o conteúdo do arquivo LISTAGE3.LST, veja que o resultado apresen-
tado está semelhante com a estrutura indicada na imagem da figura 8.13.
A estrutura geral do programa é semelhante aos programas anteriores deste tópico, mas para a definição das quebras
alguns elementos adicionais são usados. Entre as linhas 5 e 32 são definidas as associações entre os arquivos lógicos
e físicos, a definição das variáveis de apoio ao programa e variáveis de apoio a definição do relatório.
No trecho entre as linhas 35 e 92 é definida a estrutura física do relatório. Neste trecho a atenção maior deve ser con-
centrado na linha 39 com o uso da cláusula opcional LINES com PAGE LIMIT e ao trecho definido entre as linhas 65 e
83. Entre as linhas 65 e 67 é definido o título da quebra de agrupamento dos dados. Veja que na linha 65 é definido o
controle sobre o cabeçalho intermediário DEPARTAMENTO (linha 66) a partir de CONTROL HEADING F001-DEPTO.
Note que antes de apresentar este título é realizado um salto de linha (LINE + 1) e após a apresentação do título é
realizado mais um salto de linha para o próximo grupo de dados (NEXT GROUP + 1). O elemento de controle do cabeça-
lho interno CONTROL HEADING indica o uso de uma quebra de dados impressa no início de cada quebra após o uso de
NEXT GROUP. A cláusula SOURCE usada na definição de quebras refere-se à indicação do valor dos itens no momento em
que a primeira instrução GENERATE é executada, neste caso, no trecho de linhas de 104 até 108.
378 PRO G RA MA Ç ÃO CO B OL

O trecho entre as linhas 69 e 74 são conhecidos, tendo como diferença a omissão do campo relacionado a indicação do
departamento que está sendo realizado nas linhas 65 e 67. Esta parte é responsável pela composição da estrutura de regis-
tro a ser impressa.
Um detalhe adicional, necessário quando se utiliza agrupamento de dados, é a definição de um registro “nulo” para a realiza-
ção de alguns ajustes internos antes de criar o relatório propriamente dito definido entre as linhas 76 e 78. Neste caso o re-
gistro nulo utiliza a geração de uma linha em branco com 80 espaços. Este recurso é controlado efetivamente no trecho de
código entre as linhas 104 e 108 que efetua para os ajustes internos o comando GENERATE uma primeira vez (linha 108). A
segunda execução do comando GENERATE sem a definição dos registros (que é processada entre as linhas 110 e
118) efetua a preparação dos elementos REPORT HEADING, PAGE HEADING e CONTROL HEADING que necessi-
tam ser produzidos antes da apresentação da linha de registro no detalhe do corpo do relatório.
Após apresentar o título da quebra e os dados agrupados para a quebra pretendida o programa entre as linhas 82 e 83
gera uma linha em branco de separação para o próximo grupo de dados a partir do uso de CONTROL FOOTING. É
pertinente salientar que quebras produzidas com CONTROL FOOTING e mesmo com CONTROL HEADING podem usar a
cláusula FINAL, desde que seja usada apena vez. A cláusula FINAL aplica o efeito da ação do elemento na última página do
relatório. Os demais detalhes do programa, como comentado, já são conhecidos e não necessitam de outras observa-
ções.

8.1.6 Relatório com totalização no escritor de relatórios


A partir do conhecimento de como estabelecer a separação de dados de um relatório por agrupamento de registros fica
fácil proceder ações de totalização de valores numéricos. Veja o layout da figura 8,15 com a indicação da estrutura de
um relatório utilizando totalizações intermediárias em quebras de dados e totalização geral ao final do relatório.

Figura 8.15 – Layout de relatório com quebras e totalização sumarizadas


IN TE R FA C E C O M O U SUÁ R IO 379

Observe na figura 8.15 a indicação de uma página cortada de um relatório maior com totalizações e quebras. Na primei-
ra linha é definido o cabeçalho que será apresentado apenas na primeira página e não nas demais, da mesma forma na
sexagésima oitava linha é definido o rodapé do relatório que é apresentado apenas na última página tenha o relatório a
quantidade de páginas que tiver. Veja também a estrutura de cada grupo de dados definidos como quebras com indica-
ções do total de salários por departamento e no final a apresentação do total geral de salários pagos pela empresa.
A partir do layout proposto na figura 8.15, abra um projeto vazio e atribua o nome cap08ap06 e extensão “.cob” na
subpasta COBOL da pasta Documentos e codifique as instruções seguintes. Os detalhes para uso e definição de
quebras em relatório são explanados após a indicação do código do programa.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP06 AS "Capitulo 8 – Aplicacao 6".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 FILE-CONTROL.
7 SELECT FD-VIRTUAL ASSIGN TO "ARQDINIX.CLF"
8 FILE STATUS IS WS-PEGA-ERRO.
9 SELECT FD-REL01 ASSIGN TO "LISTAGE4.LST"
10 ORGANIZATION IS LINE SEQUENTIAL
11 ACCESS MODE IS SEQUENTIAL.
12 *
13 DATA DIVISION.
14 FILE SECTION.
15 COPY "FDVIRTUAL.CPY".
16 FD FD-REL01
17 REPORT IS RD-REL01.
18 *
19 WORKING-STORAGE SECTION.
20 COPY "FSCODERR.CPY".
21 COPY "TBVIRTUAL.CPY".
22 77 WS-PEGA-ERRO PIC XX.
23 77 WS-ENTER PIC X.
24 77 TB-EOF PIC X.
25 01 WS-DATA-SISTEMA.
26 05 WS-DATA-CORRENTE.
27 10 WS-DT-ANO PIC 9(04).
28 10 WS-DT-MES PIC 9(02).
29 10 WS-DT-DIA PIC 9(02).
30 77 CONTAREC PIC 9(05) VALUE 0.
31 77 CAB01-DATA PIC X(10).
32 77 TRACO PIC X(80) VALUE ALL "-".
33 *
34 REPORT SECTION.
35 RD RD-REL01
36 CONTROL IS F001-DEPTO
37 PAGE LIMIT IS 68 LINES
38 LINE LIMIT IS 80
39 HEADING IS 2
40 FIRST DETAIL IS 9.
41 * ESTRUTURA FISICA DOS ELEMENTOS DE FORMACAO DO RELATORIO
42 * >>> CABECALHO
43 * Cabecalho da primeira pagina do relatorio
------ ------------------------------------------------------------------------
380 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
44 01 TYPE IS REPORT HEADING.
45 02 LINE 1.
46 03 COLUMN 1 PIC X(19) VALUE "RELATORIO FUNCIONAL".
47 * Cabecalho da pagina
48 01 TYPE PAGE HEADING.
49 02 LINE 2.
50 03 COLUMN 1 PIC X(80) SOURCE TRACO.
51 02 LINE 3.
52 03 COLUMN 1 PIC X(12) VALUE "EMPRESA XPTO".
53 03 COLUMN 65 PIC X(05) VALUE "DATA:".
54 03 COLUMN + 2 PIC X(10) SOURCE CAB01-DATA.
55 02 LINE 4.
56 03 COLUMN 1 PIC X(23) VALUE "RELACAO DE FUNCIONARIOS".
57 03 COLUMN 65 PIC X(07) VALUE "PAGINA:".
58 03 COLUMN 73 PIC Z(07)9 SOURCE PAGE-COUNTER.
59 02 LINE + 2.
60 03 COLUMN 1 PIC X(09) VALUE "CODIGO".
61 03 COLUMN 11 PIC X(40) VALUE "NOME".
62 03 COLUMN 69 PIC X(12) VALUE "SALARIO (R$)".
63 02 LINE 7.
64 03 COLUMN 1 PIC X(80) SOURCE TRACO.
65 * >>> CORPO
66 01 TYPE CONTROL HEADING F001-DEPTO LINE + 1 NEXT GROUP + 1.
67 03 COLUMN 1 PIC X(13) VALUE "DEPARTAMENTO:".
68 03 COLUMN + 2 PIC X(05) SOURCE F001-DEPTO.
69 01 REL01-REG-IMPRES TYPE DETAIL.
70 02 LINE PLUS 1 ON NEXT PAGE.
71 03 COLUMN 1 PIC X(09) SOURCE F001-CODFUN.
72 03 COLUMN 11 PIC X(40) SOURCE F001-NOME.
73 03 COLUMN 65 PIC
74 Z,ZZZ,ZZZ,ZZ9.99 SOURCE F001-SALARIO.
75 01 REL01-REG-IMPRES-LIMPO TYPE DETAIL.
76 02 LINE PLUS 1.
77 03 COLUMN 10 PIC X(80) VALUE SPACES.
78 01 TYPE CONTROL FOOTING F001-DEPTO NEXT GROUP + 2.
79 02 LINE + 2.
80 03 COLUMN 25 PIC X(31)
81 VALUE "Total: Salarios do departamento".
82 03 COLUMN + 2 PIC 99 SOURCE F001-DEPTO.
83 03 COLUMN + 2 PIC X(04) VALUE "- R$".
84 03 COLUMN + 2 PIC
85 Z,ZZZ,ZZZ,ZZ9.99 SUM F001-SALARIO.
86 * >>> RODAPE DA PAGINA NO FINAL DO RELATORIO
87 01 TYPE CONTROL FOOTING FINAL.
88 02 LINE + 3.
89 03 COLUMN 1 PIC X(80) SOURCE TRACO.
90 02 LINE + 1.
91 03 COLUMN 1 PIC X(19) VALUE "TOTAL DE REGISTROS:".
92 03 COLUMN + 2 PIC ZZZZ9 SOURCE CONTAREC.
93 03 COLUMN 48 PIC X(16) VALUE "TOTAL GERAL - R$".
94 03 COLUMN + 2 PIC
95 Z,ZZZ,ZZZ,ZZ9.99 SUM F001-SALARIO.
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 381

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
96 02 LINE + 1 ON NEXT PAGE.
97 03 COLUMN 1 PIC X(80) SOURCE TRACO.
98 * >>> RODAPE NO FINAL DO RELATORIO - ULTIMA PAGINA
99 01 TYPE IS REPORT FOOTING.
100 02 LINE 1.
101 03 COLUMN 1 PIC X(19) VALUE "COPYRIGHT (C) 2021".
102 *
103 PROCEDURE DIVISION.
104 PROG-PRINCIPAL-PARA.
105 OPEN INPUT FD-VIRTUAL
106 OUTPUT FD-REL01.
107 MOVE FUNCTION CURRENT-DATE TO WS-DATA-SISTEMA
108 STRING WS-DT-DIA "/" WS-DT-MES "/" WS-DT-ANO
109 INTO CAB01-DATA.
110 INITIATE RD-REL01.
111 MOVE "F" TO TB-EOF
112 READ FD-VIRTUAL
113 AT END
114 MOVE "V" TO TB-EOF
115 GENERATE REL01-REG-IMPRES-LIMPO
116 END-READ
117 PERFORM UNTIL TB-EOF = "V"
118 ADD 1 TO CONTAREC
119 GENERATE REL01-REG-IMPRES
120 READ FD-VIRTUAL
121 AT END
122 MOVE "V" TO TB-EOF
123 END-READ
124 END-PERFORM.
125 TERMINATE RD-REL01.
126 CLOSE FD-VIRTUAL, FD-REL01.
127 DISPLAY "RELATORIO: GERADO NO ESCRITOR DE RELATORIOS".
128 DISPLAY "EXEMPLO: RELATORIO COM QUEBRA SUMARIZADA".
129 DISPLAY "-------------------------------------------".
130 DISPLAY X"0D".
131 DISPLAY "Tecle <ENTER> para encerrar... " WITH NO ADVANCING.
132 ACCEPT WS-ENTER.
133 STOP RUN.
134 END PROGRAM CAP08AP06.
------ ------------------------------------------------------------------------

Ao ser executado o programa peça par visualizar o conteúdo do arquivo LISTAGE4.LST, veja que o resultado apresen-
tado está semelhante com a estrutura indicada na imagem da figura 8.15.
O programa cap08ap06.cob é parecido com o programa cap08ap05.cob. A maior diferença do programa concentra-se
entre as linhas 44 a 46, 78 a 85, 87 a 95 e 99 a 101. Os trechos das linhas 44 a 46 e 99 a 101 geram respectivamente
os títulos do cabeçalho e do rodapé apresentados apenas na primeira e últimas páginas do relatório. O elemento RE-
PORT HEADING da linha 44 indica o uso do conteúdo é produzido apenas uma vez, no início do relatório, durante a execu-
ção da primeira instrução GENERATE na linha 115. Já o elemento REPORT FOOTING na linha 99 indica o uso de um con-
teúdo gerado apenas uma vez no encerramento de um relatório.
No trecho entre as linhas 78 e 85 são definidos o título de controle do rodapé da quebra do grupo de dados (linha 81)
com o uso do campo F001-DEPTO como separador da quebra (linha 82) e a realização da soma dos valores do campo
F001-SALARIO (linha 85) com om uso da cláusula SUM, sendo que o mesmo se aplica no trecho das linhas 87 a 95
382 PRO G RA MA Ç ÃO CO B OL

com o uso da cláusula SUM na linha 95, mas desta vez na definição do rodapé do relatório a ser impresso na última
página.
A cláusula SUM é usada para efetuar automaticamente a soma dos dados numéricos apontados logo após definição da
cláusula PIC(TURE), podendo ser usada apenas uma na definição de cada grupo elementar de dados vinculados pelo
elemento CONTROL FOOTING.
Para maiores detalhes a respeito do uso do modo escritor de relatórios sugere-se consulta ao manual de programação
SPC (2002) indicado na bibliografia deste trabalho.

8.2 UTILIZAÇÃO DE TELAS


Como ação no tratamento da definição da interface de comunicação entre o usuário de uma aplicação e o computador,
tem-se além do desenvolvimento de relatórios o tratamento visual das telas de um programa. Neste sentido, a lingua-
gem possui a seção chamada SCREEN SECTION definida na DATA DIVISION após definição das variáveis de opera-
ção na WORKING-STORAGE SECTION, LOCAL-STORAGE SECTION, LINKAGE SECTION ou REPORT SECTION
(quando definida).
A SCREEN SECTION caracteriza-se por ser uma seção de configuração da aparência visual das telas de programas a
partir da definição de um cabeçalho contendo ou não entradas que estabelecem a definição de níveis de uso do projeto
visual. As entradas dessa seção caracterizam a forma de aparência de uma área retangular de exibição de dados, nor-
malmente definida com dimensão horizontal de 80 colunas e dimensão vertical de 24 linhas, mas dependendo do pa-
drão do monitor de vídeo (ecrã) e das configurações de sistema em uso essa dimensão poderá ser diferente. Para este
estudo será mantida a proporção de dimensão 80x24. De maneira geral a tela de operação de um programa é dividida,
assim como um relatório, em três área básicas: cabeçalho, corpo e rodapé.
O cabeçalho de uma tela é defino no mínimo na primeira linha, podendo-se usar mais linhas. No entanto, deve-se evitar
o uso de muitas linhas. Considere em média usar no máximo cinco linhas.
O rodapé de uma tela é normalmente definido na vigésima quarta linha (ou a última linha ativa da tela) sendo destinado
a apresentar informações gerais do programa ou mensagens de operação do programa. Em média usa-se, no máximo,
as duas últimas linhas da tela para esta ação.
O corpo da tela caracteriza-se pela área subtraída da quantidade de linhas usadas na definição do cabeçalho e rodapé.
Por isso deve-se ter o cuidado de não se cometer exageros no uso do cabeçalho e rodapé. A área destinada ao corpo
poderá ser dividida em outras subáreas, dependendo obviamente da necessidade para determinado programa. A divi-
são da tela em cabeçalho, corpo e rodapé é uma formalização, podendo-se omitir os elementos de composição do
cabeçalho e rodapé e ter então toda a dimensão para uso do corpo da tela.
A área retangular definida como tela passa ser o local onde todas as operações de entrada e saída de dados devem ser
direcionadas. Não se usando diretamente os comandos DISPLAY (saída) e ACCEPT (entrada). Este recurso se confi-
gura como uma alternativa ao uso dos comandos ACCEPT e DISPLAY e sua definição para uso se assemelha a outros
recursos da linguagem, bastando seguir basicamente o que já é conhecido. Com este recurso é possível fazer o desen-
volvimento de diversas telas para uma aplicação em específico. De forma geral sua definição sintática se caracteriza
pela indicação sintática:

SCREEN SECTION.
01 <SS-tela>.
02 <SS-tela-cabeçalho>
03 <configurações>
02 <SS-tela-corpo>
03 <configurações>
02 <SS-tela-rodapé>
03 <configurações>

Onde, tela se caracteriza pelo nome de identificação que a tela tem dentro do programa e o indicativo SS é uma manei-
ra de informar que o grupo elementar em uso se refere a SCREEN SECTION. As partes que compõem a tela descre-
vem sua estrutura de composição: cabeçalho (SS-tela-cabeçalho), corpo (SS-tela-corpo) e rodapé (SS-tela-rodapé).
As configurações se referem ao uso do conjunto de cláusulas que estabelecem os critérios de formatação das telas.
IN TE R FA C E C O M O U SUÁ R IO 383

Observe que os elementos de composição de uma tela são definidos como um grupo elementar com código 01 e pode
desta forma ser composto por outro grupos elementares ou campos numerados habitualmente entre 02 e 49.
Após especificar a estrutura de uma tela é possível definir diversos atributos a partir de um conjunto de cláusulas de
configuração, destacando-se as mais comuns.

BLANK {SCREEN / LINE}


BACKGROUND-COLOR <n>
[{ HIGHLIGHT / LOWLIGHT }] FOREGROUND-COLOR <n> [{ HIGHLIGHT / LOWLIGHT }]
AUTO
BELL
COLUMN
LINE
REQUIRED
SECURE
SIGN

A cláusula BLANK SCREEN é usada para proceder a limpeza dos dados apresentados em tela, sendo mais eficiente
que o método de uso da instrução CALL "SYSTEM" USING "cls" ou CALL "SYSTEM" USING "clear" apresentada no
capítulo 5. Alternativamente pode-se fazer uso de BLANK LINE para limpar o conteúdo de certa linha de dado.
As cláusulas BACKGROUND-COLOR (cores do fundo da tela, segundo plano) e FOREGROUND-COLOR (cores da
frente da tela, primeiro plano) permitem que sejam definidas as cores de apresentação dos dados na tela. São permiti-
das até oitos cores para o fundo e frente como indicado na tabela 8.1. As definições de cores dos textos na parte da
frente da tela podem ser apresentadas em tons de baixa (LOWLIGHT) ou alta intensidade (HIGHLIGHT) sendo posicio-
nados antes ou depois da definição da cláusula FOREGROUND-COLOR perfazendo um total de 16 cores.
Tabela 8.1 – Cores de tela A cláusula AUTO permite otimizar a ação de entrada de dados do usuário, pois faz
com que o cursor salte para o próximo campo na tela quando o campo é totalmente
Cor Código preenchido. Quando o último campo de uma tela é preenchido a ação de entrada é
finalizada.
A cláusula BELL quando usada gera um a apresentação de um toque sonoro, sen-
do útil para a definição de mensagens de erro e advertência.
0 BLACK

1 BLUE As cláusulas COLUMN e LINE são usadas para posicionar elementos de dados e
cursor em tela.
A cláusula REQUIRED (obrigatório) quando definida força a entrada de pelo menos
2 GREEN

3 CYAN um caractere em cada campo de entrada ou de atualização.


A cláusula SECURE permite a definição de entrada de dados sem a apresentação
de eco. Este tipo de configuração é útil para a definição de campos de entrada de
senhas, pois é possível realizar a entrada de dados sem que os caracteres informa-
4 RED

5 MAGENTA dos sejam apresentados.


A cláusula SIGN quando em uso faz com que os campos numéricos negativos te-
6 YELLOW / BROWN nham o sinal armazenado no campo.
Além das cláusulas apontadas como as mais comuns o recurso SCREEN SECTION
possui outras cláusulas que permitem outros ajustes de comportamento.
7 WHITE

Para o típico uso deste recurso considere, por exemplo, a definição de uma tela inteira (sem a definição de cabeçalho,
corpo e rodapé) chamada TELA01 com o fundo preto com texto escrito em tom verde de baixa intensidade, com a indi-
cação da entrada obrigatória de dados em todos os campos de modo que ocorra o avanço automático ao próximo cam-
po quando o campo em foco estiver totalmente preenchido. A tela quando executada deverá ser apresentada de forma
limpa. Ao se especificar uma tela com SCREEN SECTION cria-se dentro do ambiente de programa um estilo virtual de
apresentação e uso de dados.
384 PRO G RA MA Ç ÃO CO B OL

SCREEN SECTION.
01 TELA01
05 BLANK SCREEN, BACKGROUND-COLOR IS 0 FOREGROUND-COLOR IS 2,
AUTO,
REQUIRED.

Observe os detalhes de definição de cada componente de configuração indicados para a TELA01. Veja que as vírgulas
usadas para a separação das cláusulas são opcionais podem-se inclusive dispor do conjunto de elementos separados
em linhas. O estilo indicado serve para a definição de uma única tela sem a divisão de suas partes, sendo um estilo
mais raro de uso.
Na definição de uso das cores se nada for informado sobre sua intensidade, os tons das cores apresentados por defini-
ção são LOWLIGHT. Para uso de alta intensidade deve-se aplicar após a definição da cor a cláusula HIGHLIGHT. No
entanto, ao se fazer uso de um dos modos de intensidade deve-se usar o outro modo de intensidade para alternar os
efeitos desejados. O modo habilitação de intensidade é usado imediatamente após ser definido o código numérico da
cor.
A título de uma rápida demonstração de uso da operação considere um programa que apresente no meio do corpo de
tela na posição central horizontal e vertical a mensagem "ALO, MUNDO COLORIDO!". No cabeçalho (linha 1) a apre-
sentação da mensagem "Programa exemplo" e no rodapé (linha 24) a mensagem de encerramento "Tecle <ENTER>
para encerrar...".
O texto do cabeçalho deve ser apresentado com fundo azul e texto escrito em amarelo de baixa intensidade; o corpo
deve ser apresentado com fundo preto e texto verde em alta intensidade; por último o rodapé deve ser apresentado
com fundo vermelho e texto em branco de baixa intensidade. Assim sendo, abra um projeto vazio, atribua o nome
cap08ap07 e extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP07 AS "Capitulo 8 – Aplicacao 7".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 *
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 77 WS-ENTER PIC X.
10 *
11 SCREEN SECTION.
12 * >>> TELA PRINCIPAL
13 01 SS-TELA01.
14 * efetua limpeza da tela
15 05 BLANK SCREEN.
16 * PREPARACAO DO CABECALHO DA TELA
17 05 SS-TELA01-CABECALHO.
18 * define a cor de fundo de toda a linha de cabecalho
19 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
20 BACKGROUND-COLOR 1.
21 * define a cor do texto e fundo da linha de cabecalho
22 10 LINE 01 COL 01 VALUE "Programa exemplo"
23 HIGHLIGHT FOREGROUND-COLOR 6
24 BACKGROUND-COLOR 1.
25 * PREPARACAO DO CORPO DA TELA
26 05 SS-TELA01-CORPO.
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 385

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
27 * define a cor do texto e fundo do corpo
28 10 LINE 12 COLUMN 30 PIC X(20)
29 VALUE "ALO, MUNDO COLORIDO!"
30 FOREGROUND-COLOR 2 HIGHLIGHT
31 BACKGROUND-COLOR 0.
32 * PREPARACAO DO RODAPE DA TELA
33 05 SS-TELA01-RODAPE.
34 * define a cor de toda a linha de rodape
35 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
36 BACKGROUND-COLOR 4.
37 * define a cor do texto da linha de rodape
38 10 LINE 24 COLUMN 01 PIC X(30)
39 VALUE "Tecle <ENTER> para encerrar..."
40 HIGHLIGHT FOREGROUND-COLOR 7
41 BACKGROUND-COLOR 4.
42 * define a cor do texto do campo de entrada no rodape
43 10 LINE 24 COLUMN 80 PIC X USING WS-ENTER
44 HIGHLIGHT FOREGROUND-COLOR 7
45 BACKGROUND-COLOR 4.
46 *
47 PROCEDURE DIVISION.
48 PROG-PRINCIPAL-PARA.
49 DISPLAY SS-TELA01.
50 ACCEPT SS-TELA01.
51 STOP RUN.
52 END PROGRAM CAP08AP07.
------ ------------------------------------------------------------------------

Ao ser executado o programa três mensagens são apresentadas, sendo apresentada na primeira linha o texto "Pro-
grama exemplo" ao centro horizontal e vertical da tela a primeira mensagem identificada como "ALO, MUNDO COLO-
RIDO!" e no rodapé é apresentado o texto "Tecle <ENTER> para encerrar...". Lembre-se de que a tela possui 80 colu-
nas de largura por 24 linhas de comprimento.
Entre as linhas 13 e 45 está a definição da tela SS-TELA com as três principais divisões: cabeçalho (linha 17), corpo
(linha 26) e rodapé (linha 33). Veja que antes de qualquer definição da estrutura da tela é realizado na linha 15 a limpe-
za da tela com BLANK SCREEN.
Entre as linhas 17 e 24 é definido a linha de cabeçalho. Na linha 19 é definida a apresentação de 80 espaços a partir da
primeira linha e primeira coluna (LINE 01 COL 01) configurado na linha 20 a cor de fundo em azul (BACKGROUND-
COLOR 1).
Após preparar o preenchimento da cor de fundo em tom azul para o cabeçalho é definido o texto a ser apresentado.
Isso ocorre entre as linhas 22 e 24. Na linha 23 é indicado o uso da cláusula HIGHLIGHT antes da aplicação do efeito
da cláusula FOREGROUND-COLOR.
Entre as linhas 26 e 31 encontra-se o trecho de código para a apresentação da mensagem central na tela. Observe que
na linha 28 está sendo usada a cláusula COLUMN, anteriormente definida como COL. Veja que as cláusulas COLUMN
e COL são sinônimos. Um detalhe usado na linha 30 é a aplicação diferenciada da cláusula HIGHLIGHT após o uso da
cláusula FOREGROUND-COLOR.
Para a definição do rodapé a partir da linha 33 faz-se a definição da linha de fundo em vermelho (linhas 34 e 35). Entre
as linhas 38 e 41 é definido o texto de apresentação do rodapé e entre as linhas 43 e 45 é definido o ponto de entrada
de dados. Veja que a mensagem é apresentada a partir da vigésima quarta linha e o ponto de entrada é posicionado na
vigésima quarta linha e septuagésima nona coluna. Isso é realizado para que toda a última linha seja apresentada com
o fundo colorizado. A última linha da tela exige esse cuidado.
386 PRO G RA MA Ç ÃO CO B OL

Observe nas linhas 19, 22, 29, 35 e 39 o uso da cláusula VALUE com a indicação da sequência de caracteres definidas
entre aspas inglesas ou simples a ser apresentado em tela. Além da cláusula VALUE, especifica para a apresentação
de cadeias de caracteres alfabéticos ou alfanuméricos, podem ser usadas para a apresentação de diversos dados ad-
vindos de variáveis, listas, tabelas e arquivos as cláusulas FROM, TO e USING (aplicada na linha 43).
A cláusula FROM quando usada permite exibir na posição apontada o conteúdo definido no dado vinculado a um cam-
po de saída, já a cláusula TO permite exibir na posição apontada o conteúdo definido no dado vinculado a um campo
de entrada. A cláusula USING usada na linha 43 tem por finalidade exibir na posição apontada o conteúdo definido no
dado vinculado a um campo de atualização.
Na linha 49 encontra-se a solicitação de apresentação da tela com a instrução DISPLAY SS-TELA01. Veja que o co-
mando DISPLAY está sendo usado para apresentar de uma maneira total a tela virtual definida na SCREEN SECTION.
Já na linha 50 é definido com a instrução ACCEPT SS-TELA01 a preparação da tela para a entrada de dados.
Observe que o modo SCREEN SECTION é um recurso que permite escrever a estrutura visual das telas de um pro-
grama, de certa forma, semelhante ao modo escritor de relatórios. A SCREEN SECTION permite que sejam definidas
para um programa diversas telas se assim forem necessários.
A título de exemplificação considere agora um programa muito simples que mostre apenas um pequeno menu com três
opções: entrada de dados, apresentação de dados e saída do programa. O programa possui a indicação de uma tela
principal que contém apenas o cabeçalho e o rodapé, o corpo da tela principal é formado por uma tela suplementar que
administra a apresentação do menu. As opções de entrada e saída de dados possuem suas telas, além de uma tela
exclusiva para a detecção de erros de seleção de opções. Desta forma, abra um projeto vazio, atribuindo-lhe o nome
cap08ap08 a partir da extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP08 AS "Capitulo 8 – Aplicacao 8".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 *
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 77 WS-ALGO PIC X.
10 77 WS-OPCAO PIC X.
11 *
12 SCREEN SECTION.
13 * >>> TELA PRINCIPAL SS-TELA01
14 01 SS-TELA01.
15 05 BLANK SCREEN.
16 05 SS-TELA01-CABECALHO.
17 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
18 BACKGROUND-COLOR 1.
19 10 LINE 01 COL 01
20 VALUE "PROTES | PROGRAMA TESTE | MENU PRINCIPAL"
21 HIGHLIGHT FOREGROUND-COLOR 6
22 BACKGROUND-COLOR 1.
23 05 SS-TELA01-RODAPE.
24 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
25 BACKGROUND-COLOR 4.
26 * >>> TELA SUPLEMENTAR: APRESENTACAO MENU EM SS-TELA01
27 01 SS-TELA01-MENU
28 AUTO
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 387

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
29 FOREGROUND-COLOR 2 HIGHLIGHT
30 BACKGROUND-COLOR 0.
31 05 LINE 05 COL 10 VALUE "1 - ENTRADA DE DADOS".
32 05 LINE 06 COL 10 VALUE "2 - APRESENTACAO DE DADOS".
33 05 LINE 07 COL 10 VALUE "X - SAIDA DO SISTEMA".
34 05 LINE 09 COL 10 VALUE "OPCAO >>>".
35 05 LINE 09 COL 20 PIC X USING WS-OPCAO.
36 05 LINE 24 COL 01 PIC X(33)
37 VALUE "Selecione uma das opcoes do menu."
38 HIGHLIGHT FOREGROUND-COLOR 7
39 BACKGROUND-COLOR 4.
40 * >>> TELA SECUNDARIA: OPERCAO OPCAO 1 - SS-TELA02
41 01 SS-TELA02
42 AUTO
43 FOREGROUND-COLOR 3 HIGHLIGHT
44 BACKGROUND-COLOR 0.
45 05 BLANK SCREEN.
46 05 SS-TELA02-CABECALHO.
47 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
48 BACKGROUND-COLOR 1.
49 10 LINE 01 COL 01
50 VALUE "PROTES | PROGRAMA TESTE | OPCAO 1"
51 HIGHLIGHT FOREGROUND-COLOR 6
52 BACKGROUND-COLOR 1.
53 05 SS-TELA02-CORPO.
54 10 LINE 12 COLUMN 31 PIC X(20)
55 VALUE "OPCAO 1 ACIONADA.".
56 05 SS-TELA02-RODAPE.
57 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
58 BACKGROUND-COLOR 4.
59 10 LINE 24 COL 01 PIC X(31)
60 VALUE "Tecle algo para voltar ao menu."
61 HIGHLIGHT FOREGROUND-COLOR 7
62 BACKGROUND-COLOR 4.
63 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
64 HIGHLIGHT FOREGROUND-COLOR 7
65 BACKGROUND-COLOR 4.
66 * >>> TELA SECUNDARIA: OPERCAO OPCAO 2 - SS-TELA03
67 01 SS-TELA03
68 AUTO
69 FOREGROUND-COLOR 5 HIGHLIGHT
70 BACKGROUND-COLOR 0.
71 05 BLANK SCREEN.
72 05 SS-TELA02-CABECALHO.
73 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
74 BACKGROUND-COLOR 1.
75 10 LINE 01 COL 01
76 VALUE "PROTES | PROGRAMA TESTE | OPCAO 2"
77 HIGHLIGHT FOREGROUND-COLOR 6
78 BACKGROUND-COLOR 1.
79 05 SS-TELA02-CORPO.
80 10 LINE 12 COLUMN 31 PIC X(20)
------ ------------------------------------------------------------------------
388 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
81 VALUE "OPCAO 2 ACIONADA.".
82 05 SS-TELA02-RODAPE.
83 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
84 BACKGROUND-COLOR 4.
85 10 LINE 24 COL 01 PIC X(31)
86 VALUE "Tecle algo para voltar ao menu."
87 HIGHLIGHT FOREGROUND-COLOR 7
88 BACKGROUND-COLOR 4.
89 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
90 HIGHLIGHT FOREGROUND-COLOR 7
91 BACKGROUND-COLOR 4.
92 * >>> TELA SECUNDARIA: ERRO DE OPCAO - SS-TELA04
93 01 SS-TELA04
94 AUTO
95 FOREGROUND-COLOR 6 HIGHLIGHT
96 BACKGROUND-COLOR 0.
97 05 BLANK SCREEN.
98 05 SS-TELA04-CABECALHO.
99 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
100 BACKGROUND-COLOR 1.
101 10 LINE 01 COL 01
102 VALUE "PROTES | PROGRAMA TESTE | ERRO"
103 HIGHLIGHT FOREGROUND-COLOR 6
104 BACKGROUND-COLOR 1.
105 05 SS-TELA04-CORPO.
106 10 LINE 12 COLUMN 31 PIC X(15)
107 VALUE "OPCAO INVALIDA.".
108 05 SS-TELA04-RODAPE.
109 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
110 BACKGROUND-COLOR 4.
111 10 LINE 24 COL 01 PIC X(31)
112 VALUE "Tecle algo para voltar ao menu."
113 HIGHLIGHT FOREGROUND-COLOR 7
114 BACKGROUND-COLOR 4.
115 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
116 HIGHLIGHT FOREGROUND-COLOR 7
117 BACKGROUND-COLOR 4.
118 *
119 PROCEDURE DIVISION.
120 PROG-PRINCIPAL-PARA.
121 PERFORM FOREVER
122 MOVE SPACE TO WS-OPCAO
123 DISPLAY SS-TELA01
124 DISPLAY SS-TELA01-MENU
125 ACCEPT SS-TELA01-MENU
126 IF FUNCTION UPPER-CASE(WS-OPCAO) NOT = 'X'
127 EVALUATE WS-OPCAO
128 WHEN '1'
129 PERFORM 1000-OPCAO-1
130 WHEN '2'
131 PERFORM 2000-OPCAO-2
132 WHEN OTHER
133 PERFORM 3000-OPCAO-ERRO
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 389

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
134 END-EVALUATE
135 ELSE
136 EXIT PERFORM
137 END-IF
138 END-PERFORM.
139 PROG-PRINCIPAL-FIM-PARA.
140 STOP RUN.
141 *
142 1000-OPCAO-1 SECTION.
143 MOVE SPACE TO WS-ALGO.
144 DISPLAY SS-TELA02.
145 ACCEPT SS-TELA02.
146 EXIT.
147 *
148 2000-OPCAO-2 SECTION.
149 MOVE SPACE TO WS-ALGO.
150 DISPLAY SS-TELA03.
151 ACCEPT SS-TELA03.
152 EXIT.
153 *
154 3000-OPCAO-ERRO SECTION.
155 MOVE SPACE TO WS-ALGO.
156 DISPLAY SS-TELA04.
157 ACCEPT SS-TELA04.
158 EXIT.
159 *
160 END PROGRAM CAP08AP08.
------ ------------------------------------------------------------------------

Ao ser executado o programa selecione as opções indicadas no menu e veja o resultado de cada uma das ações efeti-
vadas. Experimente a entrada de opções inválidas e observe a apresentação da mensagem de erro. Atente para os
detalhes de uso dos cabeçalhos e rodapés de todas as telas integradas em um mesmo contexto.
Entre as linhas 14 e 25 são definidas as instruções do estabelecimento da estrutura do cabeçalho (linha 16) e rodapé
(linha 23) da tela principal SS-TELA01. Neste trecho não há nenhuma novidade a não ser a omissão do corpo da tela
constituído entre as linhas 27 e 39 com a indicação do menu SS-TELA01-MENU. Na linha 48 está sendo definido o uso
da cláusula AUTO que efetua a entrada automática de um dado sem a necessidade de uso da tecla <ENTER> quando
o dado informado ocupa todo o espaço da entrada. Atente nesses dois trechos que formam a tela principal do programa
as indicações dos posicionamentos dos títulos na tela.
Nas linhas 41, 67 e 93 são definidas as telas secundárias. As três telas secundárias possuem codificações semelhan-
tes. Desta forma, atente para o trecho entre as linhas 93 e 117. Após definir a cláusula AUTO na linha 94 são definidas
as cláusulas de configuração de cor para toda a tela (linhas 95 e 96). Em seguida é definido o cabeçalho entre as linhas
98 e 104, o qual possui uma definição de cor nas linhas 100, 103 e 104 diferente da cor definida para toda a tela, sendo
que o mesmo se aplica na constituição do corpo (linha 105) e do rodapé (linha 108).
Na linha 123 é efetuada a chamada da apresentação da tela SS-TELA01 que somente apresentada dados sem a defi-
nição de alguma ação de entrada daí ser usado apenas o comando DISPPLAY. Já nas linhas 124 e 125 são indicados
o uso da ação do menu SS-TELA01-MENU que além de apresentar seu conteúdo (linha 124) tem a necessidade da
execução de entrada da opção a ser escolhida (linha 125). Os demais detalhes entre o trecho 121 e 138 são conheci-
dos. Antes de executar a linha 123 na linha 122 encontra-se a instrução MOVE SPACE TO LS-OPCAO que efetua a
limpeza da variável LS-OPCAO garantido que esteja pronta para uma nova entrada. Semelhantemente operações
idênticas são executadas nas linhas 143, 149 e 155 para a variável LS-ALGO.
390 PRO G RA MA Ç ÃO CO B OL

Nas linhas 142, 148 e 154 são definidas as seções de uso de cada uma das telas secundárias que apresentam seus
elementos (DISPLAY) e executam alguma entrada de dados (ACCEPT).
O programa cap08ap08.cob demonstra em linhas gerais os procedimentos de escrita a serem seguidos para o desen-
volvimento de código que opere a indicação de menus. No entanto é necessário pensar nas telas de entrada e saída de
dados que são gerenciadas por um menu. Neste sentido, outras clausulas podem ser aplicadas na SCREEN SECTION.
O programa a seguir apresenta de forma simplificada o uso das ações de entrada de dados para um cliente e sua ime-
diata apresentação. Para este exemplo são definidas duas telas principais: uma para a entrada de dados e outra para a
saída de dados além de outras telas suplementar de apoio. Assim sendo, abra um projeto vazio, atribuindo-lhe o nome
cap08ap09 a partir da extensão “.cob” na subpasta COBOL da pasta Documentos e codifique as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP09 AS "Capitulo 8 – Aplicacao 9".
3 *
4 ENVIRONMENT DIVISION.
5 INPUT-OUTPUT SECTION.
6 *
7 DATA DIVISION.
8 WORKING-STORAGE SECTION.
9 01 TB-VIRTUAL.
10 05 TB-CADFUN.
11 10 TB-CODFUN PIC X(09).
12 10 TB-NOME PIC X(40).
13 10 TB-DEPTO PIC 99.
14 10 TB-FUNCAO PIC X(20).
15 10 TB-SALARIO PIC 9(10)V99.
16 77 TB-SALARIO-EDIT PIC X(12).
17 77 WS-ENTER PIC X.
18 *
19 SCREEN SECTION.
20 * >>> SUB CABECALHO PARA APOIO DAS TELAS DE ENTRADA E SAIDA
21 01 SS-APOIO-CORPO
22 FOREGROUND-COLOR 3 HIGHLIGHT
23 BACKGROUND-COLOR 0.
24 05 LINE 05 COL 10 VALUE "CODIGO ........:".
25 05 LINE PLUS 01 COL 10 VALUE "NOME ..........:".
26 05 LINE PLUS 01 COL 10 VALUE "DEPARTAMENTO ..:".
27 05 LINE PLUS 01 COL 10 VALUE "FUNCAO ........:".
28 05 LINE + 01 COL 10 VALUE "SALARIO .......:".
29 * >>> ESTRUTURA DE REGISTRO - PARA EFETIVACAO DE ENTRADA
30 01 SS-APOIO-REGISTRO-ENTRADA
31 REQUIRED
32 FOREGROUND-COLOR 7
33 REVERSE-VIDEO.
34 05 LINE 05 COL 27 PIC X(09) USING TB-CODFUN.
35 05 LINE PLUS 01 COL 27 PIC X(40) USING TB-NOME.
36 05 LINE PLUS 01 COL 27 PIC X(02) USING TB-DEPTO.
37 05 LINE PLUS 01 COL 27 PIC X(20) USING TB-FUNCAO.
38 05 LINE PLUS 01 COL 27 PIC X(12) USING TB-SALARIO-EDIT.
39 * >>> ESTRUTURA DE REGISTRO - PARA EFETIVACAO DE SAIDA
40 01 SS-APOIO-REGISTRO-SAIDA
41 FOREGROUND-COLOR 7
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 391

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
42 REVERSE-VIDEO.
43 05 LINE 05 COL 27 PIC X(09) FROM TB-CODFUN.
44 05 LINE 06 COL 27 PIC X(40) FROM TB-NOME.
45 05 LINE 07 COL 27 PIC ZZ FROM TB-DEPTO.
46 05 LINE 08 COL 27 PIC X(20) FROM TB-FUNCAO.
47 05 LINE 09 COL 27 PIC Z,ZZZ,ZZZ,ZZ9.99 FROM TB-SALARIO.
48 * >>> TELA PARA A ENTRADA DE DADOS
49 01 SS-TELA01.
50 05 BLANK SCREEN.
51 05 SS-TELA01-CABECALHO.
52 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
53 BACKGROUND-COLOR 1.
54 10 LINE 01 COL 01
55 VALUE "PROTES | PROGRAMA TESTE | ENTRADA DE DADOS"
56 HIGHLIGHT FOREGROUND-COLOR 6
57 BACKGROUND-COLOR 1.
58 05 SS-TELA01-RODAPE.
59 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
60 BACKGROUND-COLOR 4.
61 10 LINE 24 COL 01 PIC X(31)
62 VALUE "Acione <TAB> para mudar campo |"
63 HIGHLIGHT FOREGROUND-COLOR 7
64 BACKGROUND-COLOR 4.
65 10 LINE 24 COL 33 PIC X(30)
66 VALUE "<ENTER> para encerrar entrada."
67 HIGHLIGHT FOREGROUND-COLOR 7
68 BACKGROUND-COLOR 4.
69 * >>> TELA PARA A SAIDE DE DADOS
70 01 SS-TELA02.
71 05 BLANK SCREEN.
72 05 SS-TELA02-CABECALHO.
73 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
74 BACKGROUND-COLOR 1.
75 10 LINE 01 COL 01
76 VALUE "PROTES | PROGRAMA TESTE | SAIDA DE DADOS"
77 HIGHLIGHT FOREGROUND-COLOR 6
78 BACKGROUND-COLOR 1.
79 05 SS-TELA02-RODAPE.
80 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
81 BACKGROUND-COLOR 4.
82 10 LINE 24 COLUMN 01 PIC X(30)
83 VALUE "Tecle <ENTER> para encerrar..."
84 HIGHLIGHT FOREGROUND-COLOR 7
85 BACKGROUND-COLOR 4.
86 10 LINE 24 COLUMN 80 PIC X USING WS-ENTER
87 HIGHLIGHT FOREGROUND-COLOR 7
88 BACKGROUND-COLOR 4.
89 *
90 PROCEDURE DIVISION.
91 PROG-PRINCIPAL-PARA.
92 * >>> ESTRUTURA DE CHAMADA PARA TELA DE ENTRADA
93 DISPLAY SS-TELA01.
94 DISPLAY SS-APOIO-CORPO.
------ ------------------------------------------------------------------------
392 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
95 DISPLAY SS-APOIO-REGISTRO-ENTRADA.
96 ACCEPT SS-APOIO-REGISTRO-ENTRADA.
97 * >>> ESTRUTURA DE CHAMADA PARA TELA DE SAIDA E SEU RODAPE
98 MOVE TB-SALARIO-EDIT TO TB-SALARIO.
99 DISPLAY SS-TELA02-CABECALHO.
100 DISPLAY SS-APOIO-CORPO.
101 DISPLAY SS-APOIO-REGISTRO-SAIDA.
102 DISPLAY SS-TELA02-RODAPE.
103 ACCEPT SS-TELA02-RODAPE.
104 PROG-PRINCIPAL-FIM-PARA.
105 STOP RUN.
106 *
107 END PROGRAM CAP08AP09.
------ ------------------------------------------------------------------------

Ao ser executado o programa entre os dados solicitados usando a tecla <Tab> para saltar os campos indicados, so-
mente acione a tecla <Enter> quando todos os campos estiverem preenchidos. Após acionar <Enter> na entrada os
dados são imediatamente apresentados.
Entre as linhas 19 e 88 são definidas as estruturas de telas do programa. Entre as linhas 21 e 28 é definida a estrutura
de apoio a formação do corpo de títulos usados tanto na tela de entrada (linha 49) como na tela de saída (linha 70).
Entre as linhas 30 e 38 é definida a estrutura de apoio a entrada de dados gerenciada pela tela SS-TELA01. Entre as
linhas 40 e 47 é definida a estrutura de apoio a saída de dados gerenciada pela tela SS-TELA02.
Na definição da tela de apoio a entrada de registros (linhas 30) é definido na linha 31 o uso da cláusula REQUIRED que
faz com que a entrada de dados em todos os campos seja obrigatória. Caso queira que um certo campo seja obrigató-
rio e outros não se deve usar REQUIRED após a definição do campo desejado. Por exemplo, considerando que o cam-
po de entrada do código funcional fosse obrigatório: 05 LINE 05 COL 27 PIC X(09) USING TB-CODFUN REQUIRED.
Outro efeito aplicado é a apresentação de cores invertidas com a cláusula REVERSE-VIDEO indicada na linha 33. Veja
também o uso de posicionamento relativo das linhas (que podem ser aplicados as colunas) com uso da cláusula PLUS
(+), também aplicada entre as linhas 25 e 26.
Entre as linhas 40 e 47 estão definidas a estrutura para a apresentação da saída de dados com uso de inversão de
cores a partir da cláusula REVERSE-VIDEO na linha 42. As definições das telas de operação da entrada (linha 49) e
saída (linha 70) não apresentam nenhuma novidade em relação ao que já foi exposto.
Na execução das chamadas das telas entre as linhas 93 e 103 são usados os comandos DISPLAY para apresentar os
dados das telas indicadas e o comando ACCEPT para a realização das ações de entradas de dados nas telas quando
necessárias. Atenção maior fica concentrada no trecho de saída de dados a partir da linha 97, veja que a construção da
saída é definida separadamente com os elementos das telas SS-TELA02-CABECALHO (linha 99), SS-APOIO-CORPO
(linha 100), SS-APOIO-REGISTRO-SAIDA (linha 101) e SS-TELA02-RODAPE (linha 102 e 103).
Para melhor controle operacional da apresentação de dados de saída de preferência para a definição da estrutura indi-
cada entre as linhas 99 e 103.
A partir das definições apresentadas neste tópico já é possível ter os recursos necessários para a definição de layouts
de telas mais elaborados. Vale ressaltar que são aqui apresentados os elementos de configuração mais comuns, exis-
tindo outros que merecem igual atenção. Para tanto, é importante avançar os estudos destes recursos além dos limites
aqui indicados.
IN TE R FA C E C O M O U SUÁ R IO 393

8.3 UTILIZAÇÃO DE TECLAS DE FUNÇÃO E OUTROS ATALHOS


A elaboração de uma estrutura de interface que facilite o uso e acesso de usuários a programas de computador, dentro
do universo COBOL, não se resume apenas a definições de relatórios e telas. É possível também fazer o tratamento de
acesso a funcionalidades de programas com o teclado a partir do uso de algumas teclas de função. Neste sentido, o
ideal é definir de um grupo elementar com código 01 do tipo lógico com campos de código 88 contendo os rótulos de
nomes internos de identificação de cada atalho e sua relação com seu valor operacional da tecla de função dentro do
sistema.
O grupo elementar lógico deve ser declarado no parágrafo SPECIAL-NAMES a partir do uso da cláusula CRT STATUS
IS na CONFIGURATION SECTION referenciado para controle com o comando EVALUATE. Desta forma sua definição
segue o estilo sintático.

CONFIGURATION SECTION.
SPECIAL-NAMES.
CRT STATUS IS <grupo>.

Onde grupo é a definição do nome do conjunto elementar lógico que contém os nomes internos de cada tecla de fun-
ção e sua relação com os valores internos declarados na seção WORKING- STORAGE ou LOCAL-STORAGE a partir
da forma sintática.

WORKING-STORAGE SECTION / LOCAL-STORAGE SECTION.


01 <grupo> PIC 9(04) VALUE 9999.
88 <tecla-função1> VALUE <valor1>.
88 <tecla-função2> VALUE <valor2>.
...
88 <tecla-funçãoN> VALUE <valorN>.

Onde grupo é o nome definido na cláusula CRT STATUS IS, tecla-função é a definição de um rótulo interno de identi-
ficação do nome da tecla de função e valor é o uso de um valor interno de identificação de uso de determinada tecla de
função. A tabela 8.2 mostra as principais relações dos códigos numéricos da sequência de valores da faixa 1000 e sua
relação com as teclas de função padrão Fn que fazem referência para o GnuCOBOL.

Tabela 8.2 – Teclas de funções Fn

Código Código Código Código


Significado Significado Significado Significado
numérico numérico numérico numérico

1001 Tecla: F1 1002 Tecla: F2 1003 Tecla: F3 1004 Tecla: F4

1005 Tecla: F5 1006 Tecla: F6 1007 Tecla: F7 1008 Tecla: F6

1009 Tecla: F9 1010 Tecla: F10 1011 Tecla: F11 1012 Tecla: F12

Além dos valores indicados na tabela 8.2 para uso das teclas de função de F1 até F12 há a existências dos valores de
1013 até 1064 respectivamente para uso das teclas de função de F13 até F64 quando disponíveis.
Além da sequência de valores da faixa 1000 tem-se a sequência de valores da faixa 2000 como apresenta a tabela 8.3
com a indicação das teclas de função de controle do teclado mais comuns.
394 PRO G RA MA Ç ÃO CO B OL

Tabela 8.3 – Teclas de funções para controle do teclado

Código Código
Significado Significado
numérico numérico

2001 Tecla: PAGE UP 2002 Tecla: PAGE DOWN

2003 Tecla: SETA PARA CIMA 2004 Tecla: SETA PARA BAIXO

2005 Tecla: ESC 2006 Tecla: PRINT

2007 Tecla: TAB 2008 Tecla: SHIFT + TAB

2009 Tecla: SETA PARA ESQUERDA 2010 Tecla: SETA PARA DIREITA

2011 Tecla: INSERT 2012 Tecla: DELETE

2013 Tecla: BACKSPACE 2014 Tecla: HOME

2015 Tecla: END

Além dos valores mostrados na tabela 8.3 existem outros valores da faixa 2000 para controle executadas por mouse e
outras ações de controle nas faixas 8000 e 9000. Para maiores detalhes a este respeito consulte preferencialmente a
documentação oficial do compilador GnuCOBOL.
O exemplo a seguir mostra um menu onde as seleções de suas opções são realizadas com o uso das teclas de funções
F1, F2 e F3. O código a seguir é idêntico ao código do programa cap08ap09.cob. Assim sendo, abra um projeto vazio,
atribuindo-lhe o nome cap08ap10 a partir da extensão “.cob” na subpasta COBOL da pasta Documentos e codifique
as instruções seguintes.

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
1 IDENTIFICATION DIVISION.
2 PROGRAM-ID. CAP08AP10 AS "Capitulo 8 – Aplicacao 10".
3 *
4 ENVIRONMENT DIVISION.
5 CONFIGURATION SECTION.
6 *
7 SPECIAL-NAMES.
8 * >>> DEFINICAO DE USO PARA TECLAS DE FUNCAO/ATALHO
9 CRT STATUS IS SN-CRT-TECLAS.
10 *
11 INPUT-OUTPUT SECTION.
12 DATA DIVISION.
13 WORKING-STORAGE SECTION.
14 77 WS-ALGO PIC X.
15 * >>> DEFINICAO DAS TECLAS DE FUNCAO/ATALHO
16 01 SN-CRT-TECLAS PIC 9(04) VALUE 9999.
17 88 TECLA-F1 VALUE 1001.
18 88 TECLA-F2 VALUE 1002.
19 88 TECLA-F3 VALUE 1003.
20 *
21 SCREEN SECTION.
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 395

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
22 01 SS-TELA01.
23 05 BLANK SCREEN.
24 05 SS-TELA01-CABECALHO.
25 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
26 BACKGROUND-COLOR 1.
27 10 LINE 01 COL 01
28 VALUE "PROTES | PROGRAMA TESTE | MENU PRINCIPAL"
29 HIGHLIGHT FOREGROUND-COLOR 6
30 BACKGROUND-COLOR 1.
31 05 SS-TELA01-RODAPE.
32 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
33 BACKGROUND-COLOR 4.
34 01 SS-TELA01-MENU
35 AUTO
36 FOREGROUND-COLOR 2 HIGHLIGHT
37 BACKGROUND-COLOR 0.
38 05 LINE 05 COL 10 VALUE "[F1] ENTRADA DE DADOS".
39 05 LINE 06 COL 10 VALUE "[F2] APRESENTACAO DE DADOS".
40 05 LINE 07 COL 10 VALUE "[F3] SAIDA DO SISTEMA".
41 05 LINE 24 COL 01 PIC X(42)
42 VALUE "Acione uma das teclas de funcao indicadas."
43 HIGHLIGHT FOREGROUND-COLOR 7
44 BACKGROUND-COLOR 4.
45 05 LINE 24 COLUMN 80 PIC X USING WS-ALGO
46 HIGHLIGHT FOREGROUND-COLOR 7
47 BACKGROUND-COLOR 4.
48 01 SS-TELA02
49 AUTO
50 FOREGROUND-COLOR 3 HIGHLIGHT
51 BACKGROUND-COLOR 0.
52 05 BLANK SCREEN.
53 05 SS-TELA02-CABECALHO.
54 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
55 BACKGROUND-COLOR 1.
56 10 LINE 01 COL 01
57 VALUE "PROTES | PROGRAMA TESTE | OPCAO 1"
58 HIGHLIGHT FOREGROUND-COLOR 6
59 BACKGROUND-COLOR 1.
60 05 SS-TELA02-CORPO.
61 10 LINE 12 COLUMN 31 PIC X(20)
62 VALUE "OPCAO [F1] ACIONADA.".
63 05 SS-TELA02-RODAPE.
64 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
65 BACKGROUND-COLOR 4.
66 10 LINE 24 COL 01 PIC X(31)
67 VALUE "Tecle algo para voltar ao menu."
68 HIGHLIGHT FOREGROUND-COLOR 7
69 BACKGROUND-COLOR 4.
70 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
71 HIGHLIGHT FOREGROUND-COLOR 7
72 BACKGROUND-COLOR 4.
73 01 SS-TELA03
74 AUTO
------ ------------------------------------------------------------------------
396 PRO G RA MA Ç ÃO CO B OL

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
75 FOREGROUND-COLOR 5 HIGHLIGHT
76 BACKGROUND-COLOR 0.
77 05 BLANK SCREEN.
78 05 SS-TELA02-CABECALHO.
79 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
80 BACKGROUND-COLOR 1.
81 10 LINE 01 COL 01
82 VALUE "PROTES | PROGRAMA TESTE | OPCAO 2"
83 HIGHLIGHT FOREGROUND-COLOR 6
84 BACKGROUND-COLOR 1.
85 05 SS-TELA02-CORPO.
86 10 LINE 12 COLUMN 31 PIC X(20)
87 VALUE "OPCAO [F2] ACIONADA.".
88 05 SS-TELA02-RODAPE.
89 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
90 BACKGROUND-COLOR 4.
91 10 LINE 24 COL 01 PIC X(31)
92 VALUE "Tecle algo para voltar ao menu."
93 HIGHLIGHT FOREGROUND-COLOR 7
94 BACKGROUND-COLOR 4.
95 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
96 HIGHLIGHT FOREGROUND-COLOR 7
97 BACKGROUND-COLOR 4.
98 01 SS-TELA04
99 AUTO
100 FOREGROUND-COLOR 6 HIGHLIGHT
101 BACKGROUND-COLOR 0.
102 05 BLANK SCREEN.
103 05 SS-TELA04-CABECALHO.
104 10 LINE 01 COL 01 PIC X(80) VALUE ALL " "
105 BACKGROUND-COLOR 1.
106 10 LINE 01 COL 01
107 VALUE "PROTES | PROGRAMA TESTE | ERRO"
108 HIGHLIGHT FOREGROUND-COLOR 6
109 BACKGROUND-COLOR 1.
110 05 SS-TELA04-CORPO.
111 10 LINE 12 COLUMN 31 PIC X(15)
122 VALUE "OPCAO INVALIDA.".
113 05 SS-TELA04-RODAPE.
114 10 LINE 24 COL 01 PIC X(80) VALUE ALL " "
115 BACKGROUND-COLOR 4.
116 10 LINE 24 COL 01 PIC X(31)
117 VALUE "Tecle algo para voltar ao menu."
118 HIGHLIGHT FOREGROUND-COLOR 7
119 BACKGROUND-COLOR 4.
120 10 LINE 24 COLUMN 80 PIC X USING WS-ALGO
121 HIGHLIGHT FOREGROUND-COLOR 7
122 BACKGROUND-COLOR 4.
123 *
124 PROCEDURE DIVISION.
125 PROG-PRINCIPAL-PARA.
126 PERFORM FOREVER
127 DISPLAY SS-TELA01
------ ------------------------------------------------------------------------
IN TE R FA C E C O M O U SUÁ R IO 397

------ -------A---B------------------------------------------------------------
LINHAS 123456789012345678901234567890123456789012345678901234567890123456789012
------ ----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
128 DISPLAY SS-TELA01-MENU
129 ACCEPT SS-TELA01-MENU
130 EVALUATE TRUE
131 WHEN TECLA-F1
132 PERFORM 1000-OPCAO-1
133 WHEN TECLA-F2
134 PERFORM 2000-OPCAO-2
135 WHEN TECLA-F3
136 EXIT PERFORM
137 WHEN OTHER
138 PERFORM 3000-OPCAO-ERRO
139 END-EVALUATE
140 END-PERFORM.
141 PROG-PRINCIPAL-FIM-PARA.
142 STOP RUN.
143 *
144 1000-OPCAO-1 SECTION.
145 MOVE SPACE TO WS-ALGO.
146 DISPLAY SS-TELA02.
147 ACCEPT SS-TELA02.
148 EXIT.
149 *
150 2000-OPCAO-2 SECTION.
151 MOVE SPACE TO WS-ALGO.
152 DISPLAY SS-TELA03.
153 ACCEPT SS-TELA03.
154 EXIT.
155 *
156 3000-OPCAO-ERRO SECTION.
157 MOVE SPACE TO WS-ALGO.
158 DISPLAY SS-TELA04.
159 ACCEPT SS-TELA04.
160 EXIT.
161 *
162 END PROGRAM CAP08AP10.
------ ------------------------------------------------------------------------

Ao ser executado o programa selecione as opções do menu com o uso das teclas de função Fn. Observe o comporta-
mento de cada ação comparando este código com o código do programa cap08ap09.cob.
O primeiro ponto de atenção a ser observado no programa está indicado entre as linhas 7 e 9. Veja a definição do pa-
rágrafo SPECIAL-NAMES (linha 7) com a indicação do rótulo SN-CRT-TECLAS junto a cláusula CRT STATUS IS na
linha 9 fazendo referência ao trecho de linhas entre 16 e 19.
Entre as linhas 16 e 19 é definida a estrutura de grupo lógico para a configuração das teclas de função para as ações
do menu junto aos atalhos F1 (linha 17), F2 (linha 18) e F3 (linha 19) respectivamente identificados com os valores de
ação 1001, 1002 e 1003. As teclas de atalho para as funções identificadas são efetivamente usadas no trecho de códi-
go entre as linhas 130 e 139.
Os programas cap08ap09.cob e cap08ap10.cob são idênticos. No entanto, atente para os detalhes gerais definidos
entre o trecho de linhas 22 e 47, mais precisamente entre as linhas 38 e 47. Observe as indicações dos detalhes opera-
cionais de informação para o usuário.
No trecho de linhas entre 126 e 140 é realizada a apresentação e validação da escolha de cada uma das opções do
menu. Veja o uso do comando EVALUATE na linha 130 com o uso da constante de identificação lógica TRUE indican-
398 PRO G RA MA Ç ÃO CO B OL

do manter o fluxo do comando sempre em execução juntamente com o laço PEFORM da linha 126 até que em algum
momento a instrução EXIT PERFORM seja executada. Observe nas linhas 131, 133 e 135 o uso dos rótulos de identifi-
cação das teclas de função configuradas entre as linhas 16 e 19.
A partir deste e dos demais detalhes apresentados neste capítulo e também nos demais capítulos deste livro você pos-
sui o conhecimento mínimo necessário e básico para o desenvolvimento de programas escritos na linguagem COBOL.
CO MPL E ME NT OS 399

A
EXECUÇÃO AUTONOMA DE PROGRAMAS

Todos os programas desenvolvidos ao longo deste trabalho foram executados dentro do ambiente de desenvolvimento.
Essa ação é adequada na fase de desenvolvimento, mas não poderá ser usada na instalação do cliente. Para o ambi-
ente do cliente é necessária uma cópia autônoma do programa que seja plenamente executada após sua instalação.
No entanto, se houver a tentativa de execução de qualquer programa compilado existente na subpasta bin da subpasta
COBOL da pasta Documentos de forma autônoma ter-se-á a apresentação de mensagem de advertência como apre-
senta a figura A.1, indicando que falta no local a biblioteca libcob-4.dll.

Figura A.1 – Mensagem de erro na tentativa de execução de programa

A sugestão dada em se fazer a reinstalação do programa não irá corrigir o problema, uma vez que essa e outras biblio-
tecas são gerenciadas internamento pelo próprio ambiente de desenvolvimento OpenCobolIDE e não são automatica-
mente disponibilizadas para uso externo, tendo-se que realizar esta ação de forma manual, lembrando que para o com-
pilador GnuCOBOL funcionar é necessário que o MinGW esteja previamente instalado e parte dessas bibliotecas de
execução são do programa MinGW.
Há duas soluções para a questão e a forma de usá-las dependerá da situação existente ou opção operacional em uso.
Uma das soluções é realizar a configuração externa das variáveis de ambiente e a outra é copiar as bibliotecas para
dentro da pasta que contém os executáveis.
A primeira solução é muito boa para a máquina de desenvolvimento, pois já estão instalados no computador os compi-
ladores GnuCOBOL e MinGW. A dependência existente entre esses compiladores se caracteriza pelo fato do compila-
dor GnuCOBOL ser uma ferramenta de ação cruzada frente ao compilador MinGW. O GnuCOBOL efetua a tradução
do código de linguagem COBOL em código de linguagem C, daí a necessidade do MinGW para criar o programa exe-
cutável.
A segunda solução é mais viável para a instalação do programa na máquina do cliente, pois bastará o programa execu-
tável e as bibliotecas necessárias copiadas para dentro de determinada pasta.
Considerando a primeira solução acesse inicialmente no OpenCobolIDE a opção Preferences no menu Edit. A partir
da apresentação da caixa de diálogo Preference selecione a guia Compiler e amplie suas bordas de modo que fique
semelhante a imagem da figura A.2.
400 PRO G RA MA Ç ÃO CO B OL

Figura A.2 – Caixa de diálogo Preferences

Veja que a guia Compiler da caixa de diálogo Preferences é formada por um conjunto de áreas de edição identificadas
com rótulos à esquerda. Observe o rótulo Compiler path e veja na subárea Environment variables as indicações das
variáveis de ambiente PATH, COB_CONFIG_DIR, COB_COPY_DIR, COB_INCLUDE_PATH e COB_LIB_PATH con-
tendo os endereços de acesso para que o compilador GnuCOBOL consiga compilar e executar os programas criados.
Anote as variáveis e as indicações dos endereços de acesso e saia da caixa de diálogo Preferences.

PATH >>> C:\Program Files\OpenCobolIDE\GnuCOBOL\bin


COB_CONFIG_DIR >>> C:\Program Files\OpenCobolIDE\GnuCOBOL\config
COB_COPY_DIR >>> C:\Program Files\OpenCobolIDE\GnuCOBOL\copy
COB_INCLUDE_PATH >>> C:\Program Files\OpenCobolIDE\GnuCOBOL\include
COB_LIB_PATH >>> C:\Program Files\OpenCobolIDE\GnuCOBOL\lib

Na sequência basta definir essas variáveis para uso no ambiente do sistema


operacional. Para tanto, selecione com um clique do ponteiro do mouse o ícone
"Este computador" com o botão de contexto do mouse, normalmente o botão
esquerdo, dê um clique sobre o ícone e selecione no menu apresentado a opção
Propriedades, como indicado na figura A.3.
Será apresentada a tela "Sistema" como mostra a figura A.4. Neste momento,
selecione o link à esquerda Configurações avançadas do sistema para apre-
sentação da caixa de diálogo Propriedades do Sistema como apresenta a figura
A.5. Figura A.3 – Menu Propriedades
CO MPL E ME NT OS 401

Figura A.4 – Tela Sistema

Na caixa de diálogo Propriedades do Sistema selecione o


botão Variáveis de Ambiente e será apresentada outra caixa
de diálogo denominada Variáveis de Ambiente como indica-
do pela figura A.6.
A caixa de diálogo Variáveis de Ambiente é dividida em duas
áreas de definição. A primeira área Variáveis de usuário para
Nome_do_usuário destinada a definição de variáveis para o
usuário ativo e a segunda área Variáveis de sistema destina-
da a definição de variáveis para uso geral do sistema, ou seja,
para todos os usuários cadastrados no computador.
Na segunda área, localize na lista a variável Path selecionan-
do-a com um clique do ponteiro do mouse. Em seguida acione
o botão "Editar..." é apresentada a caixa de diálogo Editar a
variável de ambiente como apresenta a figura A.7.
Neste instante, acione o botão Novo e no campo apresentado
informe C:\Program Files\OpenCobolIDE\GnuCOBOL\bin e
selecione o botão OK.
Na sequência, acione o botão "Novo..." e será apresentada a
Figura A.5 – Caixa de diálogo Propriedades do Sistema
caixa de diálogo Nova Variável de Sistema, como mostra a
figura A.8.
A partir deste momento, separadamente entre no campo Nome da variável cada uma das variáveis apontadas e colo-
que no campo Valor da variável para cada uma das variáveis apontadas o respectivo endereço de acesso indicado
para cada uma das variáveis. Ao final de cada configuração, acione o botão OK.
As figuras A.9, A.10, A.11 e A.12 mostram as definições a serem estabelecidas para cada uma das variáveis aponta-
das.
Após a definição do conjunto de variáveis, acione o botão OK da caixa de diálogo Variáveis de Ambiente e na se-
quência acione também o botão OK da caixa de diálogo Propriedades do Sistema. Na sequência feche a janela Sis-
tema.
Vá até a subpasta bin na subpasta COBOL da pasta Documentos e selecione com um duplo do ponteiro do mouse
qualquer programa executável existente e você verá que o programa é executado sem a apresentação de mensagem
de advertência, indicando o erro de falta de biblioteca. Veja o resultado junto a figura A.13.
402 PRO G RA MA Ç ÃO CO B OL

Figura A.6 – Caixa de diálogo Variáveis de Ambiente Figura A.7 – Caixa Editar a variável de ambiente

Figura A.8 – Caixa de diálogo Nova Variável de Sistema

Figura A.9 – Definição variável COB_CONFIG_DIR

Figura A.10 – Definição variável COB_COPY_DIR

Figura A.11 – Definição variável COB_INCLUDE_PATH


CO MPL E ME NT OS 403

Figura A.12 – Definição variável COB_LIB_PATH

Figura A.13 – Execução de programa de forma autônoma

As variáveis de ambiente COB_CONFIG_DIR, COB_COPY_DIR, COB_INCLUDE_PATH e COB_LIB_PATH podem a


qualquer instante serem removidas. Para tanto, basta estando na caixa de diálogo Variáveis de Ambiente selecionar a
variável deseja e acionar o botão Excluir.
Considerando a segunda solução é conveniente remover do ambiente as variáveis definidas. Tenha apenas o cuidado
de não remover a variável Path. No caso desta variável acione o botão "Editar...", localize na lista apresentada o ende-
reço de acesso C:\Program Files\OpenCobolIDE\GnuCOBOL\bin e o exclua (apenas este), acionando na sequência
os botões OK por três vezes.
A partir do menu Edit selecione a opção Preferences. Na caixa de diálogo Preferences selecione a guia Compiler,
caso não esteja selecionada e dê um clique com o ponteiro do mouse sobre a opção Copy runtime dlls to output
directory, abaixo do campo Output directory que pode, eventualmente, ser alterado.
Em seguida, compile um programa e todas as 24 bibliotecas necessárias serão copiadas para dentro da subpasta bin.
A partir deste instante os programas podem ser executados de forma autônoma sem nenhuma restrição.
Após a realização dos testes indicados desabilite na caixa de diálogo Preferences a opção de cópia das bibliotecas de
runtime Copy runtime dlls to output directory.
404 PRO G RA MA Ç ÃO CO B OL

Anotações

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________

________________________________________________________________________________________________
CO MPL E ME NT OS 405

B
PREPARAÇÃO DE INSTALADOR

A situação exposta no apêndice B, sobre uso de programas na máquina do cliente com executável e bibliotecas sugere
o uso de um programa de instalação com o objetivo de facilitar o uso do programa pelo próprio cliente. Para preparar
um programa instalador há diversas formas, desde confeccionar o próprio programa até fazer a aquisição de ferramen-
tas de terceiros.
Em relação a disponibilidade de ferramentas de terceiros há a possibilidade de se usar ferramentas pagas ou ferramen-
tas de uso livre. Para este apêndice está sendo considerado o uso de uma ferramenta bastante simples, gratuita e livre
utilização chamada InstallSimple. Para fazer esta aquisição vá até o sítio do desenvolvedor http://installsimple.com/
e localize InstallSimple 3.0 Free (podendo escolher a versão PRO que é paga e pode ser usada por 30 dias para expe-
rimentação) e selecione o link Download portable version (ZIP-archive, 356 KB) para usar o programa portátil que
não requer instalação. A figura B.1 apresenta a página de acesso a ferramenta.

Figura B.1 – Sítio para acesso a ferramenta InstallSimple

Assim que o programa for copiado para seu computador, descompacte-o e com um duplo clique acione para execução
o programa InstallSimple.exe que apresentará a tela inicial indicada na figura B.2 intitulada Welcome to the Install-
Simple Wizard.
Na sequência acione com o ponteiro do mouse o botão "Next >" e será apresentada a tela Make window title and
name of your product como mostra a figura B.3.
406 PRO G RA MA Ç ÃO CO B OL

Figura B.2 – Welcome to the InstallSimple Wizard. Figura B.3 – Make window title and name of your product

Neste momento, basta indicar a descrição do título da janela (Window Title) e do nome do produto (Product Name).
Para teste, no campo Window Title informe Estudo de COBOL e para Product Name informe Programa Exemplo. A
figura B.4 mostra o estado desta ocorrência.
Após fazer o preenchimento dos campos, acione o botão "Next >" e é apresenta a tela First message for user como
indica a figura B.5 que permite que sejam definidas as primeiras informações iniciais ao usuário. Entre as informações
que julgar necessárias.

Figura B.4 – Preparação inicial do título e nome Figura B.5 – First message for user

Como exemplo, considere o texto "Este programa é um exemplo de instalação de programa escrito em linguagem
COBOL a partir do estudo do livro "Programação COBOM para Windows com OpenCobol IDE 4.7.6: Primeiros
passos com formato fixo direto ao ponto" INTRODUÇÃO COM T-REX" como primeira mensagem ao usuário do
programa e sua reprodução junto a figura B.6. Na sequência acione o botão "Next >".
Será indicada a tela Last message for user para definição da mensagem de finalização, considere o texto "A aplica-
ção instalada foi gerada usando o compilador GnuCOBOL com o ambiente integrado de desenvolvimento Ope-
nCobolIDE na versão 4.7.6.", como demostra a figura B.7. Na sequência acione o botão "Next >".
A próxima etapa apresenta a tela License Agreement para publicação do texto contendo a licença de uso do programa
a ser instalado. Nesta tela, é normalmente colocado o contrasto com as regras de uso do programa, como apresenta a
figura B.8. Nesta etapa, esta tela ficará em branco, acione o botão "Next >".
Na sequência é apresentada a tela Graphics, como mostra a figura B.9, que permite estabelecer três detalhes gráficos
do programa de instalação. No campo Splash Screen é possível escolher uma imagem que será usada como apresen-
tação inicial do programa e seu tempo de apresentação junto ao campo Delay, o campo Header permite escolher uma
imagem que será usada no cabeçalho das telas do programa de instalação, podendo ser ajustada em Justify e o cam-
po Wizard permite escolher a imagem que será usada como ornamento a esquerda das telas.
CO MPL E ME NT OS 407

Figura B.6 – Texto inicial Figura B.7 – Texto final

Figura B.8 – Tela License Agreement Figura B.9 – Tela Graphics

Para o campo Wizard o programa traz duas imagens na pasta images. Toda a ação de configuração realizada nesta
etapa pode ser visualizada a partir do acionamento do botão Preview posicionado no extremo direito do campo Wizard.
Para este teste está sendo selecionado para Wizard a imagem padrão do programa 1,bmp. Na sequência acione o
botão o botão "Next >".
Nesta fase da criação do programa de instalação é apresentada a tela Files to distribute, indicada na figura B.10, em
que se escolhe os arquivos que comporão o programa de instalação. Em Source folder acione o botão "Browse... " e
selecione a subpasta bin em Documentos/COBOL. No campo Setup Path escreva o título Exemplo teste, de acordo
com a imagem da figura B.11.

Figura B.10 – Tela Files to distribute Figura B.11 – Tela Graphics


408 PRO G RA MA Ç ÃO CO B OL

A etapa seguinte apresenta a tela Shortcuts como mostra a figura B.12. Neste momento, devem ser selecionados os
arquivos que possuirão acesso por atalho. Desta forma, na lista à esquerda selecione o programa executável (neste
exemplo é c04ex01.exe) e com o ponteiro do mouse dê um clique sobre a opção Desktop, selecione também o arquivo
Unistall.exe e selecione novamente a opção Desktop. No campo Program Group escreva o título Exemplo COBOL,
como apresentado na figura B.13 e acione em seguida o botão "Next >".

Figura B.12 – Tela Shortcuts Figura B.13 – Tela Shortcuts editada

É apresentada a tela Windows registry para configuração das variáveis de registro, como registra a figura B.14. Este é
um recurso mais avançado e deve ser usado como muita prudência. Neste caso, em especial, nada será configurado,
então apenas acione o botão "Next >".
Na tela System Requirements, indicado na figura B.15, podem ser definidos alguns detalhes sobre restrições de exe-
cução do programa após a instalação. Esta é outra tela que não necessitará ser modificada. Assim sendo, acione ape-
nas o botão "Next >".

Figura B.14 – Tela Windows registry Figura B.15 – Tela System Requirements

A próxima etapa representada pela tela After Installing como apresenta a figura B.16 estabelece se é necessário reini-
cializar o computador após a instalação do programa. Não sendo esta ação necessário para o exemplo apresentado,
apenas acione o botão "Next >".
Agora é chegada a última etapa da montagem do programa de instalação a partir da tela Build Setup como exibe a
figura B.17. Nesta etapa no campo Setup File deve-se informar o nome que o programa de instalação terá. Para este
teste informe o nome CobInstall e acione o botão "Save As... " e escolha para gravação a Área de Trabalho. No cam-
po Nome informe CobInstall e acione o botão Salvar.
Na sequência acione o botão Build e aguarde a montagem do programa como mostra a figura B.18. Em seguida é
mostrada a tela Instalattion pack was successfully created como indica a figura B.19. Para finalizar acione o botão
Finish.
CO MPL E ME NT OS 409

Figura B.16 – Tela After Installing Figura B.17 – Tela Build Setup

Figura B.18 – Tela After Installing Figura B.19 – Tela Instalattion pack created

Terminada a sequência indicada haverá na Área de Trabalho o programa chamado CobInstall.exe. Neste momento,
execute-o com um duplo clique do ponteiro do mouse. Será apresentada possivelmente a caixa de diálogo perguntando
se é para instalar. Acione o botão Sim e será apresentada a tela de boas vindas como mostra a figura B.20. Acione o
botão "Next >" e será apresentada a tela com a indicação do local de gravação do programa como inca a figura B.21.
Nesta etapa basta apenas acionar o botão "Next >".

Figura B.20 – Tela de boas vindas Figura B.21 – Tela Instalattion pack created

Na sequência é apresentada a tela informando o início do processo de instalação, como indicado na figura B.22. Neste
momento acione o botão Install. Será apresentada a tela de andamento da instalação de acordo com a figura B.23 que
será bem rápida.
410 PRO G RA MA Ç ÃO CO B OL

Figura B.22 – Tela de início da instalação Figura B.23 – Tela com andamento da instalação

Ao término das ações anteriores é apresenta a tela de finalização do processo de instalação como mostra a figura B.24.
Neste momento, basta apenas acionar o botão Finish.

Figura B.24 – Finalização do processo de instalação

Observe que foram criados na Área de Trabalho dois ícones após a instalação, sendo o ícone c04ex01 o atalho de
execução do programa e Uninstall para proceder a desinstalação do programa. Experimente executar o programa e
depois realize sua desinstalação.
Antes de finalizar um detalhe extremamente importante. Caso seu programa use sub-rotinas (o que é muito provável)
não deixe de incluí-las junto as bibliotecas que obrigatoriamente devem ser instaladas para que o programa seja execu-
tado.
CO MPL E ME NT OS 411

C
CARACTERES EBCDIC

O conjunto de caracteres EBCDIC (Extended Binary Coded Decimal Interchange Code) foi desenvolvida entre 1963 e
1964 pela IBM para sua linha de computadores mainframe IBM System/360 com o objetivo de estender o código de
intercambio decimal em binário BCD (Binary-Coded Decimal) ou BCDIC (BCD Interchange Code) usado, na ocasião, para a
perfuração de cartões.
O código EBCDIC é ainda usado em sistemas IBM, pois apesar da empresa ter sido grande defensora do comitê de padroni-
zação ASCII não teve tempo hábil em lançar periféricos ASCII na época. Todos os periféricos e sistemas operacionais para
computadores IBM, sejam de médio porte ou mainframe usam EBCDIC, incluindo-se a arquitetura mais recente IBM/z.
O conjunto de caractere EBCDIC é considerado a partir de três níveis de periodicidade com tamanhos de 16, 32 ou 64 bits.
Para cada estrutura de bits a tabela apresenta algumas diferenças em relação ao uso de caracteres estendidos. A figura C.1
apresenta a estrutura da tabela de caracteres EBCDIC com periodicidade 64.
CARACTERES EBCDIC (CÓDIGO HEXADECIMAL) – PERIODICIDADE 64
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX PF HT LC DEL GE SPC SMM VT FF CR SO SI
1 DLE DC1 DC2 TM RES NL BS IL CAN EM CC CU1 IFS IGS IRS IUS
2 DS SOS FS XXX BYP LF ETB ESC XXX XXX SM CU2 XXX ENQ ACK BEL
3 XXX XXX SYN XXX PN RS UC EOT XXX XXX XXX CU3 DC4 NAK XXX SUB
4 sp XXX â ä à á ã å ç ñ ¢ . < ( + |
5 & é ê ë è í î ï ì ß ! $ * ) ; ¬
6 - / Â Ä À Á Ã Å Ç Ñ ¦ , % _ > ?
7 ø É Ê Ë È Í Î Ï Ì ` : # @ ' = "
8 Ø a b c d e f g h i « » ð ý Þ ±
9 ° j k l m n o p q r ª º æ ¸ Æ ¤
A µ ~ s t u v w x y z ¡ ¿ Ð [ þ ®
B ^ £ ¥ • © § ¶ ¼ ½ ¾ Ý ¨ ¯ ] ’ ×
C { A B C D E F G H I – ô ö ò ó õ
D } J K L M N O P Q R ¹ û ü ù ú ÿ
E \ ÷ S T U V W X Y Z ² Ô Ö Ò Ó Õ
F 0 1 2 3 4 5 6 7 8 9 ³ Û Ü Ù Ú EO
Figura C.1 – Tabela com códigos EBCDIC de 64 bits
412 PRO G RA MA Ç ÃO CO B OL

Observe que a tabela mostra um grande conjunto de caracteres. Em vermelho estão definidos os caracteres de controle de
máquina, formado por códigos que não são imprimíveis. Em azul estão os caracteres alfanuméricos convencionais mínimos
normalmente usados. Em preto estão os caracteres imprimíveis estendidos que para serem usados necessitam do aciona-
mento de um conjunto de teclas. Em verde marcado com os caracteres XXX são apenas espaços em branco no conjunto de
caracteres
O código EBCDIC é formado por conjuntos de 8 bits que permite obter-se realmente 256 combinações diferentes contra os
128 do código ASCII (ver apêndice E). No entanto, seu uso ficou restrito por uma simples questão, os caracteres alfabéticos
não são sequenciais, como mostra a faixa demarca sem azul na figura C.1, e assim tornam as operações de indexação difí-
ceis de ser executadas.
Não cabe aqui explicar o que realmente faz cada código de controle grafado em vermelho e os dois caracteres nomeados
grafados em preto, por fugir do escopo deste trabalho, mas é possível deixar o significado de cada um deles.

ACK Acknowledge BEL Bell or Alert BS Backspace


BYP Bypass CAN Cancel CC Cursor Control
CR Carraige Return CU1 Customer Use 1 CU2 Customer Use 2
CU3 Customer Use 3 DC1 Device Control 1 DC2 Device Control 2
DC4 Device Control 4 DEL Delete DLE Data Link Escape
DS Digit Select EM End of Medium ENQ Enquiry
EO Eight Ones EOT End of Transmission ESC Escape
ETB End of Transmission Block ETX End of Text FF Form Feed
FS Field Separator GE Graphic Escape HT Horizontal Tab
IFS Interchange File Separator IGS Interchange Group Separator IL Idle
IRS Interchange Record Separator IUS Interchange Unit Separator LC Lower Case
LF Line Feed NAK Negative Acknowledge NL New Line
NUL Null PF Punch Off PN Punch On
RES Restore SPC Superscript RS Reader Stop
SI Shift In SM Set Mode SMM Start of Manual Message
SO Shift Out SOH Start of Heading SOS Start of Significance
STX Start of Text SUB Substitute SYN Synchronous Idle
TM Tape Mark UC Upper Case VT Vertical Tab

Para saber mais sobre as estruturas de periodicidade usadas com EBCDIC consulte o sítio https://montcs.bloomu.ed
u/Information/Encodings/ASCII-EBCDIC.html.
CO MPL E ME NT OS 413

D
CARACTERES ASCII

O conjunto de caracteres ASCII (American Standard Code for Information Interchange) foi desenvolvido entre 1963 e
1968 com a participação de várias companhias de comunicação estadunidenses, com o objetivo de substituir o então
utilizado código de Baudot que usava apenas cinco bits e possibilitava apenas trinta e duas combinações diferentes.
Muito útil para manter a comunicação entre dois teleimpressores (conhecidos no Brasil como aparelhos de TELEX), que
usavam apenas símbolos alfanuméricos, mas impróprio para a comunicação entre computadores. O código ASCII (lê-se
asquì e não asqui dois ou como em inglês ass key) padrão permite o uso de apenas 128 símbolos diferentes, a partir de
um conjunto de 7 bits. Nesse conjunto, estão previstos 96 caracteres imprimíveis, tais como números, letras minúscu-
las, letras maiúsculas, sinais de pontuação e caracteres não imprimíveis de controle. Este código foi amplamente aceito
pelas empresas de comunicações e produção de computadores, com exceção da IBM que tinha desenvolvido o código
EBCDIC para sua nova série de computadores System/360. Veja apêndice C. A figura D.1 apresenta a estrutura da tabe-
la de caracteres ASCII a partir dos caracteres aceitos pela norma ISO-8859-1.
CARACTERES ASCII (CÓDIGO HEXADECIMAL) - ISO-8859-1
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC IFS IGS IRS IUS
2 sp ! " # $ % & ' ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ \ ] ^ _
6 ` a b c d e f g h i j k l m n o
7 p q r s t u v w x y z { | } ~ DEL
8 € XXX ‚ ƒ „ ... † ‡ ˆ ‰ Š ‹ Œ XXX Ž XXX
9 XXX ‘ ’ “ ” • – — ˜ ™ š › œ XXX ž Ÿ
A XXX ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ – ® ¯
B ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿
C À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
D Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
E à á â ã ä å æ ç è é ê ë ì í î ï
F ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
Figura DX.1 – Tabela com códigos ASCII padrão ISO-8859-1

Observe que a tabela mostra um grande conjunto de caracteres. Em vermelho estão definidos os caracteres de controle de
máquina, formado por códigos que não são imprimíveis. Em azul estão os caracteres alfanuméricos convencionais mínimos
normalmente usados. Em preto estão os caracteres imprimíveis estendidos que para serem usados necessitam do aciona-
414 PRO G RA MA Ç ÃO CO B OL

mento de um conjunto de teclas. Em verde marcado com os caracteres XXX são apenas espaços em branco no conjunto de
caracteres
Não cabe aqui explicar o que realmente faz cada código de controle grafado em vermelho e os dois caracteres nomeados
grafados em preto, por fugir do escopo deste trabalho, mas é possível deixar o significado de cada um deles.

ACK Acknowledge BEL Bell or Alert BS Backspace


CAN Cancel CR Carraige Return DC1 Device Control 1
DC2 Device Control 2 DC3 Device Control 3 DC4 Device Control 4
DEL Delete DLE Data Link Escape EM End of Medium
ENQ Enquiry EOT End of Transmission ESC Escape
ETB End of Transmission Block ETX End of Text FF Form Feed
HT Horizontal Tab IFS Interchange File Separator IGS Interchange Group Separator
IRS Interchange Record Separator IUS Interchange Unit Separator LF Line Feed
NAK Negative Acknowledge NUL Null SI Shift In
SO Shift Out SOH Start of Heading STX Start of Text
SUB Substitute SYN Synchronous Idle VT Vertical Tab

Para saber mais sobre as estruturas usadas com ASCII consulte o sítio https://montcs.bloomu.edu/Information/Enco
dings/ASCII-EBCDIC.html.
CO MPL E ME NT OS 415

E
TABELA DE CONVERSÃO EBCDIC PARA ASCII

A estrutura entre os códigos EBCDIC e ASCII é muito distinta. Há momentos em que é necessário utilizar dados forma-
tados em um padrão diferente do padrão definido e em uso. É fato que nem todos os sistemas computacionais, como
as linguagens de programação para computadores possuem recursos automatizados para a conversão de dados entre
os códigos EBCDIC e ASCII. Assim sendo, apresenta-se uma tabela em formato hexadecimal que visa auxiliar a trans-
crição de dados (caracteres) de um formato para o outro.
As figuras indicadas junto as figuras E.1 e E.2, respectivamente parte 1 e 2, mostram a relação de equivalência entre caracte-
res nos formatos EBCDIC e ASCII. Em vermelho estão definidos os caracteres de controle de máquina, formado por códigos
que não são imprimíveis. Em azul estão os caracteres alfanuméricos convencionais mínimos normalmente usados. Em preto
estão os caracteres imprimíveis estendidos. Em verde marcado com os caracteres XXX são apenas espaços em branco no
conjunto de caracteres

E A C E A C E A C E A C E A C E A C E A C E A C
B S A B S A B S A B S A B S A B S A B S A B S A
C C R C C R C C R C C R C C R C C R C C R C C R
D I A D I A D I A D I A D I A D I A D I A D I A
I I C I I C I I C I I C I I C I I C I I C I I C
C T C T C T C T C T C T C T C T
E E E E E E E E
R R R R R R R R
E E E E E E E E

00 00 NUL 10 10 DLE 20 -- DS 30 -- XXX 40 20 sp 50 26 & 60 2D - 70 F8 ø


01 01 SOH 11 11 DC1 21 -- SOS 31 -- XXX 41 -- XXX 51 E9 é 61 2F / 71 C9 É
02 02 STX 12 12 DC2 22 1C FS 32 16 SYN 42 E2 â 52 EA ê 62 C2 Â 72 CA Ê
03 03 ETX 13 13 TM 23 -- XXX 33 -- XXX 43 E4 ä 53 EB ë 63 C4 Ä 73 CB Ë
04 -- PF 14 -- RES 24 -- BYP 34 -- PN 44 E0 à 54 E8 è 64 C0 À 74 C8 È
05 09 HT 15 0A NL 25 0A LF 35 -- RS 45 E1 á 55 ED í 65 C1 Á 75 CD Í
06 -- LC 16 08 BS 26 17 ETB 36 -- UC 46 E3 ã 56 EE î 66 C3 Ã 76 CE Î
07 7F DEL 17 -- IL 27 1B ESC 37 04 EOT 47 E5 å 57 EF ï 67 C5 Å 77 CF Ï
08 -- GE 18 18 CAN 28 -- XXX 38 -- XXX 48 E7 ç 58 EC ì 68 C7 Ç 78 CC Ì
09 -- SPC 19 19 EM 29 -- XXX 39 -- XXX 49 F1 ñ 59 DF ß 69 D1 Ñ 79 60 `
0A -- SMM 1A -- CC 2A -- SM 3A -- XXX 4A A2 ¢ 5A 21 ! 6A A6 ¦ 7A 3A :
0B 0B VT 1B -- CU1 2B -- CU2 3B -- CU3 4B 2E . 5B 24 $ 6B 2C , 7B 23 #
0C 0C FF 1C 1C IFS 2C -- XXX 3C 14 DC4 4C 3C < 5C 2A * 6C 25 % 7C 40 @
0D 0D CR 1D 1D IGS 2D 05 ENQ 3D 15 NAK 4D 28 ( 5D 29 ) 6D 5F _ 7D 27 '
0E 0E SO 1E 1E IRS 2E 06 ACK 3E -- XXX 4E 2B + 5E 3B ; 6E 3E > 7E 3D =
0F 0F SI 1F 1F IUS 2F 07 BEL 3F 1A SUB 4F 7C | 5F AC ¬ 6F 3F ? 7F 22 "

Figura E.1 – Tabela de conversão EBCDIC para ASCII: Parte 1 de 00h até 7Fh
416 PRO G RA MA Ç ÃO CO B OL

E A C E A C E A C E A C E A C E A C E A C E A C
B S A B S A B S A B S A B S A B S A B S A B S A
C C R C C R C C R C C R C C R C C R C C R C C R
D I A D I A D I A D I A D I A D I A D I A D I A
I I C I I C I I C I I C I I C I I C I I C I I C
C T C T C T C T C T C T C T C T
E E E E E E E E
R R R R R R R R
E E E E E E E E

80 D8 Ø 90 B0 ° A0 B5 µ B0 5E ^ C0 7B { D0 7D } E0 5C \ F0 30 0
81 61 a 91 6A j A1 7E ~ B1 A3 £ C1 41 A D1 4A J E1 F7 ÷ F1 31 1
82 62 b 92 6B k A2 73 s B2 A5 ¥ C2 42 B D2 4B K E2 53 S F2 32 2
83 63 c 93 6C l A3 74 t B3 95 • C3 43 C D3 4C L E3 54 T F3 33 3
84 64 d 94 6D m A4 75 u B4 A9 © C4 44 D D4 4D M E4 55 U F4 34 4
85 65 e 95 6E n A5 76 v B5 A7 § C5 45 E D5 4E N E5 56 V F5 35 5
86 66 f 96 6F o A6 77 w B6 B6 ¶ C6 46 F D6 4F O E6 57 W F6 36 6
87 67 g 97 70 p A7 78 x B7 BC ¼ C7 47 G D7 50 P E7 58 X F7 37 7
88 68 h 98 71 q A8 79 y B8 BD ½ C8 48 H D8 51 Q E8 59 Y F8 38 8
89 69 i 99 72 r A9 7A z B9 BE ¾ C9 49 I D9 52 R E9 5A Z F9 39 9
8A AB « 9A AA ª AA A1 ¡ BA DD Ý CA AD – DA B9 ¹ EA B2 ² FA B3 ³
8B BB » 9B BA º AB BF ¿ BB A8 ¨ CB F4 ô DB FB û EB D4 Ô FB DB Û
8C F0 ð 9C E6 æ AC D0 Ð BC AF ¯ CC F6 ö DC FC ü EC D6 Ö FC DC Ü
8D FD ý 9D B8 ¸ AD 5B [ BD 5D ] CD F2 ò DD F9 ù ED D2 Ò FD D9 Ù
8E FE Þ 9E C6 Æ AE DE þ BE 92 ’ CE F3 ó DE FA ú EE D3 Ó FE DA Ú
8F B1 ± 9F A4 ¤ AF AE ® BF D7 × CF F5 õ DF FF ÿ EF D5 Õ FF -- EO

Figura E.2 – Tabela de conversão EBCDIC para ASCII: Parte 2 de 80h até FFh

Apesar de ambas as tabelas possuírem, em sua forma básica 256 posições o conjunto de caracteres EBCDIC não se
assemelha em parte ao conjunto de caracteres ASCII, pois existem símbolos e sinais EBCDIC que não possuem equi-
valência em ASCII e vice-versa.
Dois detalhes a serem considerados: o caractere de nova linha LN (line new em EBCDIC) é igual ao caractere de avan-
ço de linha LF (line feed em ASCII); o código de controle TM (tape mark em EBCDIC), também chamado de DCE equi-
vale ao código DC3 (device control em ASCII).
Nas figuras os campos marcados com dois traços indicam que não há equivalência do caractere EBCDIC com o carac-
tere ASCII ou não há caractere na posição EBCDIC para ser usado (marcado com XXX).
Os caracteres EBCDIC: 04, 06, 08, 09, 0A, 13, 14, 17, 1A, 1B, 20, 21, 22, 24, 25, 2A, 2B, 34, 35, 36, 37, 3B, B1, B2, BE
E FF não possuem equivalentes no código ASCII.
CO MPL E ME NT OS 417

F
TABELA DE CONVERSÃO ASCII PARA EBCDIC

A estrutura entre os códigos ASCII e EBCDIC é muito distinta. Há momentos em que é necessário utilizar dados forma-
tados em um padrão diferente do padrão definido e em uso. É fato que nem todos os sistemas computacionais, como
as linguagens de programação para computadores possuem recursos automatizados para a conversão de dados entre
os códigos ASCII e EBCDIC. Assim sendo, apresenta-se uma tabela em formato hexadecimal que visa auxiliar a trans-
crição de dados (caracteres) de um formato para o outro.
As figuras indicadas junto as figuras F.1 e F.2, respectivamente parte 1 e 2, mostram a relação de equivalência entre caracte-
res nos formatos ASCII e EBCDIC. Em vermelho estão definidos os caracteres de controle de máquina, formado por códigos
que não são imprimíveis. Em azul estão os caracteres alfanuméricos convencionais mínimos normalmente usados. Em preto
estão os caracteres imprimíveis estendidos. Em verde marcado com os caracteres XXX são apenas espaços em branco no
conjunto de caracteres

A E C A E C A E C A E C A E C A E C A E C A E C
S B A S B A S B A S B A S B A S B A S B A S B A
C C R C C R C C R C C R C C R C C R C C R C C R
I D A I D A I D A I D A I D A I D A I D A I D A
I I C I I C I I C I I C I I C I I C I I C I I C
C T C T C T C T C T C T C T C T
E E E E E E E E
R R R R R R R R
E E E E E E E E

00 00 NUL 10 10 DLE 20 40 sp 30 F0 0 40 7C @ 50 D7 P 60 79 ` 70 97 p
01 01 SOH 11 11 DC1 21 5A ! 31 F1 1 41 C1 A 51 D8 Q 61 81 a 71 98 q
02 02 STX 12 12 DC2 22 7F " 32 F2 2 42 C2 B 52 D9 R 62 82 b 72 99 r
03 03 ETX 13 13 DC3 23 7B # 33 F3 3 43 C3 C 53 E2 S 63 83 c 73 A2 s
04 37 EOT 14 3C DC4 24 5B $ 34 F4 4 44 C4 D 54 E3 T 64 84 d 74 A3 t
05 2D ENQ 15 3D NAK 25 6C % 35 F5 5 45 C5 E 55 E4 U 65 85 e 75 A4 u
06 2E ACK 16 32 SYN 26 50 & 36 F6 6 46 C6 F 56 E5 V 66 86 f 76 A5 v
07 2F BEL 17 26 ETB 27 7D ' 37 F7 7 47 C7 G 57 E6 W 67 87 g 77 A6 w
08 16 BS 18 18 CAN 28 4D ( 38 F8 8 48 C8 H 58 E7 X 68 88 h 78 A7 x
09 05 HT 19 19 EM 29 5D ) 39 F9 9 49 C9 I 59 E8 Y 69 89 i 79 A8 y
0A 15 LF 1A 3F SUB 2A 5C * 3A 7A : 4A D1 J 5A E9 Z 6A 91 j 7A A9 z
0B 0B VT 1B 27 ESC 2B 4E + 3B 5E ; 4B D2 K 5B AD [ 6B 92 k 7B C0 {
0C 0C FF 1C 1C IFS 2C 6B , 3C 4C < 4C D3 L 5C E0 \ 6C 93 l 7C 4F |
0D 0D CR 1D 1D IGS 2D 60 - 3D 7E = 4D D4 M 5D BD ] 6D 94 m 7D D0 }
0E 0E SO 1E 1E IRS 2E 4B . 3E 6E > 4E D5 N 5E B0 ^ 6E 95 n 7E A1 ~
0F 0F SI 1F 1F IUS 2F 61 / 3F 6F ? 4F D6 O 5F 6D _ 6F 96 o 7F 07 DEL

Figura F.1 – Tabela de conversão ASCII para EBCDIC: Parte 1 de 00h até 7Fh
418 PRO G RA MA Ç ÃO CO B OL

E A C E A C E A C E A C E A C E A C E A C E A C
B S A B S A B S A B S A B S A B S A B S A B S A
C C R C C R C C R C C R C C R C C R C C R C C R
D I A D I A D I A D I A D I A D I A D I A D I A
I I C I I C I I C I I C I I C I I C I I C I I C
C T C T C T C T C T C T C T C T
E E E E E E E E
R R R R R R R R
E E E E E E E E

80 -- € 90 -- XXX A0 -- XXX B0 90 ° C0 64 À D0 AC Ð E0 44 à F0 8C ð
81 -- XXX 91 -- ‘ A1 AA ¡ B1 8F ± C1 65 Á D1 69 Ñ E1 45 á F1 49 ñ
82 -- ‚ 92 BE ’ A2 4A ¢ B2 EA ² C2 62 Â D2 ED Ò E2 42 â F2 CD ò
83 -- ƒ 93 -- “ A3 B1 £ B3 FA ³ C3 66 Ã D3 EE Ó E3 46 ã F3 CE ó
84 -- „ 94 -- ” A4 9F ¤ B4 -- ´ C4 63 Ä D4 EB Ô E4 43 ä F4 CB ô
85 -- ... 95 B3 • A5 B2 ¥ B5 A0 µ C5 67 Å D5 EF Õ E5 47 å F5 CF õ
86 -- † 96 -- – A6 6A ¦ B6 B6 ¶ C6 9E Æ D6 EC Ö E6 9C æ F6 CC ö
87 -- ‡ 97 -- — A7 B5 § B7 -- · C7 68 Ç D7 BF × E7 48 ç F7 E1 ÷
88 -- ˆ 98 -- ˜ A8 BB ¨ B8 9D ¸ C8 74 È D8 80 Ø E8 54 è F8 70 ø
89 -- ‰ 99 -- ™ A9 B4 © B9 DA ¹ C9 71 É D9 FD Ù E9 51 é F9 DD ù
8A -- Š 9A -- š AA 9A ª BA 9B º CA 72 Ê DA FE Ú EA 52 ê FA DE ú
8B -- ‹ 9B -- › AB 8A « BB 8B » CB 73 Ë DB FB Û EB 53 ë FB DB û
8C -- Œ 9C -- œ AC 5F ¬ BC B7 ¼ CC 78 Ì DC FC Ü EC 58 ì FC DC ü
8D -- XXX 9D -- XXX AD CA – BD B8 ½ CD 75 Í DD BA Ý ED 55 í FD 8D ý
8E -- Ž 9E -- ž AE AF ® BE B9 ¾ CE 76 Î DE AE Þ EE 56 î FE 8F þ
8F -- XXX 9F -- Ÿ AF BC ¯ BF AB ¿ CF 77 Ï DF 59 ß EF 57 ï FF DF ÿ

Figura F.2 – Tabela de conversão ASCII para EBCDIC: Parte 2 de 80h até FFh

Apesar de ambas as tabelas possuírem, em sua forma básica 256 posições o conjunto de caracteres ASCII não se
assemelha em parte ao conjunto de caracteres EBCDIC, pois existem símbolos e sinais ASCII que não possuem equi-
valência em EBCDIC e vice-versa.
Dois detalhes a serem considerados: o caractere de nova linha LF (line feed em ASCII) é igual ao caractere de avanço
de linha LN (line new em EBCDIC); o código de controle código DC3 (device control em ASCII) equivale ao código TM
(tape mark em EBCDIC), também chamado de DCE.
Nas figuras os campos marcados com dois traços indicam que não há equivalência do caractere ASCII com o caractere
EBCDIC ou não há caractere na posição ASCII para ser usado (marcado com XXX).
Os caracteres ASCII: 80. 82, 83, 84, 85, 86, 87, 88, 89, 8ª, 8B, 8C, 8E, 91, 93, 94, 96, 97, 99, 9A, 9B, 9E E 0F não pos-
suem equivalentes no código EBCDIC.
Bi b li o graf ia 419

BIBLIOGRAFIA

APPLE. Apple III COBOL: language reference manual. Volume 1. Cupertino, CA (USA): Apple Computer Inc., 1982.

______. Apple III COBOL: language reference manual. Volume 2. Cupertino, CA (USA): Apple Computer Inc., 1982.
BULL. DPS7000/XTA NAVASCALE 7000 COBOL95: programmer´s guide, part number 47 A2 33UT 08. Angers
(France): Bull Information Systems, 2002.

______. DPS7000/XTA NAVASCALE 7000 COBOL95: user´s guide reference, part number 47 A2 06UL 06. Angers
(France): Bull Information Systems, 2002.
CA. CA-MetaCOBOL (TM) 1.1: online programming language reference, part number R203M+11DRP. New York, NY
(USA): Computer Associates International, Inc, 1992.

COMPAQ. NonStop (TM) Pathway/iTS SCREEN COBOL: reference manual, part number 4256750-001. Palo Alto, CA
(USA): Compaq Computer Corporation, 2000.
CUTLER, G. L. GnuCOBOL 2.2 Final: programmer´s guide. Boston, MA (USA): Free Software Foundation, 2017.

______, G. L. OpenCOBOL 1.1: programmer´s guide. Boston, MA (USA): Free Software Foundation, 2010.
DIGITAL, TOPS-10/TOP-20 COBOL-68: language manual, part number AA-5057B-TK. Marlboro, MA (USA): Digital
Equipment Corporation, 1981.
ENVYR. Interactive COBOL: language reference & developer´s guide, part number 011.00100-24. Raleigh, NC (USA):
Envyr Corporation, 2012.
FUJITSU. COBOL85: reference manual. 3rd ed. Minato-ku, Tokyo (Japan): Fujitsu Limited, 1996.

______. NetCOBOL V11.0: language reference, part number B1WD-3304-02ENZ0(00). Minato-ku, Tokyo (Japan):
Fujitsu Limited, 2014.
______. NetCOBOL V11.0: syntax samples, part number B1WD-3300-01ENZ0(00). Minato-ku, Tokyo (Japan): Fujitsu
Limited, 2014.
HEIRLOON. Elastic COBOL: language reference guide. San Francisco, CA (USA): Heirloon Computing Inc., 2015.

______. Elastic COBOL: programmer´s guide. San Francisco, CA (USA): Heirloon Computing Inc., 2014.
HEWLETT PACKARD. HP COBOL II/XL: programmer´s guide 900 series HP 3000 computer system HP, part number.
31500-90002 E0791. Palo Alto, CA (USA): Hewlett Packard Company, 1991.

______. HP data entry and forms management system (VPLUS): reference manual - HP 3000 MPE/iX computer
system, part number. 32209-90024 E0300. Palo Alto, CA (USA): Hewlett Packard Company, 2000.
420 PRO G RA MA Ç ÃO CO B OL

______. NonStop COBOL: manual for TNS/E and TNS/X programs, part number 863232-001. Palo Alto, CA (USA):
Hewlett Packard Company, 2016.
IBM. COBOL for OS/390 & VM: programming guide, part number SC26-9049-05. 6rd ed. New York, NY (USA): IBM
Corporation, 2000.

______. Enterprise COBOL for z/OS Version 6.3: programming guide, part number SC27-8714-02. 3rd ed. New York,
NY (USA): IBM Corporation, 2020.
______. Programming IBM Rational Development Studio for i: ILE COBOL Language Reference, part number SC09-
2539-08. New York, NY (USA): IBM Corporation, 2013.

______. Rational Development Studio for I ILE COBOL 7.1: programmer´s guide, part number SC09-2540-07. New
York, NY (USA): IBM Corporation, 2010.
______. VisualAge COBOL 3.02: programming guide, part number SC27-0812-01. 2rd ed. New York, NY (USA): IBM
Corporation, 2000.

LIANT. RM/COBOL 8.0: language reference manual, part number 401213-0303. Framingham, MA (USA): Liant
Software Corporation, 2003.

MICRO FOCUS. RM/COBOL: language reference manual. Newbury (UK): Micro Focus Ltd., 2017.

SPC. COBOL Report Writer Precompiler: programmer´s manual, part number 5798-DYR. 8rd ed. Wimbledon,
LONDON (UK): SPC Systems Ltd., 2002.
UNISYS. ClearPath Enterprise Servers COBOL ANSI-74: programming reference manual product interfaces
ClearPath MCP 18.0, part number 8600 0130-306. Volume 2. Blue Bell, PA (USA): Unisys Corporation, 2017.

______. ClearPath Enterprise Servers COBOL ANSI-74: programming reference manual basic implementation
ClearPath MCP 18.0, part number 8600 0296-210. Volume 1. Blue Bell, PA (USA): Unisys Corporation, 2017.
______. ClearPath Enterprise Servers COBOL ANSI-85: programming reference manual basic implementation
ClearPath MCP 17.0, part number 8600 1518-316. Volume 1. Blue Bell, PA (USA): Unisys Corporation, 2015.]

______. COBOL Compiler: programming reference manual, level 12R2, part number 7831 0448-005. Volume 1. Blue
Bell, PA (USA): Unisys Corporation, 2015.
______. COBOL Compiler: programming reference manual, level 12R4, part number 7831 0455-021. Volume 2. Blue
Bell, PA (USA): Unisys Corporation, 2018.

______. COBOL UNIVAC 1107: programmer´s guide technical bulletin, part number U-2582. Wilmington, DE (USA):
Sperry Rand Corporation, 1960.
______. OS 2200 ASCII COBOL: programming reference manual, level, part number 7R3K 7830 7709-002. Blue Bell,
PA (USA): Unisys Corporation, 2010.

THE OPEN GROUP. COBOL Language: technical standard, part number XO/CAE/91/200. Berkshire (UK): X/Open
Company Limited.

VMS. VSI OpenVMS/VSI COBOL: reference guide. Boston, MA (USA): VMS Software, Inc, 2018.

______. VSI OpenVMS/VSI COBOL: user manual. Boston, MA (USA): VMS Software, Inc, 2018.
Bi b li o graf ia 421
422 PRO G RA MA Ç ÃO CO B OL

Você também pode gostar