1 pièce(s) jointe(s)
[import] de données pas propres !
Salut à tous,
J'ai un fichier txt qui contient des données pas vraiment propres : il y a une variable "pack" qui parfois n'est pas remplie. Mais là où c'est pire que pas remplie, c'est qu'il n'y a pas les delimiters pour indiquer que la valeur de la variable est vide. On a par exemple (si mes delimiters sont des "|") :
var 1 | var 2 | var 3
mod1 | mod2 | mod3
mod1 |mod3
mod1 | mod2 |mod3
Ainsi, lorsque j'importe dans SAS, j'ai parfois la valeur d'une modalité de la variable 3 qui se trouve dans la colonne de la variable 2 (et tout est décalé pour les autres colonnes). Après recherches (et aide d'un d'entre vous dans un précédent post pour un souci différent mais astuce retenue!), j'arrive à ce niveau de code :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
DATA WORK.test;
%let _EFIERR_ = 0;
INFILE "C:\...\Ptest.txt" delimiter=' ' MISSOVER DSD lrecl=32767 firstobs=2 ;
input pack $ @;
if ((anydigit(substr(_INFILE_,1,1))>0 and anydigit(substr(_INFILE_,2,1))>0 and (anydigit(substr(_INFILE_,3,1))>0 or substr(_INFILE_,3,1)="-") and anydigit(substr(_INFILE_,4,1))>0) or _INFILE_="UNSPECIFIED") then do;
INPUT
Sequence : $5.
Code1 : $15.
Country : $50.
Code2 : $15.
unite : $5.
LIBELLE : $15.
valeur : COMMAX22.2
;
end;
else do;
INPUT
Sequence : $5.
pack : $120.
Code1 : $15.
Country : $50.
Code2 : $15.
unite : $5.
LIBELLE : $15.
valeur : COMMAX22.2
;
end;
FORMAT
Sequence : $5.
pack : $120.
Code1 : $15.
Country : $50.
Code2 : $15.
unite : $5.
LIBELLE : $15.
valeur : COMMAX22.2
;
INFORMAT
Sequence : $5.
pack : $120.
Code1 : $15.
Country : $50.
Code2 : $15.
unite : $5.
LIBELLE : $15.
valeur BEST12.
;
if _ERROR_ then call symputx('_EFIERR_',1);
RUN; |
L'idée que je cherche à mettre en oeuvre, c'est mettre le contenu de la variable pack dans _INFILE_, la tester et si elle a une certaine forme je reconnais qu'il s'agit en réalité de la variable d'après Code1 => j'essaie de dire à SAS de sauter cette variable dans l'import.
Je joins un petit fichier txt avec un exemple de mon souci.
J'espère avoir réussi à bien expliquer le problème que je rencontre...
Ha oui, ce que j'ai fait ne fonctionne pas du tout. Il y a quelque chose que je n'ai pas compris dans le fonctionnement des input je pense. Si je fais un put _INFILE_, j'obtiens bien le contenu de la variable pack. Par contre c'est après que ça pêche...
Merci beaucoup d'avance pour votre aide !
Pièce jointe 293835
[import] de données pas propres
Bonjour,
Voici une proposition :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| data work.test;
%let _EFIERR_ = 0;
infile "D:\temp\Ptest.txt" delimiter='09'x dsd missover firstobs=2;
input Sequence :$10. Pack :$24. @;
if anyalpha(strip(Pack)) then input Pack :$24. @; /* On lit à nouveau Pack */
input
/* Code1 :$15.*/ /* (Je pense qu'il manque les données de la variable Code1 dans le fichier texte.) */
Country :$50.
Code2 :$15.
unite :$5.
LIBELLE :$15.
valeur :8.6
;
format valeur 8.2;
if _ERROR_ then call symputx('_EFIERR_',1);
run; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| S
e C L
q o I v
u u C u B a
e P n o n E l
n a t d i L e
c c r e t L u
e k y 2 e E r
36663 9999999999 France EPC01168 KG 960.00
36664 0000010929 EPC02941 KG 910.00
36665 0000008119 EPC00000 KG 1000.00
36666 9999999999 EPC01194 KG 960.00
36667 9999999999 EPC01196 KG 960.00
36668 9999999999 EPC01195 KG 960.00
36669 0000008119 EPC00000 KG 1000.00
36670 9999999999 EPC01200 KG 960.00
36671 9999999999 EPC00901 KG 970.00
36668 9999999999 EPC01195 960.00
36669 0000008119 EPC00000 1000.00
36670 9999999999 EPC01200 960.00
36671 9999999999 EPC00901 970.00
36672 9999999999 EPC00682 L 750.00
36673 0000010650 EPC02942 KG 970.00
36674 9999999999 FRANCE~SPAIN EPC01170 KG 700.00
36675 9999999999 SPAIN EPC01170 KG 700.00
36676 9999999999 SPAIN EPC01170 KG 700.00
36677 9999999999 FRANCE EPC01170 KG 700.00
38083 0000008363 EPC00000 KG 1000.00
38084 0000008031 EPC00000 KG 1000.00
38085 0000008119 EPC00000 KG 1000.00
38086 0000008363 EPC00000 KG 1000.00
36663 9999999999 FRANCE~ITALY~NETHERLANDS~ROMANIA~SLOVENIA~SOUTH AF EPC01168 960.00
36664 0000010929 EPC02941 910.00
36665 0000008119 EPC00000 1000.00 |
Cordialement,
[import] de données pas propres
Bonjour,
Je n'avais effectivement pas compris votre demande. Voici une nouvelle version du programme.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| data work.test;
%let _EFIERR_ = 0;
infile "D:\temp\Ptest.txt" delimiter='09'x dsd missover firstobs=2;
input Sequence :$10. Code1 :$24. @; /* On lit Sequence et Code1 et on suspend la lecture */
if anyalpha(strip(Code1)) then do; /* On teste Code1 */
Pack=Code1; /* On affecte Code1 à Pack */
input Code1 :$24. @; /* On lit à nouveau Code1 et on suspend la lecture */
end;
input /* On reprend la lecture */
Country :$50.
Code2 :$15.
unite :$5.
LIBELLE :$15.
valeur :8.6
;
format valeur 8.2;
if _ERROR_ then call symputx('_EFIERR_',1);
run; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| Sequence Code1 Pack Country Code2 unite LIBELLE valeur
36663 9999999999 France EPC01168 KG 960.00
36664 0000010929 EPC02941 KG 910.00
36665 0000008119 EPC00000 KG 1000.00
36666 9999999999 EPC01194 KG 960.00
36667 9999999999 EPC01196 KG 960.00
36668 9999999999 EPC01195 KG 960.00
36669 0000008119 EPC00000 KG 1000.00
36670 9999999999 EPC01200 KG 960.00
36671 9999999999 EPC00901 KG 970.00
36668 9999999999 2,4-D abcdefghi EPC01195 960.00
36669 0000008119 Hdcntrvscrf EPC00000 1000.00
36670 9999999999 2,4-D cezrkbvyerjkscntjk EPC01200 960.00
36671 9999999999 trzcnuztiycer rtfcqtuj,o EPC00901 970.00
36672 9999999999 EPC00682 L 750.00
36673 0000010650 EPC02942 KG 970.00
36674 9999999999 FRANCE~SPAIN EPC01170 KG 700.00
36675 9999999999 SPAIN EPC01170 KG 700.00
36676 9999999999 SPAIN EPC01170 KG 700.00
36677 9999999999 FRANCE EPC01170 KG 700.00
38083 0000008363 EPC00000 KG 1000.00
38084 0000008031 EPC00000 KG 1000.00
38085 0000008119 EPC00000 KG 1000.00
38086 0000008363 EPC00000 KG 1000.00
36663 9999999999 2,4-D ctqzevrbvc FRANCE~ITALY~NETHERLANDS~ROMANIA~SLOVENIA~SOUTH AF EPC01168 960.00
36664 0000010929 DEVZRv revq Tercta EPC02941 910.00
36665 0000008119 EVT T4ZVQRE EPC00000 1000.00 |
Le @ sert à suspendre la lecture des données pour rester sur la même ligne du fichier texte. Pour comprendre, comparez les deux programmes suivants :
Code:
1 2 3 4 5 6 7 8 9
| data work.test;
%let _EFIERR_ = 0;
infile "D:\temp\Ptest.txt" delimiter='09'x dsd missover firstobs=2;
input Sequence :$10.;
input Code1 :$24.;
if _ERROR_ then call symputx('_EFIERR_',1);
run; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Sequence Code1
36663 36664
36665 36666
36667 36668
36669 36670
36671 36668
36669 36670
36671 36672
36673 36674
36675 36676
36677 38083
38084 38085
38086 36663
36664 36665 |
Code:
1 2 3 4 5 6 7 8 9
| data work.test;
%let _EFIERR_ = 0;
infile "D:\temp\Ptest.txt" delimiter='09'x dsd missover firstobs=2;
input Sequence :$10. @;
input Code1 :$24.;
if _ERROR_ then call symputx('_EFIERR_',1);
run; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| Sequence Code1
36663 9999999999
36664 0000010929
36665 0000008119
36666 9999999999
36667 9999999999
36668 9999999999
36669 0000008119
36670 9999999999
36671 9999999999
36668 2,4-D abcdefghi
36669 Hdcntrvscrf
36670 2,4-D cezrkbvyerjkscntjk
36671 trzcnuztiycer rtfcqtuj,o
36672 9999999999
36673 0000010650
36674 9999999999
36675 9999999999
36676 9999999999
36677 9999999999
38083 0000008363
38084 0000008031
38085 0000008119
38086 0000008363
36663 2,4-D ctqzevrbvc
36664 DEVZRv revq Tercta
36665 EVT T4ZVQRE |
Cordialement,