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).