Aller au contenu

%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, *ISO par 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.