Aller au contenu

%SUBARR

Une partie d'un tableau

Désigne une tranche de tableau (un élément de départ et un nombre d'éléments), pour la trier, la copier, la remplir ou l'additionner sans toucher au reste.

Syntaxe

%SUBARR(tableau : départ {: nombre})
tableau
Le tableau dont on prend une tranche.
départ
Position du premier élément de la tranche.
nombre
Nombre d'éléments de la tranche. Sans lui, la tranche va jusqu'à la fin du tableau.
Résultat
Une tranche de tableau, utilisable comme le tableau lui-même à certains endroits : après sorta, à gauche ou à droite d'une affectation, dans %xfoot.

À quoi ça sert

Un tableau est souvent à moitié plein, ou découpé en zones (les 12 mois, puis un total). %subarr permet de trier seulement les éléments utiles, de copier un bloc vers un autre tableau ou de remplir la fin avec une valeur, sans boucle.

Exemple 1 : Trier, copier, remplir, additionner

**free
// %SUBARR : travailler sur une partie d'un tableau (tri, copie, remplissage, somme).
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s ca     packed(9:2) dim(6);
dcl-s copie  packed(9:2) dim(6);
dcl-s ligne  varchar(100);
dcl-s i      int(10);

// Chiffre d'affaires de six mois, dans le desordre.
ca(1) = 1250.50;
ca(2) = 98000.00;
ca(3) = 45.10;
ca(4) = 320.00;
ca(5) = 7800.00;
ca(6) = 0.00;

// Tri des elements 2 a 5 seulement (4 elements a partir du 2e).
sorta %subarr(ca : 2 : 4);
for i = 1 to %elem(ca);
  ligne += %char(ca(i)) + ' ';
endfor;
snd-msg 'Apres tri 2-5 : ' + ligne;

// Copie des elements 4 a 6 vers les elements 1 a 3 de l'autre tableau.
%subarr(copie : 1 : 3) = %subarr(ca : 4 : 3);
snd-msg 'copie(1..3)   : ' + %char(copie(1)) + ' / ' + %char(copie(2)) + ' / ' + %char(copie(3));

// Sans le nombre d'elements, on va jusqu'a la fin du tableau.
%subarr(ca : 5) = 999;
snd-msg 'ca(4) ' + %char(ca(4)) + ', ca(5) ' + %char(ca(5)) + ', ca(6) ' + %char(ca(6));

// Somme des elements 1 a 3.
snd-msg 'Somme 1-3     : ' + %char(%xfoot(%subarr(ca : 1 : 3)));

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Apres tri 2-5 : 1250.50 45.10 320.00 7800.00 98000.00 .00 
copie(1..3)   : 7800.00 / 98000.00 / .00
ca(4) 7800.00, ca(5) 999.00, ca(6) 999.00
Somme 1-3     : 1615.60

Le tri de %subarr(ca : 2 : 4) ne touche ni le premier ni le dernier élément (1 250,50 et 0). La copie envoie les éléments 4 à 6 vers le début de l'autre tableau. %subarr(ca : 5) = 999, sans nombre, remplit du 5e élément jusqu'à la fin. Enfin, %xfoot additionne la tranche 1 à 3.

Exemple 2 : Tranche hors du tableau

**free
// %SUBARR : la plage doit rester dans le tableau, sinon le programme s'arrete.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s ca packed(9:2) dim(6);
dcl-s nb int(10) inz(4);

ca(5) = 100;
ca(6) = 50;
snd-msg 'Somme 3 a 6 : ' + %char(%xfoot(%subarr(ca : 3 : nb)));

// 5 + 4 - 1 = 8 : depasse le 6e element.
snd-msg 'Somme 5 a 8 : ' + %char(%xfoot(%subarr(ca : 5 : nb)));

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Somme 3 a 6 : 150.00
Erreur : RNQ0121 - (C G D F) Indice de tableau hors limites.

La tranche 3 à 6 est correcte (somme 150). La suivante commence à 5 et demande 4 éléments : elle finirait au 8e, alors que le tableau n'en a que 6. Le programme s'arrête avec RNQ0121 (indice hors limites), à l'exécution et non à la compilation.

Le piège

Le compilateur ne vérifie pas la tranche, l'exécution le fait. Quand départ + nombre - 1 dépasse la dimension du tableau, le programme s'arrête avec RNQ0121 (deuxième exemple). Si le nombre vient d'une variable, il faut le contrôler avant.

Autre limite : %subarr n'est pas accepté partout. Il est refusé comme second paramètre de %lookup (RNF0571) et comme premier paramètre de %maxarr (RNF0762). Ces fonctions ont leurs propres paramètres départ et nombre, dont les positions restent celles du tableau entier.