Aller au contenu

%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).