SAS9

Automatiser le traitement de multiples tables dans un dossier

Simon 12 views

Un défi fréquent pour les analystes SAS© est de devoir répéter une opération (comme un MERGE pour ajouter une colonne) sur des dizaines de tables situées dans un même répertoire. Écrire 50 fois l'appel de macro %jig(name=AB);, %jig(name=AC);... est fastidieux et source d'erreurs.

Comment faire pour que SAS© "scanne" le dossier et applique la macro automatiquement à chaque fichier ? Voici la méthode élégante proposée par WeAreCas, utilisant les métadonnées SAS©.

1. La Stratégie : Dictionnaires et CALL EXECUTE

L'approche repose sur deux piliers de la programmation dynamique SAS© :

  1. Récupérer la liste des noms : Utiliser les vues dictionnaires (SASHELP.VTABLE) pour lister automatiquement tout ce qui se trouve dans une bibliothèque.

  2. Générer le code dynamiquement : Utiliser l'instruction CALL EXECUTE dans un Data Step pour lancer la macro pour chaque nom trouvé.

2. Le Code Pas à Pas

Étape 0 : Définir la Macro de traitement

C'est le code que l'utilisateur veut exécuter pour une seule table.

1%macro jig(name);
2 DATA datdir.NEW_&name;
3 /* Attention : les deux tables doivent être triées par ID au préalable */
4 MERGE excelsheetdata datdir.&name;
5 BY ID;
6 RUN;
7%mend jig;

Étape 1 : Lister les tables cibles (PROC SQL)

Plutôt que d'écrire les noms à la main, on demande à SAS© : "Donne-moi la liste de toutes les tables non vides présentes dans la bibliothèque 'DATDIR'."

1
 
1PROC SQL;
2 create TABLE liste_tables as
3 select memname
4 from sashelp.vtable
5 where LIBNAME='DATDIR' /* Nom de la lib en MAJUSCULES */
6 and memname like 'DATA_%'; /* Filtre optionnel si besoin */
7QUIT;
Note : SASHELP.VTABLE contient les métadonnées de toutes les tables actives.
Note :
Étape 2 : L'automatisation (CALL EXECUTE)
C'est ici que la magie opère. On parcourt la liste créée à l'étape 1, et pour chaque ligne, on construit une commande textuelle qui appelle la macro.
1DATA _null_;
2 SET liste_tables;
3
4 /* Construction de la chaîne : '%jig(TABLE_1)' */
5 commande = '%jig(' || strip(memname) || ')';
6
7 /* Exécution immédiate de cette commande */
8 call execute(commande);
9RUN;

3. Analyse de la syntaxe CALL EXECUTE

Dans la solution proposée par WeAreCas, vous noterez une syntaxe un peu complexe :

call execute( '%nrstr( %%)' !! 'jig(' !! memname !! ') ' );

Pourquoi %nrstr(%%) ?

  • CALL EXECUTE résout les macros pendant l'exécution du Data Step.

  • Parfois, on veut retarder cette exécution ou protéger certains caractères spéciaux.

  • Dans la plupart des cas simples (comme ici), call execute('%jig(' || memname || ')'); suffit.

  • L'ajout de %nrstr sert souvent à éviter que SAS© n'essaie de résoudre la macro trop tôt si elle contient des variables macro conflictuelles.

Résumé de la Méthode

MéthodeAvantageInconvénient
ManuelleSimple à comprendre.Long, répétitif, risque d'oubli.
Wildcards (ex: DATA_: )Rapide pour un SET simple.Ne fonctionne pas pour un MERGE complexe.
Dictionnaires + Call ExecuteEntièrement automatique, flexible.Demande de connaître SQL et la méta-programmation.

Le conseil technique : N'oubliez pas que pour qu'un MERGE fonctionne, toutes vos tables (les 50 !) doivent être préalablement triées par la variable clé (ID). Si ce n'est pas le cas, vous devrez ajouter une PROC SORT à l'intérieur de votre macro %jig.