1. MOVE — sintaxe básica

O MOVE copia o valor de uma origem para um ou mais destinos. A origem não é alterada.

COBOL Sintaxe do MOVE
       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.

COBOL MOVE alfanumérico
       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.

COBOL MOVE numérico
       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:

COBOL MOVE entre tipos
       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:

COBOL MOVE para vários campos
       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.

COBOL MOVE de grupo
       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.

COBOL MOVE CORRESPONDING
       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.

COBOL INITIALIZE básico
       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:

COBOL INITIALIZE REPLACING
       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

COBOL Comparação
             * 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

COBOL Verbos aritméticos
             * 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):

COBOL COMPUTE
       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

COBOL ON SIZE ERROR
       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

COBOL Figurativos perigosos
             * 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

COBOL Espaços 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

COBOL ADD TO vs ADD GIVING
             * 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.