1. O que são Level Numbers?
Level Numbers (números de nível) são valores numéricos que você coloca antes do nome de cada variável na DATA DIVISION. Eles dizem ao compilador qual é a posição daquele campo na hierarquia — se é um grupo pai ou um campo filho.
🦕 Analogia — organograma de empresa
Imagine o organograma de uma empresa:
🏢 Nível 01 = A empresa inteira (WS-FUNCIONARIO)
👔 Nível 05 = Departamentos (WS-DADOS-PESSOAIS, WS-DADOS-SALARIAIS)
👷 Nível 10 = Times dentro de cada depto (WS-NOME, WS-CARGO)
👩 Nível 15 = Pessoas individuais (WS-PRIMEIRO-NOME, WS-SOBRENOME)
Quanto maior o número de nível, mais "dentro" da hierarquia você está.
2. Níveis gerais: 01 a 49
Os níveis de 01 a 49 são os mais comuns e servem para criar qualquer estrutura de dados:
| Nível | Onde começa | Uso típico |
|---|---|---|
| 01 | Área A (col. 8) | Sempre o nível raiz — grupo ou campo independente |
| 02–49 | Área A ou B | Sub-grupos e campos dentro de um grupo 01 |
WORKING-STORAGE SECTION. *--- Registro de funcionário (grupo raiz) 01 WS-FUNCIONARIO. 05 WS-DADOS-PESSOAIS. 10 WS-NOME. 15 WS-PRIMEIRO-NOME PIC X(20). 15 WS-SOBRENOME PIC X(30). 10 WS-CPF PIC 9(11). 10 WS-DATA-NASC. 15 WS-DIA PIC 9(02). 15 WS-MES PIC 9(02). 15 WS-ANO PIC 9(04). 05 WS-DADOS-SALARIAIS. 10 WS-SALARIO-BRUTO PIC 9(08)V99. 10 WS-DESCONTO-INSS PIC 9(06)V99. 10 WS-SALARIO-LIQUIDO PIC 9(08)V99.
✅ Por que usar 05, 10, 15 em vez de 02, 03, 04?
Por convenção, programadores COBOL pulam de 5 em 5 (ou de 10 em 10). Isso permite inserir novos níveis entre os existentes sem precisar renumerar todo o código. É o mesmo raciocínio de numerar linhas de 10 em 10 nos editores antigos — deixa espaço para crescer.
3. Variáveis de grupo vs. elementares
Essa distinção é fundamental em COBOL:
| Tipo | Definição | Tem PIC? |
|---|---|---|
| Variável de grupo | Contém outros campos dentro dela | ❌ Nunca |
| Variável elementar | É um campo "folha" — não tem filhos | ✅ Sempre |
01 WS-ENDERECO. * GRUPO (sem PIC) 05 WS-LOGRADOURO PIC X(40). * ELEMENTAR 05 WS-NUMERO PIC 9(05). * ELEMENTAR 05 WS-COMPLEMENTO PIC X(20). * ELEMENTAR 05 WS-CIDADE PIC X(30). * ELEMENTAR 05 WS-UF PIC X(02). * ELEMENTAR 05 WS-CEP PIC 9(08). * ELEMENTAR * Você pode usar o grupo inteiro como um bloco: MOVE SPACES TO WS-ENDERECO * limpa todos os campos * Ou acessar campos individuais: MOVE 'SP' TO WS-UF * só o estado
💗 Dica importante
Quando você faz MOVE SPACES TO WS-ENDERECO, está limpando todos os campos filhos de uma vez. É como esvaziar uma gaveta inteira em vez de tirar item por item. Muito usado para inicializar registros antes de preencher com novos dados.
4. Nível 77 — variáveis independentes
O nível 77 declara variáveis elementares independentes — campos que não pertencem a nenhum grupo. Tecnicamente é como um nível 01 elementar, mas com a restrição de que não pode ter campos filhos.
WORKING-STORAGE SECTION. 77 WS-CONTADOR PIC 9(04) VALUE ZEROS. 77 WS-INDICADOR PIC X(01) VALUE SPACES. 77 WS-TAXA-INSS PIC 9(02)V99 VALUE 11.00.
⚠️ Nível 77 está em desuso
Em código moderno, prefira usar nível 01 para variáveis independentes. O nível 77 foi amplamente utilizado em código legado, então você vai encontrá-lo bastante ao fazer manutenção — mas não precisa usá-lo em código novo. A funcionalidade é idêntica.
5. Nível 88 — condition names (nomes de condição)
O nível 88 é um dos recursos mais elegantes do COBOL e muito subutilizado por quem está aprendendo. Ele não declara uma variável nova — ele define nomes para valores específicos de uma variável pai, tornando as condições muito mais legíveis.
🦕 Analogia — semáforo
Imagina que WS-STATUS-PEDIDO é um campo que guarda "A", "P", "E" ou "C". Sem nível 88, você escreve IF WS-STATUS-PEDIDO = 'A' e torce para quem lê saber o que "A" significa.
Com nível 88, você escreve IF PEDIDO-APROVADO — e todo mundo entende na hora, como um semáforo verde que todo mundo sabe que significa "pode passar".
WORKING-STORAGE SECTION. 01 WS-STATUS-PEDIDO PIC X(01). 88 PEDIDO-APROVADO VALUE 'A'. 88 PEDIDO-PENDENTE VALUE 'P'. 88 PEDIDO-ENVIADO VALUE 'E'. 88 PEDIDO-CANCELADO VALUE 'C'. 01 WS-IDADE PIC 9(03). 88 MENOR-DE-IDADE VALUE 0 THRU 17. 88 MAIOR-DE-IDADE VALUE 18 THRU 999. PROCEDURE DIVISION. * SEM nível 88 — difícil de ler: IF WS-STATUS-PEDIDO = 'A' PERFORM 2000-PROCESSAR-APROVADO END-IF * COM nível 88 — lê como inglês: IF PEDIDO-APROVADO PERFORM 2000-PROCESSAR-APROVADO END-IF * Você também pode SETAR um nível 88 (seta o valor no pai): SET PEDIDO-ENVIADO TO TRUE * (equivale a MOVE 'E' TO WS-STATUS-PEDIDO)
✅ Boas práticas com nível 88
- Use sempre para campos de status, flags e códigos — elimina "números mágicos" do código
- Pode usar
THRUpara definir intervalos de valores - Pode definir múltiplos valores:
VALUE 'A' 'B' 'C' SET nome-condicao TO TRUEé mais legível queMOVE 'X' TO campo
6. Nível 66 — RENAMES
O nível 66 permite renomear e reagrupar campos já declarados, criando um "apelido" que abrange um conjunto de campos contíguos. É pouco utilizado hoje, mas você pode encontrá-lo em código legado.
01 WS-DATA-COMPLETA. 05 WS-DIA PIC 9(02). 05 FILLER PIC X(01) VALUE '/'. 05 WS-MES PIC 9(02). 05 FILLER PIC X(01) VALUE '/'. 05 WS-ANO PIC 9(04). * Nível 66 cria um apelido para DIA + FILLER + MES 66 WS-DIA-E-MES RENAMES WS-DIA THRU WS-MES.
7. Exemplos de estruturas reais
Veja como Level Numbers modelam situações do mundo real:
01 WS-BOLETO. 05 WS-CEDENTE. 10 WS-CNPJ-CEDENTE PIC 9(14). 10 WS-NOME-CEDENTE PIC X(40). 05 WS-SACADO. 10 WS-CPF-SACADO PIC 9(11). 10 WS-NOME-SACADO PIC X(50). 05 WS-VALORES. 10 WS-VALOR-NOMINAL PIC 9(11)V99. 10 WS-VALOR-JUROS PIC 9(09)V99. 10 WS-VALOR-TOTAL PIC 9(11)V99. 05 WS-VENCIMENTO PIC 9(08). *AAAAMMDD 05 WS-STATUS-BOLETO PIC X(01). 88 BOLETO-ABERTO VALUE 'A'. 88 BOLETO-PAGO VALUE 'P'. 88 BOLETO-VENCIDO VALUE 'V'. 88 BOLETO-CANCELADO VALUE 'C'.
🟣 Para experientes — alinhamento de memória
Em COBOL, campos numéricos com USAGE COMP (binários) têm requisitos de alinhamento na memória. Campos COMP-4 (binário puro) ficam mais eficientes se declarados em posições alinhadas a 2 ou 4 bytes. Para dados de arquivo sequencial isso não importa, mas para WORKING-STORAGE de programas CICS de alto volume, o layout pode impactar performance. O compilador oferece a cláusula SYNCHRONIZED para garantir alinhamento automático.