SAS Macro  •  Module IX  •  2 h
Les macro-programmes
M2 TIDE — Stage de programmation SAS — Enseignement 100 % distanciel
Objectifs du module
  • É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 ;
Exercice IX.1 (21) — Créer un macro-programme DATE_HEURE_SESSION qui renvoie la date et l'heure de l'ouverture de la session.
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.

Exercice IX.2 (221-A1) — Créer un macro-programme qui permet d'afficher le listing des élèves présents dans la table SASHELP.CLASS.
Voir le corrigé
%macro listing ;
    proc print data=sashelp.class ;
    run ;
%mend listing ;

%listing
Exercice IX.3 (221-A2) — Adapter ce macro-programme pour faire un listing pour les hommes ou pour les femmes, en passant le sexe en paramètre du macro-programme.
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.

Exercice IX.4 (222-A1 et A2) — Adapter les deux exercices précédents avec des paramètres mots-clés.
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.

  1. Étape 1 — Écrivez et déboguez un programme SAS sans langage macro. Puis assurez-vous que le programme SAS fonctionne avec des valeurs fixes.
  2. É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.
  3. Étape 3 — Créez un macro-programme avec %MACRO et %MEND. Remplacez les instructions %LET par des macro-paramètres.
  4. Étape 4 — Ajoutez des instructions du langage macro comme %IF-%THEN.
Ces quatre étapes ne sont pas une recommandation de confort : elles constituent la seule méthode réaliste pour déboguer. Un macro-programme écrit d'un seul jet est presque impossible à corriger, parce que l'erreur peut se situer soit dans le code généré, soit dans la génération elle-même.
Exercice IX.5 (231-A) — Ajouter un test conditionnel sur le genre pour afficher un titre différent, selon le genre passé en paramètre.
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)
Exercice IX.6 (231-B) — Créer un macro-programme %PROD, avec le paramètre ANALYSE, qui : si le paramètre vaut PRODUITS, exécute une analyse descriptive de la table SASHELP.PRDSAL3 pour la variable ACTUAL, avec des sous-groupes par produits ; sinon, si le paramètre vaut TYPES, exécute une analyse descriptive de la table SASHELP.PRDSAL3 pour la variable ACTUAL, avec des sous-groupes par type de produits.
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.

Exercice IX.7 (232-A) — À partir de la table SASHELP.PRDSAL3, créer une macro %TRIM, sans paramètre, qui permet d'analyser les ventes par type de produit pour l'année 1998 en créant un rapport par trimestre.
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.

Exercice IX.8 (232-B) — À l'aide d'une boucle %DO %WHILE, créer une macro %bouclewhile qui permet de créer les tables CLASS_11, CLASS_12, CLASS_13 à partir de la table SASHELP.CLASS, où CLASS_XX représente les élèves de XX ans.
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.

Exercice IX.9 (232-C) — Écrire une macro %boucleuntil qui permet d'obtenir les mêmes tables que l'exercice précédent.
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
Différence à ne pas perdre de vue : %DO %WHILE teste la condition avant la première itération — la boucle peut donc ne jamais s'exécuter — tandis que %DO %UNTIL teste après, ce qui garantit au moins un passage. C'est exactement ce que vous devez observer en comparant les résultats des exercices IX.8 et IX.9.
Point de contrôle — à faire avant de continuer
Reprenez l'exercice IX.7 et activez l'option MPRINT avant l'appel de la macro. Lisez dans la LOG le code réellement généré pour chacun des quatre trimestres. Si le code généré vous surprend, c'est le bon moment pour revenir à l'étape 2 des bonnes pratiques.
Pour valider ce module
  • QCM — QCM Module IX — 6 questions, auto-évaluation
Modifié le: mardi 11 août 2026, 14:18
Accessibilité

Couleur de fond Couleur de fond

Police Police

Crénage de la police Crénage de la police

Visibilité de l’image Visibilité de l’image

Hauteur de ligne Hauteur de ligne

1.2

Surbrillance de lien Surbrillance de lien

Alignement du texte Alignement du texte

Taille de police Taille de police

1

Espacement des lettres Espacement des lettres

0

Couleur de texte Couleur de texte

Largeur de paragraphe Largeur de paragraphe

0