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 12/07/2011, 11h41   #1
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Par défaut Problème création de macrovariables dans une boucle

Bonjour

J'ai un petit problème avec des macro-variables créées par des call symput qui se trouvent elles-mêmes dans des macros...
Normalement, si elles sont créées ainsi, il n'y a pas de soucis pour les réutiliser hors de la macro. Le problème que j'ai constaté, est que lorsqu'elles sont créées dans une boucle, elles ne peuvent être utilisées hors de la macro.

Voici mon code qui a pour but de récupérer les moyennes de mes données.
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
DATA theta;
	input compteur1 lambdat;
	cards;
	1 2
	2 4
	3 6 
	4 8
	5 10
	6 12
	7 14
	8 16
	9 18
 
	;
run;
proc means DATA=theta noprint;
	class compteur1;
	var lambdat;
	output out=moy mean=moy;
run;
%macro macrovar();
	DATA _null_;
		SET moy;
		IF _n_=1 then call symput("esp",moy);
		call symput("nb",_n_-1);
	run;
	DATA _null_;
		SET moy;
		%do i=2 %TO &nb.;
			IF _n_=&i. then call symput("esp"||LEFT(_n_-1),moy);
		%end;
	run;
	%put &esp1.;
	%put &esp2.;
	%put &esp3.;
	%put &esp4.;
%mend;
%macrovar();
/*Ces macrovariables ne fonctionnent pas :(*/
%put &esp1.;
%put &esp2.;
%put &esp3.;
%put &esp4.;
/*Mais ces deux là fonctionnent!*/
%put &esp.;
%put &nb.;
Je vous remercie pour votre aide

Bonne journée!!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 11h59   #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
Hello,
beaucoup d'anomalies dans ton programme.
il faut procéder par étape.

j te donne un exemple, essaies de t'inspérer:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
 
%macro test;
 
DATA _null_;
SET sashelp.class end=fin;
IF fin then call symput ('nb', _n_);
call symput   ('age' !!LEFT(_n_),age);
run;
 
%do i=1 %TO &nb;
%put l age de la ligne numéro &i est de : &&age&i.;
%end; 
 
 
%mend;
 
%test;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 11h59   #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
C'est ce que tu veux ?

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
OPTION mprint;
%macro macrovar;
DATA _null_;
SET moy;
IF _n_=1 then call symputx("esp",moy);
call symput("nb",_n_-1);
run;
DATA _null_;
SET moy;
IF _n_ > 1 then call symputx(cats('esp',_n_-1),moy);
 
run;
 
%mend;
%macrovar;
 
%put _user_;
__________________
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 12/07/2011, 12h13   #4
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Wouhou! Merci

En m'inspirant de vos deux codes, j'ai fait :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
%macro macrovar();
	DATA _null_;
		SET moy;
		IF _n_=1 then call symput("esp",moy);
		IF _n_>1 then call symput("esp"||LEFT(_n_-1),moy);
		call symput("nb",_n_-1);
	run;
%do i=1 %TO &nb;
%put &&esp&i.;
%end; 
%mend;
%macrovar();
Quelle est la différence entre différence entre "call symput" et "call symputx"?
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 12h16   #5
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
call symputx alligne les macro variables à gauche. Uniquement en V9.
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 12h49   #6
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
Le 2e intérêt de CALL SYMPUTX par rapport à CALL SYMPUT est de permettre d'indiquer si une macro-variable est globale (= utilisable en dehors du macro-programme où elle est créée) ou locale (cantonnée au macro-programme et détruite en fin d'exécution du MP).
Code :
1
2
3
4
5
6
7
8
9
10
11
12
%macro macrovar();
	DATA _null_;
		SET moy;
		IF _n_=1 then call symputX("esp",moy,"G");
		IF _n_>1 then call symputX("esp"||LEFT(_n_-1),moy,"G");
		call symput("nb",_n_-1);
	run;
%do i=1 %TO &nb;
%put &&esp&i.;
%end; 
%mend;
%macrovar();
Et comme ça tu peux utiliser &esp, &esp1, &esp2 après l'exécution du macro-programme %MACROVAR.
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 15h20   #7
Invité régulier
 
Inscription : avril 2009
Messages : 60
Détails du profil
Informations forums :
Inscription : avril 2009
Messages : 60
Points : 8
Points : 8
Super! Merci, je ne savais pas qu'on pouvait les déclarer ainsi en global!
Misspatate est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 16h03   #8
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
Je te rassure elles l'étaient déjà.

Voici un test pour t'en assurer.

Code :
1
2
3
4
5
6
7
8
9
%symdel memoire;
%macro test;
DATA _null_;
SET sashelp.class;
call symputx('memoire',_n_);
run;
%mend;
%test;
%put memoire=&memoire;
__________________
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 12/07/2011, 16h38   #9
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
par défaut, avec le CALL SYMPUT les macro variables sont GLOBAL.

Code :
1
2
3
4
5
6
7
8
 
DATA _null_;
SET sashelp.class;
call symput ('n',_n_);
call symput ('var'!!LEFT(_n_),age);
run;
 
%put _global_;
s_a_m est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/07/2011, 17h27   #10
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
Stéphane, SAM, en fait les macro-variables créées dans une étape DATA (CALL SYMPUT ou SYMPUTX) ne sont pas systématiquement globales par défaut. La règle est en effet la suivante (je simplifie un chouia) :
  • si la table des macro-variables locales est vide, CALL SYMPUT(X) crée une MV globale
  • s'il y a au moins une MV locale, CALL SYMPUT(X) créera une MV aussi locale
Attention, une proc SQL crée systématiquement plusieurs MV locales quand on est dans un macro-programme. D'où des résultats comme
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
%MACRO test ;
  PROC SQL ;
    CREATE TABLE work.toto AS 
	  SELECT *
	  FROM sashelp.class ;
	DROP TABLE work.toto ;
  QUIT ;
  DATA _NULL_ ;
    SET sashelp.class NOBS=nobs ;
	CALL SYMPUTX("n",nobs) ;
	STOP ;
  RUN ;
%MEND ;
%test ;
%PUT &n ;
Si au lieu du SQL on fait un %LET, même problème.
D'où mon conseil de profiter de CALL SYMPUTX pour bien clarifier la portée des macro-variables qu'on crée : "G" pour global, "L" pour local, et éviter d'être à la merci de ce genre de règles à la !
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 12/07/2011, 17h47   #11
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
Merci Olivier.
Personnellement j'ai toujours utilisé le %GLOBAL et %LOCAL pour référer mes macros.
C’est vrai qu'avec le Call SYMPUX c'est encore plus simple à coder et à déterminer le champs d’exécution de nous macro variables. Et oui il faut vivre avec son époque.
s_a_m 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 06h29.


 
 
 
 
Partenaires

Hébergement Web