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 :

Variable d'entrée et de sortie à la fois dans une macro


Sujet :

Macro

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut Variable d'entrée et de sortie à la fois dans une macro
    Bonjour à tous,

    Voici mon code,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    %let num=1;
    %macro step1(n);
    %let n=&n+1;
    %put step1;
    %mend step1;
    %step1(num);
    %put #
    Voici la sortie SAS,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    %let num=1;
    %macro step1(n);
    %let n=&n+1;
    %put step1;
    %mend step1;
    %step1(num);
    step1
    %put #
    1
    Or je m'attendais à voir s'afficher la valeur 2 plutôt que 1.

    Quel est le problème ?

    Merci !

  2. #2
    Responsable SAS


    Inscrit en
    Septembre 2006
    Messages
    3 176
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 176
    Points : 16 157
    Points
    16 157
    Par défaut
    Bonjour,
    Je ne pense pas que ton programme marche dans l'état actuel : opération de macro variable sans %eval mauvais affichage %put &n, tu ne fais pas référence aux macro-variables avec le caractère & ..... bref!!
    Si tu fais ce programme ça marche très bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    %let num=1;
    %macro step1(n);
    %let n=%eval(&n+1);
    %PUT &n;
    %mend step1;
    %step1(&num);

  3. #3
    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 : 47
    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
    Fabrice a raison, un %EVAL est indispensable si tu veux récupérer la valeur 2 plutôt que 1+1.
    L'autre problème, c'est qu'une macro-variable créée au cours d'un macro-programme (comme N) est locale à ce macro-programme. Donc pas disponible une fois que le MP a fini de s'exécuter. En plus, ce que tu passes en paramètre, c'est seulement la VALEUR de num, donc il n'y a pas de raison que num soit modifiée au final.
    Une solution qui épouse la logique de ton programme prend comme paramètre le NOM de la macro-variable à modifier. Du coup, pour accéder à sa valeur, il faudra un &&& devant le nom du paramètre. &nomVar = nom de la MV à modifier, et &&&nomVar = valeur de la MV à modifier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    %let num=1;
    %macro step1(nomMV);
    %GLOBAL &nomMV ;
    %let &nomMV=%EVAL(&&&nomMV+1);
    %PUT &&&nomMV;
    %mend step1;
    %step1(num);
    %PUT #
    Comme c'est un peu (super) lourd, je te propose de faire plutôt une macro-fonction, c'est à dire qu'elle renvoie directement une valeur plutôt que de faire une mise à jour.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    %let num=1;
    %macro step1(num);
       %EVAL(&num+1);
    %mend step1;
    %PUT %step1(&num);
    %LET num = %step1(&num);
    %PUT &num ;
    Olivier

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut Un train peut en cacher un autre
    En effet cela ne pouvait pas marcher. Mais le problème originel était le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    %let num=1;
    %macro step1(n);
    %let n=2;
    %put step1;
    %mend step1;
    %step1(num);
    %put #
    Le programme en lui-même a peu d'utilité, il sert à tester comment créer une macro avec une variable qui soit à la fois en entrée et en sortie. Je veux que la valeur d'entrée soit remplacée par une affectation interne nouvelle sans calcul à partir de l'ancienne.
    Pourquoi me renvoie-t-on 1 au lieu de 2 ?

  5. #5
    Responsable SAS


    Inscrit en
    Septembre 2006
    Messages
    3 176
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 3 176
    Points : 16 157
    Points
    16 157
    Par défaut
    Bonjour,
    Si tu veux changer la valeur de ta macro-variable directement à partir d'un macro-programme, le programme d'Olivier correspond parfaitement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    %let num=1;
    %macro step1(nomMV);
    %GLOBAL &nomMV ;
    %let &nomMV=%EVAL(&&&nomMV+1);
    %mend step1;
    %PUT #
    %step1(num);
    %PUT #

  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 : 47
    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
    Ce qui est assez perturbant avec le langage macro quand on est habitué à coder avec d'autres langages, c'est qu'une macro-variable, ce n'est pas une référence à une adresse mémoire, pas un pointeur, mais juste UN BOUT DE TEXTE.
    Quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    %macro step1(n);
    %let n=2;
    %put step1;
    %mend step1;
    et qu'ensuite tu exécutes %step1(num); les deux macro-variables (NUM et N) ne se "parlent" pas. Elles ne sont jamais connectées l'une à l'autre.

    Tu peux faire ça, sans paramètre, mais la macro-variable en entrée et en sortie devra toujours s'appeller NUM.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    %LET num=1 ;
    %MACRO plus1 ;
    	%GLOBAL num ;
    	%LET num = %EVAL(&num + 1) ;
    %MEND plus1 ;
    %plus1 ;
    %PUT num = &num ;
    Une fois que tu es convaincu que seul le code ci-dessus a le droit de modifier la valeur d'une MV, tu vois mieux pourquoi la solution de ce genre de manipulation passera forcément par un paramètre qui contient le NOM de la macro-variable mise à jour, pas sa valeur. Comme dans l'exemple posté plus haut.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2009
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 17
    Points : 12
    Points
    12
    Par défaut
    Merci pour vos réponses.

    Je pense qu'avec %global je devrais m'en tirer.
    L'idée générale est d'appeler une macro par la macro-variable step selon la valeur de step, ceci dans une macro plus grosse contenant 6 macros.

Discussions similaires

  1. Réponses: 1
    Dernier message: 28/03/2011, 13h00
  2. Réponses: 4
    Dernier message: 20/04/2010, 11h24
  3. Réponses: 0
    Dernier message: 15/03/2010, 14h59
  4. Réponses: 8
    Dernier message: 20/06/2008, 09h00
  5. Réponses: 7
    Dernier message: 15/05/2006, 13h36

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