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