Subrotinas Gravadas em REXX

Nesta seção:

Como:

Referência:

A solicitação pode chamar uma surotina codificada em REXX. Estas subrotinas, também chamadas de macros FUSREXX, fornecem uma opção 4GL para as linguagens com suporte para subrotinas gravadas pelo usuário.

As subrotinas REXX possuem suporte no ambiente z/OS. Uma subrotina REXX contém o código de fonte REXX. O código REXX compilado não possui suporte.

Uma subrotina REXX contém o código de fonte REXX. O código REXX compilado não possui suporte.

As subrotinas REXX não são necessariamente as mesmas em todos os ambientes operacionais. Portanto, alguns dos exemplos podem utilizar funções REXX que não se encontram disponíveis no seu ambiente.

Devido aos requerimentos de CPU, o uso de subrotinas REXX em trabalhos de produção grandes devem ser monitorados com cuidado.

Para obter mais informações sobre as subrotinas REXX, consulte a sua documentação REXX.


Topo da página

x
Referência: Como Armazenar e Pesquisar uma Subrotina REXX

Para armazenar uma subrotina REXX, o DDNAME FUSREXX deve ser alocado em um PDS. Esta biblioteca é pesquisada antes de outras bibliotecas do z/OS.

A ordem de pesquisa para uma subrotina REXX é:

  1. FUSREXX.
  2. Ordem de pesquisa padrão do z/OS.

Topo da página

x
Sintaxe: Como Chamar uma Subrotina REXX
DEFINE FILE filename
						 
fieldname/{An|In} = subname(inlen1, inparm1, ..., outlen, outparm);
END

ou

{DEFINE|COMPUTE} fieldname/{An|In} = subname(inlen1, inparm1, ...,  
outlen, outparm);

ou

-SET &var = subname(inlen1, inparm1, ..., outlen, outparm);

onde:

fieldname

É o campo que contém o resultado.

An, In

É o formato do campo que contém o resultado.

subname

É o nome da subrotina REXX.

inlen1, inparm1 ...

São parâmetros de entrada. Cada parâmetro é formado por um valor de comprimento e um de parâmetro alfanumérico. Você pode fornecer o valor, o nome de um campo alfanumérico que contém o valor ou uma expressão que resulta no valor. Há suporte para até 13 pares de parâmetros de entrada. Cada valor de parâmetro pode ter até 256 bytes.

O Dialogue Manager converte argumentos numéricos para o formato de precisão dupla com ponto flutuante. Portanto, é possível passar apenas parâmetros de entrada numéricos para uma subrotina REXX utilizando -SET.

outlen, outparm

É o par de parâmetros de saída, que é formado por um comprimento e um resultado. Na maioria dos casos, o resultado deve ser alfanumérico, mas número inteiros também são suportados. O resultado pode ser um campo ou uma variável do Dialogue Manager que contém o valor, ou o formato do valor entre aspas simples. O valor de retorno pode ter, no mínimo, um byte e, no máximo (para valores alfanuméricos), 256 bytes.

Observação: Se o valor retornado for um número inteiro, outlen deverá ser 4, pois o WebFOCUS reserva quatro bytes para campos inteiros.

&var

É o nome da variável do Dialogue Manager que contém o resultado.



Exemplo: Como Exibir o Dia da Semana

A subrotina REXX DOW retorna o dia da semana que corresponde à data de contratação de um funcionário. A rotina contém um par de parâmetros de entrada e um de campo de retorno.

DEFINE FILE EMPLOYEE 
1. AHDT/A6 = EDIT(HIRE_DATE) ; 
2. DAY_OF_WEEK/A9 WITH AHDT = DOW(6, AHDT, 9, DAY_OF_WEEK);
   END
TABLE FILE EMPLOYEE
PRINT LAST_NAME HIRE_DATE DAY_OF_WEEK
END

O procedimento processa da seguinte forma:

  1. A função EDIT converte HIRE_DATE para o formato alfanumérico e armazena o resultado em um campo com o formato A6.
  2. O resultado é armazenado no campo DAY_OF_THE_WEEK e pode ter até nove bytes.

A saída é:

LAST_NAME        HIRE_DATE  DAY_OF_WEEK
---------        ---------  -----------
STEVENS           80/06/02  Monday
SMITH             81/07/01  Wednesday
JONES             82/05/01  Saturday
SMITH             82/01/04  Monday
BANNING           82/08/01  Sunday
IRVING            82/01/04  Monday
ROMANS            82/07/01  Thursday
MCCOY             81/07/01  Wednesday
BLACKWOOD         82/04/01  Thursday
MCKNIGHT          82/02/02  Tuesday
GREENSPAN         82/04/01  Thursday
CROSS             81/11/02  Monday

A subrotina REXX aparece abaixo. Ela lê a data de entrada, a reformata para MM/DD/YY e retorna o dia da semana utilizando uma chamada REXX DATE.

/* DOW routine. Return WEEKDAY from YYMMDD format date */
Arg ymd .
Return Date('W',Translate('34/56/12',ymd,'123456'),'U')


Exemplo: Como Passar Diversos Argumentos para uma Subrotina REXX

A subrotina REXX INTEREST possui quatro parâmetros de entrada.

DEFINE FILE EMPLOYEE 
1. AHDT/A6     = EDIT(HIRE_DATE); 
2. ACSAL/A12   = EDIT(CURR_SAL); 
3. DCSAL/D12.2 = CURR_SAL; 
4. PV/A12    = INTEREST(6, AHDT, 6, '&YMD', 3, '6.5', 12, ACSAL, 12, PV);
   END
 
TABLE FILE EMPLOYEE
PRINT LAST_NAME FIRST_NAME HIRE_DATE DCSAL PV
END

O procedimento processa da seguinte forma:

  1. EDIT converte HIRE_DATE para o formato alfanuméricos e armazena o resultado em AHDT.
  2. EDIT converte CURR_SAL para o formato alfanuméricos e armazena o resultado em ACSAL.
  3. CURR_SAL é convertido para um campo de precisão dupla com ponto flutuante que inclui vírgulas, e o resultado é armazenado em DCSAL.
  4. O segundo campo de entrada possui seis bytes. Os dados são passados como uma variável de caractere &YMD no formato YYMMDD.

    O terceiro campo de entrada é um valor de caractere de 6,5 com três bytes para acomodar a vírgula na string de caracteres.

    O quarto campo de entrada possui 12 bytes. Ele passa o campo de caracteres ACSAL.

    O campo de retorno possui até 12 bytes de comprimento, e seu nome é PV.

A saída é:

LAST_NAME        FIRST_NAME  HIRE_DATE           DCSAL            PV
---------        ----------  ---------           -----            --
STEVENS          ALFRED       80/06/02       11,000.00      14055.14
SMITH            MARY         81/07/01       13,200.00      15939.99
JONES            DIANE        82/05/01       18,480.00      21315.54
SMITH            RICHARD      82/01/04        9,500.00      11155.60
BANNING          JOHN         82/08/01       29,700.00      33770.53
IRVING           JOAN         82/01/04       26,862.00      31543.35
ROMANS           ANTHONY      82/07/01       21,120.00      24131.19
MCCOY            JOHN         81/07/01       18,480.00      22315.99
BLACKWOOD        ROSEMARIE    82/04/01       21,780.00      25238.25
MCKNIGHT         ROGER        82/02/02       16,100.00      18822.66
GREENSPAN        MARY         82/04/01        9,000.00      10429.03
CROSS            BARBARA      81/11/02       27,062.00      32081.82

A subrotina REXX aparece abaixo. O comando REXX Format é utilizado para formatar o valor de retorno.

/* Simple INTEREST program. dates are yymmdd format  */
Arg start_date,now_date,percent,open_balance, .
 
begin = Date('B',Translate('34/56/12',start_date,'123456'),'U')
stop  = Date('B',Translate('34/56/12',now_date,'123456'),'U')
valnow = open_balance * (((stop - begin) * (percent / 100)) / 365)
 
Return Format(valnow,9,2)


Exemplo: Como Aceitar Diversos Tokens em um Parâmetro

A subrotina REXX pode aceitar diversos tokens em um parâmetro. O procedimento a seguir passa as informações do funcionário (PAY_DATE e MO_PAY) como tokens separados no primeiro parâmetro. Ele passa três parâmetros de entrada e um campo de retorno.

DEFINE FILE EMPLOYEE 
1.  COMPID/A256 = FN | ' ' | LN | ' ' |  DPT | ' ' | EID ; 
2.  APD/A6 = EDIT(PAY_DATE); 
3.  APAY/A12 = EDIT(MO_PAY); 
4.  OK4RAISE/A1 = OK4RAISE(256, COMPID, 6, APD, 12, APAY, 1, OK4RAISE);
    END
 
TABLE FILE EMPLOYEE
PRINT EMP_ID FIRST_NAME LAST_NAME DEPARTMENT
IF OK4RAISE EQ '1'
END

O procedimento processa da seguinte forma:

  1. COMPID é a concatenação de diversos campos de caracteres passados como o primeiro parâmetro e armazenados em um campo com o formato A256. Cada um dos outros parâmetros é um argumento único.
  2. EDIT converte PAY_DATE para o formato alfanumérico.
  3. EDIT converte MO_PAY para o formato alfanumérico.
  4. OK4RAISE é executado, e o resultado é armazenado em OK4RAISE.

A saída é:

EMP_ID     FIRST_NAME         LAST_NAME      DEPARTMENT
------     ----------         ---------      ----------
071382660  ALFRED             STEVENS        PRODUCTION

A subrotina REXX aparece abaixo. Vírgulas separam parâmetros FUSREXX. O comando ARG especifica diversos nomes de variáveis antes da primeira vírgula e, portanto, separa o primeiro parâmetro FUSREXX em variáveis REXX separadas utilizando espaços em branco como delimitadores entre as variáveis.

/* OK4RAISE routine. Parse separate tokens in the 1st parm, */
/* then more parms */
 
Arg fname lname dept empid,  pay_date,  gross_pay, .
 
If dept = 'PRODUCTION' & pay_date < '820000'
Then retvalue = '1'
Else retvalue = '0'
 
Return retvalue

As subrotinas REXX devem utilizar a subrotina REXX RETURN para retornar dados. REXX EDIT é aceitável, mas é normalmente utilizado para finalizar um EXEC, não uma função.

Correct
/* Some FUSREXX function */
Arg input
some rexx process ...
Return data_to_WebFOCUS
Not as Clear
/* Another FUSREXX function */
Arg input
some rexx process ...
Exit 0


x
Formatos e Subrotinas REXX

Uma subrotina REXX necessita de dados de entrada para possuir o formato alfanumérico. A maioria das saídas é retornada em formato alfanumérico. Se o formato de um argumento de entrada for numérico, utilize as funções EDIT ou FTOA para converter o argumento em alfanumérico. É possível utilizar as funções EDIT ou ATODBL para converter a saída de volta para o formato numérico.

O comprimento da saída da chamada de subrotina deve ser quatro. Variáveis de caracteres não podem possuir mais de 256 bytes. Este limite também se aplica às subrotinas REXX. As rotinas FUSREXX retornam dados de comprimento de variáveis. Por esta razão, você deve fornecer o comprimento dos argumentos de entrada e o comprimento máximo dos dados de saída.

A subrotina REXX não exige qualquer parâmetro de entrada, mas exige um parâmetro de retorno, que deve retornar pelo menos um byte de dados. É possível que uma subrotina REXX não necessite de entrada, como uma função que retorna USERID.

Uma subrotina REXX não suporta argumentos de entrada de data do WebFOCUS. Ao trabalhar com datas, você pode:



Exemplo: Como Retornar um Resultado no Formato Alfanumérico

A subrotina NUMCNT retorna o número de cópias de cada filme clássico no formato alfanumérico. Ele passa um parâmetro de entrada e um campo de retorno.

TABLE FILE MOVIES 
   PRINT TITLE AND COMPUTE  
1. ACOPIES/A3 = EDIT(COPIES); AS 'COPIES'
   AND COMPUTE 
2. TXTCOPIES/A8 = NUMCNT(3, ACOPIES, 8, TXTCOPIES);
   WHERE CATEGORY EQ 'CLASSIC'
   END

O procedimento processa da seguinte forma:

  1. O campo EDIT converte COPIES para o formato alfanumérico e armazena o resultado em ACOPIES.
  2. O resultado é armazenado em um campo alfanumérico de oito bytes TXTCOPIES.

A saída é:

TITLE                                    COPIES  TXTCOPIES
-----                                    ------  ---------
EAST OF EDEN                             001     One
CITIZEN KANE                             003     Three
CYRANO DE BERGERAC                       001     One
MARTY                                    001     One
MALTESE FALCON, THE                      002     Two
GONE WITH THE WIND                       003     Three
ON THE WATERFRONT                        002     Two
MUTINY ON THE BOUNTY                     002     Two
PHILADELPHIA STORY, THE                  002     Two
CAT ON A HOT TIN ROOF                    002     Two
CASABLANCA                               002     Two

A subrotina é:

/* NUMCNT routine. */
/* Pass a number from 0 to 10 and return a character value */ 
Arg numbr .
data = 'Zero One Two Three Four Five Six Seven Eight Nine Ten'
numbr = numbr + 1           /* so 0 equals 1 element in array */
Return Word(data,numbr)


Exemplo: Como Retornar um Resultado no Inteiro Formato Inteiro

No exemplo a seguir, a subrotina NUMDAYS encontra o número de dias entre HIRE_DATE e DAT_INC e retorna o resultado no formato de número inteiro.

   DEFINE FILE EMPLOYEE 
1. AHDT/A6 = EDIT(HIRE_DATE); 
2. ADI/A6 = EDIT(DAT_INC); 
3. BETWEEN/I6 = NUMDAYS(6, AHDT, 6, ADI, 4, 'I6') ;
   END
 
TABLE FILE EMPLOYEE
PRINT LAST_NAME HIRE_DATE DAT_INC BETWEEN
IF BETWEEN NE 0
END

O procedimento processa da seguinte forma:

  1. EDIT converte HIRE_DATE para o formato alfanuméricos e armazena o resultado em AHDT.
  2. EDIT converte DAT_INC para o formato alfanuméricos e armazena o resultado em ADI.
  3. NUMDAYS encontra o número de dias entre AHDT e ADI e armazena o resultado no formato de número inteiro.

A saída é:

LAST_NAME      HIRE_DATE   DAT_INC  BETWEEN
---------      ---------   -------  -------
STEVENS        80/06/02    82/01/01     578
STEVENS        80/06/02    81/01/01     213
SMITH          81/07/01    82/01/01     184
JONES          82/05/01    82/06/01      31
SMITH          82/01/04    82/05/14     130
IRVING         82/01/04    82/05/14     130
MCCOY          81/07/01    82/01/01     184
MCKNIGHT       82/02/02    82/05/14     101
GREENSPAN      82/04/01    82/06/11      71
CROSS          81/11/02    82/04/09     158

A subrotina aparece abaixo. O valor retornado é convertido de caracteres REXX para HEX e formatado para conter quatro bytes.

/* NUMDAYS routine.  */
/* Return number of days between 2 dates in yymmdd format */
/* The value returned will be in hex format               */
 
Arg first,second .
 
base1 = Date('B',Translate('34/56/12',first,'123456'),'U')
base2 = Date('B',Translate('34/56/12',second,'123456'),'U')
 
Return D2C(base2 - base1,4)


Exemplo: Como Passar um Valor de Datacomo Campo Alfanumérico com Opções de Data

No exemplo a seguir, uma data é utilizada para passar um campo alfanumérico com opções de data para a subrotina DATEREX1. DATEREX1 utiliza dois argumentos de entrada: uma data alfanumérica no formato A8YYMD e um número de dias no formato de caracteres. Retorna uma data inteligente no formato YYMD que representa a data de entrada mais o número de dias. O formato A8YYMD corresponde ao formato Padrão REXX ('S').

O número 693959 representa a diferença, em número de dias, entre as datas de base do WebFOCUS e do REXX:

/* REXX DATEREX1 routine. Add indate (format A8YYMD) to days */
Arg indate, days .
Return D2C(Date('B',indate,'S')+ days - 693959, 4)

A solicitação a seguir utiliza o macro DATEREX1 para calcular a data que cai 365 dias após a data de contratação de cada funcionário. Os argumentos de entrada são a data de contratação e o número de dias a serem adicionados. Como HIRE_DATE está no formato I6YMD, deve ser convertido para A8YYMD antes de ser passado para o macro:

TABLE FILE EMPLOYEE
PRINT LAST_NAME FIRST_NAME HIRE_DATE
AND COMPUTE
  ADATE/YYMD =  HIRE_DATE; NOPRINT
AND COMPUTE
  INDATE/A8YYMD= ADATE; NOPRINT
AND COMPUTE
  NEXT_DATE/YYMD = DATEREX1(8, INDATE, 3, '365', 4, NEXT_DATE);
BY LAST_NAME NOPRINT
END

A saída é:

LAST_NAME        FIRST_NAME  HIRE_DATE  NEXT_DATE 
---------        ----------  ---------  --------- 
BANNING          JOHN         82/08/01  1983/08/01
BLACKWOOD        ROSEMARIE    82/04/01  1983/04/01
CROSS            BARBARA      81/11/02  1982/11/02
GREENSPAN        MARY         82/04/01  1983/04/01
IRVING           JOAN         82/01/04  1983/01/04
JONES            DIANE        82/05/01  1983/05/01
MCCOY            JOHN         81/07/01  1982/07/01
MCKNIGHT         ROGER        82/02/02  1983/02/02
ROMANS           ANTHONY      82/07/01  1983/07/01
SMITH            MARY         81/07/01  1982/07/01
SMITH            RICHARD      82/01/04  1983/01/04
STEVENS          ALFRED       80/06/02  1981/06/02


Exemplo: Como Passar uma Data como uma Data Convertida para o Formato Alfanumérico

No exemplo a seguir, a data é passada para a subrotina como uma data inteligente convertida para o formato alfanumérico. A subrotina DATEREX2 utiliza dois argumentos de entrada: um número alfanumérico de dias que representa uma data inteligente e um número de dias a ser adicionado. Retorna uma data inteligente no formato YYMD que representa a data de entrada mais o número de dias. Ambas as datas de entrada e saída estão no formato de data de base REXX ('B').

O número 693959 representa a diferença, em número de dias, entre as datas de base do WebFOCUS e do REXX:

/* REXX DATEREX2 routine. Add indate (original format YYMD) to days */
Arg indate, days .
Return D2C(Date('B',indate+693959,'B') + days - 693959, 4)

A solicitação a seguir utiliza DATEREX2 para calcular a data que cai 365 dias após a data de contratação de cada funcionário. Os argumentos de entrada são a data de contratação e o número de dias a serem adicionados. Como HIRE_DATE está no formato I6YMD, deve ser convertido para um número alfanumérico de dias antes de ser passado para o macro:

TABLE FILE EMPLOYEE
PRINT LAST_NAME FIRST_NAME HIRE_DATE
AND COMPUTE
  ADATE/YYMD =  HIRE_DATE; NOPRINT
AND COMPUTE
  INDATE/A8 = EDIT(ADATE); NOPRINT
AND COMPUTE
  NEXT_DATE/YYMD = DATEREX2(8,INDATE,3,'365',4,NEXT_DATE);
BY LAST_NAME NOPRINT
END

A saída é:

LAST_NAME        FIRST_NAME  HIRE_DATE  NEXT_DATE 
---------        ----------  ---------  --------- 
BANNING          JOHN         82/08/01  1983/08/01
BLACKWOOD        ROSEMARIE    82/04/01  1983/04/01
CROSS            BARBARA      81/11/02  1982/11/02
GREENSPAN        MARY         82/04/01  1983/04/01
IRVING           JOAN         82/01/04  1983/01/04
JONES            DIANE        82/05/01  1983/05/01
MCCOY            JOHN         81/07/01  1982/07/01
MCKNIGHT         ROGER        82/02/02  1983/02/02
ROMANS           ANTHONY      82/07/01  1983/07/01
SMITH            MARY         81/07/01  1982/07/01
SMITH            RICHARD      82/01/04  1983/01/04
STEVENS          ALFRED       80/06/02  1981/06/02

Information Builders