IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macro Discussion :

Problème création de macrovariables dans une boucle


Sujet :

Macro

  1. #1
    Nouveau membre du Club
    Inscrit en
    Avril 2009
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 63
    Points : 32
    Points
    32
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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!!

  2. #2
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    Hello,
    beaucoup d'anomalies dans ton programme.
    il faut procéder par étape.

    j te donne un exemple, essaies de t'inspérer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  3. #3
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    C'est ce que tu veux ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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é !

  4. #4
    Nouveau membre du Club
    Inscrit en
    Avril 2009
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 63
    Points : 32
    Points
    32
    Par défaut
    Wouhou! Merci

    En m'inspirant de vos deux codes, j'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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"?

  5. #5
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    call symputx alligne les macro variables à gauche. Uniquement en V9.
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  6. #6
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.
    Bon courage.
    Olivier

  7. #7
    Nouveau membre du Club
    Inscrit en
    Avril 2009
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 63
    Points : 32
    Points
    32
    Par défaut
    Super! Merci, je ne savais pas qu'on pouvait les déclarer ainsi en global!

  8. #8
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Je te rassure elles l'étaient déjà.

    Voici un test pour t'en assurer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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é !

  9. #9
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    par défaut, avec le CALL SYMPUT les macro variables sont GLOBAL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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_;
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  10. #10
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 !
    Bon courage.
    Olivier

  11. #11
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    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.
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [E-03] Création de graph dans une boucle
    Par chichichocho dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 01/01/2009, 19h22
  2. [MySQL] Création de variables dans une boucle et récupération de données avec une requête
    Par lavande4 dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 15/09/2008, 11h10
  3. Création d'objets dans une boucle for
    Par urban_p dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 02/06/2008, 10h34
  4. Création d'instance dans une boucle ?
    Par stabe dans le forum C#
    Réponses: 15
    Dernier message: 03/01/2008, 16h48
  5. probleme de création de variable dans une boucle
    Par misterweb dans le forum Langage
    Réponses: 2
    Dernier message: 16/01/2007, 19h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo