1. MOVE — sintaxe básica
O MOVE copia o valor de uma origem para um ou mais destinos. A origem não é alterada.
MOVE origem TO destino * Origem pode ser: literal, variável ou figurativo MOVE 'JOAO' TO WS-NOME *literal texto MOVE 100 TO WS-VALOR *literal número MOVE WS-VALOR TO WS-COPIA *variável para variável MOVE ZEROS TO WS-CONTADOR *figurativo: zera campo MOVE SPACES TO WS-NOME *figurativo: espaços
🦕 Analogia — MOVE é um formulário carbono
Pense no MOVE como aqueles formulários em papel carbono dos anos 80: você escreve na primeira via e o valor aparece nas outras. A origem continua igual, e o destino recebe uma cópia. Simples assim.
2. Como o MOVE trata tipos diferentes
Aqui mora a maior parte das pegadinhas. O COBOL tem regras bem definidas sobre o que acontece quando origem e destino têm tipos ou tamanhos diferentes.
Campo alfanumérico → alfanumérico (PIC X → PIC X)
O valor é copiado da esquerda para a direita. Se o destino for maior, o excesso é preenchido com espaços à direita. Se for menor, o valor é truncado à direita.
WORKING-STORAGE SECTION. 01 WS-ORIGEM PIC X(10) VALUE 'COBOL'. 01 WS-MAIOR PIC X(15). 01 WS-MENOR PIC X(03). PROCEDURE DIVISION. MOVE WS-ORIGEM TO WS-MAIOR * WS-MAIOR = 'COBOL ' (5 + 10 espaços) MOVE WS-ORIGEM TO WS-MENOR * WS-MENOR = 'COB' (truncado à direita)
⚠️ Atenção — truncamento silencioso
O COBOL não avisa quando trunca um campo alfanumérico. Se você mover 'PRIMAVERA' para um PIC X(04), vai ficar 'PRIM' sem nenhum erro em tempo de execução. Sempre confira os tamanhos dos campos.
Campo numérico → numérico (PIC 9 → PIC 9)
O valor é alinhado à direita. Se o destino for maior, zeros são adicionados à esquerda. Se for menor, dígitos são truncados à esquerda.
WORKING-STORAGE SECTION. 01 WS-VALOR PIC 9(05) VALUE 12345. 01 WS-MAIOR PIC 9(08). 01 WS-MENOR PIC 9(03). PROCEDURE DIVISION. MOVE WS-VALOR TO WS-MAIOR * WS-MAIOR = 00012345 (zeros à esquerda) MOVE WS-VALOR TO WS-MENOR * WS-MENOR = 345 (perde os dígitos à esquerda!)
💗 Para iniciantes — X vs. 9 no MOVE
Alfanumérico alinha à esquerda e trunca à direita. Numérico alinha à direita e trunca à esquerda. Um jeito fácil de lembrar: numérico funciona igual a uma calculadora — o que importa são os dígitos mais à direita.
MOVE entre tipos diferentes
Você pode mover um numérico para alfanumérico e vice-versa, mas com cuidado:
01 WS-NUM PIC 9(05) VALUE 42. 01 WS-TEXT PIC X(05). 01 WS-BACK PIC 9(05). MOVE WS-NUM TO WS-TEXT *WS-TEXT = '00042' MOVE WS-TEXT TO WS-BACK *WS-BACK = 42 (ok, era número) * Perigo: mover texto com letras para campo numérico MOVE 'ERRO' TO WS-BACK *ABEND! letras num PIC 9
3. MOVE para múltiplos destinos
O COBOL permite mover o mesmo valor para vários campos de uma vez — útil para inicializar ou replicar dados:
MOVE ZEROS TO WS-TOTAL WS-CONTADOR WS-SOMA MOVE SPACES TO WS-NOME WS-ENDERECO WS-CIDADE
✅ Dica — evite linhas longas demais
Nas colunas 72+ o COBOL ignora o conteúdo. Ao listar múltiplos destinos, quebre a linha e alinhe os nomes verticalmente — fica mais legível e evita que algum campo seja cortado silenciosamente.
4. MOVE em variáveis de grupo
Quando o destino é uma variável de grupo (nível 01 com subordinados), o COBOL trata o grupo como um campo PIC X do tamanho total. O valor é copiado byte a byte, sem considerar a estrutura interna.
WORKING-STORAGE SECTION. 01 WS-REGISTRO-A. 05 WS-NOME-A PIC X(20). 05 WS-CPF-A PIC X(11). 01 WS-REGISTRO-B. 05 WS-NOME-B PIC X(20). 05 WS-CPF-B PIC X(11). PROCEDURE DIVISION. MOVE WS-REGISTRO-A TO WS-REGISTRO-B * Copia os 31 bytes inteiros: nome + CPF de uma vez
🦕 Analogia — MOVE de grupo é xerox de documento
Mover um grupo é como tirar xerox de uma folha inteira. O conteúdo é copiado igualzinho, campo por campo, sem o COBOL "entender" o que está dentro. Muito útil para duplicar registros inteiros com um único comando.
5. MOVE CORRESPONDING
O MOVE CORRESPONDING (ou MOVE CORR) copia automaticamente os campos que têm o mesmo nome entre dois grupos — sem precisar listar cada campo individualmente.
WORKING-STORAGE SECTION. 01 WS-CLIENTE. 05 NOME PIC X(40). 05 CPF PIC X(11). 05 SALDO PIC 9(12)V99. 01 WS-EXTRATO. 05 NOME PIC X(40). 05 CPF PIC X(11). 05 DATA PIC X(08). *só existe em WS-EXTRATO PROCEDURE DIVISION. MOVE CORRESPONDING WS-CLIENTE TO WS-EXTRATO * Copia NOME e CPF (existem nos dois grupos) * SALDO e DATA são ignorados (não têm correspondente)
🟣 Para quem já programa — MOVE CORR em produção
O MOVE CORRESPONDING é conveniente, mas use com critério em sistemas bancários. Se alguém renomear um campo em um dos grupos, o CORR para de copiar silenciosamente e você pode perder dados sem nenhum erro. Em código crítico, prefira MOVEs explícitos campo a campo — eles são mais verbosos, mas rastreáveis.
6. INITIALIZE
O INITIALIZE limpa uma variável ou grupo para seu valor padrão: espaços para campos alfanuméricos (PIC X) e zeros para campos numéricos (PIC 9). É o jeito mais seguro de "resetar" variáveis antes de reutilizá-las.
WORKING-STORAGE SECTION. 01 WS-CLIENTE. 05 WS-NOME PIC X(40). 05 WS-IDADE PIC 9(03). 05 WS-ATIVO PIC X(01). PROCEDURE DIVISION. INITIALIZE WS-CLIENTE * WS-NOME = ' ' (40 espaços) * WS-IDADE = 000 * WS-ATIVO = ' ' (espaço, pois é PIC X)
INITIALIZE com REPLACING
É possível customizar o valor de inicialização para cada tipo:
INITIALIZE WS-CLIENTE REPLACING ALPHABETIC BY '*' ALPHANUMERIC BY SPACES NUMERIC BY -1 * Útil para marcar campos não preenchidos com valor sentinela
INITIALIZE vs. MOVE SPACES/ZEROS
* Zerando grupo inteiro com MOVE — precisa saber o tipo MOVE SPACES TO WS-NOME WS-ATIVO MOVE ZEROS TO WS-IDADE * Com INITIALIZE — um comando limpa tudo corretamente INITIALIZE WS-CLIENTE
✅ Dica — prefira INITIALIZE para grupos
Quando você precisa zerar um grupo com campos mistos (X e 9), o INITIALIZE é mais seguro e legível do que uma série de MOVE SPACES e MOVE ZEROS. Ele sabe o tipo de cada campo e aplica o valor correto automaticamente.
7. Operações aritméticas
COBOL tem verbos aritméticos próprios e também o COMPUTE para expressões mais complexas.
Verbos aritméticos: ADD, SUBTRACT, MULTIPLY, DIVIDE
* ADD: soma ADD 10 TO WS-CONTADOR *WS-CONTADOR = WS-CONTADOR + 10 ADD WS-A WS-B TO WS-TOTAL *WS-TOTAL = WS-TOTAL + A + B ADD WS-A TO WS-B GIVING WS-RESULTADO *WS-RESULTADO = A + B (A e B intactos) * SUBTRACT: subtrai SUBTRACT 1 FROM WS-CONTADOR *decrementa SUBTRACT WS-DESC FROM WS-PRECO GIVING WS-LIQUIDO * MULTIPLY: multiplica MULTIPLY WS-QTD BY WS-PRECO GIVING WS-SUBTOTAL * DIVIDE: divide DIVIDE WS-TOTAL BY 12 GIVING WS-MEDIA REMAINDER WS-RESTO
COMPUTE — expressões completas
O COMPUTE permite escrever expressões matemáticas de forma mais natural, combinando operadores + - * / ** (potência):
COMPUTE WS-RESULTADO = (WS-A + WS-B) * WS-C / 100 COMPUTE WS-JUROS = WS-PRINCIPAL * (1 + WS-TAXA) ** WS-MESES * ROUNDED arredonda o resultado para o tamanho do campo COMPUTE WS-MEDIA ROUNDED = (WS-A + WS-B + WS-C) / 3
ON SIZE ERROR — tratando estouro
COMPUTE WS-RESULTADO = WS-A * WS-B ON SIZE ERROR MOVE 'OVERFLOW' TO WS-ERRO PERFORM 9000-TRATA-ERRO NOT ON SIZE ERROR PERFORM 2000-PROCESSA-RESULTADO END-COMPUTE
🟣 Para quem já programa — COMPUTE vs. verbos aritméticos
Em sistemas bancários, você vai encontrar ambos. Os verbos individuais (ADD, SUBTRACT) são mais autodocumentados em operações simples — ADD 1 TO WS-CONTADOR é mais legível que COMPUTE WS-CONTADOR = WS-CONTADOR + 1. Reserve o COMPUTE para fórmulas com múltiplas operações, onde a precedência de operadores importa.
8. Erros comuns e armadilhas
1. Mover HIGH-VALUES ou LOW-VALUES para campo numérico
* HIGH-VALUES coloca X'FF' em cada byte — inválido num PIC 9 MOVE HIGH-VALUES TO WS-CHAVE-ALFANUM *OK — PIC X MOVE HIGH-VALUES TO WS-CONTADOR *PERIGO — PIC 9: ABEND
2. MOVE SPACES em campo numérico
* Espaço não é zero! Pode causar S0C7 (data exception) MOVE SPACES TO WS-VALOR *ERRADO se WS-VALOR é PIC 9 MOVE ZEROS TO WS-VALOR *CORRETO * Ou use INITIALIZE para deixar o COBOL decidir: INITIALIZE WS-VALOR *coloca zero em PIC 9 automaticamente
3. Esquecer o GIVING e sobrescrever a origem
* ADD TO modifica o destino somando a ele ADD WS-A TO WS-B *WS-B = WS-B + WS-A (WS-B muda!) * ADD GIVING preserva origem e destino ADD WS-A TO WS-B GIVING WS-C *WS-C = WS-A + WS-B (A e B intactos)
⚠️ O erro clássico do S0C7
O abend S0C7 (Data Exception) é o erro mais comum em COBOL e quase sempre significa que um campo numérico (PIC 9) está com conteúdo inválido — espaços, letras ou HIGH-VALUES. Quando aparecer, verifique se algum MOVE SPACES ou leitura de arquivo colocou dado inválido num campo numérico antes de usá-lo em cálculo.