1. A hierarquia do COBOL
Um programa COBOL é organizado em camadas hierárquicas, do mais geral para o mais específico:
| Nível | O que é | Exemplo |
|---|---|---|
| Divisão | A maior unidade. Todo programa tem 4. | IDENTIFICATION DIVISION. |
| Seção | Grupo de parágrafos dentro de uma divisão. | WORKING-STORAGE SECTION. |
| Parágrafo | Bloco lógico com nome, contém sentenças. | 0000-INICIO. |
| Sentença | Uma ou mais instruções terminadas com ponto. | MOVE 0 TO WS-CONTADOR. |
| Instrução | A menor unidade executável. | MOVE 0 TO WS-CONTADOR |
🦕 Analogia — COBOL como uma peça de teatro
Pense num programa COBOL como uma peça de teatro:
🎭 Divisão = o próprio teatro (estrutura que contém tudo)
🎬 Seção = os atos (partes da história)
📝 Parágrafo = as cenas (ação específica)
💬 Sentença = as falas de uma cena
🗣️ Instrução = cada palavra dita por um ator
2. IDENTIFICATION DIVISION
É a primeira divisão e funciona como a capa de um documento: identifica quem é o programa, quem o escreveu e quando. É a única divisão obrigatória que não executa nenhuma lógica — é pura documentação.
Parágrafos disponíveis
| Parágrafo | Obrigatório? | Descrição |
|---|---|---|
PROGRAM-ID | ✅ Sim | Nome único do programa (máx. 8 caracteres) |
AUTHOR | Não | Nome da autora/autor |
DATE-WRITTEN | Não | Data de criação |
DATE-COMPILED | Não | Preenchido automaticamente pelo compilador |
INSTALLATION | Não | Nome da empresa ou instalação |
SECURITY | Não | Classificação de segurança do programa |
IDENTIFICATION DIVISION. PROGRAM-ID. CALC-FOL. AUTHOR. LADY COBOL. DATE-WRITTEN. 2024-01-15. INSTALLATION. BANCO DO MAINFRAME S/A. SECURITY. CONFIDENCIAL - USO INTERNO.
✅ Boas práticas de nomenclatura
O PROGRAM-ID deve ter no máximo 8 caracteres, sem espaços. Use nomes que descrevam o programa: CALC-FOL (cálculo de folha), EXTR-SAL (extrato de saldo), REL-MENS (relatório mensal). Isso facilita muito a manutenção.
3. ENVIRONMENT DIVISION
Define o ambiente de execução do programa — principalmente os arquivos de entrada e saída. É aqui que você "conecta" os nomes lógicos usados no código com os datasets físicos que existem no mainframe.
Possui duas seções principais:
CONFIGURATION SECTION
Configurações gerais do ambiente de compilação. Raramente utilizada em programas modernos — a maioria dos parâmetros tem defaults razoáveis.
INPUT-OUTPUT SECTION
A mais usada. É aqui que você declara os arquivos que o programa vai ler ou escrever, usando a cláusula SELECT.
ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-370. OBJECT-COMPUTER. IBM-370. INPUT-OUTPUT SECTION. FILE-CONTROL. * Nome lógico ---> Nome no JCL (DDNAME) SELECT ARQ-FUNCIONARIOS ASSIGN TO FUNCION * DD FUNCION no JCL ORGANIZATION IS SEQUENTIAL ACCESS MODE IS SEQUENTIAL FILE STATUS IS WS-STATUS-ARQ. SELECT ARQ-RELATORIO ASSIGN TO RELAT ORGANIZATION IS SEQUENTIAL.
🦕 Analogia — SELECT é como uma agenda de contatos
Imagine que no seu código você chama sempre "minha melhor amiga". No SELECT você define que "minha melhor amiga = Maria, telefone (11) 9999-8888". O código não precisa saber o número de telefone — só o apelido. O JCL (que é como a agenda real) é quem sabe onde o arquivo de verdade está no mainframe.
4. DATA DIVISION
É a divisão mais extensa da maioria dos programas. Aqui você declara todos os dados que o programa vai usar — variáveis, estruturas de arquivos, registros. O COBOL não permite declarar variáveis dentro do código (como em Python ou Java): tudo vai na DATA DIVISION.
Seções da DATA DIVISION
FILE SECTION
Descreve a estrutura dos registros de cada arquivo declarado no SELECT. Cada arquivo tem um FD (File Description) seguido da estrutura do registro.
WORKING-STORAGE SECTION
Variáveis de trabalho do programa — equivalente às variáveis locais de outras linguagens, mas persistidas durante toda a execução do programa. É a seção mais usada.
LOCAL-STORAGE SECTION
Similar ao WORKING-STORAGE, mas reinicializada a cada chamada do programa (útil para sub-programas chamados via CALL).
LINKAGE SECTION
Define os parâmetros recebidos de programas externos (via CALL). É o "contrato" de comunicação entre programas.
DATA DIVISION. FILE SECTION. FD ARQ-FUNCIONARIOS RECORDING MODE IS F RECORD CONTAINS 100 CHARACTERS. 01 REG-FUNCIONARIO. 05 REG-MATRICULA PIC 9(06). 05 REG-NOME PIC X(40). 05 REG-SALARIO PIC 9(07)V99. 05 REG-DEPARTAMENTO PIC X(03). 05 FILLER PIC X(44). *completa 100 bytes WORKING-STORAGE SECTION. 01 WS-STATUS-ARQ PIC X(02) VALUE SPACES. 01 WS-FLAG-FIM PIC X(01) VALUE 'N'. 88 FIM-DE-ARQUIVO VALUE 'S'. 01 WS-TOTAIS. 05 WS-TOT-FUNCIONARIOS PIC 9(06) VALUE ZEROS. 05 WS-TOT-SALARIOS PIC 9(11)V99 VALUE ZEROS.
💗 Dica para iniciantes — FILLER
FILLER é um campo que existe no registro mas que o programa não vai usar. É como uma caixa de papelão vazia que mantém o espaço: necessário para que os campos posteriores comecem na posição certa. Muito comum em registros de arquivo flat para "completar" até o tamanho do registro.
5. PROCEDURE DIVISION
É onde a mágica acontece — a lógica do programa. Tudo que o programa faz de fato (abrir arquivos, calcular, comparar, exibir) está aqui. É organizada em parágrafos, que funcionam como sub-rotinas nomeadas.
🦕 Analogia — Parágrafos como funções
Se você vem de Python ou Java, pense nos parágrafos da PROCEDURE DIVISION como funções sem parâmetros. Você define a função (o parágrafo) e chama ela com PERFORM:
Python: def calcular_salario(): ... → chamada: calcular_salario()
COBOL: 1000-CALCULAR-SALARIO. → chamada: PERFORM 1000-CALCULAR-SALARIO
A diferença é que em COBOL os dados são sempre globais (WORKING-STORAGE), não passados como parâmetro.
PROCEDURE DIVISION. *--- Parágrafo principal --- 0000-INICIO. PERFORM 1000-ABRIR-ARQUIVOS PERFORM 2000-PROCESSAR UNTIL FIM-DE-ARQUIVO *condição nível 88 PERFORM 3000-FECHAR-ARQUIVOS STOP RUN. *--- Abrir arquivos --- 1000-ABRIR-ARQUIVOS. OPEN INPUT ARQ-FUNCIONARIOS OPEN OUTPUT ARQ-RELATORIO READ ARQ-FUNCIONARIOS AT END MOVE 'S' TO WS-FLAG-FIM END-READ. *--- Processar cada registro --- 2000-PROCESSAR. ADD 1 TO WS-TOT-FUNCIONARIOS ADD REG-SALARIO TO WS-TOT-SALARIOS READ ARQ-FUNCIONARIOS AT END MOVE 'S' TO WS-FLAG-FIM END-READ. *--- Fechar arquivos --- 3000-FECHAR-ARQUIVOS. CLOSE ARQ-FUNCIONARIOS CLOSE ARQ-RELATORIO.
✅ Convenção de numeração de parágrafos
A convenção mais comum é numerar os parágrafos em blocos de 1000: 0000 para o principal, 1000 para inicialização, 2000 para processamento, 3000 para finalização, 9000 para tratamento de erros. Isso facilita inserir novos parágrafos sem precisar renumerar tudo.
6. O formato de colunas
COBOL legado usa um formato de coluna fixo herdado dos cartões perfurados de 80 colunas. Cada coluna tem um propósito específico:
| Colunas | Nome | Uso |
|---|---|---|
| 1–6 | Número de sequência | Opcional. Usado para numerar linhas nos tempos dos cartões. |
| 7 | Indicador | * = comentário - = continuação de linha / = nova página |
| 8–11 | Área A | Divisões, seções, parágrafos e FD |
| 12–72 | Área B | Instruções, declarações de variáveis, cláusulas |
| 73–80 | Identificação | Ignorado pelo compilador. Era o nome do programa no cartão. |
⚠️ Erro clássico de iniciante
Colocar o nome de um parágrafo na Área B (a partir da coluna 12) é um dos erros mais comuns. Parágrafos, seções e divisões precisam começar na Área A (coluna 8 ou 9). Se você ver um erro de compilação "paragraph name out of sequence" ou similar, verifique as colunas primeiro.
7. Programa completo comentado
Agora veja todas as divisões juntas, num programa que lê um arquivo de funcionários e exibe o total de salários:
*================================================================* * PROGRAMA : CALC-SAL * * FUNCAO : Totaliza salarios de arquivo de funcionarios * *================================================================* IDENTIFICATION DIVISION. PROGRAM-ID. CALC-SAL. AUTHOR. LADY COBOL. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT ARQ-ENTRADA ASSIGN TO ENTRADA ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-ST-ENT. DATA DIVISION. FILE SECTION. FD ARQ-ENTRADA RECORD CONTAINS 50 CHARACTERS. 01 REG-ENTRADA. 05 RE-NOME PIC X(30). 05 RE-SALARIO PIC 9(08)V99. 05 FILLER PIC X(10). WORKING-STORAGE SECTION. 01 WS-ST-ENT PIC X(02) VALUE SPACES. 01 WS-FIM PIC X(01) VALUE 'N'. 88 FIM-ARQUIVO VALUE 'S'. 01 WS-TOTAL-SAL PIC 9(11)V99 VALUE ZEROS. 01 WS-QTD-FUNC PIC 9(06) VALUE ZEROS. PROCEDURE DIVISION. 0000-PRINCIPAL. PERFORM 1000-INICIALIZAR PERFORM 2000-PROCESSAR UNTIL FIM-ARQUIVO PERFORM 3000-FINALIZAR STOP RUN. 1000-INICIALIZAR. OPEN INPUT ARQ-ENTRADA READ ARQ-ENTRADA AT END MOVE 'S' TO WS-FIM END-READ. 2000-PROCESSAR. ADD 1 TO WS-QTD-FUNC ADD RE-SALARIO TO WS-TOTAL-SAL READ ARQ-ENTRADA AT END MOVE 'S' TO WS-FIM END-READ. 3000-FINALIZAR. CLOSE ARQ-ENTRADA DISPLAY 'FUNCIONARIOS PROCESSADOS: ' WS-QTD-FUNC DISPLAY 'TOTAL DE SALARIOS.....: ' WS-TOTAL-SAL.
🟣 Para quem já conhece COBOL — AT END vs NOT AT END
No exemplo acima usamos AT END para detectar fim de arquivo. Em programas mais robustos, você também vai querer tratar o FILE STATUS: se WS-ST-ENT não for "00" (sucesso) nem "10" (fim de arquivo), há um erro real (disco, alocação, etc.) e o programa deve ser abortado com mensagem clara. Nunca ignore o File Status em produção.