Aller au contenu

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, atteint ENDSR, puis reprend après l'EXSR. Passer devant un BEGSR ne l'exécute pas. *INZSR est exécuté tout seul avant le premier calcul du programme. *PSSR est 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;