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;