Aller au contenu

Code opération RPG III / RPG/400 · IBM i (AS/400) · Sous-programmes et appels

EXSR

Appeler un sous-programme

Exécute le sous-programme interne nommé en facteur 2, puis reprend à la ligne suivante.

Syntaxe

     C                     EXSR nomsr
     C   50                EXSR nomsr
     C  N50                EXSR nomsr
Indicateurs de conditionnement (9-17)
Facultatifs : l'appel n'a lieu que si l'indicateur est dans l'état demandé (N50 : indicateur 50 éteint).
Facteur 2 (33-42)
Le nom d'un sous-programme défini dans le programme par un BEGSR (6 caractères au plus).
Facteur 1 (18-27)
Doit rester vide (QRG5010, « La zone Facteur 1 n'est pas à blanc pour l'opération définie », si on y met quelque chose).
Effet
L'exécution passe dans le sous-programme jusqu'à son ENDSR, puis revient à la ligne qui suit l'EXSR. Aucun indicateur n'est positionné, aucune valeur n'est transmise : le sous-programme travaille directement sur les zones du programme. Un sous-programme peut en appeler un autre (appels imbriqués).

À quoi ça sert

EXSR est l'outil de découpage du RPG III. Un programme de gestion tient souvent en quelques lignes de programme principal (EXSR INIT, EXSR TRAITE, EXSR FIN) et le reste en sous-programmes nommés.

Exemple 1 : Appels imbriqués et appel conditionné

     H*  EXSR : appel imbrique et appel conditionne par un indicateur
     C                     Z-ADD3         NBLIG   30
     C                     Z-ADD0         TOTAL   50
     C                     SETOF                     50
     C  N50                EXSR BOUCLE
     C           TOTAL     DSPLY
     C                     SETON                     50
     C  N50                EXSR BOUCLE
     C           TOTAL     DSPLY
     C                     SETON                     LR
     C           BOUCLE    BEGSR
     C                     DO   NBLIG
     C                     EXSR AJOUT
     C                     END
     C                     ENDSR
     C           AJOUT     BEGSR
     C                     ADD  10        TOTAL
     C                     ENDSR

Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :

   30
   30

BOUCLE appelle AJOUT trois fois (3 x 10 = 30). Le premier EXSR est conditionné par N50 avec l'indicateur 50 éteint : il s'exécute et le total vaut 30. Le second, avec l'indicateur 50 allumé, est sauté : le total reste à 30.

Exemple 2 : Pas de variable locale

     H*  EXSR : pas de variable locale, tout est global
     C                     Z-ADD5         I       30
     C                     EXSR COMPTE
     C           I         DSPLY
     C                     SETON                     LR
     C           COMPTE    BEGSR
     C                     DO   3         I
     C                     END
     C                     ENDSR

Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :

  4

Le sous-programme COMPTE utilise I comme compteur de DO. C'est la même zone I que celle du programme principal : à la sortie, elle vaut 4 (la boucle l'a laissée à son maximum plus un) et plus 5.

Le piège

Toutes les zones sont globales. Un sous-programme qui réutilise un nom de zone (compteur, zone de travail) écrase la valeur que l'appelant attendait (deuxième exemple). Donnez des noms distincts aux compteurs d'un sous-programme.

Pas de récursion. Un sous-programme qui s'appelle lui-même est refusé à la compilation : QRG7112 (gravité 30), « EXSR ou CASxx appelle le sous-programme où elle se trouve. Spécification ignorée. »

Le nom doit exister. Un EXSR ABSENT sans BEGSR ABSENT donne QRG7018 (gravité 30), « Le nom en Facteur 2 de l'opération EXSR ne fait pas référence à un BEGSR. La spécification n'est pas prise en compte. »

En RPG ILE full free

L'instruction est identique en RPG ILE. Pour avoir de vraies variables locales ou des paramètres, on écrit une procédure : ses zones déclarées dans la procédure n'existent que pendant l'appel.

exsr boucle;

begsr boucle;
  for n = 1 to nblig;
    exsr ajout;
  endfor;
endsr;

dcl-proc ajout;
  dcl-pi *n;
  end-pi;
  dcl-s tmp packed(5);   // locale
end-proc;