SAS9

Automatiser le traitement de multiples tables dans un dossier

Simon 25 vues
Niveau de difficulté
Confirmé
Publié le :
Simon

Le conseil de l'expert

Simon

La subtilité de CALL EXECUTE réside dans le moment où la macro est résolue. L'utilisation de %nrstr est souvent indispensable pour "geler" l'exécution de la macro jusqu'à ce que le code soit passé au processeur, empêchant ainsi SAS de tenter (et d'échouer) de résoudre des variables macro qui n'existent pas encore lors de la compilation de l'étape DATA.

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.