Code opération RPG III / RPG/400 · IBM i (AS/400) · Sous-programmes et appels
BEGSR
Définir un sous-programme (BEGSR et ENDSR)
Ouvre un sous-programme interne dont le nom, de 6 caractères au plus, est en facteur 1 ; ENDSR le ferme. Le sous-programme ne s'exécute que lorsqu'un EXSR l'appelle, sauf *INZSR et *PSSR qui sont lancés par le programme lui-même.
Syntaxe
C nomsr BEGSR
C ...
C ENDSR
C *INZSR BEGSR
C *PSSR BEGSR
- Facteur 1 (18-27)
- Le nom du sous-programme, 6 caractères au plus, unique dans le programme. Deux noms ont un rôle particulier :
*INZSR(initialisation, lancé automatiquement une seule fois au démarrage) et*PSSR(erreur de programme, lancé automatiquement sur une erreur de programme, par exemple une division par zéro). - ENDSR
- Ferme le sous-programme et ramène l'exécution à la ligne qui suit l'
EXSR. Elle s'écrit sans facteur 1 ni facteur 2 dans l'usage courant. - Effet
- Un sous-programme est du code qu'on appelle par
EXSR: l'exécution y va, atteintENDSR, puis reprend après l'EXSR. Passer devant unBEGSRne l'exécute pas.*INZSRest exécuté tout seul avant le premier calcul du programme.*PSSRest exécuté tout seul sur une erreur de programme (division par zéro, par exemple) ; une fois terminé, le programme s'arrête quand même sur l'erreur d'origine (deuxième exemple).
À quoi ça sert
Un programme RPG III n'a pas de procédures : tout le découpage passe par des sous-programmes internes. Ils servent à nommer une étape (« calculer la TVA », « lire le client »), à ne pas dupliquer du code appelé à plusieurs endroits, et à garder un programme principal lisible.
Tous les sous-programmes se placent à la fin des spécifications de calcul, après le code principal. Les zones sont globales : un sous-programme lit et modifie les mêmes zones que le reste du programme.
Exemple 1 : TVA appelée deux fois
H* BEGSR : un sous-programme calcule le TTC, appele deux fois
C Z-ADD1000 HT 72
C EXSR TVA
C TTC DSPLY
C Z-ADD250 HT
C EXSR TVA
C TTC DSPLY
C SETON LR
C TVA BEGSR
C HT MULT 1.2 TTC 92
C ENDSR
Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :
120000
30000
Le sous-programme TVA lit HT et range le résultat dans TTC. Le programme principal charge HT, appelle le sous-programme, affiche, recommence avec une autre base. Les montants s'affichent sans virgule : 120000 est 1200,00.
Exemple 2 : *INZSR et *PSSR
H* BEGSR : *INZSR s'execute avant tout, *PSSR sur erreur
C Z-ADD0 QTE 30
C TAUX DSPLY
C 1000 DIV QTE UNIT 70
C UNIT DSPLY
C 'Fin' DSPLY
C SETON LR
C *INZSR BEGSR
C Z-ADD20 TAUX 30
C ENDSR
C *PSSR BEGSR
C 'Erreur' DSPLY
C ENDSR
Résultat réel, compilé par CRTRPGPGM et exécuté sur IBM i 7.5 :
20
Erreur
Erreur : RPG0102 - Z3BEGSR2 400 a tenté une division par zéro (facteur 2) (C G S D F).
*INZSR n'est jamais appelé par un EXSR : il s'exécute avant la première ligne, c'est pourquoi TAUX vaut déjà 20 à l'affichage. La division par zéro déclenche *PSSR (message « Erreur »), puis le programme s'arrête quand même sur RPG0102 : la ligne Fin n'est jamais affichée.
Le piège
Aucune opération de calcul ne peut suivre un ENDSR. Un sous-programme est la dernière chose du programme : si l'on écrit une ligne de calcul (même un DSPLY ou le SETON LR final) après un ENDSR, le compilateur la refuse : QRG5005 (gravité 30), « L'opération suivant l'opération ENDSR est incorrecte. » Mettez le SETON LR avant le premier BEGSR.
*PSSR n'absorbe pas l'erreur. Il permet de réagir (message, fermeture, journal), mais sans point de retour le programme se termine malgré tout, avec le message d'origine (RPG0102 dans le deuxième exemple).
En RPG ILE full free
En RPG ILE full free, BEGSR et ENDSR existent toujours, avec EXSR. Pour un code neuf, on préfère une procédure (dcl-proc), qui a ses propres variables locales et reçoit des paramètres. *PSSR et *INZSR sont remplacés par monitor et par une initialisation explicite.
exsr tva;
// ...
begsr tva;
ttc = ht * 1.2;
endsr;
monitor;
unit = 1000 / qte;
on-error;
dsply 'Erreur';
endmon;