Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 21/06/2011, 15h26   #1
Membre à l'essai
 
Homme Bruno
Inscription : avril 2003
Messages : 69
Détails du profil
Informations personnelles :
Nom : Homme Bruno
Localisation : Belgique

Informations professionnelles :
Secteur : Conseil

Informations forums :
Inscription : avril 2003
Messages : 69
Points : 20
Points : 20
Par défaut proc import dans macro, passage de variable

Bonjour,
Je me bats depuis plusieurs jours avec ce programme et je n'arrive toujours pas à le faire fonctionner correctement. Je voudrais lire plusieurs fichiers contenus dans un répertoire. Dans un premier temps, data all liste les fichiers du répertoire et met dans la table le nom des fichiers (champ name) et le nom complet du chemin+nom fichier (champ chemin). Je boucle sur cette table dans data _null_ et je fais passer la variable chemin dans la macro. Dans la macro importer, put &path; affiche bien la valeur de la variable (donc le chemin complet du fichier). Mais proc import... ne donne pas de résultat. Dans le log, il affiche: ERROR: Physical file does not exist, U:\chemin. C'est comme si il prenait la chaîne "chemin" et non la valeur de la variable. J'ai tout essayé: avec ou sans &, un double &, un "&path", etc. Rien ne passe.

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
%let directo = 'C:\Documents and Settings\etc\';
filename direct pipe 'dir "C:\Documents and Settings\etc\" /b';
%let directy = 'C:\Documents and Settings\etc\fichier.csv';
 
%macro importer(path=);
	put &path;
 
	proc import datafile= "&path" out= output dbms=csv replace;
		delimiter=";";
		getnames=yes;
	run;
%mend importer;
 
data all;
	infile direct truncover;
	input name $26.;
	chemin=trim(&directo || name);
run;
 
data _null_;
	set all;
	%importer (path=chemin)
	run;
run;
J'ai testé la macro indépendamment de la table en mettant directement le nom complet du chemin via la variable directy, ça fonctionne.
Quelqu'un peut-il me dire comment je dois procéder svp ?
Cupidon est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 15h31   #2
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
il faut mettre d'abord
Code :
1
2
 
x cd 'C:\Documents and Settings\etc';
puis dir
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 15h31   #3
Rédacteur
 
Homme Stéphane
Consultant et formateur SAS et Cognos
Inscription : avril 2009
Messages : 1 791
Détails du profil
Informations personnelles :
Nom : Homme Stéphane
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Consultant et formateur SAS et Cognos
Secteur : Conseil

Informations forums :
Inscription : avril 2009
Messages : 1 791
Points : 4 012
Points : 4 012
Sans tout casser (c'est tentant) je pense qu'il te faut un CALL EXECUTE dans ta DATA _null_ finale.

Autrement, décompose la création de la table avec les chemins et les fichiers, puis crée une macro variable pour chacun de ces fichiers. Fini par une boucle autour de la proc IMPORT permettant de reprendre chaque macro-variable. Mais le CALL EXECUTE est plus simple peut-être.
__________________
N'oubliez pas de cliquer sur lorsque votre problème est réglé !

Moteur de recherche dans les papiers SAS
datametric est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 15h41   #4
Modérateur
 
Homme Samir SELMANE
Consultant en Business Intelligence
Inscription : février 2011
Messages : 1 006
Détails du profil
Informations personnelles :
Nom : Homme Samir SELMANE
Localisation : France

Informations professionnelles :
Activité : Consultant en Business Intelligence
Secteur : Conseil

Informations forums :
Inscription : février 2011
Messages : 1 006
Points : 1 703
Points : 1 703
oui aussi,
sinon autre alternative: filevar dans l'infile
regardes ce poste et ce lien
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 16h03   #5
Membre à l'essai
 
Homme Bruno
Inscription : avril 2003
Messages : 69
Détails du profil
Informations personnelles :
Nom : Homme Bruno
Localisation : Belgique

Informations professionnelles :
Secteur : Conseil

Informations forums :
Inscription : avril 2003
Messages : 69
Points : 20
Points : 20
merci pour ces réponses.
1) s_a_m:
Code :
x cd ':\Documents and Settings\etc';
donne le même résultat

2) datametric: call execute donne le même résultat. A ce propos, je vois que l'erreur est plutôt ceci : ERROR: Physical file does not exist, C:\Documents and
Settings\...\CHEMIN
. C'est étrange car je fais passer la variable chemin qui contient c:\...\fichier.csv.
Concernant ta deuxième solution, je ne la comprends pas. D'ailleurs je ne sais pas affecter à une variable macro la valeur d'un champ d'une table. Comment tu fais ?

3) s_a_m: filevar est une option qui m'avait plue mais il faut avoir une structure de fichier identique et bien la connaître. Or les fichiers csv contiennent une colonne qui contient une chaîne de caractères variant à chaque ligne. Je pourrais la mettre dans chaine $100. par exemple mais je préfère la flexibilité de proc import qui sépare toutes les colonnes directement.
Cupidon est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/06/2011, 16h39   #6
Membre Expert
 
Avatar de MEGAMIND2
 
Homme Brice Beare
Paris
Inscription : janvier 2011
Messages : 956
Détails du profil
Informations personnelles :
Nom : Homme Brice Beare
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Paris

Informations forums :
Inscription : janvier 2011
Messages : 956
Points : 1 366
Points : 1 366
J'avais bricolé une macro qui marche très bien. Elle prend en paramètre le repertoire où sont stockés tes fichiers csv.


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
options mprint mlogic symbolgen ;
 
%MACRO IMPORT(dir=);
 
DATA fichierscsv ;
	LENGTH fic $ 1000;
	INFILE "&dir.\*.csv" FILENAME = fic ;
	INPUT ;
	fichier = fic ;
 
RUN ;
 
proc sort DATA=fichierscsv nodupkey;
BY fichier;
run;
 
 
DATA fichierscsv ;
	ATTRIB nom_fichier FORMAT=$10000.;
	SET fichierscsv ;
	nom_fichier=TRANWRD(TRANWRD(scan(fichier,-1,'\'),'.csv', ' '),',', '.');
		fichier=quote(cats(fichier));
RUN;
 
 
 
DATA _NULL_;
	SET fichierscsv;
	CALL SYMPUT("NB",_N_);
	CALL SYMPUT("nom_fichier"!!LEFT(_N_),nom_fichier);
	CALL SYMPUT("rep"!!LEFT(_N_),fichier);
RUN;
 
%DO i=1 %TO &NB;
	PROC IMPORT DATAFILE =&&rep&i	
		OUT = &&nom_fichier&i.					
		DBMS = csv  replace;	
         delimiter=";";	
 
	getnames=yes; 
run;
 
%END;
 
%MEND;
%IMPORT(dir=C:\Documents and Settings\wwwww);
MEGAMIND2 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 22/06/2011, 12h04   #7
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
La raison pour laquelle ton programme ne fonctionne pas actuellement : c'est que le compilateur macro travaille toujours AVANT le compilateur SAS. Donc quand tu incrustes un appel à ton macro-programme à l'intérieur de l'étape DATA, il exécute d'abord le macro-programme (c'est à dire qu'il fait un copier/coller de ce que le macro-programme contient) avant d'exécuter l'étape DATA.
C'est donc comme si tu avais exécuté, sans macro :
Code :
1
2
3
4
5
6
7
8
9
10
DATA _null_;
	SET ALL;
	put &path;
 
	proc import datafile= "&path" out= output dbms=csv REPLACE;
		delimiter=";";
		getnames=yes;
	run;
	run;
run;
On voit bien alors qu'il y a beaucoup (trop) de RUN; et surtout qu'ils ne sont pas bien placés. Quant à la proc IMPORT, SAS ne peut pas l'exécuter sans finir l'étape DATA. Donc il affiche (instruction PUT) à toutes les observations puis attaque la proc IMPORT, avec un fichier à importer qui n'est pas mentionné.
Si tu crées autant de macro-variables qu'il y a de fichiers à importer (avec CALL SYMPUTX) tu devras en plus faire une boucle. Brice te montre très bien comment faire.
Sinon, la solution de CALL EXECUTE proposée par Stéphane ressemble plus à l'esprit actuel de ton programme.
Bon courage en tout cas.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/06/2011, 09h37   #8
Membre à l'essai
 
Homme Bruno
Inscription : avril 2003
Messages : 69
Détails du profil
Informations personnelles :
Nom : Homme Bruno
Localisation : Belgique

Informations professionnelles :
Secteur : Conseil

Informations forums :
Inscription : avril 2003
Messages : 69
Points : 20
Points : 20
Merci Olivier pour ces précisions !
Je ne connais pas les subtilités de SAS. Maintenant, je comprends mieux pourquoi la variable ne passe pas correctement dans la macro. Je suis plutôt habitué aux langages linéaire et objet. En effet, le programme proposé par Brice fonctionne très bien et me convient bien. Merci beaucoup !
Cupidon est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h53.


 
 
 
 
Partenaires

Hébergement Web