"call" permet d'appeler un sous-programme s'exécutant avec ses propres variables locales avec retour au traitement appelant. Des paramètres peuvent être passés.
SYNTAXE 1
Call sous_prog [ '(' liste_args ')' ] [ From traitement ]
SYNTAXE 2
Call sous_prog [ With '(' liste_args ')' ] [ From traitement ]
Elément | Description | Restrictions |
sous_prog | sous-programme défini sous l'une des formes suivantes : | Doit correspondre à un Subprog dans le traitement correspondant. |
exp_nomprg | Expression de type Char dont le résultat est un nom de sous-programme. | En cas d'argument, on utilise la syntaxe 2. |
traitement | Traitement dans lequel est défini le sous-programme (par défaut, il s'agit du traitement courant), sous l'une des formes suivantes : | Le traitement doit être accessible. |
exp_nomtrt | Expression de type Char dont le résultat est un nom de traitement. | Le traitement doit être accessible. |
liste_args | Liste d'arguments séparés par ','. Ces arguments peuvent être des variables ou des expressions. | Aucune. |
# Appel d'un sous-programme d'incrémentation de compteur dans le
# traitement TRTCPT. Dans cette instruction, on passe un argument par
# sa valeur. Le paramètre correspondant du sous-programme INCR_CPT
# doit être déclaré nécessairement avec le mode Value.Call INCR_CPT(10)
# Un peu plus loin dans le même traitement...
Subprog INCR_CPT(DELTA)
Value Integer DELTA
Trbegin [ACM]
Lock COMPTEUR With lockwait = 5
If fstat : Rollback : End : Endif
[C]COMPTEUR += DELTA
Commit
# Appel d'un sous-programme sans argument dans un autre traitement
# de la première application de référence.
Call INCR1_CPT From = adxmother(0)+".TRTCPT"
# Appel d'un sous-programme avec arguments.
# Le nom du sous-programme est stocké dans la variable WWPROG.
# Il est donc nécessaire d'utiliser la syntaxe 2
If [F:AMA]ACTION="SPE" : WWTRT = [F:AMK]TRTSPE : Endif
If [F:AMA]ACTION="STD" : WWTRT = [F:AMK]TRTSTD : Endif
WWPROG = "AV_"+[F:AMZ]CODZONCall =WWPROG With VALEUR From =WWTRT
# Appel d'un sous-programme avec un tableau en argument
Local Char T(10)(0..2)
Call VERIF(T)
EndSubprog VERIF(T)
Variable Char T
End
# si le premier poste est différent de 0 (valeur par défaut)
# préciser les bornes du tableau, dans le traitement appelant et le sous-programme
Local Char T(10)(1..3)
Call VERIF(T)
EndSubprog VERIF(T)
Variable Char T()(1..3)
End
"call" permet de lancer un sous-programme avec passage éventuel de paramètres. A l'issue de cette exécution, le traitement appelant reprend son exécution à l'instruction suivant l'instruction "call", les variables locales au sous-programme et les OBJets ouverts par lui en mode Local étant refermés.
Lorsque l'appel "call" est fait sans préciser de traitement, le sous- programme doit se trouver dans le traitement lui-même.
Les arguments passés dans le "call" doivent être en nombre égaux à ceux du sous-programme. L'ordre des paramètres dans "call" étant mis en correspondance avec ceux de Subprog.
Les arguments peuvent être des expressions ou des variables. Si c'est une expression, son passage doit obligatoirement se faire par valeur (Value); l'argument de Subprog ne doit pas être dimensionné.
Une variable passée en argument peut être dimensionnée. Elle doit alors avoir la même dimension que la variable correspondante du Subprog. On peut ne passer qu'une partie.
Exemple : soit un tableau d'entiers à 2 dimensions déclaré par :
Integer T2(I1..I2,J1..J2)
Avec I1 <= I11 <= I21 <= I2 et J1 <= J11 <= J21 <= J2Si on fait Call SUBPRG( T2 ), on passera tout le tableau.
Si on fait Call SUBPRG( T2(I1..I2,J1..J2)) idem.
Si on fait Call SUBPRG( T2(I11,J1..J2)) on ne passera qu'une "ligne".
Si on fait Call SUBPRG( T2(I1..I2,J11)) une "colonne".
Si on fait Call SUBPRG( T2(I11,J11) un seul "élément".
si on fait Call SUBPRG( T2(I11..I21,J1..J2)) plusieurs "lignes".
etc.
Pendant un "call", les informations suivantes sont conservées :
Par contre sont perdues :
Pendant l'exécution d'un "call", il y a création d'une classe de variables locales au sous-programme d'abréviation [L]. Cette classe locale devient la classe par défaut, la classe locale au traitement appelant n'étant alors plus accessible. Au retour au traitement, on retrouve la classe locale par défaut, préexistante à l'appel.
Il n'y a pas de niveau de localité pour les masques : si un écran est ouvert dans un traitement et dans le sous-programme sous la même abréviation, il n'y a qu'un buffer. (fonctionnement différent des tables, qui elles, ont des niveaux de localité.
Si on modifie pendant l'exécution d'un "call" les classes par défaut, les masques, les fichiers ouverts , il est impératif d'utiliser pour ce faire les instructions Local Mask, Local File. En effet, les instructions Mask, File influent sur les objets ouverts, ce qui pose des problèmes au retour du "call".
Un "call" peut s'appeler récursivement, le nombre de "call" imbriqués n'est pas limité mais il faudra faire attention à la mémoire disponible, aux nombre d'OBJets ouverts et, en particulier, au nombre de fichiers ouverts en mode Local car chaque sous programme est vu comme indépendant. Exemple :
Close File : adxmto = 10 : Call SBPRG
# Avec
Subprog SBPRG
Local File FIC1 : Call SBPRG : End
# Au bout de 10 appels, une erreur TROPFIC arrêtera ce traitement.
Erreur | Description |
PAFIC (20) | Traitement inexistant. |
ERDIM (55) | Nombre de dimensions incorrect. |
ERARGNO (69) | Nombre d'arguments déclarés dans Subprog ne correspondant pas au nombre passé en Call. |
ERARGTY (70) | mode de passage incompatible. |
ERLAB (39) | Sous-programme inexistant. |
ERMODE (10) | exp_nomtrt n'est pas une chaîne de caractères. |