Aller au contenu

%CONCAT

Assembler des textes avec un séparateur

Concatène plusieurs chaînes en intercalant un séparateur entre chacune.

Syntaxe

%CONCAT(séparateur : chaîne1 : chaîne2 {: chaîne3 …})
séparateur
Le texte placé entre deux chaînes : un blanc, une virgule, un point-virgule. Il peut être vide ('').
chaîne1, chaîne2…
Les textes à assembler. Chacun est repris tel quel.
Résultat
Une chaîne : les textes bout à bout, le séparateur entre chaque paire.

À quoi ça sert

Construire un nom complet, une adresse, une ligne CSV : avec l'opérateur +, il faut répéter le séparateur entre chaque terme. %CONCAT l'écrit une seule fois, et on n'oublie plus de l'ajouter quand on ajoute une colonne.

Exemple 1 : Nom complet et adresse

**free
// %CONCAT : assembler plusieurs textes avec un separateur.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s prenom char(15)    inz('Jean');
dcl-s nom    char(20)    inz('Dupont');
dcl-s ville  varchar(20) inz('Montpellier');
dcl-s cp     char(5)     inz('34000');

snd-msg 'Nom complet : [' + %concat(' ' : %trim(prenom) : %trim(nom)) + ']';
snd-msg 'Sans trim   : [' + %concat(' ' : prenom : nom) + ']';
snd-msg 'Adresse     : [' + %concat(', ' : %trim(nom) : cp + ' ' + ville) + ']';
snd-msg 'Sans espace : [' + %concat('' : %trim(prenom) : %trim(nom)) + ']';
snd-msg 'Avec nombre : [' + %concat(' - ' : %trim(nom) : %char(1250.5) + ' EUR') + ']';

*inlr = *on;

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

Nom complet : [Jean Dupont]
Sans trim   : [Jean            Dupont              ]
Adresse     : [Dupont, 34000 Montpellier]
Sans espace : [JeanDupont]
Avec nombre : [Dupont - 1250.5 EUR]

Avec %TRIM sur chaque zone, le prénom et le nom sont joints par un seul blanc : Jean Dupont. Sans %TRIM, on obtient les zones entières : le prénom de 15 et le nom de 20 caractères gardent leurs blancs de fin.

Le séparateur peut faire plusieurs caractères (, ) ou être vide, et un nombre passe par %CHAR.

Exemple 2 : Ligne CSV et champ vide

**free
// %CONCAT : ligne CSV a partir de zones, et champ vide conserve.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s numcli packed(5:0)  inz(100);
dcl-s nom    char(30)     inz('Dupont SA');
dcl-s ville  char(20)     inz('Montpellier');
dcl-s solde  packed(9:2)  inz(1250.50);
dcl-s email  varchar(40)  inz('');
dcl-s ligne  varchar(100);
dcl-s morceau varchar(30);
dcl-s nb     int(10);

ligne = %concat(';' : %char(numcli) : %trim(nom) : %trim(ville) : %char(solde) : email);
snd-msg 'Ligne CSV  : [' + ligne + ']';

// Un champ vide est bien conserve : deux separateurs de suite.
ligne = %concat(';' : %char(numcli) : '' : %trim(ville));
snd-msg 'Champ vide : [' + ligne + ']';

// Mais %SPLIT ne le restitue pas : on perd un champ a la relecture.
for-each morceau in %split(ligne : ';');
  nb += 1;
endfor;
snd-msg 'Relecture  : ' + %char(nb) + ' champs au lieu de 3';

*inlr = *on;

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

Ligne CSV  : [100;Dupont SA;Montpellier;1250.50;]
Champ vide : [100;;Montpellier]
Relecture  : 2 champs au lieu de 3

Six colonnes assemblées avec ;. L'adresse électronique est vide : la ligne finit par un point-virgule, la colonne existe bien. De même, un champ vide au milieu donne deux séparateurs de suite : 100;;Montpellier.

Relue avec %SPLIT, cette ligne ne redonne que deux champs : le champ vide a disparu.

Le piège

%CONCAT ne retire aucun blanc. Les zones fixes sont assemblées avec leurs blancs de fin : %CONCAT(' ' : prenom : nom) avec un char(15) et un char(20) donne le prénom suivi de ses blancs de fin, le séparateur, puis le nom. Il faut mettre un %TRIM sur chaque terme.

Second point : un terme vide est gardé et son séparateur aussi (a--b), alors que %SPLIT ignore les champs vides. L'aller-retour %CONCAT puis %SPLIT ne redonne donc pas toujours la liste de départ.