%SPLIT
Découper une chaîne en morceaux
Découpe un texte selon un ou plusieurs caractères séparateurs et renvoie la liste des morceaux, à parcourir avec FOR-EACH ou à ranger dans un tableau.
Syntaxe
%SPLIT(chaîne)
%SPLIT(chaîne : séparateurs)
chaîne- Le texte à découper.
séparateurs- Facultatif : les caractères qui séparent les morceaux. Chacun des caractères coupe :
',;'coupe sur la virgule et sur le point-virgule. Sans ce paramètre, le séparateur est le blanc. - Résultat
- Une liste de chaînes, sans le séparateur. Elle s'utilise dans un
FOR-EACHou s'affecte à un tableau ;%ELEMcompte alors les morceaux si le tableau est déclaré avecdim(*auto : n).
À quoi ça sert
Lire une ligne CSV, séparer les mots d'une phrase, découper un chemin ou une liste de paramètres : avant %SPLIT, il fallait une boucle de %SCAN et de %SUBST. Maintenant, un FOR-EACH suffit, et le morceau arrive déjà découpé.
Exemple 1 : Champs d'une ligne, mots, tableau
**free
// %SPLIT : decouper une ligne en morceaux, dans une boucle FOR-EACH ou dans un tableau.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s ligne varchar(60) inz('Dupont SA;Montpellier;1250.50');
dcl-s phrase varchar(60) inz('Bernard Transports Brest');
dcl-s morceau varchar(30);
dcl-s champs varchar(30) dim(*auto : 10);
dcl-s solde packed(9:2);
// Le separateur est le point-virgule.
for-each morceau in %split(ligne : ';');
snd-msg 'Champ : [' + morceau + ']';
endfor;
// Sans separateur indique, le blanc est utilise.
for-each morceau in %split(phrase);
snd-msg 'Mot : [' + morceau + ']';
endfor;
// Dans un tableau : %ELEM donne ensuite le nombre de morceaux.
champs = %split(ligne : ';');
solde = %dec(champs(3) : 9 : 2);
snd-msg 'Nombre de champs : ' + %char(%elem(champs));
snd-msg 'Solde + 100 : ' + %char(solde + 100);
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Champ : [Dupont SA]
Champ : [Montpellier]
Champ : [1250.50]
Mot : [Bernard]
Mot : [Transports]
Mot : [Brest]
Nombre de champs : 3
Solde + 100 : 1350.50
La ligne Dupont SA;Montpellier;1250.50 est parcourue champ par champ. Sans séparateur indiqué, la phrase Bernard Transports Brest est coupée sur les blancs.
Dans un tableau déclaré dim(*auto : 10), on affecte directement %SPLIT. %ELEM donne 3, et le troisième champ se convertit avec %DEC.
Exemple 2 : Champs vides, blancs, tableau trop petit
**free
// %SPLIT : champs vides ignores, blancs conserves, tableau trop petit.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s morceau varchar(30);
dcl-s nb int(10);
dcl-s petit varchar(30) dim(2);
// 1. Deux separateurs de suite : le champ vide disparait, les positions sont decalees.
nb = 0;
for-each morceau in %split('100;;Lyon' : ';');
nb += 1;
snd-msg 'Vide ignore ' + %char(nb) + ' : [' + morceau + ']';
endfor;
// 2. Avec un blanc entre les separateurs, le champ est conserve.
nb = 0;
for-each morceau in %split('100; ;Lyon' : ';');
nb += 1;
snd-msg 'Un blanc ' + %char(nb) + ' : [' + morceau + ']';
endfor;
// 3. Les blancs autour d'un champ ne sont pas retires.
for-each morceau in %split('a; b ;c' : ';');
snd-msg 'Espaces : [' + morceau + ']';
endfor;
// 4. Plusieurs caracteres separateurs : chacun coupe.
nb = 0;
for-each morceau in %split('a,b;c' : ',;');
nb += 1;
endfor;
snd-msg 'Virgule et point-virgule : ' + %char(nb) + ' morceaux';
// 5. Chaine vide : aucun tour de boucle.
nb = 0;
for-each morceau in %split('' : ';');
nb += 1;
endfor;
snd-msg 'Chaine vide : ' + %char(nb) + ' tour de boucle';
// 6. Tableau trop petit : le surplus est perdu, sans erreur.
petit = %split('a,b,c' : ',');
snd-msg 'Tableau de 2 : [' + petit(1) + '] [' + petit(2) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Vide ignore 1 : [100]
Vide ignore 2 : [Lyon]
Un blanc 1 : [100]
Un blanc 2 : [ ]
Un blanc 3 : [Lyon]
Espaces : [a]
Espaces : [ b ]
Espaces : [c]
Virgule et point-virgule : 3 morceaux
Chaine vide : 0 tour de boucle
Tableau de 2 : [a] [b]
Six cas de découpe. Dans 100;;Lyon, le champ vide n'apparaît pas : la boucle ne fait que deux tours et Lyon se retrouve en deuxième position. Si le champ contient un blanc (100; ;Lyon), il est conservé.
Les blancs autour d'un champ restent ( b ). Avec deux caractères séparateurs, chacun coupe. Une chaîne vide ne donne aucun tour. Enfin, une affectation dans un tableau de 2 éléments ne garde que a et b, sans erreur.
Le piège
Les champs vides disparaissent. %SPLIT('100;;Lyon' : ';') renvoie deux morceaux, 100 et Lyon, et non trois. Pour un fichier CSV où une colonne peut être vide, la position ne veut plus rien dire : la ville se retrouve dans la colonne du courriel. Il faut soit remplacer les champs vides par un blanc avant le découpage, soit lire le texte avec %SCAN.
Deux autres surprises : les blancs autour des morceaux ne sont pas retirés (utilisez %TRIM), et un tableau trop petit reçoit le début de la liste sans message d'erreur, le reste est perdu.