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 :

Pouvoir utiliser la valeur numerique d'une macro variable pour une boucle


Sujet :

Macro

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut Pouvoir utiliser la valeur numerique d'une macro variable pour une boucle
    Bonjour,

    Je suis toujours confronté a un probleme dans mes boucles, mais en reprenant les differentes aides je pense avoir identifié mon probleme, quelqu'un aurait il le moyen pour convertir une macro variable en une variable numerique,

    pour etre precis j'utilise ce code afin d'avoir le nombre de clients que je possede

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CALL SYMPUT("nb_clients",_N_);
    run;
    Le probleme est que apres j'ai besoin de realiser une boucle je pensais pouvoir utiliser un %eval ou un %input(&nb_clients,2.); mais ni l'un ni l'autre ne semble marcher.

  2. #2
    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
    tu n'en n'as pas besoin :

    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_);
    run;
     
    %do i = 1 %to &n ;
    ...
    %end;

  3. #3
    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
    Avec ce code tu transformes une valeur numérique en macro variable. Si je comprends bien tu veux ensuite utiliser le contenu de la macro variable pour la transformer en variable numérique. D'où la question (dépendant de la configuration du problème): pourquoi ne pas utiliser directement la valeur numérique initiale?

    maintenant, voici comment faire pour transformer une macro variable (contenant un nombre même s'il est de type caractère) en une variable de type de numérique, dans une étape data:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    VARNUM=input("&nb_clients.", best12.);

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    EN fait voila mon code est dans le journal l'erreur est qu'il attend une variable numerique enfi d'apres ce que je comprends voila le code puis mon journal ca sera plus simple

    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 test2();
    data _NULL_;
    set alz.clients;
    CALL SYMPUT(COMPRESS("client"||compress(put(_N_,3.))),nom_client);
    CALL SYMPUT("nb_client",_N_);
    run;
     
    %put _all_;
     
    %do i=1 %to &nb_client.;
    data alz.temporaire;
    set alz.bna_travail;
    if nom_client=&&client&i then do; output alz.temporaire; end;
    run;
     
    %end;
     
    %MEND test2;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ERROR: Requested function is not supported.
     
    WARNING: Apparent symbolic reference NB_CENTRES not resolved.
    ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
           %input(&nb_centres,2.) 
    ERROR: The %TO value of the %DO I loop is invalid.
    ERROR: The macro TEST2 will stop executing.

  5. #5
    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
    Je te propose d'y aller par étape, une par étape data.

    1. ta première m'a l'air à peu près correcte. Dans le premier call symput tu peux convertir la bariable _n_ en caratère de sorte à ne plus avoir de warning dans la log. Le nombre à afficher dans le put dépend du nbr d'obs de ton fichier (3 si inférieur ou égale à 999, 4 si inf ou égal à 9999, etc.)

    %put _user_; affiche les macros variables créées par l'utilisateur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    DATA _NULL_;
    SET alz.clients;
    CALL SYMPUT(COMPRESS("client"||compress(put(_N_,3.))),nom_client);
    CALL SYMPUT("nb_client",_N_);
    run;
     
    %put _user_;
    mets la deuxième partie en commentaire et vois ce que ca donne.

    2/ Tu n'a pas besoin du input vu que es en macro (c'est un %do et non un do)

    %do i=1 %TO &nb_client.; tu devras rajouter un ou & avant client dans l'étape data. La résolution de la macro se passe en en deux étapes. dans la première le && se transforme en & avant client et &i se transforme en la valeur considérée de la boucle. En 2, la macro variable se résout. par exemple si tu est en &i=3 la macro variable &client3 se résout en sa valeur affectée à l'étape précédente.

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    Oui la premiere partie fonctionne bien j'ai verifié avec le put justement

    Bon j'ai modifié mon code malgré tout en rajoutant le compress comme tu m'avais dit, j'ai modifié dans le premier message, mais il me sort toujours cette erreur, je comprends pas bien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    WARNING: Apparent symbolic reference NB_CLIENT not resolved.
    ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 
           &nb_client. 
    ERROR: The %TO value of the %DO I loop is invalid.
    ERROR: The macro TEST2 will stop executing.

  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
    mets la deuxième partie de ton code en commentaire, à partir du %do. En exécutant la première partie la log doit t'afficher les macro variables que tu as créées, comprenant nb_client. Vérifie les macros variables créées.

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    oui ca c'est bon ca marche bien.

  9. #9
    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
    donc ca affiche quoi pour nb_client?

  10. #10
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    GLOBAL NB_CLIENT 254

  11. #11
    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
    essaie ca (à priori il semble que tu n'aies pas besoin de faire 254 étapes data):

    tu peux aussi spécifier les options symbolgen mprint mlogic

    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
    DATA _NULL_;
    SET alz.clients;
    CALL SYMPUT(COMPRESS("client"||compress(put(_N_,3.))),nom_client);
    CALL SYMPUT("nb_client",_N_);
    run;
     
    %put _user_;
    %put &nbclient.;
    %do i=1 %to &nbclient.;
    %put &i.;
    %end;
     
     
    DATA alz.temporaire;
    SET alz.bna_travail;
    %do i=1 %TO &nb_client.;IF nom_client=&&client&i then do; output alz.temporaire; end;
    run;

  12. #12
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    En realité le but final est de pouvoir creer un rapport pour chaque client, avec une simple proc freq et un ods afin de generer un fichier resultat different a chaque fois, donc je ne peux pas boucler a l'interieur du data, sinon mon fichier s'ecrasera a chaque pas.

  13. #13
    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
    tu peux le gérer avec un by dans ta freq, à toi de voir si ce type de sortie convient. dans ton exemple précédent tu écrases les 253 premières version de alz.temporaire pour ne retenir que la dernière.

  14. #14
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    Je pense voir ce que tu me conseilles alors dis moi si je me trompe, j'avoue que je commence a m'arracherun pu lescheveux et je suis pas sure de tout bien comprendre...
    Mais si je fais un freq avec un by, je vais avoir un seul rapport pour toius mes clients, mon probleme est qu'il y a un coté confidentialité, je peux pas me permettre que tous les clients aient acces a toutes les informations des autres clients, et c'est pour ca que je pensais faire une boucle en dehors de mon data, afin de pouvoir mettre mon freq et un ods qui varie afin de pouvoir enregistrer un rapport par patient. Mais j'avoue que je suis pas sure que ce soit possible

  15. #15
    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
    Dans ces cas la oui ton approche est bonne. il faut juste que tu insères la freq dans ta boucle et nomme un fichier spécifique pour chaque itération en sortie de cette freq.

    Tu peux également faire une freq globale comme je disais, utiliser OneWayFreqs pour récupérer une fichier de fréquence tout client confondu, puis créer des rapports spécifique.

    Pour la méthode à retenir, ca dépend des stat que tu veux et du formattage de sortie escompté.

  16. #16
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    Oui le mieux ce serait d'avoir un rapport a chaque fois mon probleme est que je n'arrive deja pas a generer une table a chaque fois, alors pour faire des requetes je suis pas pret d'y arriver ^^
    La je reste bloquer avec ce code et je comprends pas ce qui le gene, mais j'avoue que j'ai pas du tout compris la difference entre le do et le %do pour l'integration dans un data...

    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 test2();
    data _NULL_;
    set alz.clients;
    CALL SYMPUT(COMPRESS("clients"||compress(put(_N_,3.))),num_client);
    CALL SYMPUT("nb_clients",_N_);
    run;
     
    %put _user_;
     
     
    %do i=1 %to &nb_clients.;
    data alz.temporaire;
    set alz.bna_travail;
    if num_client=&&clients..&i. then do; output alz.temporaire; end;
    run;
     
    %end;
    %MEND test2;
    je suis désolé mais c'est vrai que la je me perds un peu

  17. #17
    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
    T'y étais presque. C'est juste les "." qui génaient pour résolution des macros variables. Il ne te reste plus qu' à gérer les sorties.

    Avec un do, tu n'est pas en language macro. Tu ne peux le faire que dans une étape data, cela crée une variable utilisée pour le comptage (ton i), et tu ne peux pas faire des résolutions à deux niveaux comme tu le fais la (d'abord &i et &&, puis &clienti).

    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
    data clients;
    set sashelp.bweight;
    num_client=_N_;
    if _N_<=256;
    run;
     
    %MACRO test2();
    DATA _NULL_;
    SET clients;
    CALL SYMPUTx("clients"||compress(put(_N_,3.)),num_client);
    CALL SYMPUTx("nb_clients",put(_N_,3.));
    run;
     
    %put _user_;
     
    %do i=1 %TO &nb_clients.;
    DATA temporaire;
    SET clients;
    IF num_client=&&clients&i. then do; output temporaire; end;
    run;
     
    %end;
    %MEND test2;

  18. #18
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    Merci pour ta patience, je comprends pas bien cette partie



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    DATA clients;
    SET sashelp.bweight;
    num_client=_N_;
    IF _N_<=256;
    run;
    il me dit ca : ERROR: File SASHELP.BWEIGHT.DATA does not exist.

  19. #19
    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 parce que je n'ai pas tes données, j'ai créé un dataset qui ressemble aux données que tu utilises à partir de la sashelp. Tu n'as pas besoin de cette partie. J'ai également retiré l'affectation vers la librairie alz, pour les même raisons évoquées au dessus. Tu as qq (toutes petites) modications à effectuer et ca fonctionne dans ton cas. Il te suffit de repartir de versions précédentes.

    num_client=_N_;
    la je crée la variable num_client, que je place égale au numéro de l'observation.

    IF _N_<=256;
    permet de sortir seulement les observations <=256(tu n'as pas besoin de plus, en relisant les discussions au dessus j'aurais pu mettre 254). Il y a un output implicite. tu peux lire cette instruction comme:
    IF _N_<=256 then output;

  20. #20
    Membre régulier
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Juillet 2010
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Juillet 2010
    Messages : 155
    Points : 96
    Points
    96
    Par défaut
    bon je comprends pas bien, sas reconnait les variables que l'on créé avec notre &clients&&i. mais il semble qu'apres je n'en fasse pas ce qu'il veut, je te mets l'erreur qu'il me sort.


    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
    %MACRO test2();
    data _NULL_;
    set alz.clients;
    CALL SYMPUT(COMPRESS("clients"||compress(put(_N_,3.))),client_num);
    CALL SYMPUT("nb_clients",put(_N_,3.));
    run;
     
    %put _user_.;
     
     
    %do i=1 %to &nb_clients.;
    data alz.temporaire;
    set alz.bna_travail;
    if client_num=&&clients&i.;
    run;
    proc freq data=alz.temporaire;
    tables client_num;
    run;
    %end;
     
    %MEND test2;
    Sinon j'ai continué a chercher, et je suis tombé la dessus ca semble correspondre a ce que je veux aussi, mais helas ca me sors aucun resultat ou du moins rien de visible ^^

    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
    1. Identifier le nom des sorties : un exemple avec une variable
     
    ods trace on/listing;
     
    *Exemple 1 : Proc Freq, une variable;
    proc freq data=sashelp.class;
       table age;
    run;
     
    ods trace off;
     
    On obtient deux types de tables selon qu’il s’agisse d’un tableau à une dimension ou à plusieurs dimensions.
     
        * OneWayFreqs: Dans le cas d’un PROC FREQ avec une seule variable, on parle de OneWayFreqs.
        * CrossTabFreqs: Dans le cas d’un tableau croisé, la sortie se nomme CrossTabFreqs.
     
    Output Added:
    ————-
    Name: OneWayFreqs
    Label: One-Way Frequencies
    Template: Base.Freq.OneWayFreqs
    Path: Freq.Table1.OneWayFreqs

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. Réponses: 3
    Dernier message: 30/05/2012, 09h24
  2. Réponses: 2
    Dernier message: 26/01/2012, 16h24
  3. Réponses: 7
    Dernier message: 03/01/2012, 11h14
  4. Valeurs d'une macro-variable dans une table SAS
    Par patril dans le forum Macro
    Réponses: 2
    Dernier message: 03/08/2011, 13h23
  5. utilisation d'une macro Excel dans une macro Word
    Par Tommy24 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 05/05/2011, 14h36

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