1. Batch vs. online — o mundo CICS
A diferença fundamental entre um programa batch e um programa CICS está em quem dispara a execução e quanto tempo ela dura:
Característica Batch (JCL) CICS Online
───────────────── ──────────────────────── ────────────────────────────
Iniciado por Scheduler / operador Usuário digitando TRANSID
Duração Minutos a horas Milissegundos a segundos
Interação Nenhuma (arquivo entrada) Tela → programa → tela
Múltiplos usuários Um job por vez Milhares simultâneos
Acesso a arquivos OPEN/READ/CLOSE direto Via comandos EXEC CICS
Acesso a DB2 EXEC SQL direto EXEC SQL (mesma sintaxe)
Termina com STOP RUN EXEC CICS RETURN
Memória Working-Storage persiste Working-Storage reinicia
durante o job a cada transação!
⚠️ Working-Storage não persiste entre telas no CICS
No batch, a Working-Storage existe durante toda a execução do job. No CICS pseudo-conversacional, o programa termina ao enviar cada tela e é recarregado do zero quando o usuário pressiona Enter. Isso significa que todos os campos da Working-Storage voltam ao valor inicial declarado. O dado que precisa sobreviver entre uma tela e a próxima deve ser passado via COMMAREA.
Conceitos-chave do CICS
TRANSID Código de 4 caracteres que identifica uma transação
(ex: CONS, TRAN, EXTX) — o usuário digita isso na tela
TASK Uma execução de uma transação para um usuário
TERMINAL O terminal 3270 do usuário (ID único, ex: TRM1)
MAPSET PDS member com definições de telas BMS compiladas
MAP Uma tela individual dentro de um MAPSET
COMMAREA Área de comunicação passada entre ciclos ou programas
EIB Execute Interface Block — informações da tarefa atual
EIBRESP Código de resposta do último EXEC CICS
EIBCALEN Comprimento da COMMAREA recebida (0 = primeira vez)
2. EXEC CICS — sintaxe básica
Assim como o SQL usa EXEC SQL … END-EXEC, os comandos CICS usam EXEC CICS … END-EXEC. O pré-compilador CICS (DFHECP1$) os transforma em CALLs antes da compilação COBOL.
IDENTIFICATION DIVISION. PROGRAM-ID. PGMCONS. DATA DIVISION. WORKING-STORAGE SECTION. * Copia o EIB (Execute Interface Block) — sempre inclua COPY DFHEIBLK. * Copia definições de resposta CICS (DFHRESP) COPY DFHAID. *teclas de atenção: DFHENTER, DFHPF1…PF24, DFHCLEAR 01 WS-RESP S9(08) COMP. 01 WS-RESP2 S9(08) COMP. LINKAGE SECTION. 01 DFHCOMMAREA PIC X(100). *COMMAREA recebida PROCEDURE DIVISION. 0000-INICIO. IF EIBCALEN = 0 PERFORM 1000-PRIMEIRA-VEZ ELSE PERFORM 2000-RETORNO-USUARIO END-IF. 9999-FIM. EXEC CICS RETURN TRANSID('CONS') COMMAREA(WS-COMMAREA) LENGTH(100) END-EXEC. *aguarda próximo Enter do usuário
✅ COPY DFHEIBLK e DFHAID são obrigatórios
DFHEIBLK gera a estrutura do EIB (Execute Interface Block) com campos como EIBCALEN, EIBTRNID, EIBTERMID, EIBAID e EIBRESP. DFHAID gera constantes para as teclas de atenção (DFHENTER, DFHPF3, DFHCLEAR etc.) que você compara com EIBAID para saber qual tecla o usuário pressionou.
3. Modelo pseudo-conversacional
No modelo conversacional, o programa fica esperando o usuário digitar — isso ocuparia uma task inteira e seus recursos durante segundos (uma eternidade para o mainframe). No modelo pseudo-conversacional, o programa envia a tela, devolve o controle ao CICS com EXEC CICS RETURN TRANSID(…), e só é recarregado quando o usuário pressiona uma tecla:
Usuário digita CONS ──► CICS inicia PGMCONS
│
EIBCALEN = 0? SIM
│
Monta tela vazia
EXEC CICS SEND MAP
EXEC CICS RETURN TRANSID('CONS')
│
Programa termina ◄── CICS suspende task
(Working-Storage liberada)
│
Usuário preenche e ──► CICS reinicia PGMCONS
pressiona ENTER (Working-Storage zerada!)
│
EIBCALEN > 0? SIM — lê COMMAREA
EXEC CICS RECEIVE MAP — lê campos
Valida, processa, atualiza DB2
EXEC CICS SEND MAP (resultado)
EXEC CICS RETURN TRANSID('CONS')
│
Ciclo se repete ◄── CICS suspende task novamente
🦕 Analogia — o garçom que some entre pedidos
Imagine um restaurante onde o garçom anota o pedido, entrega na cozinha e desaparece. Quando o prato fica pronto, qualquer garçom disponível o leva à mesa. O cliente não percebe a diferença — parece que foi o mesmo garçom. No CICS, o "garçom" é a task COBOL: ela entrega a tela (pedido), termina, e é recriada quando o usuário responde. A COMMAREA é a anotação do pedido que o garçom novo recebe para saber o contexto.
4. COMMAREA — passando dados entre ciclos
A COMMAREA é uma área de memória que o CICS preserva entre os ciclos de uma mesma transação, e também entre programas chamados via LINK. No programa, ela é recebida na LINKAGE SECTION como DFHCOMMAREA.
WORKING-STORAGE SECTION. * Estrutura que será passada como COMMAREA 01 WS-COMMAREA. 05 CA-TRANSACAO PIC X(02). *fase: '01'=entrada, '02'=confirma 05 CA-NR-CONTA PIC X(10). 05 CA-VL-SALDO S9(13)V99 COMP-3. 05 CA-NOME X(40). 05 CA-MSG-ERRO X(60). LINKAGE SECTION. 01 DFHCOMMAREA. *CICS preenche com a COMMAREA do ciclo anterior 05 CA-TRANSACAO PIC X(02). 05 CA-NR-CONTA PIC X(10). 05 CA-VL-SALDO S9(13)V99 COMP-3. 05 CA-NOME X(40). 05 CA-MSG-ERRO X(60). PROCEDURE DIVISION. 0000-INICIO. IF EIBCALEN = 0 * Primeira execução — inicializa WS-COMMAREA INITIALIZE WS-COMMAREA MOVE '01' TO CA-TRANSACAO OF WS-COMMAREA ELSE * Retorno do usuário — copia DFHCOMMAREA para WS MOVE DFHCOMMAREA TO WS-COMMAREA END-IF EVALUATE CA-TRANSACAO OF WS-COMMAREA WHEN '01' PERFORM 1000-TELA-ENTRADA WHEN '02' PERFORM 2000-TELA-CONFIRMA WHEN OTHER PERFORM 9000-ERRO-FASE END-EVALUATE EXEC CICS RETURN TRANSID('CONS') COMMAREA(WS-COMMAREA) LENGTH(117) END-EXEC.
💗 EIBCALEN = 0 significa "primeira vez"
EIBCALEN (EIB Communication Area Length) contém o tamanho da COMMAREA recebida. Na primeira execução de uma transação, não há COMMAREA — logo EIBCALEN = 0. Em todas as execuções subsequentes (o usuário pressionou Enter), EIBCALEN > 0 e DFHCOMMAREA tem os dados do ciclo anterior. Checar EIBCALEN = 0 é a forma padrão de detectar a "primeira vez".
5. BMS — mapas de tela
O BMS (Basic Mapping Support) define as telas do terminal 3270. Um mapa BMS é um arquivo de macro assembler que descreve campos, posições, atributos (proteção, cor, intensidade) e é compilado gerando um mapset em PDS. O COBOL não desenha a tela diretamente — envia e recebe o mapa já compilado.
MSCONSUL DFHMSD TYPE=MAP, X
LANG=COBOL, X
MODE=INOUT, X
STORAGE=AUTO, X
TIOAPFX=YES
MPCONSUL DFHMDI SIZE=(24,80), X
LINE=1,COLUMN=1
DFHMDF POS=(1,1),LENGTH=30, X
INITIAL=' CONSULTA DE CONTA CORRENTE', X
ATTRB=(PROT,ASKIP)
DFHMDF POS=(3,1),LENGTH=12, X
INITIAL='NR. CONTA :',ATTRB=(PROT,ASKIP)
CONTAO DFHMDF POS=(3,14),LENGTH=10,ATTRB=(UNPROT,FSET)
DFHMDF POS=(5,1),LENGTH=12, X
INITIAL='TITULAR :',ATTRB=(PROT,ASKIP)
NOMEO DFHMDF POS=(5,14),LENGTH=40,ATTRB=(PROT,ASKIP)
DFHMDF POS=(7,1),LENGTH=12, X
INITIAL='SALDO :',ATTRB=(PROT,ASKIP)
SALDOO DFHMDF POS=(7,14),LENGTH=16,ATTRB=(PROT,ASKIP)
MSGO DFHMDF POS=(23,1),LENGTH=78,ATTRB=(PROT,ASKIP,BRT)
DFHMSD TYPE=FINAL
O DCLGEN do mapa (gerado pela compilação BMS) cria uma estrutura COBOL que o programa usa:
* Estrutura de INPUT (sufixo I) — lida com RECEIVE MAP
01 MPCONSULI.
02 FILLER PIC X(12). *header do mapa
02 CONTAL S9(4) COMP. *comprimento do campo
02 CONTAA X(1). *atributo
02 CONTAI X(10). *valor digitado pelo usuário
… outros campos …
* Estrutura de OUTPUT (sufixo O) — enviada com SEND MAP
01 MPCONSULO.
02 FILLER X(12).
02 CONTAL S9(4) COMP.
02 CONTAA X(1). *você pode mudar atributo em runtime
02 CONTAO X(10). *valor a exibir
02 NOMEO X(40).
02 SALDOO X(16).
02 MSGO X(78). *linha de mensagem
6. SEND MAP e RECEIVE MAP
1000-ENVIA-TELA-ENTRADA. INITIALIZE MPCONSULO MOVE 'INFORME O NUMERO DA CONTA E PRESSIONE ENTER' TO MSGO EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL') FROM(MPCONSULO) ERASE *limpa a tela antes de enviar CURSOR *posiciona cursor no 1o campo UNPROT RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP. 2000-RECEBE-ENTRADA. INITIALIZE MPCONSULI EXEC CICS RECEIVE MAP('MPCONSUL') MAPSET('MSCONSUL') INTO(MPCONSULI) RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP * Verifica qual tecla o usuário pressionou EVALUATE EIBAID WHEN DFHENTER PERFORM 3000-PROCESSA-CONTA WHEN DFHPF3 PERFORM 9900-ENCERRA WHEN DFHCLEAR PERFORM 1000-ENVIA-TELA-ENTRADA WHEN OTHER MOVE 'TECLA INVALIDA' TO MSGO PERFORM 1000-ENVIA-TELA-ENTRADA END-EVALUATE. 3000-PROCESSA-CONTA. MOVE CONTAI TO CA-NR-CONTA *campo digitado pelo usuário * … busca DB2, monta resposta … MOVE CA-NOME TO NOMEO MOVE WS-SALDO-EDIT TO SALDOO MOVE 'CONSULTA REALIZADA COM SUCESSO' TO MSGO EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL') FROM(MPCONSULO) DATAONLY *envia só dados, não relayout RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP.
✅ ERASE vs DATAONLY
- ERASE — limpa a tela inteira antes de enviar o mapa. Use na primeira exibição ou quando quer redesenhar tudo.
- DATAONLY — envia apenas os campos de dados, sem reenviar labels e bordas do mapa. Mais eficiente para atualizar só parte da tela.
- Sem nenhuma opção — envia o mapa completo sobrepondo a tela atual sem limpar primeiro.
7. RESP e EIBRESP — tratando erros
Cada comando EXEC CICS pode gerar uma condição de erro. O mecanismo moderno usa a opção RESP para capturar o código e DFHRESP para comparar:
WORKING-STORAGE SECTION. 01 WS-RESP S9(08) COMP. 01 WS-RESP2 S9(08) COMP. PROCEDURE DIVISION. EXEC CICS READ FILE('CONTA') INTO(WS-REG-CONTA) RIDFLD(WS-NR-CONTA) LENGTH(200) RESP(WS-RESP) RESP2(WS-RESP2) END-EXEC EVALUATE TRUE WHEN WS-RESP = DFHRESP(NORMAL) PERFORM 2000-PROCESSA WHEN WS-RESP = DFHRESP(NOTFND) MOVE 'CONTA NAO ENCONTRADA' TO MSGO PERFORM 1000-ENVIA-TELA-ENTRADA WHEN OTHER PERFORM 9900-ERRO-CICS END-EVALUATE. 9000-TRATA-RESP. IF WS-RESP NOT = DFHRESP(NORMAL) PERFORM 9900-ERRO-CICS END-IF. 9900-ERRO-CICS. EXEC CICS SEND TEXT FROM(WS-MSG-ERRO) LENGTH(80) ERASE FREEKB END-EXEC EXEC CICS RETURN END-EXEC. *sem TRANSID = encerra a transação
| DFHRESP | Quando ocorre | Comando típico |
|---|---|---|
NORMAL | Sucesso | Todos |
NOTFND | Registro não encontrado | READ, DELETE |
DUPREC | Chave duplicada | WRITE |
LENGERR | Tamanho de campo errado | READ, WRITE, SEND |
MAPFAIL | Nenhum dado digitado pelo usuário | RECEIVE MAP |
PGMIDERR | Programa não encontrado no CSD | LINK, XCTL |
DISABLED | Arquivo desabilitado no CICS | READ, WRITE |
INVREQ | Requisição inválida para o recurso | Vários |
8. LINK e XCTL — chamando programas
No CICS, você não usa CALL para chamar outro programa — usa EXEC CICS LINK ou EXEC CICS XCTL:
* LINK — chama e retorna (como CALL) * O programa chamado termina com EXEC CICS RETURN (sem TRANSID) * O controle volta para a próxima linha depois do LINK EXEC CICS LINK PROGRAM('PGMVALID') COMMAREA(WS-COMMAREA) LENGTH(117) RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP * Retorna aqui após PGMVALID terminar IF CA-RETORNO = 'OK' PERFORM 3000-PROCESSA END-IF * XCTL — transfere controle (como GO TO entre programas) * O programa atual termina; PGMMENU assume o controle * Não há retorno para o programa que fez XCTL EXEC CICS XCTL PROGRAM('PGMMENU') COMMAREA(WS-COMMAREA) LENGTH(117) RESP(WS-RESP) END-EXEC.
9. Lendo e gravando VSAM via CICS
No CICS, arquivos VSAM não são abertos com OPEN — eles são definidos no CSD (CICS System Definition) e acessados com comandos EXEC CICS READ/WRITE/REWRITE/DELETE:
WORKING-STORAGE SECTION. 01 WS-REG-CONTA PIC X(200). 01 WS-NR-CONTA PIC X(10). 01 WS-LEN S9(04) COMP VALUE 200. PROCEDURE DIVISION. 3000-LE-CONTA. EXEC CICS READ FILE('CONTA') *nome no CSD INTO(WS-REG-CONTA) RIDFLD(WS-NR-CONTA) *campo chave LENGTH(WS-LEN) RESP(WS-RESP) END-EXEC. 4000-LE-ATUALIZA. EXEC CICS READ FILE('CONTA') INTO(WS-REG-CONTA) RIDFLD(WS-NR-CONTA) LENGTH(WS-LEN) UPDATE *bloqueia para atualização RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP * modifica WS-REG-CONTA… EXEC CICS REWRITE FILE('CONTA') FROM(WS-REG-CONTA) LENGTH(WS-LEN) RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP. 5000-INCLUI-CONTA. EXEC CICS WRITE FILE('CONTA') FROM(WS-REG-CONTA) RIDFLD(WS-NR-CONTA) LENGTH(WS-LEN) RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP. 6000-EXCLUI-CONTA. EXEC CICS DELETE FILE('CONTA') RIDFLD(WS-NR-CONTA) RESP(WS-RESP) END-EXEC PERFORM 9000-TRATA-RESP.
⚠️ READ UPDATE sem REWRITE causa deadlock
Quando você faz READ … UPDATE, o CICS bloqueia o registro. Se o programa terminar (via RETURN) sem ter feito REWRITE ou DELETE, o lock é liberado automaticamente. Mas se outra task tentar ler o mesmo registro com UPDATE enquanto o lock existe, ela ficará esperando — podendo gerar um AKCS (deadlock timeout). Sempre complete o ciclo READ UPDATE → REWRITE/DELETE no mesmo ciclo da transação.
10. Exemplo completo
O programa PGMCONS implementa uma consulta de saldo pseudo-conversacional completa: primeira vez exibe tela vazia, retorno do usuário lê a conta no DB2, exibe saldo formatado ou mensagem de erro:
*----------------------------------------------------------------
* PGMCONS — consulta de saldo (transação CONS)
*----------------------------------------------------------------
IDENTIFICATION DIVISION.
PROGRAM-ID. PGMCONS.
DATA DIVISION.
WORKING-STORAGE SECTION.
EXEC SQL INCLUDE SQLCA END-EXEC
COPY DFHEIBLK.
COPY DFHAID.
COPY MPCONSUL. *mapa BMS (gera MPCONSULI e MPCONSULO)
COPY DCCONTA. *DCLGEN da tabela CONTA
01 WS-RESP S9(08) COMP.
01 WS-SALDO-EDIT Z.ZZZ.ZZZ,99-.
01 WS-COMMAREA.
05 CA-FASE PIC X(02).
05 CA-NR-CONTA PIC X(10).
LINKAGE SECTION.
01 DFHCOMMAREA.
05 CA-FASE PIC X(02).
05 CA-NR-CONTA PIC X(10).
PROCEDURE DIVISION.
0000-INICIO.
IF EIBCALEN = 0
INITIALIZE WS-COMMAREA
MOVE '01' TO CA-FASE
ELSE
MOVE DFHCOMMAREA TO WS-COMMAREA
END-IF
EVALUATE CA-FASE
WHEN '01' PERFORM 1000-TELA-INICIAL
WHEN '02' PERFORM 2000-PROCESSA-ENTRADA
END-EVALUATE
EXEC CICS RETURN
TRANSID(EIBTRNID)
COMMAREA(WS-COMMAREA)
LENGTH(12)
END-EXEC.
1000-TELA-INICIAL.
INITIALIZE MPCONSULO
MOVE 'INFORME O NUMERO DA CONTA' TO MSGO
MOVE '02' TO CA-FASE
EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
FROM(MPCONSULO) ERASE CURSOR RESP(WS-RESP)
END-EXEC
PERFORM 9000-TRATA-RESP.
2000-PROCESSA-ENTRADA.
EVALUATE EIBAID
WHEN DFHPF3
EXEC CICS RETURN END-EXEC
WHEN DFHENTER
CONTINUE
WHEN OTHER
MOVE 'USE ENTER OU PF3' TO MSGO
EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
FROM(MPCONSULO) DATAONLY RESP(WS-RESP)
END-EXEC
PERFORM 9000-TRATA-RESP
STOP RUN
END-EVALUATE
EXEC CICS RECEIVE MAP('MPCONSUL') MAPSET('MSCONSUL')
INTO(MPCONSULI) RESP(WS-RESP)
END-EXEC
IF WS-RESP = DFHRESP(MAPFAIL)
MOVE 'INFORME O NUMERO DA CONTA' TO MSGO
EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
FROM(MPCONSULO) DATAONLY RESP(WS-RESP)
END-EXEC
STOP RUN
END-IF
PERFORM 9000-TRATA-RESP
MOVE CONTAI TO CA-NR-CONTA
PERFORM 3000-BUSCA-DB2.
3000-BUSCA-DB2.
EXEC SQL
SELECT NM_TITULAR, VL_SALDO, CD_STATUS
INTO :NM-TITULAR, :VL-SALDO, :CD-STATUS
FROM SCHEMA1.CONTA
WHERE NR_CONTA = :CA-NR-CONTA
END-EXEC
EVALUATE TRUE
WHEN SQLCODE = 0
MOVE NM-TITULAR-TEXT TO NOMEO
MOVE VL-SALDO TO WS-SALDO-EDIT
MOVE WS-SALDO-EDIT TO SALDOO
MOVE 'CONSULTA REALIZADA' TO MSGO
WHEN SQLCODE = +100
MOVE 'CONTA NAO ENCONTRADA' TO MSGO
WHEN OTHER
MOVE 'ERRO AO CONSULTAR BANCO DE DADOS' TO MSGO
END-EVALUATE
EXEC CICS SEND MAP('MPCONSUL') MAPSET('MSCONSUL')
FROM(MPCONSULO) DATAONLY CURSOR RESP(WS-RESP)
END-EXEC
PERFORM 9000-TRATA-RESP
MOVE '01' TO CA-FASE. *próximo Enter = nova consulta
9000-TRATA-RESP.
IF WS-RESP NOT = DFHRESP(NORMAL)
EXEC CICS ABEND ABCODE('CSER') END-EXEC
END-IF.
11. Erros comuns e abends CICS
Abends CICS mais frequentes
| Abend | Causa | Como corrigir |
|---|---|---|
ASRA | Program check (S0C7, S0C4 etc.) dentro da task CICS | Analisar CEEDUMP com offset da instrução falha |
AICA | Loop infinito — task excedeu runaway interval | Encontrar e corrigir o PERFORM sem saída |
AKCS | Deadlock — timeout aguardando recurso bloqueado | Revisar ordem de locks; usar READ UPDATE apenas quando necessário |
AFCA | Erro de acesso a arquivo VSAM | Verificar RESP/RESP2 e definição do arquivo no CSD |
AEXN | EXEC CICS ABEND chamado pelo programa | Ver ABCODE gerado pelo programa para identificar ponto |
AEY9 | DB2 não disponível ou não conectado à region CICS | Verificar attachment DB2/CICS e nome do plan |
1. Usar STOP RUN em programa CICS
* ❌ STOP RUN encerra a região CICS inteira — não use! IF WS-ERRO STOP RUN * ✅ Encerre com EXEC CICS RETURN (sem TRANSID p/ fechar task) IF WS-ERRO EXEC CICS SEND TEXT FROM(WS-MSG) LENGTH(80) ERASE END-EXEC EXEC CICS RETURN END-EXEC
2. OPEN/CLOSE de arquivo no CICS
* ❌ Comandos COBOL nativos de arquivo não funcionam no CICS OPEN INPUT ARQ-CONTA READ ARQ-CONTA INTO WS-REG * ✅ Use EXEC CICS READ com nome do arquivo definido no CSD EXEC CICS READ FILE('CONTA') INTO(WS-REG) RIDFLD(WS-CHAVE) LENGTH(200) RESP(WS-RESP) END-EXEC
3. Working-Storage não persiste — usar COMMAREA
WORKING-STORAGE SECTION. 01 WS-CONTA-PESQ PIC X(10) VALUE SPACES. PROCEDURE DIVISION. * 1o ciclo: usuário informa conta '1234567890' MOVE CONTAI TO WS-CONTA-PESQ *guardou na WS EXEC CICS RETURN TRANSID('CONS') END-EXEC * 2o ciclo: WS-CONTA-PESQ = SPACES! (reiniciou) * ❌ Dado perdido entre ciclos * ✅ Grave na COMMAREA antes do RETURN: MOVE CONTAI TO CA-NR-CONTA EXEC CICS RETURN TRANSID('CONS') COMMAREA(WS-COMMAREA) LENGTH(12) END-EXEC
4. MAPFAIL não tratado causa ASRA
EXEC CICS RECEIVE MAP('MPCONSUL') MAPSET('MSCONSUL') INTO(MPCONSULI) RESP(WS-RESP) END-EXEC * ❌ Se não checar MAPFAIL e tentar usar MPCONSULI, pode ASRA MOVE CONTAI TO CA-NR-CONTA * ✅ Trate MAPFAIL antes de usar os campos do mapa IF WS-RESP = DFHRESP(MAPFAIL) MOVE 'PREENCHA OS CAMPOS OBRIGATORIOS' TO MSGO PERFORM 1000-REENVIA-TELA STOP RUN END-IF