En esta sección: Cómo: Referencia: |
Las solicitudes pueden llamar a subrutinas codificadas en REXX. Estas subrutinas, también denominadas macros FUSREXX, ofrecen una opción de 4GL para los lenguaje compatibles con subrutinas escritas por los usuarios.
Las subrutinas REXX son compatibles con el entorno z/OS. Las subrutinas REXX contienen el código fuente de REXX. El código REXX compilado no es compatible.
Las subrutinas REXX contienen el código fuente de REXX. El código REXX compilado no es compatible.
Las subrutinas REXX no tienen por qué ser las mismas en todos los entornos operativos. Por tanto, puede que algunos de los ejemplos empleen funciones REXX que no están disponibles en su entorno.
Debido a los requisitos de CPU, el uso de subrutinas REXX en trabajos de producción de gran tamaño debe controlarse minuciosamente.
Para más información sobre las subrutinas REXX, consulte su documentación de REXX.
Para almacenar una subrutina REXX, DDNAME FUSREXX debe estar asignado a un PDS. Primero se realiza una búsqueda en la biblioteca y después, en el resto de bibliotecas de z/OS.
El orden de búsqueda de las subrutinas REXX es:
DEFINE FILE filename fieldname/{An|In} = subname(inlen1, inparm1, ..., outlen, outparm); END
o
{DEFINE|COMPUTE} fieldname/{An|In} = subname(inlen1, inparm1, ..., outlen, outparm);
o
-SET &var = subname(inlen1, inparm1, ..., outlen, outparm);
donde:
El campo que contiene el resultado.
El formato del campo que contiene el resultado.
El nombre de la subrutina REXX.
Los parámetros de entrada. Cada parámetro está compuesto por una longitud y un valor de parámetro alfanumérico. Puede proporcionar el valor, el nombre de un campo alfanumérico que contenga el valor o una expresión que devuelva el valor. Puede usar hasta 13 pares de parámetros. Cada valor de parámetro puede tener hasta 256 bytes.
Dialogue Manager convierte los argumentos numéricos al formato de punto flotante, de doble precisión. Por tanto, sólo puede pasar parámetros de entrada alfanuméricos a la subrutina REXX, mediante -SET.
Es la pareja del parámetro de salida: una longitud y un resultado. En la mayoría de los casos, el resultado debe ser alfanumérico, aunque los números enteros también son compatibles. El resultado puede ser un campo o una variable de Dialogue Manager que contenga el valor, o el formato del valor entre comillas simples. La longitud mínima del valor devuelto es de 1 byte, la máxima (en valores alfanuméricos), de 256.
Nota: Si el valor devuelto es un número entero, outlen debe ser 4, ya que WebFOCUS reserva cuatro bytes para los campos de número entero.
El nombre de la variable de Dialogue Manager que contiene el resultado.
La subrutina DOW de REXX devuelve el día de la semana correspondiente a la fecha de contratación de un empleado. La rutina contiene una pareja del parámetro de entrada y una pareja del campo de devolución.
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
El procedimiento se procesa del siguiente modo:
La salida es:
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
La subrutina REXX aparece más abajo. Lee la fecha de entrada, cambia el formato a MM/DD/YY y devuelve el día de la semana mediante una llamada a REXX DATE.
/* DOW routine. Return WEEKDAY from YYMMDD format date */ Arg ymd . Return Date('W',Translate('34/56/12',ymd,'123456'),'U')
La subrutina INTEREST de REXX tiene cuatro 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
El procedimiento se procesa del siguiente modo:
El tercer campo de entrada es un valor de caracteres de 6.5, con una longitud de tres bytes, para acomodar el punto decimal de la cadena de caracteres.
El cuarto campo de entrada es de 12 bytes. Esto sirve para pasar el campo de caracteres ACSAL.
El campo de devolución puede tener hasta 12 bytes y se llama PV.
La salida es:
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
La subrutina REXX aparece más abajo. El comando REXX Format se usa para aplicar un formato al valor devuelto.
/* 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)
Las subrutinas REXX pueden aceptar varios tokens en un parámetro. El siguiente procedimiento pasa la información del empleado (PAY_DATE y MO_PAY) como tokens independientes, en el primer parámetro. Pasa tres parámetros de entrada y un campo devuelto.
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
El procedimiento se procesa del siguiente modo:
La salida es:
EMP_ID FIRST_NAME LAST_NAME DEPARTMENT ------ ---------- --------- ---------- 071382660 ALFRED STEVENS PRODUCTION
La subrutina REXX aparece más abajo. Los parámetros FUSREXX se separan mediante comas. El comando ARG especifica múltiples nombres de variables antes de la primera coma y, por tanto, separa el primer parámetro FUSREXX en distintas variables REXX, utilizando espacios en blanco como delimitadores entre las variables.
/* 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
Las subrutinas REXX deben usar la subrutina REXX RETURN para devolver datos. REXX EXIT es válido, aunque se suele utilizar para finalizar un EXEC, no una FUNCTION.
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 |
Las subrutinas REXX requieren que los datos de entrada estén en formato alfanumérico. La mayor parte de la salida se devuelve en este formato. Si el formato de un argumento de entrada es numérico, use las funciones EDIT o FTOA para convertirlo en alfanumérico. A partir de ese momento, podrá utilizar las funciones EDIT o ATODBL para reconvertir la salida a numérico.
La longitud de salida en la llamada de subrutina debe ser de cuatro. Las variables de caracteres no pueden tener más de 256 bytes. Este límite también se aplica a las subrutinas REXX. Las subrutinas FUSREXX devuelven datos de longitud variable. Por esta razón, debe proporcionar la longitud de los argumentos de entrada y la longitud máxima de los datos de salida.
Las subrutinas REXX no requieren parámetros de entrada, aunque sí uno devuelto, que debe incluir al menos un byte de datos. Puede haber casos en que una subrutina no necesite entrada, como una función que devuelve USERID.
Las subrutinas REXX no son compatibles con los argumentos de entrada de fechas de WebFOCUS. Si está trabajando con fechas, puede seguir uno de estos métodos:
Los campos de fecha contienen el número entero de los días transcurridos desde la fecha base 12/31/1900. REXX tiene una función de fechas capaz de aceptar y devolver varios tipos de formatos de fecha, incluido el formato Base ('B'), que contiene el número de días desde la fecha base de REXX, 01/01/0001. Debe tener en cuenta la diferencia en cuanto al número de días entre la fecha base de WebFOCUS y la de REXX, y convertir el resultado a un número entero.
La subrutina NUMCNT devuelve el número de copias de cada película clásica en formato alfanumérico. Pasa un parámetro de entrada y un campo devuelto.
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
El procedimiento se procesa del siguiente modo:
La salida es:
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
La subrutina es:
/* 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)
En el siguiente ejemplo, la subrutina NUMDAYS calcula el número de días entre HIRE_DATE y DAT_INC, y devuelve el resultado en el formato de número entero.
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
El procedimiento se procesa del siguiente modo:
La salida es:
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
La subrutina aparece más abajo. El valor devuelto se convierte del carácter REXX a HEX y se le aplica un formato de cuatro bytes de largo.
/* 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)
En el siguiente ejemplo, la fecha se utiliza pasando un campo alfanumérico con opciones de fecha a la subrutina DATEREX1. DATEREX1 toma dos argumentos de entrada: una fecha alfanumérica en formato A8 y un número de días en formato de caracteres. Devuelve una fecha inteligente en formato YYMD, que representa la fecha de entrada más el número de días. El formato A8YYMD corresponde al formato REXX estándar ('S').
El número 693959 representa la diferencia en días entre la fecha base de WebFOCUS y la de REXX:
/* REXX DATEREX1 routine. Add indate (format A8YYMD) to days */ Arg indate, days . Return D2C(Date('B',indate,'S')+ days - 693959, 4)
La siguiente solicitud usa el macro DATEREX1 para calcular la fecha que está a 365 días de la fecha de contratación de cada empleado. Los argumentos de entrada son la fecha de contratación y el número de días que se va a añadir. Puesto que HIRE_DATE está en el formato I6YMD, debe convertirse a A8YYMD antes de poder pasarse al 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
La salida es:
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
En el siguiente ejemplo, la fecha se ha pasado a la subrutina como fecha inteligente convertida al formato alfanumérico. La subrutina DATEREX2 toma dos argumentos de entrada: un número de días alfanumérico, que representa una fecha inteligente, y el número de días que se va a añadir. Devuelve una fecha inteligente en formato YYMD, que representa la fecha de entrada más el número de días. La fecha de entrada y la de salida están en el formato de fecha estándar de REXX ('B').
El número 693959 representa la diferencia en días entre la fecha base de WebFOCUS y la de REXX:
/* REXX DATEREX2 routine. Add indate (original format YYMD) to days */ Arg indate, days . Return D2C(Date('B',indate+693959,'B') + days - 693959, 4)
La siguiente solicitud usa el macro DATEREX2 para calcular la fecha que está a 365 días de la fecha de contratación de cada empleado. Los argumentos de entrada son la fecha de contratación y el número de días que se va a añadir. Puesto que HIRE_DATE está en el formato I6YMD, debe convertirse en un número de días alfanumérico antes de ser pasado al 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
La salida es:
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
WebFOCUS |