Sous-routines écrites en REXX

Dans cette section :

Comment :

Référence :

Une requête peut appeler une sous-routine codée dans REXX. Ces sous-routines, aussi nommées macros FUSREXX offrent une option 4GL aux langues prises en charge pour les sous-routines écrites par l'utilisateur.

Les sous-routines REXX sont prises en charge dans l'environnement z/OS. Une sous-routine REXX contient le code source REXX. Le code REXX compilé n'est pas pris en charge.

Une sous-routine REXX contient le code source REXX. Le code REXX compilé n'est pas pris en charge.

Les sous-routines REXX ne sont pas nécessairement les mêmes dans tous les environnements d'exploitation. Par conséquent, certains des exemples peuvent utiliser les fonctions REXX non disponibles dans votre environnement.

En raison des conditions requises CPU, l'utilisation des sous-routines REXX dans des travaux de large production devraient être surveillée avec beaucoup d'attention.

Pour plus d'informations sur les sous-routines REXX, consultez votre documentation REXX.


Haut de page

x
Référence : Stocker et rechercher une sous-routine REXX

Pour stocker une sous-routine REXX, DDNAME FUSREXX doit être alloué à un PDS. Cette bibliothèque est explorée avec les autres bibliothèques z/OS.

L'ordre de recherche pour une sous-routine REXX est :

  1. FUSREXX.
  2. Ordre de recherche standard z/OS.

Haut de page

x
Syntaxe : Appeler une sous-routine 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);

où :

fieldname

est le champ contenant le résultat.

An, In

est le format du champ contenant le résultat.

subname

est le nom de la sous-routine REXX.

inlen1, inparm1 ...

sont les paramètres d'entrée. Chaque paramètre consiste en une valeur de paramètre alphanumérique et une longueur. Vous pouvez fournir la valeur réelle, le nom d'un champ numérique contenant la valeur ou une expression qui renvoie celle-ci. Sont pris en charge jusqu'à 13 paires de paramètres d'entrée. Chaque valeur de paramètre peut être long de 256 octets.

Le gestionnaire de dialogue convertit des arguments numériques au format virgule flottante en double précision. Par conséquent, vous ne pouvez transmettre que des paramètres d'entrée alphanumériques à une sous-routine REXX à l'aide de -SET.

outlen, outparm

est la paire de paramètres d'entrée, qui consiste en une longueur et un résultat. Dans la majeur partie des cas, le résultat devrait être alphanumérique, mais les résultats entiers sont également pris en charge. Le résultat peut être un champ ou une variable Gestionnaire de dialogue qui contient la valeur, ou le format de la valeur entre guillemets simples. La valeur de renvoie peut être au minimum long d'un octet et de 256 au maximum (pour une valeur alphanumérique).

Remarque : si la valeur renvoyée est un entier, outlen doit être 4 parce que WebFOCUS réserve 4 octets pour les champs entiers.

&var

est le nom de la variable Gestionnaire de dialogue contenant le résultat.



Exemple : Renvoyer le jour de la semaine

La sous-routine REXX DOW renvoie le jour de la semaine correspondant à la date d'embauche de l'employé. La routine contient une pair de paramètres d'entrée et une paire de champs de renvoi.

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

La procédure est la suivante :

  1. La fonction EDIT convertit HIRE_DATE au format alphanumérique et stocke le résultat dans un champ au format A6.
  2. Le résultat est stocké dans le champ DAY_OF_THE_WEEK, et peut contenir jusqu'à neuf octets.

La sortie est :

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 sous-routine REXX apparaît ci-dessous. Elle lit la date d'entrée, la reformate au format MM/DD/YY, et renvoie le jour de la semaine avec un appel REXX DATE.

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


Exemple : Passer plusieurs arguments à une sous-routine REXX

La sous-routine REXX INTEREST contient quatre paramètres d'entrée.

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

La procédure est la suivante :

  1. EDIT convertit HIRE_DATE au format alphanumérique et stocke le résultat dans AHDT.
  2. EDIT convertit CURR_SAL au format alphanumérique et stocke le résultat dans ACSAL.
  3. CURR_SAL est converti en un champ virgule flottante en double précision qui comprend des points, et le résultat est stocké dans DCSAL.
  4. Le second champ d'entrée est long de six octets. Les données sont passée comme variable de caractère &YMD au format YYMMDD.

    Le troisième champ d'entrée est une valeur de caractère de 6.5, qui est long de trois octets à considérer pour le point décimal dans la chaîne de caractères.

    Le quatrième champ d'entrée est long de 12 octets. Il transmet le champ de caractère ACSAL.

    Le champ de retour est long de 12 octets maximum et s'intitule PV.

La sortie est :

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 sous-routine REXX apparaît ci-dessous. La commande du format REXX est utilisée pour formater la valeur de retour.

/* 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)


Exemple : Accepter plusieurs jeutons dans un paramètre

Une sous-routine REXX peut accepter plusieurs jeutons dans un paramètre. La procédure suivante transmet les informations sur l'employé (PAY_DATE et MO_PAY) comme jeutons distincts dans le premier paramètre. Elle transmet trois paramètres d'entrée et un champ de retour.

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

La procédure est la suivante :

  1. COMPID est la concaténation de plusieurs champs de caractères transmis comme premier caractère et est stocké dans un champ au format A256. Chacun des autres paramètres est un argument unique.
  2. EDIT convertit PAY_DATE au format alphanumérique.
  3. EDIT convertit MO_PAY au format alphanumérique.
  4. OK4RAISE exécute, et le résultat est stocké dans OK4RAISE.

La sortie est :

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

La sous-routine REXX apparaît ci-dessous. Des virgules délimitent les paramètres FUSREXX. La commande ARG spécifie plusieurs noms de variables avant la première virgule, par conséquent elle délimite le premier paramètre FUSREXX en variables distinctes REXX, à l'aide de blancs comme délimiteurs entre 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

Les sous-routines REXX devraient utiliser la sous-routine REXX RETURN pour renvoyer les données. REXX EXIT est acceptable, mais est généralement utilisé pour terminer un EXEC, pas une 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


x
Formats et sous-routines REXX

Une sous-routine REXX nécessite que les données d'entrée soient au format alphanumérique. La majeur partie des sorties sont renvoyées au format alphanumérique. Si le format d'un argument d'entrée est numérique, utilisez les fonctions EDIT ou FTOA pour convertir l'argument en format alphanumérique. Vous pouvez ensuite utiliser les fonctions EDIT ou ATODBL pour reconvertir la sortie en format numérique.

La longueur de la sortie de la sous-routine doit être de quatre. Les variables de caractères ne peuvent pas dépasser 256 octets. Cette limite s'applique également aux sous-routines REXX. Les routines FUSREXX renvoient des données de longueurs variables. Pour cette raison, vous devez fournir la longueur des arguments d'entrées et la longueur maximale des données de sortie.

Une sous-routine REXX ne nécessite pas de paramètres d'entrée, mais un paramètre de retour, qui doit renvoyer au moins un octet de données. Il est possible pour une sous-routine REXX qu'elle ne nécessite pas d'entrée, comme par exemple une fonction qui renvoie USERID.

Une sous-routine REXX ne prend pas en charge des arguments d'entrée de date WebFOCUS. Lorsque vous travaillez avec des dates, vous disposez des options suivantes :



Exemple : Renvoyer un résultat au format alphanumérique

La sous-routine NUMCNT renvoie le nombre de copies de chaque film classique au format alphanumérique. Elle transmet un paramètre d'entrée et un champ de retour.

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

La procédure est la suivante :

  1. Le champ EDIT convertit COPIES au format alphanumérique et stocke le résultat dans ACOPIES.
  2. Le résultat est stocké dans un champ alphanumérique à 8 octets TXTCOPIES.

La sortie est :

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 sous-routine est :

/* 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)


Exemple : Renvoyer un résultat au format Entier

Dans l'exemple suivant, la sous-routine NUMDAYS trouve le nombre de jours entre HIRE_DATE et DATE_INC et renvoie le résultat au format entier.

   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

La procédure est la suivante :

  1. EDIT convertit HIRE_DATE au format alphanumérique et stocke le résultat dans AHDT.
  2. EDIT convertit DAT_INC au format alphanumérique et stocke le résultat dans ADI.
  3. NUMDAYS trouve le nombre de jours entre AHDT et ADI et stocke le résultat au format entier.

La sortie est :

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

Voici les résultats de l'utilisation de BARWIDTH, BARSPACE et GRID. La valeur de renvoi est convertie d'un caractère REXX en HEX et formatée pour être longue de quatre octets.

/* 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)


Exemple : Transmettre une valeur de date comme champ alphanumérique avec des options de date

Dans l'exemple suivant, une date est utilisée pour transmettre un champ alphanumérique avec des options de date vers la sous-routine DATEREX1. DATEREX1 prend deux arguments d'entrée : une date numérique au format A8YYMD et un numéro de jour au format de caractère. Une date intelligente est prise au format YYMD qui représente la date d'entrée et le nombre de jours. Le format A8YYMD correspond au format standard REXX ('S').

Le nombre 693959 représente la différence en nombre de jours entre la date de base WebFOCUS et la date REXX :

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

La requête suivante utilise le macro DATEREX1 pour calculer la date qui est à 365 jours de la date d'embauche de chaque employé. Les arguments d'entrée sont la date d'embauche et le nombre de jours à ajouter. Puisque HIRE_DATE est au format I6YMD, il doit être converti à A8YYMD avant d'être transmis au 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 sortie est :

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


Exemple : Transmettre un date comme date convertie au format alphanumérique

Dans l'exemple suivant, une date est transmise à la sous-routine comme date intelligente convertie au format alphanumérique. La sous-routine DATEREX2 prend deux arguments d'entrée : un nombre alphanumérique de jours représentant une date intelligente, et un nombre de jours à ajouter. Une date intelligente est prise au format YYMD qui représente la date d'entrée et le nombre de jours. Les dates d'entrée et de sortie sont au format de date de base ('B') REXX.

Le nombre 693959 représente la différence en nombre de jours entre la date de base WebFOCUS et la date 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 requête suivante utilise DATEREX2 pour calculer la date qui est à 365 jours de la date d'embauche de chaque employé. Les arguments d'entrée sont la date d'embauche et le nombre de jours à ajouter. Puisque HIRE_DATE est au format I6YMD, il doit être converti en un nombre numérique de jours avant d'être transmis au 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 sortie est :

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