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 :

Lire une table ligne par ligne


Sujet :

Macro

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 376
    Par défaut Lire une table ligne par ligne
    Bonjour,

    Je souhaiterai stocker dans des macro-variables les données d'une table lue ligne par ligne.
    Les macro-variables créés seront utilisés dans la même macro.
    Je ne connais pas le nombre de lignes ni le nombre de colonnes de la table.

    Par exemple :

    Avec contenu de la table :
    A B C D E
    1 1 8 7 4
    2 9 1 4 2

    Afficher
    variable A a pour valeur 1 en ligne 1
    variable B a pour valeur 1 en ligne 1
    variable C a pour valeur 8 en ligne 1
    variable D a pour valeur 7 en ligne 1
    variable E a pour valeur 4 en ligne 1

    variable A a pour valeur 2 en ligne 2
    variable B a pour valeur 9 en ligne 2
    variable C a pour valeur 1 en ligne 2
    variable D a pour valeur 4 en ligne 2
    variable E a pour valeur 8 en ligne 2

    Mon code n'est pas correct mais illustre l'idée :
    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
     
    %Macro read (table=) ;
    	%DO i = 1 %TO nombredelignedelatable ;
            %let nomcolonnes = récupérer les colonnes pour la ligne 1;
        	       PROC SQL;
    			SELECT &nomcolonnes.
    			FROM &table.
    			WHERE ligne a lire = &i.;
    		QUIT;
    	%END;
    	%let var1= call symputx((put(i,3.), colonne_table(1)) ;
            %let var2= call symputx((put(i,3.), colonne_table(2)) ;
            %put variable &nomcolonne(1) a pour valeur &var. en ligne &i.;
            %END
    %Mend ;
    %read (table=ods.table);
    Merci pour l'aide

  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 : 52
    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
    Par défaut
    J'en perd mon latin avec vos questions tordues en ce moment

    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
    data test;
    input A B C D E;
    cards;
    1 1 8 7 4
    2 9 1 4 2
    ;
    run;
     
    data _null_;
    set test;
    array ar (*) _all_;
     
    do i = 1 to dim(ar);
    call symputx(cats(vname(ar(i)) , _n_) , ar(i) );
    y= cats(vname(ar(i)) , _n_ , '=', ar(i)) ;
    put y;
    end;
     
    run;
    Y n'est là que pour afficher le résultat contenu dans chaque macro variable dont le nom est constitué du nom de la colonne et du numéro de lignes.
    J'espère que cela t'aidera

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 376
    Par défaut
    Merci Stéphane pour cette réponse rapide.
    C'est vrai que mes questions sont un peu tordues ,
    Mais vos réponse sont pertinentes et peuvent aider d'autres membres.

    Votre code fonctionne très bien merci. Je voudrais juste faire quelques ajustements :

    Passer les données des colonnes en paramètre à une macro et exécuter cette macro en bouclant sur chaque lignes.
    Dans mon cas, il y a 4 colonnes. Mais le nombre de lignes est inconnu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    DATA _null_;
    SET test;
    array ar (*) _all_;
    do i = 1 TO dim(ar);
    	%MAMACRO (ar(i);ar(i+1);ar(i+2);ar(i+3));
    end;
    run;
    Merci beaucoup

  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 : 52
    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
    Par défaut
    C'est vrai que mes questions sont un peu tordues
    en fait cela ne valait pas que pour toi, c'était général

    bref...

    Passer les données des colonnes en paramètre à une macro et exécuter cette macro en bouclant sur chaque lignes.
    Dans mon cas, il y a 4 colonnes. Mais le nombre de lignes est inconnu.
    non là je ne comprends plus

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 376
    Par défaut
    Je me suis mal exprimé désolé.

    Au lieu d'afficher "noncolonne numérocolonne = données", je souhaiterai maintenant ajouter seulement les "données" dans une macro en parcourant par lignes.
    %unemacro() est une autre macro SAS qui utilise en paramètres les données de la table.

    Par exemple :
    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
     
    DATA test;
    input A B C D E;
    cards;
    1 1 8 7 4
    2 9 1 4 2;
    run;
     
    DATA _null_;
    SET test;
    array ar (*) _all_;
    do i = 1 TO dim(ar); /*Boucle ligne par lignes*/
    	%unemacro(ar(i);ar(i+1);ar(i+2);ar(i+3)); /*récupération des données de chaque colonnes pour la ligne i*/
    end;
    run;
    Si i (ligne) est égal à 1 alors exécuter %unemacro(1,1,8,7,4);
    Si i (ligne) est égal à 2 alors exécuter %unemacro(2,9,1,4,2);

    Merci

  6. #6
    Membre émérite
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    747
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 747
    Par défaut
    salut,

    Un peu d'accord avec datametric :

    Citation Envoyé par datametric Voir le message
    J'en perd mon latin avec vos questions tordues en ce moment
    En général on voit des demandes bien biscornues, et vu que SAS est un langage assez puissant on pourra toujours tout faire...

    Cependant : est-ce que cela doit être fait de cette manière?, est-ce pertinent?

    Depuis que je bosse, je n'ai jamais eu à faire ce que tu demandes.

    Est-ce que tu veux bien re-expliquer ton besoin, (ton vrai besoin )

    a+

    xav

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    376
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 376
    Par défaut
    Mon besoin a évolué donc à partir de mon 2ème post mes questions était différentes.
    Je vais expliquer plus succinctement :

    Je dispose d'une macro qui utilise 4 paramètres.
    (Ces 4 paramètres proviennent des données en colonne d'une table)
    exemple :
    %macro(A,B,C,D);

    J'ai une table qui contient les données que je doit faire passer en paramètres à la macro.
    Contenu de ma table :
    A B C D
    E R N C
    M I K O

    Je souhaiterais exécuter la macro pour chaque ligne lue de la table.
    exemple :
    %macro(A,B,C,D);
    %macro(E,R,N,C);
    %macro(M,I,K,O);

    Merci

  8. #8
    Membre émérite
    Homme Profil pro
    responsable adjoint service stat
    Inscrit en
    Mars 2009
    Messages
    448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : responsable adjoint service stat
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2009
    Messages : 448
    Par défaut
    La parole du sage revient ce jour à xav2229 : toujours revenir au besoin !
    Voilà une façon de faire :

    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
    /* Table d'exemple */
    data MA_TABLE_PARAMETRE ;
        input Parametre_1 $ Parametre_2 $ Parametre_3 $ Parametre_4 $ ;
        cards ;
    A B C D
    E R N C
    M I K O
    ;
    run ;
     
    /* Macro qui boucle sur une table de paramètre */
    %MACRO LOOP_ON_TABLE_PARAMETRE (TABLE_PARAMETRE = ) ;
        proc sql noprint ;
            SELECT count(*)
            INTO : NB_LIGNE_PARAMETRES
            FROM &TABLE_PARAMETRE ;
        quit ;
     
        %do LOOP = 1 %to &NB_LIGNE_PARAMETRES. ;
            data _NULL_ ;
                set &TABLE_PARAMETRE. (obs = &LOOP. firstobs = &LOOP.) ;
                call symputx ("PARAMETRE_1", PARAMETRE_1) ;
                call symputx ("PARAMETRE_2", PARAMETRE_2) ;
                call symputx ("PARAMETRE_3", PARAMETRE_3) ;
                call symputx ("PARAMETRE_4", PARAMETRE_4) ;
            run ;        
            %put  ==> Placer ici la macro utilisant %nrstr(&PARAMETRE_1-4) = &PARAMETRE_1. &PARAMETRE_2. &PARAMETRE_3. &PARAMETRE_4.  ;
        %end ; 
    %MEND LOOP_ON_TABLE_PARAMETRE ;
     
    /* Appel de la macro sur la table d'exemple */
    %LOOP_ON_TABLE_PARAMETRE (TABLE_PARAMETRE = MA_TABLE_PARAMETRE ) ;

  9. #9
    Membre Expert
    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
    Par défaut
    Le principe d'une étape data est d'éxécuter les instructions contenues dans cette étape, ligne par ligne. C'est à dire qu'il va éxécuter les instructions pour la première ligne de ton fichier de données (_N_=1), puis le deuxième et ainsi de suite jusqu'à le dernière ligne.

    ton fichier source, qu'on apellera datain, est de la forme:
    A B C D
    E R N C
    M I K O

    chaque ligne contient 4 colonnes, qu'on appelera colonne1, colonne2, colonne3, colonne4.

    ta macro contient 4 paramètres, des macros variables, qu'on apellera param1 à param4.

    Logiquement tu ne dois donc appeler qu'une seule fois, puisque cet appel correspond à une ligne donnée, et que toutes les lignes seront considérées...

    lors de la définition de ton macro fonction, tu devras utiliser les macros paramètres param1-Param évoqués au dessus.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     data _null_/*A voir pour le data _null_, ca dépend de ce que tu veux en sortie*/;
    set datain;
    %mamacro(&param1.,&param2.,&param3.,&param4.);/*ne pas nommer une macro "macro" car c'est le code utilisé pour définir un macro-fonction*/
    run;

  10. #10
    Membre chevronné
    Inscrit en
    Janvier 2010
    Messages
    235
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 235
    Par défaut
    Bonjour Deciprog, si ta macro le permet, je te conseillerais d'utiliser un call execute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    data _null_;
    set dataparam;
    call execute(
    	cats('%macro(' , var1, 	' , ', var2 ,	' , ', var3,	' , ', var4, ');') 
    			) ;
    run;
    où dataparam est ta table :
    A B C D
    E R N C
    M I K O

    Mais attention au call execute :
    SAS déroule d'abord toute la table dataparam pour "écrire" le code qui va ensuite être exécuté. Si bien que si tu crées des objets dans ta macro (macro-variables ou tables) et que tu fais des tests sur l'existence de ces objets, cela peut produire des résultats inattentus puisqu'à "l'écriture" du code ces objets n'existent pas encore.

    Par exemple si dans ta macro tu as ceci :
    data test;
    set _null_;
    run;

    %if %sysfunc(exist(test)) %then %put YES;
    %else %put NO;

    alors tu n'obtiendras dans ta log que des NO... car à l'écriture du code test n'existe pas encore dans ta work...





    Citation Envoyé par Deciprog Voir le message
    Mon besoin a évolué donc à partir de mon 2ème post mes questions était différentes.
    Je vais expliquer plus succinctement :

    Je dispose d'une macro qui utilise 4 paramètres.
    (Ces 4 paramètres proviennent des données en colonne d'une table)
    exemple :
    %macro(A,B,C,D);

    J'ai une table qui contient les données que je doit faire passer en paramètres à la macro.
    Contenu de ma table :
    A B C D
    E R N C
    M I K O

    Je souhaiterais exécuter la macro pour chaque ligne lue de la table.
    exemple :
    %macro(A,B,C,D);
    %macro(E,R,N,C);
    %macro(M,I,K,O);

    Merci

  11. #11
    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 : 52
    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
    Par défaut
    On ne pourrait pas simplement remplacer l'action de la macro par une programmation dans une étape data dans ce cas ?
    Avec des Array pour gérer toute la liste des variables ?

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

Discussions similaires

  1. lire une base de donnee ligne par ligne
    Par thildouille dans le forum Langage
    Réponses: 9
    Dernier message: 03/06/2011, 00h50
  2. Lire une table partie par partie
    Par hoccha dans le forum Requêtes
    Réponses: 2
    Dernier message: 11/01/2010, 11h06
  3. lire un fichier de string ligne par ligne
    Par bilzzbenzbilz dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 11/02/2009, 10h44
  4. Réponses: 12
    Dernier message: 14/05/2008, 17h15
  5. Réponses: 3
    Dernier message: 16/10/2007, 20h45

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