Curso de COBOL - Aula 5
Notas da aula de 13.12.2008 (Aula #5) do Curso de COBOL da
Escola Alcides Maya com o Professor Roberto Cabral de Mello Borges
--------------------------------------------------
Calcular os dígitos de controle dos CPFs
Exemplo: 015.749.790-xy
Algarismo 0 1 5 7 4 9 7 9 0
Peso D1 10 9 8 7 6 5 4 3 2
Produto1 0 9 40 49 24 45 28 27 0 Soma dos produtos: 222
Para a dezena dos Dígitos de Controle
D1 = (11 – soma mod 11) mod 11 mod 10 =
Soma = (0 . 10) + (1 . 9) + (5 . 8) + (7 . 7) +
(4 . 6) + (9 . 5) + (7 . 4) + (9 . 3) + (0 . 2) = 222
D1 = (11 – 222 mod 11) mod 11 mod 10 =
D1 = (11 – 2) mod 11 mod 10 =
D1 = 9 mod 11 mod 10 =
D1 = 9 mod 10 =
D1 = 9
Algarismo 0 1 5 7 4 9 7 9 0 9
Peso D2 11 10 9 8 7 6 5 4 3 2
Produto2 0 10 45 56 28 54 35 36 0 18
Soma dos produtos2: 282
Para a unidade dos Dígitos de Controle
D2 = (11 – soma mod 11) mod 11 mod 10 =
Soma = (0 . 11) + (1 . 10) + (5 . 9) + (7 . 8) + (4 . 7) +
(9 . 6) + (7 . 5) + (9 . 4) + (0 . 3) + (9 . 2) = 282
D2 = (11 – 282 mod 11) mod 11 mod 10 =
D2 = (11 – 7) mod 11 mod 10 =
D2 = 4 mod 11 mod 10 =
D2 = 4 mod 10 =
D2 = 4
Em COBOL:
IDENTIFICATION DIVISION.
PROGRAM-ID. VERIFICAÇÃO DO CPF.
AUTHOR. CABRAL.
DATE-WRITTEN. 13/12/08.
DATE-COMPILED.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SOURCE-COMPUTER. PC ATHLON 64-XP.
OBJECT-COMPUTER. PC ATHLON 64-XP.
SPECIAL-NAMES. DECIMAL-POINT IS COMMA.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 IND PIC 99.
77 D1 PIC 9.
77 D2 PIC 9.
77 SOMA PIC 999.
77 LIMITE PIC 99 VALUE 9.
01 CPF-DADOS.
03 CPF PIC 9(11).
03 CPF-RED REDEFINES CPF.
05 TAB-CPF PIC 9 OCCURS 11 TIMES.
* Genial este REDEFINES! Não precisa criar outro campo!!!
PROCEDURE DIVISION.
LER.
ACCEPT CPF.
IF CPF = 0
STOP RUN.
MOVE 9 TO LIMITE.
PERFORM LOOP VARYING IND FROM 1 BY 1 UNTIL IND > LIMITE.
DIVIDE SOMA BY 11 GIVING TALLY REMAINDER D1.
* Tally é uma variável “fantasminha” predefinida, só pra “pegar” o
- quociente, que a gente não usa!
COMPUTE D1 = 11 – D1.
MOVE 10 TO LIMITE.
PERFORM LOOP VARYING IND FROM 1 BY 1 UNTIL IND > LIMITE.
DIVIDE SOMA BY 11 GIVING TALLY REMAINDER D2.
* Tally é uma variável “fantasminha” predefinida, só pra “pegar”
- o quociente, que a gente não usa!
IF D1 = TAB-CPF(10) AND D2 = TAB-CPF(11)
DISPLAY “CPF OK ”, CPF
ELSE
DISPLAY “CPF INVÁLIDO “, CPF.
GO TO LER.
LOOP.
COMPUTE SOMA = SOMA + TAB-CPF(IND) * (LIMITE + 2 – IND).
--------------------------------------------------
Report Writer
* Mecanismo de preparação dos relatórios, para usar só o comando
- GENERATE para gerar uma página de relatório.
DATA DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT RELATORIO ASSIGN TO PRINTER.
FILE SECTION.
FD RELATORIO REPORT IS RELAT.
REPORT SECTION.
RD RELAT
PAGE LIMIT IS 63 LINES.
HEADING 2
FIRST DETAIL 7
LAST DETAIL 60
FOOTING 62.
* Relatórios às vezes têm página de abertura (RH), e de fechamento
- (RF), como se fosse cabeçalho e rodapé geralzão.
* Cada página tem o seu cabeçalho (PH) e rodapé (PF) de página,
- e os detalhes (DE), eventualmente com os subtotais.
RH (report heading)
PH (page heading)
CH (control heading)
DE (detail)
CF (control footing)
PF (page footing)
RF (report footing)
01 TYPE IS PAGE-HEADING.
03 LINE 2.
05 COLUMN 1 PIC X(40) VALUE “COMPANHIA TELEFONICA BLABLABLA”.
05 COLUMN 70 PIC X(4) VALUE “PAG. “.
05 COLUMN 75 PIC Z9 SOURCE PAGE-COUNTER.
* SOURCE faz um “MOVE” automático.
03 LINE 3.
05 COLUMN 1 PIC X(35) VALUE “CONTA MENSAL TELEF.FIXA”.
05 COLUMN 40 PIC X(6) VALUE “MÊS DE”.
* SOURCE busca nas variáveis ou campos
05 COLUMN 47 PIC X(14) SOURCE MÊS-ANO.
* Tamanho definido pelo maior (fevereiro)
03 LINE 5.
* COBOL sabe que “pulou” a linha 4
05 COLUMN 1 PIC X(12) VALUE “NUM.TELEFONE”.
05 COLUMN 14 PIC X VALUE “(”.
05 COLUMN 15 PIC 99 SOURCE DDD.
05 COLUMN 17 PIC X VALUE “)”.
05 COLUMN 18 PIC 9999-9999 SOURCE FONE.
01 TYPE IS CONTROL-HEADING TIPO-LIGACAO ON NEXT PAGE.
* ISTO AQUI vai na próxima página
03 ...
01 DETALHE TYPE IS DETAIL.
03 LINE PLUS 1.
* próxima linha
05 COLUMN 1 PIC ZZ9 SOURCE SEQUENCIA.
* SOURCE Busca DATA-LIGACAO de um campo!
05 COLUMN 3 PIC 99/99/99 SOURCE DATA-LIGACAO GROUP INDICATE.
05 COLUMN 12 PIC Z9:99:99 SOURCE HORA-LIGACAO.
05 COLUMN 35 PIC ZZ.ZZ9,99 SOURCE VALOR.
01 TYPE IS CONTROL-FOOTING TIPO-LIGACAO NEXT GROUP NEXT PAGE.
* próximo grupo vai na próxima página
* poderia ser também
* TIPO-LIGACAO é o agrupador para o subtotal do SUM.
01 TYPE IS CONTROL-FOOTING TIPO-LIGACAO NEXT GROUP PLUS 3.
* depois do subtotal pula 2 linhas
03 LINE PLUS 2.
* deixa uma linha em branco – SUM é esperto e se autozera!
05 COLUMN 34 PIC ZZZ.ZZ9,99 SUM VALOR.
* pode acumular com VALUE RESET ON FINAL
01 TYPE IS PAGE-FOOTING.
* uma casa a mais, para uma soma grandona
03 LINE 62.
05 COLUMN 20 PIC X(20) VALUE “FELIZ NATAL”.
PROCEDURE DIVISION.
ABRIR.
OPEN OUTPUT RELATORIO.
INITIATE RELAT.
* zera variáveis do Report Writer: page-counter, line-counter, “SUM”
LER.
READ CADASTRO AT END GO TO FIM.
GENERATE DETALHE.
GO TO LER.
FIM.
TERMINATE RELAT.
CLOSE RELATORIO, CADASTRO.
STOP RUN.
TABELAS FIXAS (para tabelas variáveis, usar arquivo)
* Exemplo: nomes dos dias da semana, nomes dos meses do ano,
- nomes dos setores da empresa, etc.
WORKING-STORAGE SECTION.
01 DIAS-DA-SEMANA.
03 TEXTO-FIXO-DIA-SEMANA.
* Truque (para usar os mesmos espaços) é escrever no final da linha
- (contando até a coluna 72 – cabendo o maior campo – neste caso
- 13 espaços) e usar só aspas de abertura, e o sinal de continuação - (-), fechando as aspas só no final.
05 FILLER PIC X(91) VALUE “DOMINGO
- “SEGUNDA-FEIRA
- “TERCA-FEIRA
- “QUARTA-FEIRA
- “QUINTA-FEIRA
- “SEXTA-FEIRA
- “SABADO
- “”.
03 TAB-DIAS REDEFINES TEXTO-FIXO-DIA-SEMANA.
* REDEFINES como uma matrizinha de 7x13 :)
05 DIA-SEM PIC X(13) OCCURS 7 TIMES.
* DISPLAY DIA-SEM(7) = SABADO
01 MESES-ANO.
03 TEXTO-FIXO-MES.
05 FILLER PIC X(108) VALUE “ JANEIRO
- “FEVEREIRO
- “ MARCO
- “ ABRIL
- “ MAIO
- “ JUNHO
- “ JULHO
- “ AGOSTO
- “SETEMBRO
- “ OUTUBRO
- “NOVEMBRO
- “DEZEMBRO
- “”.
03 TAB-MESES REDEFINES TEXTO-FIXO-MÊS.
05 MESES PIC X(9) OCCURS 12 TIMES.
* DISPLAY MESES(MES) = 
* 05 MESES PIC X(9) OCCURS 13 TIMES.
* um jeito usado para o décimo-terceiro salário
Curiosidades:
* COBOL recebe números e alinha pela direita (completa os zeros à esquerda); se recebe texto, alinha pela esquerda.
* O SORT do COBOL só "perde" em eficiência para o QuickSort (mas aí é covardia!)
* Tally é uma variável “fantasminha” predefinida, usada aqui só pra “pegar” o quociente, que a gente não usa!
* Quando a conta telefônica da CRT-Brasil-Telecom era feita em COBOL, tinha mais informações em menos papel. Hoje tem 20 linhas de “cabeçalho”, quase um terço da página! :-P
* O cabeçalho nunca deve ser maior que 10% ou 15% do total de linhas da página! Em tela de 24 linhas, até 3 linhas.
* Densidade vertical média de impressão normalmente usada é de 6 linhas por polegada. Papel A4 dá 66 linhas.
* COBOL tem um PAGE-COUNTER. Que nunca será zero. E vai até 11 dígitos. E não precisa definir.
* Padrão para “enfeitar” números de telefone com 8 dígitos: (51)2345-6789.
* Todos os telefones no Brasil já estão com 8 dígitos.
* Só COBOL tem um GROUP INDICATE – que ajuda a não repetir termos iguais (data da ligação, por exemplo) sem fazer loops ou IFs (quando troca de página, repete!)
* Hierarquia estado-cidade-bairro-rua deve ser mantida na impressão.
* O DOC em folha separada (ou destacável), pq quando junto, o “caixa do banco” podia ver as ligações (situação embaraçosa).
* Toda essa parte de relatórios não tem equivalente em outras linguagens (especialmente GROUP INDICATE e SUM).
* Linguagens de quarta geração (um comando faz milhares de coisas).
* Comando GENERATE, por exemplo, verifica se é a primeira linha do programa, imprime ReportHeading (se houver), imprime PageHeading (se houver), imprime ControlHeading (se houver), alimenta os campos SOURCE, imprime linha de detalhe, soma 1 ao LineCouter, atualiza o PageCounter, imprime ControlFooting, PageFooting (se houver), controla também a impressão pulando linhas que vai para a próxima página.
* TERMINATE imprime todos os ControlFooting, PageFooting e ReportFooting pendentes.
* De todas as coisas que enfiaram no COBOL, GENERATE é o recurso mais sofisticado em termos de controle lógico!
* Margens de DOCs vêm como ZERO, mas se o nosso navegador está diferente de zero, gera uma página vazia :-P
* Códigos de barras (com linha digitável) têm 1+3 dígitos de controle, e uma fórmula maluca para conferir. (um para cada um dos três blocos dos 47 algarismos que têm que ser digitados, mais um para o código de barras – p/o micro).