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 :

Appel d'une macro dans une proc sql


Sujet :

Macro

  1. #1
    Membre expert
    Appel d'une macro dans une proc sql
    Bonjour,

    Je souhaite appeler une macro SAS dans une proc sql .

    Voici le code SAS :

    Code SAS :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 changecarac (value=);
     
    value=tranwrd(value,'é','e');
    value=tranwrd(value,'è','e');
    value=tranwrd(value,'à','a');
     
    %mend changecarac;
     
    proc sql;
     
    create table my_table as
     
    select champ1 , champ2 , %changecarac(value=champ3) as champ3bis
    from my_table_origin;
     
    quit;


    Que pensez vous de ce code ?

    Étrangement SAS ne reconnait pas la macro .

    Merci de m'aiguiller

  2. #2
    Membre habitué
    bonjour,
    il y a ici quelques confusions dans l'utilisation de la macro.
    Notamment l'usage de la macro comme une fonction ... mais une macro n'est PAS une fonction. Donc l'appel à la macro ne renvoie pas un résultat mais exécute tout simplement le code de la macro ... sauf qu'exécuter des lignes de code à l'intérieur d'une proc SQL, on comprend que SAS en perde son latin ! (en plus, si cela marchait, l'appel à la "fonction" s'appliquerait au mot "champ" et non pas au contenu de la variable champ ... et il ne se passerait donc rien !)
    J'espère que j'ai été assez clair ?
    Voici ce que tu pourrais faire, beaucoup plus simplement et sans macro, pour obtenir ce que tu souhaites :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    data my_table(keep=champ1 champ2 champ3bis);
       set my_table_origin; 
       champ3bis =  tranwrd(champ3,'é','e');
       champ3bis =  tranwrd(champ3bis,'è','e');
       champ3bis =  tranwrd(champ3bis,'à','a');
    run;

  3. #3
    Membre expert
    Bonjour ,

    Citation Envoyé par jlp65 Voir le message
    il y a ici quelques confusions dans l'utilisation de la macro.
    Notamment l'usage de la macro comme une fonction ... mais une macro n'est PAS une fonction. Donc l'appel à la macro ne renvoie pas un résultat mais exécute tout simplement le code de la macro ... sauf qu'exécuter des lignes de code à l'intérieur d'une proc SQL, on comprend que SAS en perde son latin ! (en plus, si cela marchait, l'appel à la "fonction" s'appliquerait au mot "champ" et non pas au contenu de la variable champ ... et il ne se passerait donc rien !)
    J'espère que j'ai été assez clair ?
    L'utilité d'une macro est bien permettre d'éviter une tache répétitive on est d’accord ? Je ne vois pas le lien entre une fonction est ma macro pour le coup


    Citation Envoyé par jlp65 Voir le message
    Voici ce que tu pourrais faire, beaucoup plus simplement et sans macro, pour obtenir ce que tu souhaites :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    data my_table(keep=champ1 champ2 champ3bis);
       set my_table_origin; 
       champ3bis =  tranwrd(champ3,'é','e');
       champ3bis =  tranwrd(champ3bis,'è','e');
       champ3bis =  tranwrd(champ3bis,'à','a');
    run;
    L'idée de l'étape data n'est pas mauvaise il est vrai . J'avais vaguement pensé à un " select mon_champ case " , qui devient vite lourd ...

  4. #4
    Membre habitué
    Citation Envoyé par tanaka59 Voir le message

    L'utilité d'une macro est bien permettre d'éviter une tache répétitive on est d’accord ?
    Oui ! Tout à fait ! C'est également le cas pour les fonctions. Mais le fonctionnement d'une macro et celui d'une fonction ne sont pas identiques : une macro permet d'effectuer un ensemble de lignes de code et, éventuellement de calculer certaines données-résultats - par exemple des macro-variables -. Ces résultats peuvent ensuite être utilisés, mais pas sous la forme de fonction. Le code suivant est correct :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    %macro calcul(id);
    %global ma_var;
    %let ma_var=%eval(&id.+1);
    %mend calcul;
    %calcul(12);
    data t;x=&ma_var.;run;

    Mais si l'on remplace la dernière ligne par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    data t;x=%calcul(12);run;

    ça ne peut pas marcher.
    Il n'est pas possible (à ma connaissance) de construire ses propres macro-fonctions sous SAS. Mais il existe quelques macro-fonctions dans le langage (exemple %substr(str,car,l) qui fonctionne de la même façon que la fonction SAS substr)

  5. #5
    Membre expert
    Citation Envoyé par jlp65 Voir le message
    Oui ! Tout à fait ! C'est également le cas pour les fonctions. Mais le fonctionnement d'une macro et celui d'une fonction ne sont pas identiques : une macro permet d'effectuer un ensemble de lignes de code et, éventuellement de calculer certaines données-résultats - par exemple des macro-variables -. Ces résultats peuvent ensuite être utilisés, mais pas sous la forme de fonction. Le code suivant est correct :
    Donc j'en déduis que le tranwrd ne peut pas être utilisé dans une macro pour le coup ...

    Citation Envoyé par jlp65 Voir le message
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    %macro calcul(id);
    %global ma_var;
    %let ma_var=%eval(&id.+1);
    %mend calcul;
    %calcul(12);
    data t;x=&ma_var.;run;

    Mais si l'on remplace la dernière ligne par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    data t;x=%calcul(12);run;

    ça ne peut pas marcher.
    Il n'est pas possible (à ma connaissance) de construire ses propres macro-fonctions sous SAS. Mais il existe quelques macro-fonctions dans le langage (exemple %substr(str,car,l) qui fonctionne de la même façon que la fonction SAS substr)
    la fonction substr de sas est la fonction tranwrd .

    Pourquoi au départ j'ai voulu mettre les tranwrd dans une macro. C'était pour éviter de me retrouver avec ceci :

    Code SAS :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    proc sql ;
     
    create table exit_table as 
     
    select field1 , field2 ,  
     
    CASE field3  
           WHEN field3 like '%é%' THEN tranwrd(field3,'é','e')
    	   WHEN field3 like '%è%' THEN tranwrd(field3,'è','e')
    	   ELSE tranwrd(field3,'à','a')
    END
     
    from my_table_origin ;
     
    quit;


    Des cas de taille délirante et un code peu lisible ...

  6. #6
    Membre expérimenté
    Le macro code génère du texte qui sera ensuite executé par l'intepreteur SAS sous forme de code : en deux mots le macro code est un générateur de texte et rien d'autre.

    S'en servir pour réaliser des calculs lorsqu'il semble être la façon la plus commode de faire quelque chose est de ce fait souvent très très sous optimal en terme de temps de traitement (performances divisées d'un ordre de grandeur de 100 à 1000 ).

    La façon la plus propre de faire ce que tu veux faire (fonction utilisable dans une proc sql) est de réaliser un fonction utilisateur via la PROC FCMP (https://support.sas.com/documentatio...se/91/fcmp.pdf )


    Cdt

  7. #7
    Membre expert
    Bonjour,

    Je prend note de cette proc .

    Je vous remercie.

###raw>template_hook.ano_emploi###