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 :

Pour chaque ligne d'une table appeler une macro : utilisation de symput (compress())


Sujet :

Macro

  1. #1
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut Pour chaque ligne d'une table appeler une macro : utilisation de symput (compress())
    Re-Bonjour

    Voici ce que je voudrais faire:
    Parcourir une table et pour chaque ligne, appeler ma macro.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Table A
    dataset_name (--> le nom de mon champ)
    --------------
      valeur1
      valeurj
      valeurk
     
    %mamacro(valeur1)
    %mamacro(valeurj)
    %mamacro(valeurk)
    J'ai regardé sur le net et je suis tombé sur le magnifique call symput.
    Ensuite, j'ai rencontré le call symput (compress()) pour créer des variables automatiquement.

    Le problème est que dans ce exemples, je n'ai pas trouvé comment appeler cette variable concaténée avec symput/compress.

    Ci-dessous le code:
    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 t;
    	DATA _null_;
    	SET Duplicates_datasets_listing;
    	call symput("fin",_n_); /*nombre de lignes*/
    	call symput(compress("test"||_n_), dataset_name); 
    	run;
    	%do i = 1 %to &fin ;
    		%sstest (&test&i);
    	%end;
    %mend;
     
    %macro sstest(var);
    	%put &var;
    %mend;
    %t;
    En fait ma sortie est pourrie, je pense avoir un problème au niveau le l'appel à le macro sstest.
    Voilà, n'ayant pas encore réellement appris les macro en SAS, je ne sais pas si ceci est la solution la plus élégante mais je voulais absolument éviter une solution avec du SQL.

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    53
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 53
    Points : 44
    Points
    44
    Par défaut
    Bonjour,

    il faudrait que tu travailles a partir de la proc contents,

    Pour recuperer le nombre de ligne : tu fais le code suivant ceci te permettra de parcourir toute la table.

    Ensuite veux tu parcourir toutes les variables de ta table? pas bien compris

    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
    %macro test1() ;
     
    data contents;
    set  contents;
     
     call symput('nbc',left(put(Num,8.)));
     
     run;
     
    data table ;
    set table;
     
    %do i=1 %to &nbc ;
     
     
    %end;
    %mend;       
     
    %test();

  3. #3
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut
    En fait, le nombre de ligne, je l'ai déjà.

    Je ne veux pas parcourir toutes les variables (colonnes) de ma table mais bien toutes les observations de la colonne X.

    Le nombre de ligne de ma table me sert juste à savoir quan arrêter ma boucle.

    Le but ici est d'appeler une macro (toujours la même) avec des paramètres différents. Ces paramètres sont en fait les observations de ma table.
    Par exemple, dans ma table T, j'ai une colonne X qui comporte les observations suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Jean
    Michel
    Alex
    J'ai une macro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    %mamacro(var);
    /*....*/
    %mend;
    Et je voudrais donc faire un appel de cette macro avec les observations de la colonne X de ma table T:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    %mamacro(Jean);
    %mamacro(Michel);
    %mamacro(Alex);

  4. #4
    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 ne sais pas trop ce que fait mamacro mais l'appel comme cela me fait plutôt t'orienter vers un CALL EXECUTE
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  5. #5
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut
    Pour l'instant, ma macro ne fait qu'un affichage (pour le test)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    %macro sstest(var);
    	%put &var;
    %mend;
    Je viens der la faire en SQL et ça fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    proc sql;
    	/*dataset_name est le nom de mon champ */
                 select distinct '%sstest('||strip(dataset_name)||');'
    	into :mytest separated by " "
    	from Duplicates_datasets_listing;
    quit;
     
    %macro sstest(var);
    	%put &var;
    %mend;
     
    &mytest;
    Ce qui me donne comme résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    nameds1
    nameds2
    nameds3
    ...
    Je ne sais pas si j'ai bien exprimé mon problème...
    Je voudrais faire l'équivalent du programme ci-dessus sans passer par une proc sql.

    D'après ce que j'ai lu, si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    %macro t;
    	DATA _null_;
    	SET Duplicates_datasets_listing;
    	call symput("fin",_n_); /*nombre de lignes*/
    	%mend;
    fin prend le nombre de ligne car un data step va parcourir toute ma table.
    Ce qui fait que si ma table a 3 observations _n_ prendra les valeurs suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    _n_ = 1
    _n_ = 2
    _n_ = 3
    Donc fin prendra la dernière valeur de _n_ (donc 3).

    Ce qu'il m'aurait fallu, c'est de céer automatiquement une variable pour chaque observation du data set.
    De cette manière, j'aurais pu avoir (variable = "test")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    test1 = nameds1
    test2 = nameds2
    test3 = nameds3
    Ensuite, il faudrait que je fasse une boucle (un %do par exemple) afin de pouvoir appeler ma macro avec le nom de variable qui a été créé.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    %ma_macro(test1);
    %ma_macro(test2);
    %ma_macro(test3);
    Ce qui m'aurait donné le résultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    nameds1
    nameds2
    nameds3
    puisque ma_macro ne fait qu'un %put (pour le test).

  6. #6
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut

    J'ai trouvé.

    Le problème se situe au niveau de ma boucle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    %sstest (&&tests&i);
    Il fallait rajouter un & afin que sas comprenne que ma variable devienne &tests1 et pas tests1!

    En effet tests1 ne représente pas un nom correct de macro variable.

  7. #7
    Membre chevronné
    Homme Profil pro
    Biostatisticien
    Inscrit en
    Juin 2009
    Messages
    1 206
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Irlande

    Informations professionnelles :
    Activité : Biostatisticien
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 206
    Points : 1 868
    Points
    1 868
    Par défaut
    C'est le même principe sauf que le call symput devient(nameds est une de tes variable c'est bien ca):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call symput("test"||put(_n_,3.),nameds);

  8. #8
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut
    C'est le même principe sauf que le call symput devient(nameds est une de tes variable c'est bien ca):


    Code :
    call symput("test"||put(_n_,3.),nameds);
    Tout à fait!
    nameds est le nom d'un variable de mon dataset (donc le nom du champ de ma table).

    Par contre si je fais le test avec ta ligne, ca ne fonctionne pas car ma variable contiendrait des blancs dans son nom. Il faudrait probalement faire un split ou quelque chose comme ça...

    J'ai donc testé ceci qui fonctionne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call symput("test"||put(_n_),dataset_name);
    et qui est, à mon sens, effectivement plus clair que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    call symput(compress("test"||_n_), dataset_name);
    Merci à tous

  9. #9
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Mars 2002
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Mars 2002
    Messages : 244
    Points : 200
    Points
    200
    Par défaut
    En fait je viens de trouver un code plus court.
    J'ai enfin compris ce que datametric voulait dire.
    J'utilise un call execute:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    DATA _null_;
    	SET Duplicates_datasets_listing;
    	call execute ('%sstest ('||dataset_name||')');
    run;
     
    %macro sstest(vars);
    	%put &vars;
    %mend;
    par contre, quand je regarde dans le log j'ai le message suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NOTE: CALL EXECUTE routine executed successfully, but no SAS statements were generated.
    Je ne comprends pas très bien ce que je dois en déduire

    Voici le log complet.
    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
    1306  DATA _null_;
    1307      SET Duplicates_datasets_listing;
    1308      call execute ('%sstest ('||dataset_name||')');
    1309  run;
     
    test
    sdfs
    NOTE: There were 2 observations read from the data set WORK.DUPLICATES_DATASETS_LISTING.
    NOTE: DATA statement used (Total process time):
          real time           0.01 seconds
          cpu time            0.01 seconds
     
     
    NOTE: CALL EXECUTE routine executed successfully, but no SAS statements were generated.
    1310
    1311  %macro sstest(vars);
    1312      %put &vars;
    1313  %mend;

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

Discussions similaires

  1. copier une table d'une BDD dans une table d'une autre BDD
    Par faniette dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/05/2013, 10h17
  2. Réponses: 1
    Dernier message: 19/10/2011, 12h13
  3. Réponses: 7
    Dernier message: 25/03/2011, 10h52
  4. [AC-2003] insert des données d'une table dans une table d'une base externe
    Par marieo dans le forum VBA Access
    Réponses: 1
    Dernier message: 30/11/2009, 14h29
  5. Copier les enregistrements d'une table vers une table d'une autre DB
    Par karinette21 dans le forum Requêtes et SQL.
    Réponses: 4
    Dernier message: 18/11/2008, 21h50

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