%MIN
La plus petite de plusieurs valeurs
Renvoie la plus petite des valeurs passées (nombres, dates ou texte).
Syntaxe
%MIN(valeur1 : valeur2 {: valeur3 …})
valeur1, valeur2…- Deux valeurs ou plus, de même nature : des nombres, des dates ou du texte.
- Résultat
- La plus petite des valeurs, avec le type de l'expression (un nombre pour des nombres, une date pour des dates, du texte pour du texte).
À quoi ça sert
Sert à plafonner : %min(remise : 100) ne dépasse jamais 100. Combiné à %max, il encadre une valeur entre deux bornes sans if. Avec des dates, on obtient la plus ancienne.
Exemple 1 : Plafonner et encadrer
**free
// %MIN : la plus petite de plusieurs valeurs, nombres ou dates.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s achat1 packed(9:2) inz(1250.50);
dcl-s achat2 packed(9:2) inz(98000.00);
dcl-s achat3 packed(9:2) inz(45.10);
dcl-s remise packed(5:2) inz(130.00);
dcl-s cree date inz(d'2019-06-30');
dcl-s modifie date inz(d'2024-01-08');
dcl-s livre date inz(d'2021-11-02');
snd-msg 'Plus petit achat : ' + %char(%min(achat1 : achat2 : achat3));
// Plafonner une remise a 100 %.
snd-msg 'Remise plafonnee : ' + %char(%min(remise : 100));
// Avec des dates : la plus ancienne.
snd-msg 'Premiere date : ' + %char(%min(cree : modifie : livre));
// Encadrer une valeur entre 0 et 100 : %min et %max ensemble.
remise = -15;
snd-msg 'Remise encadree : ' + %char(%min(%max(remise : 0) : 100));
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Plus petit achat : 45.10
Remise plafonnee : 100.00
Premiere date : 2019-06-30
Remise encadree : .00
Le plus petit achat est 45,10. Une remise de 130 % est ramenée à 100, et parmi trois dates on garde la plus ancienne (2019-06-30). La dernière ligne encadre une remise de -15 entre 0 et 100 : %max(remise : 0) la ramène à 0, puis %min(… : 100) la plafonne.
Exemple 2 : Du texte, dans l'ordre EBCDIC
**free
// %MIN sur du texte : l'ordre est celui de l'EBCDIC, pas celui du dictionnaire.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s a char(10) inz('Brest');
dcl-s b char(10) inz('Lyon');
snd-msg 'Brest / Lyon : [' + %min(a : b) + ']';
// Une minuscule est plus petite qu'une majuscule : "zoe" gagne contre "Alice".
snd-msg 'zoe / Alice : [' + %min('zoe' : 'Alice') + ']';
// Un chiffre est plus grand qu'une lettre.
snd-msg '9 rue / Zola : [' + %min('9 rue' : 'Zola') + ']';
// Solution : mettre les deux textes en majuscules avant de comparer.
snd-msg 'ZOE / ALICE : [' + %min(%upper('zoe') : %upper('Alice')) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Brest / Lyon : [Brest ]
zoe / Alice : [zoe]
9 rue / Zola : [Zola]
ZOE / ALICE : [ALICE]
« Brest » est plus petit que « Lyon ». Mais « zoe », en minuscules, est plus petit que « Alice », et « Zola » plus petit que « 9 rue » : en EBCDIC, les minuscules précèdent les majuscules, et les lettres précèdent les chiffres. Avec %upper des deux côtés, l'ordre alphabétique est respecté.
Le piège
Sur du texte, « plus petit » suit l'EBCDIC, pas le dictionnaire. %min('zoe' : 'Alice') renvoie zoe : les minuscules passent avant les majuscules. Mettre les deux côtés en majuscules avec %upper règle le problème pour des noms saisis librement (second exemple).