| Bellacosa Mainframe e os relatorios cobol descubra os caracteres asa |
☕ Um Café no Bellacosa Mainframe
Relatórios COBOL e Caracteres ASA sem Mistérios
Quando um Programador Descobre que a Primeira Coluna Não é um Dado… É o Comandante da Impressora!
Durante décadas, antes dos dashboards coloridos, PDFs responsivos, planilhas com gráficos e executivos pedindo “só mais um filtro”, o mainframe já produzia milhares de relatórios empresariais por dia.
Folhas de pagamento, extratos bancários, balanços contábeis, posições de estoque, movimentos financeiros, faturas, auditorias e relatórios de produção eram gerados por programas batch COBOL e enviados para enormes impressoras de linha.
Mas essas impressoras tinham uma característica curiosa:
Elas não recebiam apenas o texto que deveria ser impresso.
Recebiam também uma instrução dizendo como o papel deveria ser movimentado antes de imprimir aquela linha.
Essa instrução geralmente ocupava o primeiro byte do registro e ficou conhecida como:
Caractere de controle ASA
Para um programador COBOL Padawan, o ASA parece inicialmente apenas uma coluna misteriosa no início do relatório.
Para um veterano do mainframe, porém, ele é o pequeno Mestre Jedi responsável por decidir:
quando saltar para uma nova página;
quando deixar uma linha em branco;
quando deixar duas linhas em branco;
quando imprimir por cima da linha anterior;
quando posicionar o papel em uma área específica do formulário.
Em outras palavras:
O programa COBOL cria o conteúdo, mas o caractere ASA dirige o papel.
1. O que significa ASA?
ASA significa American Standards Association, organização norte-americana responsável pela padronização de diferentes tecnologias e processos.
A organização foi criada originalmente em 1918 como American Engineering Standards Committee. Em 1928, foi reorganizada e passou a se chamar American Standards Association, ou ASA. Posteriormente, passou por novas reorganizações até receber, em 1969, o nome atual: ANSI — American National Standards Institute.
Por isso, os caracteres de controle de impressão podem aparecer na documentação com nomes como:
ASA carriage control;
ANSI carriage control;
ASA print-control characters;
ANSI print-control characters.
No universo mainframe, o nome ASA continuou sendo amplamente utilizado.
2. Por que os caracteres ASA foram criados?
As antigas impressoras de linha não funcionavam como uma impressora doméstica moderna.
Elas eram equipamentos industriais capazes de imprimir centenas ou milhares de linhas por minuto. Muitas utilizavam papel contínuo, com furos laterais, alimentado por mecanismos chamados tratores.
O programa precisava informar à impressora:
o texto que seria impresso;
o movimento que deveria ser realizado no papel;
se a impressão deveria começar em uma nova página;
se deveria haver espaçamento;
se a linha deveria ser sobreposta.
Em vez de enviar comandos complexos, estabeleceu-se uma convenção simples:
O primeiro caractere de cada registro controlaria o avanço do papel.
Esse caractere não fazia parte visualmente do relatório.
Ele era interpretado pelo sistema de impressão.
Imagine o registro:
1RELATORIO MENSAL DE FATURAMENTO
O caractere 1 não seria impresso.
Ele ordenaria:
Avance para o início da próxima página e depois imprima o restante da linha.
O resultado visual seria:
RELATORIO MENSAL DE FATURAMENTO
A primeira posição era consumida como comando.
3. A primeira coluna é o cockpit da impressora
Em um arquivo comum com RECFM=FB, todos os bytes são tratados como dados.
Em um arquivo com RECFM=FBA, o primeiro byte é tratado como caractere de controle ASA.
O significado de FBA é:
F — Fixed: registros de tamanho fixo;
B — Blocked: vários registros podem ser armazenados em um bloco físico;
A — ASA: o primeiro byte contém controle de impressão.
A IBM também reconhece formatos como:
FA— fixo, não blocado, com ASA;FBA— fixo, blocado, com ASA;VA— variável com ASA;VBA— variável, blocado, com ASA.
A documentação IBM identifica FBA e VBA como formatos que contêm caracteres de controle de impressão ASA.
Regra fundamental
Se o relatório possui:
132 posições imprimíveis;
mais uma posição de controle ASA;
o arquivo físico normalmente terá:
LRECL=133
Assim:
Posição 1 = controle ASA
Posições 2-133 = conteúdo imprimível
A primeira posição é o comandante.
As outras 132 são os soldados.
4. Os principais caracteres ASA
ASA espaço — avanço de uma linha
O caractere espaço significa:
Avance uma linha e imprima.
Representação:
' '
Exemplo lógico:
DETALHE DO PRIMEIRO CLIENTE
DETALHE DO SEGUNDO CLIENTE
DETALHE DO TERCEIRO CLIENTE
O espaço inicial não é impresso.
Visualmente:
DETALHE DO PRIMEIRO CLIENTE
DETALHE DO SEGUNDO CLIENTE
DETALHE DO TERCEIRO CLIENTE
É o controle mais comum nas linhas de detalhe.
Uso típico
linhas normais do relatório;
registros de clientes;
produtos;
transações;
movimentos bancários;
itens de uma fatura.
Analogia Bellacosa Mainframe
É o equivalente ao comando COBOL:
CONTINUE
Nada extraordinário acontece.
A impressora apenas segue para a próxima linha.
ASA 0 — avanço de duas linhas
O caractere zero significa:
Avance duas linhas antes de imprimir.
Representação:
0
Na prática, deixa uma linha em branco entre a linha anterior e a nova linha.
Exemplo:
RELATORIO DE VENDAS
0FILIAL: CAMPINAS
Visualmente:
RELATORIO DE VENDAS
FILIAL: CAMPINAS
Uso típico
separar blocos;
separar subtítulos;
destacar subtotais;
iniciar uma nova seção;
melhorar a legibilidade.
Atenção
O 0 não significa imprimir o número zero.
Quando utilizado na primeira posição de um arquivo ASA, ele é uma instrução.
O número zero é um Sith infiltrado no relatório: parece dado, mas está controlando o papel.
ASA - — avanço de três linhas
O caractere hífen significa:
Avance três linhas antes de imprimir.
Representação:
-
Isso produz duas linhas em branco antes da impressão.
Exemplo:
TOTAL DA FILIAL: 125.000,00
-RESUMO GERAL DA EMPRESA
Visualmente:
TOTAL DA FILIAL: 125.000,00
RESUMO GERAL DA EMPRESA
Uso típico
separar grandes seções;
destacar totais gerais;
criar uma ruptura visual;
separar o detalhe de um resumo;
iniciar uma seção importante sem mudar de página.
Comentário do veterano
Use com moderação.
Um relatório cheio de - pode consumir papel como se não houvesse amanhã.
Na época do papel contínuo, cada salto desnecessário representava:
mais papel;
mais caixas;
mais transporte;
mais arquivamento;
mais olhares furiosos da equipe de produção.
ASA + — não avançar o papel
O caractere mais curioso é o sinal de mais:
+
Ele significa:
Não avance o papel. Imprima sobre a mesma linha.
Isso era conhecido como overprint ou sobreimpressão.
Exemplo conceitual:
Primeiro registro:
VALOR TOTAL: 1000
Segundo registro:
+ ____
A segunda linha seria impressa sobre a primeira.
Esse recurso permitia:
sublinhar textos;
reforçar caracteres;
imprimir símbolos sobre caracteres;
criar efeitos especiais;
produzir determinados formulários.
Exemplo de sublinhado
Primeira impressão:
TOTAL GERAL
Segunda impressão, sem avançar:
+___________
Resultado aproximado:
TOTAL GERAL
-----------
Dependendo da impressora, a segunda impressão ocorria exatamente sobre a posição atual.
Cuidado moderno
Em visualizadores de spool, conversores para PDF ou impressoras modernas, o overprint pode:
não aparecer corretamente;
aparecer como duas linhas separadas;
ser ignorado;
gerar resultados diferentes conforme o produto de impressão.
Portanto, o + é um poderoso artefato arqueológico.
Use apenas quando o ambiente realmente suportar sobreimpressão.
ASA 1 — nova página
O caractere 1 significa:
Avance para o início da próxima página antes de imprimir.
Representação:
1
Exemplo:
1RELATORIO DE MOVIMENTACAO BANCARIA
A linha será impressa no topo de uma nova página.
Uso típico
cabeçalho de página;
início do relatório;
mudança de página;
mudança de filial;
início de uma nova conta;
reinício após atingir o limite de linhas.
Analogia Bellacosa Mainframe
O ASA 1 é o:
NEW-PAGE
É como executar um IPL na página atual.
A página antiga termina.
Uma nova página sobe limpa, organizada e pronta para produção.
5. ASA de canais: 2 a 9, A, B e C
Além dos comandos mais conhecidos, o padrão ASA permitia saltar para posições específicas de um formulário.
Os controles eram:
2
3
4
5
6
7
8
9
A
B
C
Eles significavam:
Avance o papel até o canal correspondente.
Esses canais estavam associados às posições configuradas no mecanismo da impressora.
O que eram canais?
Impressoras antigas podiam utilizar uma fita de controle de carro, conhecida como:
Carriage Control Tape
Nessa fita eram perfurados canais que representavam posições específicas do formulário.
Por exemplo:
Canal 1 = topo da página
Canal 2 = início do endereço
Canal 3 = área de detalhes
Canal 4 = rodapé
Canal 9 = posição próxima ao fim da página
Canal 12 = última região do formulário
Os caracteres ASA estabeleciam uma forma lógica de solicitar esses saltos.
Uma configuração hipotética poderia ser:
1 = canal 1
2 = canal 2
3 = canal 3
...
9 = canal 9
A = canal 10
B = canal 11
C = canal 12
Importante
A interpretação dos canais dependia:
da configuração da impressora;
do formulário utilizado;
do JES;
do FSS;
do software de impressão;
das definições da instalação.
Por isso, programas modernos normalmente utilizam principalmente:
espaço
0
-
1
+
Os demais controles aparecem com mais frequência em sistemas antigos, formulários especiais e aplicações legadas.
| Bellacosa Mainframe exemplifica o caractere ASA |
6. Tabela resumida dos caracteres ASA
| ASA | Ação antes da impressão | Uso comum |
|---|---|---|
| Espaço | Avança uma linha | Linha normal de detalhe |
0 | Avança duas linhas | Separar blocos |
- | Avança três linhas | Separar grandes seções |
+ | Não avança | Sobreimpressão |
1 | Salta para nova página/canal 1 | Cabeçalho de página |
2 | Salta para canal 2 | Posição configurada |
3 | Salta para canal 3 | Posição configurada |
4 | Salta para canal 4 | Posição configurada |
5 | Salta para canal 5 | Posição configurada |
6 | Salta para canal 6 | Posição configurada |
7 | Salta para canal 7 | Posição configurada |
8 | Salta para canal 8 | Posição configurada |
9 | Salta para canal 9 | Posição configurada |
A | Salta para canal 10 | Formulários especiais |
B | Salta para canal 11 | Formulários especiais |
C | Salta para canal 12 | Formulários especiais |
7. Duas maneiras de gerar controle ASA em COBOL
Existem duas estratégias principais.
Estratégia 1 — controlar manualmente a primeira posição
O programa declara uma linha com 133 bytes:
01 WS-LINHA-RELATORIO.
05 WS-ASA PIC X.
05 WS-CONTEUDO PIC X(132).
Antes de cada WRITE, o programa move o controle desejado:
MOVE '1' TO WS-ASA
MOVE 'RELATORIO DE CLIENTES' TO WS-CONTEUDO
WRITE REG-RELATORIO FROM WS-LINHA-RELATORIO
Essa forma deixa explícito exatamente o que será gravado.
É excelente para treinamento, manutenção e depuração.
Estratégia 2 — utilizar WRITE ... ADVANCING
O COBOL também permite comandos como:
WRITE REG-RELATORIO
AFTER ADVANCING 1 LINE
Ou:
WRITE REG-RELATORIO
AFTER ADVANCING PAGE
A documentação do Enterprise COBOL informa que, quando AFTER ADVANCING é utilizado para o arquivo, são empregados controles ASA e o arquivo deve ser compatível com FBA.
Exemplos:
WRITE REG-RELATORIO
AFTER ADVANCING 1 LINE
WRITE REG-RELATORIO
AFTER ADVANCING 2 LINES
WRITE REG-RELATORIO
AFTER ADVANCING 3 LINES
WRITE REG-RELATORIO
AFTER ADVANCING PAGE
Equivalência conceitual:
| COBOL | Controle ASA aproximado |
|---|---|
AFTER ADVANCING 1 LINE | Espaço |
AFTER ADVANCING 2 LINES | 0 |
AFTER ADVANCING 3 LINES | - |
AFTER ADVANCING PAGE | 1 |
| Sem avanço | + |
Para fins didáticos, utilizaremos o controle manual, pois ele permite visualizar claramente o primeiro byte.
| Bellacosa Mainframe e a era de ouro dos formularios continuos |
8. Nosso relatório de exemplo
Vamos criar um programa chamado:
RELCLI01
Ele produzirá um relatório de clientes contendo:
código;
nome;
cidade;
saldo;
cabeçalho;
numeração da página;
linhas de detalhe;
total geral;
quebra automática de página.
Layout do arquivo de entrada
Cada registro terá 60 bytes:
Posições 1-5 Código do cliente
Posições 6-35 Nome
Posições 36-50 Cidade
Posições 51-60 Saldo com duas casas decimais implícitas
Exemplo:
00001ANA SKYWALKER CAMPINAS 0000125000
O saldo 0000125000 representa:
1.250,00
9. Programa COBOL completo
IDENTIFICATION DIVISION.
PROGRAM-ID. RELCLI01.
AUTHOR. BELLACOSA-MAINFRAME.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ARQ-CLIENTES
ASSIGN TO CLIENTES
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-FS-CLIENTES.
SELECT ARQ-RELATORIO
ASSIGN TO RELATORIO
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-FS-RELATORIO.
DATA DIVISION.
FILE SECTION.
FD ARQ-CLIENTES
RECORDING MODE IS F
RECORD CONTAINS 60 CHARACTERS.
01 REG-CLIENTE.
05 CLI-CODIGO PIC 9(05).
05 CLI-NOME PIC X(30).
05 CLI-CIDADE PIC X(15).
05 CLI-SALDO PIC 9(08)V99.
FD ARQ-RELATORIO
RECORDING MODE IS F
RECORD CONTAINS 133 CHARACTERS.
01 REG-RELATORIO PIC X(133).
WORKING-STORAGE SECTION.
01 WS-FILE-STATUS.
05 WS-FS-CLIENTES PIC XX.
05 WS-FS-RELATORIO PIC XX.
01 WS-CONTROLE.
05 WS-FIM-ARQUIVO PIC X VALUE 'N'.
88 FIM-ARQUIVO VALUE 'S'.
88 NAO-FIM-ARQUIVO VALUE 'N'.
05 WS-LINHA PIC 9(03) VALUE ZERO.
05 WS-PAGINA PIC 9(04) VALUE ZERO.
05 WS-LIMITE-PAGINA PIC 9(03) VALUE 55.
05 WS-QTD-CLIENTES PIC 9(07) VALUE ZERO.
05 WS-TOTAL-SALDOS PIC 9(13)V99 VALUE ZERO.
01 WS-LINHA-SAIDA.
05 WS-ASA PIC X.
05 WS-TEXTO PIC X(132).
01 CABECALHO-1.
05 FILLER PIC X(40)
VALUE 'EMPRESA BELLACOSA MAINFRAME'.
05 FILLER PIC X(52) VALUE SPACES.
05 FILLER PIC X(07) VALUE 'PAGINA:'.
05 CAB1-PAGINA PIC ZZZ9.
05 FILLER PIC X(29) VALUE SPACES.
01 CABECALHO-2.
05 FILLER PIC X(132) VALUE
'RELATORIO GERAL DE CLIENTES E POSICAO DE SALDOS'.
01 CABECALHO-3.
05 FILLER PIC X(07) VALUE 'CODIGO'.
05 FILLER PIC X(03) VALUE SPACES.
05 FILLER PIC X(30) VALUE 'NOME'.
05 FILLER PIC X(03) VALUE SPACES.
05 FILLER PIC X(15) VALUE 'CIDADE'.
05 FILLER PIC X(05) VALUE SPACES.
05 FILLER PIC X(16) VALUE 'SALDO'.
05 FILLER PIC X(53) VALUE SPACES.
01 DETALHE-CLIENTE.
05 DET-CODIGO PIC 9(05).
05 FILLER PIC X(05) VALUE SPACES.
05 DET-NOME PIC X(30).
05 FILLER PIC X(03) VALUE SPACES.
05 DET-CIDADE PIC X(15).
05 FILLER PIC X(03) VALUE SPACES.
05 DET-SALDO PIC ZZ.ZZZ.ZZZ.ZZ9,99-.
05 FILLER PIC X(54) VALUE SPACES.
01 LINHA-TOTAL.
05 FILLER PIC X(55)
VALUE 'TOTAL GERAL DOS SALDOS:'.
05 TOTAL-SALDOS-ED PIC ZZZ.ZZZ.ZZZ.ZZ9,99-.
05 FILLER PIC X(58) VALUE SPACES.
01 LINHA-QUANTIDADE.
05 FILLER PIC X(55)
VALUE 'QUANTIDADE DE CLIENTES:'.
05 TOTAL-CLIENTES-ED PIC Z.ZZZ.ZZ9.
05 FILLER PIC X(69) VALUE SPACES.
PROCEDURE DIVISION.
0000-PRINCIPAL.
PERFORM 1000-INICIALIZAR
PERFORM 2000-PROCESSAR
UNTIL FIM-ARQUIVO
PERFORM 3000-FINALIZAR
GOBACK.
1000-INICIALIZAR.
OPEN INPUT ARQ-CLIENTES
OUTPUT ARQ-RELATORIO
IF WS-FS-CLIENTES NOT = '00'
DISPLAY 'ERRO ABERTURA CLIENTES: '
WS-FS-CLIENTES
MOVE 12 TO RETURN-CODE
GOBACK
END-IF
IF WS-FS-RELATORIO NOT = '00'
DISPLAY 'ERRO ABERTURA RELATORIO: '
WS-FS-RELATORIO
MOVE 12 TO RETURN-CODE
GOBACK
END-IF
PERFORM 4000-LER-CLIENTE
IF NAO-FIM-ARQUIVO
PERFORM 5000-IMPRIMIR-CABECALHO
END-IF.
2000-PROCESSAR.
IF WS-LINHA > WS-LIMITE-PAGINA
PERFORM 5000-IMPRIMIR-CABECALHO
END-IF
MOVE CLI-CODIGO TO DET-CODIGO
MOVE CLI-NOME TO DET-NOME
MOVE CLI-CIDADE TO DET-CIDADE
MOVE CLI-SALDO TO DET-SALDO
MOVE SPACE TO WS-ASA
MOVE DETALHE-CLIENTE TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
ADD 1 TO WS-QTD-CLIENTES
ADD CLI-SALDO TO WS-TOTAL-SALDOS
PERFORM 4000-LER-CLIENTE.
3000-FINALIZAR.
IF WS-QTD-CLIENTES > ZERO
MOVE WS-TOTAL-SALDOS TO TOTAL-SALDOS-ED
MOVE WS-QTD-CLIENTES TO TOTAL-CLIENTES-ED
MOVE '0' TO WS-ASA
MOVE LINHA-TOTAL TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
MOVE SPACE TO WS-ASA
MOVE LINHA-QUANTIDADE TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
ELSE
MOVE '1' TO WS-ASA
MOVE 'NENHUM CLIENTE ENCONTRADO'
TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
END-IF
CLOSE ARQ-CLIENTES
ARQ-RELATORIO
DISPLAY 'RELATORIO GERADO COM SUCESSO'
DISPLAY 'CLIENTES PROCESSADOS: ' WS-QTD-CLIENTES
DISPLAY 'FILE STATUS RELATORIO: ' WS-FS-RELATORIO.
4000-LER-CLIENTE.
READ ARQ-CLIENTES
AT END
SET FIM-ARQUIVO TO TRUE
NOT AT END
CONTINUE
END-READ
IF WS-FS-CLIENTES NOT = '00'
AND WS-FS-CLIENTES NOT = '10'
DISPLAY 'ERRO DE LEITURA: ' WS-FS-CLIENTES
MOVE 12 TO RETURN-CODE
SET FIM-ARQUIVO TO TRUE
END-IF.
5000-IMPRIMIR-CABECALHO.
ADD 1 TO WS-PAGINA
MOVE WS-PAGINA TO CAB1-PAGINA
MOVE '1' TO WS-ASA
MOVE CABECALHO-1 TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
MOVE SPACE TO WS-ASA
MOVE CABECALHO-2 TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
MOVE '0' TO WS-ASA
MOVE CABECALHO-3 TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
MOVE SPACE TO WS-ASA
MOVE ALL '-' TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
MOVE 4 TO WS-LINHA.
6000-GRAVAR-LINHA.
MOVE WS-LINHA-SAIDA TO REG-RELATORIO
WRITE REG-RELATORIO
IF WS-FS-RELATORIO NOT = '00'
DISPLAY 'ERRO GRAVANDO RELATORIO: '
WS-FS-RELATORIO
MOVE 12 TO RETURN-CODE
SET FIM-ARQUIVO TO TRUE
END-IF
ADD 1 TO WS-LINHA.
10. Entendendo o programa passo a passo
O arquivo de saída
FD ARQ-RELATORIO
RECORDING MODE IS F
RECORD CONTAINS 133 CHARACTERS.
O registro possui 133 bytes porque queremos:
1 byte de controle ASA
132 bytes de conteúdo
A estrutura de montagem
01 WS-LINHA-SAIDA.
05 WS-ASA PIC X.
05 WS-TEXTO PIC X(132).
Essa estrutura representa exatamente o registro físico.
Exemplo:
MOVE '1' TO WS-ASA
MOVE CABECALHO-1 TO WS-TEXTO
O registro produzido será:
1EMPRESA BELLACOSA MAINFRAME...
Quando interpretado como ASA:
1manda saltar a página;o restante é impresso.
Cabeçalho com ASA 1
MOVE '1' TO WS-ASA
MOVE CABECALHO-1 TO WS-TEXTO
PERFORM 6000-GRAVAR-LINHA
Sempre que o cabeçalho é produzido:
incrementa a página;
move a página para o campo editado;
grava o cabeçalho com ASA
1;o relatório começa em nova página.
Título com ASA espaço
MOVE SPACE TO WS-ASA
MOVE CABECALHO-2 TO WS-TEXTO
O título é impresso na linha seguinte.
Cabeçalho das colunas com ASA 0
MOVE '0' TO WS-ASA
MOVE CABECALHO-3 TO WS-TEXTO
Antes dos nomes das colunas, é deixada uma linha em branco.
Isso melhora a legibilidade.
Detalhes com ASA espaço
MOVE SPACE TO WS-ASA
MOVE DETALHE-CLIENTE TO WS-TEXTO
Cada cliente é impresso sequencialmente, uma linha após a outra.
Total com ASA 0
MOVE '0' TO WS-ASA
MOVE LINHA-TOTAL TO WS-TEXTO
O total fica separado dos detalhes por uma linha em branco.
Visualmente:
00003 HAN SOLO SOROCABA 8.750,00
TOTAL GERAL DOS SALDOS: 21.500,00
11. JCL para executar o programa
//RELCLI01 JOB (ACCT),'RELATORIO ASA',
// CLASS=A,
// MSGCLASS=X,
// MSGLEVEL=(1,1),
// NOTIFY=&SYSUID
//*
//STEP01 EXEC PGM=RELCLI01
//*
//STEPLIB DD DSN=BELLACOSA.LOADLIB,DISP=SHR
//*
//CLIENTES DD *
00001ANA SKYWALKER CAMPINAS 0000125000
00002LUKE MAINFRAME ITATIBA 0000095000
00003HAN SOLO SOROCABA 0000875000
00004LEIA ORGANA SAO PAULO 0000257500
00005OBI-WAN COBOL JUNDIAI 0000312500
/*
//RELATORIO DD SYSOUT=*,
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0)
//SYSOUT DD SYSOUT=*
//CEEDUMP DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//
12. Explicando o JCL
EXEC PGM=RELCLI01
//STEP01 EXEC PGM=RELCLI01
Executa o módulo de carga criado pelo processo de compilação e link-edit.
STEPLIB
//STEPLIB DD DSN=BELLACOSA.LOADLIB,DISP=SHR
Informa onde está o módulo executável.
Em algumas instalações, a biblioteca pode já estar presente no:
JOBLIB;LNKLST;
STEPLIB de uma procedure;
ambiente do compilador.
Arquivo de entrada
//CLIENTES DD *
Fornece os clientes diretamente no JCL.
Em produção, normalmente seria utilizado:
//CLIENTES DD DSN=EMPRESA.CLIENTES.ARQUIVO,
// DISP=SHR
Arquivo de relatório
//RELATORIO DD SYSOUT=*,
// DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0)
Aqui está o coração da Matrix.
SYSOUT=*
Envia o relatório para uma classe de saída do JES, normalmente herdando a classe definida para o job ou instalação.
Também seria possível utilizar:
//RELATORIO DD SYSOUT=A
ou uma classe específica para impressão.
RECFM=FBA
Informa:
O primeiro byte de cada registro é um controle ASA.
Sem o A, o JES ou visualizador poderia mostrar o primeiro caractere como parte do conteúdo.
Em vez de:
RELATORIO DE CLIENTES
poderia aparecer:
1RELATORIO DE CLIENTES
LRECL=133
Define:
1 byte ASA + 132 bytes imprimíveis
BLKSIZE=0
Permite que o sistema escolha um tamanho de bloco adequado.
É geralmente preferível a codificar um tamanho arbitrário sem conhecer:
dispositivo;
SMS;
instalação;
características do data set.
13. Como o spool pode mostrar o relatório
Quando corretamente interpretado, a saída será semelhante a:
EMPRESA BELLACOSA MAINFRAME PAGINA: 1
RELATORIO GERAL DE CLIENTES E POSICAO DE SALDOS
CODIGO NOME CIDADE SALDO
-----------------------------------------------------------------------
00001 ANA SKYWALKER CAMPINAS 1.250,00
00002 LUKE MAINFRAME ITATIBA 950,00
00003 HAN SOLO SOROCABA 8.750,00
00004 LEIA ORGANA SAO PAULO 2.575,00
00005 OBI-WAN COBOL JUNDIAI 3.125,00
TOTAL GERAL DOS SALDOS: 16.650,00
QUANTIDADE DE CLIENTES: 5
No arquivo físico, os registros seriam aproximadamente:
1EMPRESA BELLACOSA MAINFRAME...
RELATORIO GERAL DE CLIENTES...
0CODIGO NOME...
----------------------------------------------------------------...
00001 ANA SKYWALKER...
00002 LUKE MAINFRAME...
0TOTAL GERAL DOS SALDOS...
QUANTIDADE DE CLIENTES...
O caractere inicial existe fisicamente, mas não deve aparecer como conteúdo impresso.
14. Controle de quebra de página
Um relatório profissional não deve continuar imprimindo indefinidamente.
No exemplo:
05 WS-LIMITE-PAGINA PIC 9(03) VALUE 55.
Antes de imprimir cada detalhe:
IF WS-LINHA > WS-LIMITE-PAGINA
PERFORM 5000-IMPRIMIR-CABECALHO
END-IF
Quando o limite é atingido:
incrementa o número da página;
grava ASA
1;salta para nova página;
reimprime o cabeçalho;
continua os detalhes.
Essa é uma característica essencial dos relatórios batch clássicos.
Sem ela, o relatório poderia:
cortar linhas no rodapé;
imprimir detalhes fora da área útil;
perder cabeçalhos;
produzir páginas sem identificação.
15. Armadilhas clássicas
Armadilha 1 — usar RECFM=FB com ASA manual
Programa:
MOVE '1' TO WS-ASA
JCL:
RECFM=FB
Resultado possível:
1RELATORIO DE CLIENTES
DETALHE 1
0TOTAL GERAL
Os comandos aparecem como dados.
O sistema não foi informado de que a primeira posição contém controle ASA.
Armadilha 2 — declarar 132 posições quando precisava de 133
Se você deseja 132 colunas imprimíveis e controla manualmente o ASA, precisa reservar:
132 + 1 = 133
Caso contrário, poderá:
perder a última coluna;
truncar valores;
desalojar campos;
provocar incompatibilidade de DCB.
Armadilha 3 — esquecer de limpar a linha
Antes de montar uma nova linha, garanta que campos antigos não permanecerão na área.
Uma técnica segura é:
MOVE SPACES TO WS-LINHA-SAIDA
Depois:
MOVE SPACE TO WS-ASA
MOVE DETALHE-CLIENTE TO WS-TEXTO
Isso evita o clássico fantasma do buffer anterior.
Armadilha 4 — misturar ASA manual e ADVANCING
Evite fazer simultaneamente:
MOVE '1' TO WS-ASA
WRITE REG-RELATORIO
AFTER ADVANCING PAGE
Você estaria tentando controlar a impressora de duas formas.
É como colocar dois programadores alterando o mesmo membro da PROCLIB sem ENQ.
Escolha uma estratégia:
ASA manual;
ou
WRITE ... ADVANCING.
Armadilha 5 — não conferir o FILE STATUS
Um relatório também pode falhar.
Por isso, utilize:
FILE STATUS IS WS-FS-RELATORIO
E depois de gravar:
IF WS-FS-RELATORIO NOT = '00'
DISPLAY 'ERRO GRAVANDO RELATORIO'
END-IF
Um programa que ignora o FILE STATUS está confiando na Força sem ter treinado com Yoda.
Armadilha 6 — total editado sendo usado para cálculo
Nunca acumule valores em campos formatados:
PIC ZZZ.ZZZ.ZZ9,99
Mantenha:
05 WS-TOTAL-SALDOS PIC 9(13)V99.
E apenas na impressão mova para:
05 TOTAL-SALDOS-ED PIC ZZZ.ZZZ.ZZZ.ZZ9,99-.
Campo numérico calcula.
Campo editado apresenta.
Misturar os dois é convocar um S0C7 para a reunião.
16. Dicas de um programador veterano
Centralize a gravação
Utilize um único parágrafo:
6000-GRAVAR-LINHA.
Assim você centraliza:
o
WRITE;o tratamento de erro;
a contagem de linhas;
mensagens de diagnóstico.
Separe cabeçalho, detalhe e total
Uma boa estrutura é:
5000-IMPRIMIR-CABECALHO
5100-IMPRIMIR-SUBCABECALHO
6000-IMPRIMIR-DETALHE
7000-IMPRIMIR-SUBTOTAL
8000-IMPRIMIR-TOTAL
Isso facilita:
manutenção;
testes;
leitura;
inclusão de novos campos;
alteração do layout.
Use nomes que revelem intenção
Prefira:
WS-ASA-NOVA-PAGINA
WS-ASA-LINHA-NORMAL
WS-ASA-DUPLO-ESPACO
Em vez de espalhar literais:
MOVE '1' ...
MOVE '0' ...
MOVE '-' ...
Uma alternativa:
01 WS-CONTROLES-ASA.
05 WS-ASA-LINHA-NORMAL PIC X VALUE SPACE.
05 WS-ASA-DUPLO PIC X VALUE '0'.
05 WS-ASA-TRIPLO PIC X VALUE '-'.
05 WS-ASA-SOBREPOR PIC X VALUE '+'.
05 WS-ASA-NOVA-PAGINA PIC X VALUE '1'.
Depois:
MOVE WS-ASA-NOVA-PAGINA TO WS-ASA
Muito mais legível.
Controle órfãos de página
Não permita que um título seja impresso como última linha da página e seus detalhes apareçam apenas na página seguinte.
Antes de iniciar uma seção, verifique se há espaço suficiente:
IF WS-LINHA > 50
PERFORM 5000-IMPRIMIR-CABECALHO
END-IF
O relatório precisa ser compreensível para humanos, não apenas tecnicamente correto.
Guarde os totais sem formatação
Acumuladores devem ser numéricos:
PIC 9(13)V99 COMP-3
Para volumes grandes, COMP-3 pode reduzir espaço e ser adequado para cálculos decimais.
Apenas no momento de imprimir:
MOVE WS-TOTAL TO TOTAL-EDITADO
Teste casos de fronteira
Teste relatórios com:
zero registros;
um registro;
exatamente uma página;
uma página mais um registro;
saldo zero;
saldo negativo;
valores máximos;
mudança de grupo;
erro de leitura;
erro de gravação.
O bug mais traiçoeiro não acontece na linha 20.
Ele acontece exatamente na linha 56, quando a página deveria ter sido reiniciada.
17. ASA e SDSF
Ao visualizar a saída no SDSF, o comportamento pode depender:
da classe de saída;
do formato do spool;
dos atributos do SYSOUT;
do visualizador;
da configuração da instalação.
Em alguns ambientes, os controles são interpretados e você vê o relatório já formatado.
Em outros, pode ser necessário usar comandos ou modos de exibição que revelem os caracteres de controle.
Se aparecer:
1CABECALHO
DETALHE
0TOTAL
investigue:
o
RECFM;o
LRECL;a classe SYSOUT;
o software de visualização;
se o arquivo foi transferido para Windows como texto comum;
se houve conversão que removeu ou preservou incorretamente o primeiro byte.
18. ASA em arquivos transferidos para outras plataformas
Quando um arquivo FBA é enviado para Linux ou Windows, o primeiro byte pode continuar presente.
Um editor comum poderá mostrar:
1RELATORIO MENSAL
CLIENTE 00001
CLIENTE 00002
0TOTAL
Isso não significa necessariamente que o relatório esteja corrompido.
Significa que o programa receptor não está interpretando ASA.
Ao converter para:
PDF;
HTML;
CSV;
texto;
Excel;
e-mail;
é necessário decidir o que fazer com cada controle:
Espaço → quebra normal de linha
0 → duas quebras de linha
- → três quebras de linha
1 → quebra de página
+ → sobreposição ou tratamento especial
Essa conversão precisa ser planejada.
Simplesmente remover a primeira coluna elimina os comandos, mas também elimina a paginação e os espaçamentos.
19. Easter eggs do universo ASA
Easter egg 1 — o primeiro byte invisível
O relatório possui 133 bytes, mas o usuário enxerga apenas 132 colunas.
O primeiro byte existe, trabalha, movimenta páginas e nunca aparece.
É o verdadeiro sysprog do relatório:
Faz tudo funcionar, mas quase ninguém sabe que está ali.
Easter egg 2 — 1 não é “uma linha”
O iniciante pode imaginar:
1 = avance uma linha
Mas quem faz isso é o espaço.
O 1 significa, normalmente:
Nova página ou canal 1
O caractere mais aparentemente óbvio é justamente o mais enganoso.
Easter egg 3 — 0 não significa zero linhas
O 0 manda avançar duas linhas.
Logo:
Espaço = 1 linha
0 = 2 linhas
- = 3 linhas
Não tente encontrar lógica decimal perfeita.
É um protocolo histórico, não uma função intrínseca COBOL.
Easter egg 4 — o + é uma máquina do tempo
Enquanto os demais avançam o papel, o + se recusa a seguir em frente.
Ele permanece na linha atual e imprime novamente.
É o único caractere ASA que diz:
Não avance. Ainda não terminamos com esta linha.
Easter egg 5 — ASA sobreviveu às impressoras
Mesmo com:
spool eletrônico;
SDSF;
PDFs;
impressão IP;
armazenamento digital;
relatórios distribuídos por e-mail;
o conceito ASA continua presente em muitos sistemas legados e interfaces de impressão.
A IBM ainda documenta formatos como FBA e o uso de ASA em operações de saída.
É mais uma prova de uma velha lei do mainframe:
Uma solução simples, padronizada e confiável pode sobreviver a várias gerações de hardware.
20. ASA manual ou WRITE ADVANCING?
Use ASA manual quando:
estiver mantendo um programa legado;
precisar controlar exatamente o primeiro byte;
o layout já trabalhar com 133 posições;
houver integração com produtos específicos;
quiser visualizar o controle no arquivo;
os padrões da empresa exigirem essa técnica.
Use WRITE ... ADVANCING quando:
desejar código mais declarativo;
o compilador e o ambiente estiverem corretamente configurados;
não precisar manipular diretamente o controle;
estiver criando um relatório novo;
o padrão de desenvolvimento da instalação recomendar essa forma.
Exemplo moderno:
WRITE REG-RELATORIO
FROM CABECALHO-1
AFTER ADVANCING PAGE
Linha normal:
WRITE REG-RELATORIO
FROM DETALHE-CLIENTE
AFTER ADVANCING 1 LINE
Separação:
WRITE REG-RELATORIO
FROM LINHA-TOTAL
AFTER ADVANCING 2 LINES
A IBM estabelece que o uso de AFTER ADVANCING corresponde ao controle ASA e requer formato de registro apropriado, como FBA.
21. Checklist de produção
Antes de promover o programa, verifique:
[ ] O primeiro byte é ASA?
[ ] O JCL utiliza RECFM=FBA?
[ ] O LRECL inclui o byte de controle?
[ ] O cabeçalho utiliza ASA 1?
[ ] As linhas normais utilizam espaço?
[ ] Os subtotais usam espaçamento adequado?
[ ] Existe controle de quebra de página?
[ ] O cabeçalho é repetido em todas as páginas?
[ ] O programa trata arquivo vazio?
[ ] Os FILE STATUS são verificados?
[ ] Os totais são numéricos antes da edição?
[ ] Valores negativos foram testados?
[ ] O relatório foi visualizado no SDSF?
[ ] A última página foi conferida?
[ ] A transferência para outras plataformas foi testada?
Conclusão
Criar um relatório COBOL em mainframe não é simplesmente concatenar campos e executar um WRITE.
Um bom relatório exige:
organização;
paginação;
cabeçalhos;
campos editados;
totais;
subtotais;
tratamento de erros;
controle de linhas;
compatibilidade com spool;
conhecimento do formato físico do arquivo.
O caractere ASA representa uma solução elegante desenvolvida para uma era em que impressoras eram equipamentos mecânicos gigantescos e o papel precisava ser controlado diretamente pelo programa.
Com apenas um byte, era possível ordenar:
avance uma linha;
avance duas linhas;
avance três linhas;
não avance;
inicie uma nova página;
salte para uma posição do formulário.
É um protocolo pequeno, histórico e extremamente eficiente.
Para o programador COBOL Padawan, a lição final é simples:
Nunca despreze a primeira coluna de um relatório mainframe.
Ela pode parecer apenas um espaço, um zero, um hífen ou um número.
Mas, na Matrix do JES, essa coluna controla o destino de toda a página.
E quando o ASA 1 aparece, não é apenas uma nova folha.
É o relatório executando seu próprio IPL.
Sem comentários:
Enviar um comentário