Instruction RPG full free · IBM i (AS/400) · Procédures, sous-programmes et erreurs
CALLP
Appeler une procédure ou un programme
Appelle une procédure ou un programme décrit par un prototype, en ignorant la valeur éventuellement renvoyée, et permet de capter l'erreur d'appel avec l'extension E.
Syntaxe
CALLP{(E)} nom-procedure({parametre1 : parametre2 ...});
nom-procedure({parametre1 : parametre2 ...});
nom-procedure- Le nom du prototype (
dcl-pr) ou de la procédure à appeler. Un prototype avecextpgmappelle un programme, par exempleQCMDEXC. parametres- Les valeurs passées, séparées par
:. Un paramètre déclaréconstaccepte une expression ou une constante. Sansconst, il est passé par référence : la procédure modifie la zone de l'appelant. (E)- Extension d'erreur. Si l'appel échoue, le programme ne s'arrête pas :
%ERRORpasse à*ONet%STATUSreçoit le code de l'erreur. - Effet
- L'appel lui-même ne positionne rien. Avec l'extension (E),
%ERRORvaut*ONsi l'appel a échoué et%STATUScontient le code (211 pour un programme introuvable, 202 pour un appel terminé en erreur, dans les exemples). Si la procédure renvoie une valeur,CALLPla jette.
À quoi ça sert
En full free, le mot CALLP est facultatif : ajouter(encours : 50.25); fait exactement la même chose que callp ajouter(encours : 50.25);. On l'écrit surtout pour deux raisons : rendre l'intention explicite quand la valeur renvoyée est volontairement ignorée, et pouvoir ajouter l'extension (E).
En RPG IV en colonnes, c'était le code opération CALLP. Dès qu'on veut utiliser la valeur renvoyée par la procédure, on l'appelle dans une expression, sans CALLP.
Exemple 1 : Programme, procédure et paramètre par référence
**free
// CALLP : appeler une procedure ou un programme, avec ou sans le mot CALLP.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr qcmdexc extpgm('QCMDEXC');
cmd char(200) const;
lng packed(15:5) const;
end-pr;
dcl-pr majuscule char(30);
texte char(30) const;
end-pr;
dcl-pr ajouter ind;
total packed(9:2);
montant packed(9:2) const;
end-pr;
dcl-s encours packed(9:2) inz(1250.50);
dcl-s nom char(30) inz('Dupont SA');
dcl-s ok ind;
// Appel d'un programme : CALLP ou appel direct, c'est equivalent.
callp qcmdexc('CHKOBJ OBJ(JOBIRPG/CLIENT) OBJTYPE(*FILE)' : 200);
snd-msg 'Fichier CLIENT trouve';
// Appel d'une procedure qui renvoie une valeur : on peut l'ignorer avec CALLP.
callp majuscule(nom);
snd-msg 'Nom apres CALLP : [' + %trim(nom) + ']';
// Dans une expression, la valeur renvoyee est utilisee.
snd-msg 'Nom en majuscules : [' + %trim(majuscule(nom)) + ']';
// Le parametre sans CONST est passe par reference : l'appelant voit la modification.
ok = ajouter(encours : 100.00);
snd-msg 'Encours apres ajout : ' + %char(encours) + ', retour ' + %char(ok);
ajouter(encours : 50.25);
snd-msg 'Encours apres ajout sans CALLP : ' + %char(encours);
*inlr = *on;
dcl-proc majuscule;
dcl-pi *n char(30);
texte char(30) const;
end-pi;
return %upper(texte);
end-proc;
dcl-proc ajouter;
dcl-pi *n ind;
total packed(9:2);
montant packed(9:2) const;
end-pi;
total += montant;
return *on;
end-proc;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Fichier CLIENT trouve
Nom apres CALLP : [Dupont SA]
Nom en majuscules : [DUPONT SA]
Encours apres ajout : 1350.50, retour 1
Encours apres ajout sans CALLP : 1400.75
Le premier appel de QCMDEXC vérifie que le fichier existe. majuscule renvoie une valeur : avec callp elle est ignorée et nom reste inchangé ; dans l'expression suivante, elle est utilisée. Enfin total est passé par référence : encours passe de 1250.50 à 1350.50 puis à 1400.75, avec ou sans callp.
Exemple 2 : Capter l'échec d'un appel avec (E)
**free
// CALLP(E) : l'extension E capte l'erreur d'appel, sans elle le programme s'arrete.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-pr appeler extpgm('B4INEXIST');
numcli packed(5:0) const;
end-pr;
dcl-pr qcmdexc extpgm('QCMDEXC');
cmd char(200) const;
lng packed(15:5) const;
end-pr;
// Programme absent, avec (E) : %ERROR est positionne, le programme continue.
callp(e) appeler(100);
if %error;
snd-msg 'Appel de B4INEXIST en erreur, statut ' + %char(%status);
endif;
// Commande valide, avec (E) : pas d'erreur.
callp(e) qcmdexc('CHKOBJ OBJ(JOBIRPG/CLIENT) OBJTYPE(*FILE)' : 200);
snd-msg 'CHKOBJ CLIENT : erreur = ' + %char(%error);
// Commande qui echoue, avec (E) : on lit le statut sans planter.
callp(e) qcmdexc('CHKOBJ OBJ(JOBIRPG/PASCLIENT) OBJTYPE(*FILE)' : 200);
snd-msg 'CHKOBJ PASCLIENT : erreur = ' + %char(%error) + ', statut ' + %char(%status);
// Sans (E), la meme erreur arrete le programme.
callp qcmdexc('CHKOBJ OBJ(JOBIRPG/PASCLIENT) OBJTYPE(*FILE)' : 200);
snd-msg 'Cette ligne n est jamais atteinte';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Appel de B4INEXIST en erreur, statut 211
CHKOBJ CLIENT : erreur = 0
CHKOBJ PASCLIENT : erreur = 1, statut 202
Erreur : RNQ0202 - (C G D F) Appel à *LIBL/QCMDEXC terminé en erreur.
L'appel d'un programme qui n'existe pas donne le statut 211, une commande qui échoue le statut 202. La dernière ligne appelle la même commande sans (E) : l'erreur n'est plus captée et le programme s'arrête avec l'erreur d'exécution RNQ0202 ; le message qui suit n'est jamais affiché.
Le piège
Sans (E), une erreur d'appel arrête le programme. Le deuxième exemple se termine par RNQ0202 - Appel à *LIBL/QCMDEXC terminé en erreur : %ERROR n'a de sens qu'avec l'extension. Avec CALLP(E), testez %ERROR tout de suite après l'appel, avant qu'une autre opération ne le réinitialise.
Un paramètre sans const est modifiable par la procédure appelée : c'est pratique pour renvoyer un résultat, dangereux si on ne s'y attend pas.