%ELEM
Nombre d'éléments d'un tableau
Renvoie le nombre d'éléments d'un tableau : sa dimension déclarée, ou, pour un tableau dim(*auto), le nombre d'éléments actuellement utilisés.
Syntaxe
%ELEM(tableau)
%ELEM(tableau : *MAX)
tableau- Un tableau de zones, ou un tableau de structures de données (
dcl-ds … dim(n)). *MAX- Pour un tableau
dim(*auto : max)seulement : renvoie la dimension maximalemaxau lieu du nombre d'éléments en cours. - Résultat
- Un entier. Pour un tableau à dimension fixe, c'est une constante connue à la compilation (on peut donc l'utiliser dans un
dcl-c). Pour un tableaudim(*auto), c'est le nombre d'éléments ajoutés ; il peut aussi être affecté pour réduire ou vider le tableau.
À quoi ça sert
On écrit for i = 1 to %elem(villes) plutôt que for i = 1 to 5 : si la dimension change dans la déclaration, toutes les boucles suivent, sans aller les chercher une par une.
Avec dim(*auto), le tableau devient une vraie liste : tableau(*next) = valeur ajoute un élément, %elem dit combien il y en a, et on n'a plus besoin d'un compteur à part.
Exemple 1 : Tableau à dimension fixe
**free
// %ELEM : nombre d'elements d'un tableau, dimension fixe ou dim(*auto).
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s villes char(12) dim(5);
dcl-ds ligne qualified dim(3);
numcli packed(5:0);
nom char(20);
end-ds;
dcl-s i int(10);
// %elem est une constante calculee a la compilation.
dcl-c NB_VILLES %elem(villes);
ligne(1).numcli = 100;
ligne(1).nom = 'Dupont SA';
villes(1) = 'Montpellier';
villes(2) = 'Lyon';
// La dimension est fixe : 5 elements, meme si 2 seulement sont remplis.
snd-msg 'Elements de villes : ' + %char(%elem(villes));
snd-msg 'Elements de ligne : ' + %char(%elem(ligne));
// Parcours complet grace a %elem : le compilateur garde la borne a jour.
for i = 1 to %elem(villes);
snd-msg 'villes(' + %char(i) + ') = [' + villes(i) + ']';
endfor;
snd-msg 'Constante NB_VILLES = ' + %char(NB_VILLES);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Elements de villes : 5
Elements de ligne : 3
villes(1) = [Montpellier ]
villes(2) = [Lyon ]
villes(3) = [ ]
villes(4) = [ ]
villes(5) = [ ]
Constante NB_VILLES = 5
Le tableau villes a 5 éléments dont 2 seulement sont remplis : %elem répond 5. Il en va de même pour le tableau de structures ligne, dont la dimension est 3. Comme la valeur est connue à la compilation, elle peut servir à définir la constante NB_VILLES.
Exemple 2 : dim(*auto) : un tableau qui grandit
**free
// %ELEM avec dim(*auto) : le nombre d'elements suit le contenu du tableau.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s noms varchar(20) dim(*auto : 100);
dcl-s i int(10);
snd-msg 'Au depart : ' + %char(%elem(noms));
snd-msg 'Maximum : ' + %char(%elem(noms : *max));
noms(*next) = 'Dupont SA';
noms(*next) = 'Martin et fils';
noms(*next) = 'Leroy SARL';
snd-msg 'Apres 3 ajouts : ' + %char(%elem(noms));
for i = 1 to %elem(noms);
snd-msg 'noms(' + %char(i) + ') = [' + noms(i) + ']';
endfor;
// Reduire ou vider : on affecte %elem.
%elem(noms) = 1;
snd-msg 'Apres reduction : ' + %char(%elem(noms));
%elem(noms) = 0;
snd-msg 'Apres vidage : ' + %char(%elem(noms));
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Au depart : 0
Maximum : 100
Apres 3 ajouts : 3
noms(1) = [Dupont SA]
noms(2) = [Martin et fils]
noms(3) = [Leroy SARL]
Apres reduction : 1
Apres vidage : 0
Au départ le tableau est vide : %elem vaut 0, alors que %elem(noms : *max) donne le maximum (100). Chaque noms(*next) = … ajoute un élément et %elem suit. On peut ensuite affecter %elem pour réduire le tableau (1) ou le vider (0).
Exemple 3 : Dépasser le maximum de dim(*auto)
**free
// dim(*auto : 2) : le maximum est une vraie limite, %elem ne le depasse jamais.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s ville varchar(20) dim(*auto : 2);
ville(*next) = 'Lyon';
ville(*next) = 'Brest';
snd-msg 'Elements : ' + %char(%elem(ville)) + ' sur ' + %char(%elem(ville : *max));
// Le troisieme ajout depasse le maximum : le programme s'arrete.
ville(*next) = 'Rennes';
snd-msg 'Cette ligne n''est jamais atteinte';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Elements : 2 sur 2
Erreur : RNQ0124 - 3 n'est pas un nombre d'éléments valide pour le tableau (C G D F).
Le maximum déclaré (2) est une vraie limite : le troisième (*next) arrête le programme avec le message RNQ0124. Il faut donc prévoir un maximum assez large.
Le piège
Sur un tableau à dimension fixe, %elem ne compte pas les éléments remplis. Il renvoie toujours la dimension déclarée : 5 pour villes dans le premier exemple, alors que deux éléments seulement contiennent une valeur. Les autres sont à blanc (ou à zéro pour un tableau numérique) et une boucle sur %elem les parcourt aussi.
Pour un nombre d'éléments utiles, il faut soit un compteur tenu à la main, soit un tableau dim(*auto). Et avec dim(*auto), on ne dépasse pas le maximum : le troisième exemple s'arrête sur RNQ0124.