%CHAR
Convertir en texte
Transforme un nombre, une date, une heure ou un horodatage en chaîne de caractères, prête à être concaténée, affichée ou écrite dans un message.
Syntaxe
%CHAR(expression)
%CHAR(date-heure : format)
expression- Ce qu'il faut convertir : une zone ou une expression numérique (packed, zoned, int, float…), une date, une heure, un horodatage, ou une zone graphique ou UCS-2.
format- Pour une date, une heure ou un horodatage seulement : le format du texte produit (
*ISO,*EUR,*DMY,*ISO0…). Sans format, c'est celui de la zone qui s'applique,*ISOpar défaut. - Résultat
- Une valeur caractère. Pour un nombre : sans zéros à gauche ni blancs, avec le signe moins s'il est négatif et le point décimal. Pour une date ou une heure : dans le format demandé, avec ses séparateurs (sauf les formats en 0 comme
*ISO0).
À quoi ça sert
En RPG full free, on ne peut pas concaténer un nombre ou une date avec du texte : 'Total : ' + montant ne compile pas (RNF7421). %CHAR fait la conversion, au plus court : pas de zéros ni de blancs à supprimer ensuite, contrairement à une zone de travail alphanumérique.
C'est la fonction qu'on utilise sans y penser pour tout ce qui s'affiche : un message avec snd-msg, un libellé d'écran, une ligne de fichier CSV, un nom de fichier construit avec une date.
Exemple 1 : Nombres, dates et heures
**free
// %CHAR : convertir un nombre, une date ou une heure en texte.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s montant packed(7:2) inz(1234.50);
dcl-s negatif packed(7:2) inz(-42.10);
dcl-s demi packed(5:2) inz(0.5);
dcl-s compte int(10) inz(42);
dcl-s jour date inz(d'2026-09-30');
dcl-s heure time inz(t'14.05.00');
snd-msg 'Montant : [' + %char(montant) + ']';
snd-msg 'Negatif : [' + %char(negatif) + ']';
snd-msg '0,5 : [' + %char(demi) + ']';
snd-msg 'Entier : [' + %char(compte) + ']';
snd-msg 'Date : [' + %char(jour) + ']';
snd-msg 'Date *EUR : [' + %char(jour : *eur) + ']';
snd-msg 'Date *DMY : [' + %char(jour : *dmy) + ']';
snd-msg 'Date *ISO0 : [' + %char(jour : *iso0) + ']';
snd-msg 'Heure *HMS : [' + %char(heure : *hms) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Montant : [1234.50]
Negatif : [-42.10]
0,5 : [.50]
Entier : [42]
Date : [2026-09-30]
Date *EUR : [30.09.2026]
Date *DMY : [30/09/26]
Date *ISO0 : [20260930]
Heure *HMS : [14:05:00]
Les crochets montrent qu'il n'y a aucun blanc autour du résultat. Le montant de 1 234,50 donne 1234.50 : pas de séparateur de milliers, point décimal. Pour une date, le format choisit l'ordre et les séparateurs ; *ISO0 les supprime, pratique pour un nom de fichier.
Regardez la troisième ligne : 0,5 donne .50, sans le zéro. C'est le piège décrit plus bas.
Exemple 2 : Virgule décimale et zéro avant la virgule
**free
// %CHAR avec DECEDIT : virgule decimale et zero avant la virgule.
ctl-opt dftactgrp(*no) actgrp(*new) decedit('0,');
dcl-s montant packed(7:2) inz(1234.50);
dcl-s negatif packed(7:2) inz(-42.10);
dcl-s demi packed(5:2) inz(0.5);
snd-msg 'Montant : [' + %char(montant) + ']';
snd-msg 'Negatif : [' + %char(negatif) + ']';
snd-msg '0,5 : [' + %char(demi) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Montant : [1234,50]
Negatif : [-42,10]
0,5 : [0,50]
Le mot-clé decedit('0,') de ctl-opt change la présentation pour tout le programme : virgule au lieu du point, et un zéro devant la virgule quand la partie entière est nulle. 0,5 devient enfin 0,50.
Le piège
Un nombre inférieur à 1 perd son zéro. Par défaut, %CHAR(0.5) renvoie .50, et %CHAR(-0.25) renvoie -.25. Dans un fichier CSV lu par Excel ou dans un message pour un utilisateur, ça passe mal.
Passer par %EDITC ne règle rien : %EDITC(0.5 : 'J') donne .50 , toujours sans zéro, et avec des blancs autour. La solution est ctl-opt decedit('0,'), ou decedit('0.') pour garder le point : elle s'applique à %CHAR comme à %EDITC, dans tout le programme.