1. ADDRESS — escolhendo o ambiente de execução

O REXX pode enviar comandos para diferentes ambientes. O ADDRESS define qual ambiente recebe os comandos que não são instruções REXX:

/* Chamar comando TSO */ ADDRESS TSO 'LISTDS MINHA.PDS MEMBERS' /* Chamar serviço ISPF */ ADDRESS ISPEXEC 'VGET (ZUSER) SHARED' /* Mudar o ambiente padrão para toda a sessão */ ADDRESS TSO 'LISTCAT LEVEL(USUARIO) NAME' /* vai para TSO */ 'STATUS' /* também vai para TSO */ /* Voltar ao padrão (TSO é o padrão em ambiente TSO) */ ADDRESS

💡 Aspas simples nos comandos TSO

Sempre coloque o comando TSO entre aspas simples: ADDRESS TSO 'LISTCAT ...'. Sem aspas, o REXX tenta interpretar as palavras como instrução REXX em vez de passar para o TSO. Quando o comando contém nomes de datasets com aspas (ex.: LISTDS 'USUARIO.DS'), use aspas duplas ao redor e simples dentro: ADDRESS TSO "LISTDS 'USUARIO.DS'".

2. Capturando RC de comandos TSO

Após qualquer ADDRESS TSO, a variável especial RC contém o return code do comando. Use isso para tratar erros:

ADDRESS TSO 'LISTDS USUARIO.MEUS.DADOS' IF RC \= 0 THEN DO SAY 'Dataset não encontrado. RC=' RC EXIT 8 END SAY 'Dataset existe.'
/* Submeter job e verificar se foi aceito */ ADDRESS TSO "SUBMIT 'USUARIO.MEU.JCL(CALCJOB)'" SELECT WHEN RC = 0 THEN SAY 'Job submetido com sucesso' WHEN RC = 4 THEN SAY 'Aviso na submissão — verifique' OTHERWISE SAY 'Falha na submissão. RC=' RC END

3. OUTTRAP — capturando saída de comandos

O OUTTRAP redireciona a saída de um comando TSO para um stem (array) REXX em vez de exibi-la na tela. Isso permite processar a saída programaticamente:

/* Capturar saída do LISTCAT em um stem */ CALL OUTTRAP 'SAIDA.' /* capturar em SAIDA.1, SAIDA.2... */ ADDRESS TSO 'LISTCAT LEVEL(USUARIO) NAME' CALL OUTTRAP 'OFF' /* parar captura */ SAY 'Linhas capturadas:' SAIDA.0 /* Processar cada linha */ DO I = 1 TO SAIDA.0 LINHA = SAIDA.I IF POS('NONVSAM', LINHA) > 0 THEN SAY 'Dataset sequencial:' STRIP(LINHA) END

🦕 Analogia — OUTTRAP como pipe do shell

No Linux você faz ls | grep ".txt" para filtrar a saída de um comando. No REXX com OUTTRAP você faz o mesmo: captura a saída do comando TSO no stem, depois percorre o stem com um loop e filtra as linhas que interessam. É o modelo de "pipeline" do mainframe.

4. LISTDSI — informações de datasets

A função LISTDSI é específica do REXX em TSO e retorna informações de um dataset em variáveis REXX prontas para usar — sem precisar parsear saída de texto:

RESULT = LISTDSI("'USUARIO.MEUS.DADOS'" DIRECTORY) IF RESULT = 0 THEN DO SAY 'Dataset:' SYSDSNAME SAY 'DSORG:' SYSDSORG SAY 'RECFM:' SYSRECFM SAY 'LRECL:' SYSLRECL SAY 'Membros:' SYSMEMBERS SAY 'Usado %:' SYSUSED END ELSE SAY 'Erro LISTDSI:' SYSREASON

Principais variáveis populadas pelo LISTDSI:

VariávelConteúdo
SYSDSNAMENome completo do dataset
SYSDSORGPO, PS, VSAM...
SYSRECFMFB, VB, U...
SYSLRECLLogical record length
SYSBLKSIZEBlock size
SYSMEMBERSNúmero de membros (PDS)
SYSUSEDPercentual de espaço usado
SYSCREATEData de criação
SYSREFDATEData do último acesso

5. ISPEXEC — serviços ISPF

Com ADDRESS ISPEXEC você acessa os serviços do ISPF de dentro do REXX — lê e escreve variáveis do pool, exibe mensagens e navega entre painéis:

/* Ler variável do pool ISPF (ex: user ID) */ ADDRESS ISPEXEC 'VGET (ZUSER ZDATE ZTIME) SHARED' SAY 'Usuário:' ZUSER SAY 'Data:' ZDATE /* Escrever variável no pool */ MINHAVAR = 'valor exportado' ADDRESS ISPEXEC 'VPUT (MINHAVAR) PROFILE' /* Exibir mensagem na tela atual */ ADDRESS ISPEXEC 'SETMSG MSG(ISRZ001)' /* Navegar para um painel ISPF */ ADDRESS ISPEXEC 'DISPLAY PANEL(MEUPANEL)'

💡 ZUSER e outras variáveis de sistema

O ISPF mantém dezenas de variáveis de sistema no pool compartilhado — ZUSER (user ID), ZDATE (data), ZTIME (hora), ZSYSID (ID do sistema), ZPFKEY (última PF key pressionada). Use VGET para lê-las. São ideais para personalizar execs e registrar logs com contexto do usuário.

6. Lendo datasets linha a linha com LMOPEN/LMGET

Os serviços LM (Library Management) do ISPF permitem ler e escrever datasets linha a linha de dentro do REXX — sem precisar de JCL ou OUTTRAP. Ideal para processar arquivos de configuração ou gerar relatórios:

/* Ler dataset linha a linha */ ADDRESS ISPEXEC "LMOPEN DATAID(MEUDD) OPTION(INPUT)" /* Alocar o dataset antes de abrir */ ADDRESS ISPEXEC "LMINIT DATAID(MEUDD) DATASET('USUARIO.ENTRADA')" ADDRESS ISPEXEC "LMOPEN DATAID(MEUDD) OPTION(INPUT)" DO FOREVER ADDRESS ISPEXEC "LMGET DATAID(MEUDD) MODE(INVAR) DATALOC(LINHA) DATALEN(LLEN)" IF RC = 8 THEN LEAVE /* RC=8 = fim do arquivo */ SAY STRIP(LINHA, 'T') /* processar cada linha */ END ADDRESS ISPEXEC "LMCLOSE DATAID(MEUDD)" ADDRESS ISPEXEC "LMFREE DATAID(MEUDD)"

✅ Sempre feche e libere o DATAID

Assim como arquivos em qualquer linguagem, DATAIDs abertos com LMINIT precisam ser fechados com LMCLOSE e liberados com LMFREE. Se o exec terminar sem liberar, o dataset pode ficar alocado na sessão TSO do usuário, impedindo outros jobs de acessá-lo. Use SIGNAL ON ERROR para garantir que o cleanup acontece mesmo em caso de erro.