📖 Module IX - Les macros-programmes
- Écrire, compiler et appeler un macro-programme
- Choisir entre paramètres positionnels et paramètres mots-clés
- Écrire des traitements conditionnels avec %IF ... %THEN ... %ELSE
- Écrire les trois formes de boucles macro : %DO %TO, %DO %WHILE, %DO %UNTIL
1. Définition et syntaxe des macro-programmes
Un macro-programme, également appelé macro SAS, permet de générer du code SAS, d'utiliser des conditions et des boucles, d'exécuter un même code avec des paramètres différents.
Syntaxe de création et de compilation :
%MACRO MACRO1 (param1, ..., paramn) ;
<INSTRUCTIONS>
%MEND <MACRO1> ;
Les macro-instructions %MACRO, suivie du nom du macro-programme, servent à déclarer le macro-programme, et %MEND marque la fin de celui-ci. Le nom du macro-programme ne doit pas commencer par un chiffre et ne peut pas contenir de caractères spéciaux ou accentués autres que le tiret bas.
Un macro-programme possède généralement des paramètres déclarés dans la macro-instruction %MACRO. Ces paramètres sont en réalité des macro-variables disponibles lors de l'exécution du macro-programme et sont donc créées en environnement LOCAL. Leur utilisation est la même que celle décrite au module précédent.
Syntaxe d'appel d'un macro-programme, pour son exécution :
%MACRO1(param1, ..., paramn) ;
2. Le stockage des macro-programmes
L'exécution du code source du macro-programme entraîne la compilation de celui-ci et le stockage de l'objet compilé correspondant dans le catalogue SASMACR. Le macro-programme compilé est alors disponible pour une utilisation ultérieure.
Pour éviter d'avoir à recompiler les macros à chaque ouverture, SAS offre la possibilité de stocker les macro-programmes compilés dans une autre librairie. Pour cela, il faut utiliser l'option globale MSTORED et l'option STORE lors de la déclaration du macro-programme.
Exemple : stockage du macro-programme MACRO1 dans le répertoire TIDE.
libname toto "C:\My documents\macros_perso" ;
OPTIONS MSTORED SASMSTORE = toto ;
%macro NOM_MACRO / STORE ;
<INSTRUCTIONS>
%mend ;
Voir le corrigé
%macro date_heure_session ;
%put Session ouverte le %sysfunc(date(), date9.) a %sysfunc(time(), time8.) ;
%mend date_heure_session ;
%date_heure_session
3. Les paramètres d'un macro-programme
Les macro-programmes peuvent être définis avec une liste de paramètres correspondant aux macro-variables référencées dans la macro. Il existe deux types de paramètres :
- Positionnels : valeur du paramètre obligatoire lors de l'appel au macro-programme
- Mots-clés : valeur du paramètre optionnelle lors de l'appel au macro-programme
Comparaison des deux écritures sur un même exemple :
/* Parametres positionnels */ /* Parametres a mot cle */
%macro print(table, vars) ; %macro print(table=, vars=sex) ;
proc print data = &table ; proc print data = &table ;
var &vars ; var &vars ;
run ; run ;
%mend ; %mend ;
%print(sashelp.class, name age) %print(table = sashelp.class)
Avantages des paramètres à mot-clé : on peut les mettre dans n'importe quel ordre, et leur donner une valeur par défaut.
Les paramètres positionnels. Lors de l'appel à un macro-programme, les paramètres positionnels doivent être renseignés dans l'ordre dans lequel ils ont été déclarés. On peut ne pas renseigner la valeur d'un ou plusieurs des paramètres positionnels lors de l'appel, mais il faut alors remplacer cette valeur par un espace.
Voir le corrigé
%macro listing ;
proc print data=sashelp.class ;
run ;
%mend listing ;
%listing
Voir le corrigé
%macro listing_sexe(sexe) ;
proc print data=sashelp.class ;
where sex = "&sexe" ;
run ;
%mend listing_sexe ;
%listing_sexe(M)
%listing_sexe(F)
Les paramètres mots-clés. Ce type de paramètre donne la possibilité de lui assigner une valeur par défaut, qui est utilisée si le paramètre n'est pas cité lors de l'appel. Ici, ce n'est plus l'ordre d'appel des paramètres qui est important mais bien leur nom, suivi du signe égal. En cas de mélange, ces paramètres doivent être cités après les paramètres positionnels.
Voir le corrigé
%macro listing(sexe=) ;
proc print data=sashelp.class ;
%if &sexe ne %then %do ;
where sex = "&sexe" ;
%end ;
run ;
%mend listing ;
%listing()
%listing(sexe=F)
Sans argument, %IF &sexe ne %THEN est faux (la macro-variable est vide) : la clause WHERE n'est pas générée et tous les élèves s'affichent.
4. Traitement conditionnel : %IF ... %THEN ... %ELSE
Dans un macro-programme, il est possible d'utiliser les conditions %IF, %THEN, %ELSE. Les macro-instructions présentées ci-après ne peuvent être utilisées que dans un macro-programme.
%IF condition %THEN %DO ;
<Instruction1 - n>
%END ;
%ELSE %DO ;
<Instruction1 - n>
%END ;
Avec :
- condition : en référence à la valeur d'une macro-variable. Attention, la distinction minuscule / majuscule est importante lors du test.
- Instruction1 - n : un ensemble d'instructions SAS/Base ou de macro-instructions
Bonnes pratiques de programmation : les 4 étapes à suivre pour écrire un macro-programme.
- Étape 1 — Écrivez et déboguez un programme SAS sans langage macro. Puis assurez-vous que le programme SAS fonctionne avec des valeurs fixes.
- Étape 2 — Généralisez le code en substituant les valeurs spécifiées par des macro-variables. Initialisez les valeurs avec l'instruction %LET. Utilisez l'option SYMBOLGEN pour déboguer, expliquée au module X.
- Étape 3 — Créez un macro-programme avec %MACRO et %MEND. Remplacez les instructions %LET par des macro-paramètres.
- Étape 4 — Ajoutez des instructions du langage macro comme %IF-%THEN.
Voir le corrigé
%macro listing_titre(sexe=) ;
%if &sexe = M %then %do ;
title "Liste des garcons" ;
%end ;
%else %if &sexe = F %then %do ;
title "Liste des filles" ;
%end ;
%else %do ;
title "Liste de tous les eleves" ;
%end ;
proc print data=sashelp.class ;
%if &sexe ne %then %do ;
where sex = "&sexe" ;
%end ;
run ;
title ;
%mend listing_titre ;
%listing_titre(sexe=M)
Voir le corrigé
%macro prod(analyse=) ;
%if &analyse = PRODUITS %then %do ;
proc means data=sashelp.prdsal3 ;
class product ;
var actual ;
run ;
%end ;
%else %if &analyse = TYPES %then %do ;
proc means data=sashelp.prdsal3 ;
class prodtype ;
var actual ;
run ;
%end ;
%mend prod ;
%prod(analyse=PRODUITS)
%prod(analyse=TYPES)
5. Les boucles
Dans une macro, il est possible d'utiliser des boucles : DO ... TO ... END, DO ... WHILE ... END, DO ... UNTIL ... END.
%DO ... %TO ... %END. Cette boucle effectue n fois un traitement, de l'indice de début à l'indice de fin d'itération. Sa syntaxe est analogue à celle du DO ... TO ... END du langage SAS/Base.
%DO indice = debut %TO fin ;
<Instruction1 - n> ;
%END ;
Avec indice qui fait référence à une macro-variable créée et gérée automatiquement par le macro-processeur, et Instruction1 - n qui est un ensemble d'instructions SAS/Base ou de macro-instructions.
Voir le corrigé
%macro trim ;
%do i = 1 %to 4 ;
%let debut = %eval((&i-1)*3 + 1) ;
%let fin = %eval(&i*3) ;
proc means data=sashelp.prdsal3 ;
class prodtype ;
var actual ;
where year=1998 and month between &debut and &fin ;
title "Trimestre &i - annee 1998" ;
run ;
%end ;
title ;
%mend trim ;
%trim
%DO %WHILE ... %END. Cette boucle effectue n fois un traitement, tant que la condition d'exécution est vérifiée. Sa syntaxe est analogue à celle du DO WHILE ... END du langage SAS/Base.
%DO %WHILE (condition d'execution) ;
<Instruction1 - n>
%END ;
Où la condition d'exécution fait référence à la valeur d'une macro-variable, et Instruction1 - n est un ensemble d'instructions SAS/Base ou de macro-instructions.
Voir le corrigé
%macro bouclewhile ;
%let age = 11 ;
%do %while (&age <= 13) ;
data class_&age ;
set sashelp.class ;
where age = &age ;
run ;
%let age = %eval(&age + 1) ;
%end ;
%mend bouclewhile ;
%bouclewhile
%DO %UNTIL ... %END. Cette boucle effectue n fois un traitement, jusqu'à ce que la condition d'arrêt soit vérifiée. Sa syntaxe est analogue à celle du DO UNTIL ... END du langage SAS/Base.
%DO %UNTIL (condition d'arret) ;
<Instruction1 - n>
%END ;
Où la condition d'arrêt fait référence à la valeur d'une macro-variable, et Instruction1 - n est un ensemble d'instructions SAS/Base ou de macro-instructions.
Voir le corrigé
%macro boucleuntil ;
%let age = 11 ;
%do %until (&age > 13) ;
data class_&age ;
set sashelp.class ;
where age = &age ;
run ;
%let age = %eval(&age + 1) ;
%end ;
%mend boucleuntil ;
%boucleuntil
- QCM — QCM Module IX — 6 questions, auto-évaluation
Couleur de fond
Police
Crénage de la police
Visibilité de l’image
Hauteur de ligne
Surbrillance de lien
Alignement du texte
Taille de police
Espacement des lettres
Couleur de texte
Largeur de paragraphe