Translate

Mostrar mensagens com a etiqueta Impressão Batch. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Impressão Batch. Mostrar todas as mensagens

domingo, 18 de novembro de 2018

Relatórios COBOL e Caracteres ASA sem Mistérios

 

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:

  1. o texto que seria impresso;

  2. o movimento que deveria ser realizado no papel;

  3. se a impressão deveria começar em uma nova página;

  4. se deveria haver espaçamento;

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

ASAAção antes da impressãoUso comum
EspaçoAvança uma linhaLinha normal de detalhe
0Avança duas linhasSeparar blocos
-Avança três linhasSeparar grandes seções
+Não avançaSobreimpressão
1Salta para nova página/canal 1Cabeçalho de página
2Salta para canal 2Posição configurada
3Salta para canal 3Posição configurada
4Salta para canal 4Posição configurada
5Salta para canal 5Posição configurada
6Salta para canal 6Posição configurada
7Salta para canal 7Posição configurada
8Salta para canal 8Posição configurada
9Salta para canal 9Posição configurada
ASalta para canal 10Formulários especiais
BSalta para canal 11Formulários especiais
CSalta para canal 12Formulá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:

COBOLControle ASA aproximado
AFTER ADVANCING 1 LINEEspaço
AFTER ADVANCING 2 LINES0
AFTER ADVANCING 3 LINES-
AFTER ADVANCING PAGE1
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:

  • 1 manda 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:

  1. incrementa a página;

  2. move a página para o campo editado;

  3. grava o cabeçalho com ASA 1;

  4. 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:

  1. incrementa o número da página;

  2. grava ASA 1;

  3. salta para nova página;

  4. reimprime o cabeçalho;

  5. 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:

  1. o RECFM;

  2. o LRECL;

  3. a classe SYSOUT;

  4. o software de visualização;

  5. se o arquivo foi transferido para Windows como texto comum;

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