Aller au contenu

%UPPER

Passer en majuscules

Renvoie le texte converti en majuscules, accents compris, sans modifier la zone d'origine.

Syntaxe

%UPPER(chaîne)
chaîne
Le texte à convertir : zone caractère, graphique ou UCS-2, littéral ou expression.
Résultat
Une valeur du même type et de la même longueur que la chaîne, avec les lettres en majuscules. La zone d'origine n'est pas modifiée.

À quoi ça sert

L'usage principal est la comparaison sans tenir compte de la casse : %UPPER(saisie) = 'OUI' accepte Oui, oui et OUI. C'est aussi ce qui permet d'afficher un nom ou une ville en capitales.

%UPPER connaît la table de caractères de la zone (CCSID) : un é devient É, ce que le %XLATE sur les 26 lettres ne fait pas.

Exemple 1 : Comparer sans tenir compte de la casse

**free
// %UPPER : passer un texte en majuscules pour comparer sans tenir compte de la casse.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s saisie  char(10)    inz('Oui');
dcl-s ville   varchar(20) inz('Montpellier');
dcl-s villeF  char(15)    inz('Lyon');
dcl-s majF    char(15);

snd-msg 'Ville       : [' + %upper(ville) + ']';
if saisie = 'OUI';
  snd-msg 'Sans %UPPER   : reponse reconnue';
else;
  snd-msg 'Sans %UPPER   : reponse non reconnue';
endif;
if %upper(saisie) = 'OUI';
  snd-msg 'Avec %UPPER   : reponse reconnue';
endif;

// Sur une zone fixe, le resultat garde la meme longueur.
majF = %upper(villeF);
snd-msg 'Zone fixe   : [' + majF + ']';
snd-msg 'Longueur    : ' + %char(%len(%upper(villeF)));
snd-msg 'Origine     : [' + villeF + ']';

*inlr = *on;

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

Ville       : [MONTPELLIER]
Sans %UPPER   : reponse non reconnue
Avec %UPPER   : reponse reconnue
Zone fixe   : [LYON           ]
Longueur    : 15
Origine     : [Lyon           ]

La saisie Oui n'est pas égale à 'OUI' : le test direct échoue. Avec %UPPER, la réponse est reconnue.

Sur une zone fixe de 15, le résultat garde 15 caractères, blancs de fin compris. La zone d'origine reste Lyon, car la fonction renvoie une valeur et ne modifie rien.

Exemple 2 : Lettres accentuées, avec %XLATE en comparaison

**free
// %UPPER et les lettres accentuees, comparees a %XLATE.
ctl-opt dftactgrp(*no) actgrp(*new);

// "Cafe" avec e accent aigu, ecrit en octets UTF-8 : la source reste sans accent.
dcl-s brut  char(5) ccsid(*hex) inz(x'436166C3A9');
dcl-s utf8  varchar(20) ccsid(1208);
dcl-s texte varchar(20);
dcl-c MIN 'abcdefghijklmnopqrstuvwxyz';
dcl-c MAJ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';

utf8 = brut;
texte = utf8;

snd-msg 'Origine       : [' + texte + ']';
snd-msg '%UPPER        : [' + %upper(texte) + ']';
snd-msg '%XLATE a-z    : [' + %xlate(MIN : MAJ : texte) + ']';
snd-msg '%UPPER UTF-8  : [' + %upper(utf8) + ']';

*inlr = *on;

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

Origine       : [Café]
%UPPER        : [CAFÉ]
%XLATE a-z    : [CAFé]
%UPPER UTF-8  : [CAFÉ]

Le texte Café est fabriqué à partir de ses octets UTF-8. %UPPER donne CAFÉ, que la zone soit en UTF-8 ou dans le CCSID du travail. Le %XLATE qui convertit seulement de a-z en A-Z laisse le é tel quel : CAFé.

Le piège

Pour les accents, %XLATE ne suffit pas. Une table a-z vers A-Z ne connaît pas les lettres accentuées : Café devient CAFé, ce qui casse une comparaison ou un tri. %UPPER donne CAFÉ.

Autre point : sur une zone fixe, le résultat garde la longueur de la zone. %LEN(%UPPER(ville)) vaut 15 pour un char(15) qui contient Lyon, et les blancs de fin restent. Ajoutez %TRIMR pour construire un message. Enfin, la zone d'origine n'est jamais modifiée : il faut affecter le résultat à une zone pour le conserver.