Posts Tagged ‘macro’

h1

SAS : obtenez des couleurs sympas dans vos rapports en 5 minutes

août 20, 2018

Publicités
h1

Passer de CLASS CLAS à « CLASS » « CLAS » dans une macro variable

février 1, 2013

Mettre toutes les mots contenus dans une macro variable entre guillemets (quote en anglais) est un tâche plus fréquente qu’elle n’y paraît.
Une vois le code écrit, il est souvent plus rapide de faire du copier/coller et ensuite de modifier. Voici un exemple où DSN=CLASS CLAS sert à créer DSN_QUOTE= »CLASS » « CLAS ».

1. Exemple dans une macro

Dans l’exemple, la macro est PRINTDSN. Elle a pour tâche d’imprimer dans la log tous les datasets présents dans la bibliothèque SASHELP qui sont cités dans le paramètre de macro DSN, s’ils existent.

%macro printdsn (dsn=);

%let dsn      =upcase(&dsn.);
%let dsn_quote=%sysfunc(tranwrd(%nrstr(%")&dsn.%nrstr(%"),%str( ),%str(" ");

proc sql;
 create table ref as
 select memname
 from dictionary.tables
 where upcase(libname)='SASHELP' and
       upcase(memname) in (&dsn_quote.);
quit;

data _null_;
 set ref;
 call execute ('proc print data=' || memname || ';');
 call execute ('run;');
run;
%mend printdsn;
%printdsn(dsn=class clas);

Pour ma part j’ai pris l’habitude de mettre le contenu des macros paramètres en majuscule, et ce dès le début du programme, sauf besoin spécifique contraire. Ceci explique la ligne %let dsn=upcase(&dsn.);

De plus j’ai pris l’habitude de rajouter le suffixe _quote au nom de la macro variable. Dans notre exemple il y a la macro variable DSN mise en majuscule. Cette variable est ensuite mise entre guillemets.

La macro fonction %sysfunc() permet d’utiliser la fonction tranwrd dans une expression macro. La fonction tranwrd est composée de trois paramètres :

  1. le texte d’origine entre guillemets
  2. le partie de texte à remplacer dans cette chaîne de caractères
  3. le texte de remplacement

2. Le même exemple sans macro

L’exemple est présenté dans une macro. Pour tester le code, un simple %let et %put feront l’affaire. Le résultat s’affiche alors dans la log.

%let dsn=CLASS CLAS;
%let dsn_quote=%sysfunc(tranwrd(%nrstr(%")&dsn.%nrstr(%"),%str( ),%str(" ");
%put &dsn_quote.;
h1

Macro : mini-programmes/routines pour tester la validité d’un nom de variable

juin 27, 2010

Après avoir appris les bases de la programmation, vous allez vous rendre compte que certaines tâches se répètent de programme à programme. Une partie d’entre eux peut se résumer à quelques lignes. Il est alors tentant d’écrire un programme de manière « officielle » et de le valider au lieux d’avoir à écrire le code à chaque fois.

Voici un petit exemple. Il s’agit du descriptif d’une macro qui va indiquer si le nom de variable donné est conforme aux règles requises par SAS. Ici vous avez la spécification et les tests de validation.

1. Spécification : Quelles sont les règles ?

Le nom d’une variable ne peut pas avoir plus de 32 caractères.

Le premier caractère est une des 26 lettres de l’alphabet ou un chiffre.

Les autres caractères  peuvent être des lettres de l’alphabet, un chiffre ou un tiret bas (underscore).

2. Spécification : Quelques contraintes ?

Vous développez une macro disons VARNAME_VALID ayant un paramètre VARNAME où vous pourrez entrer le nom d’une variable à tester. Si ce nom entre dans les critères de définition de SAS, alors une macro variable varname_ok=1 sinon la macro variable varname_ok=o.

3. Test Cases : Quand tout va bien: un nom de variable avec une seule lettre, deux lettre, commençant par un tiret bas, écrit en majuscule, avec un chiffre au milieu, avec un chiffre à la fin

Qu’est ce qui est testé : un nom de variable suivant les règles requises par SAS.

Quel est le code à soumettre :

%varname_valid(varname=a);
%varname_valid(varname=ab);
%varname_valid(varname=_ab);
%varname_valid(varname=AB);
%varname_valid(varname=ab1a);
%varname_valid(varname=ab1);

Quel est le résultat attendu :

La macro variable garde la valeur un

&varname_ok.=1

Un message dans la log est affiché :

NOTE: (VARNAME_VALID) Nom de variable correct.
NOTE: (VARNAME_VALID) Valeur actuelle :  ab

D’autres programmes peuvent être appelés après.

4. Test Cases : Violation des pré-requis de la macro

4.1 Violation pré-requis : le paramètre est manquant

Qu’est ce qui est testé : Un nom de variable doit être donné dans le paramètre de la macro

Quel est le code à soumettre : %varname_valid(varname=);

Quel est le résultat attendu :

La macro variable VARNAME_OK prend la valeur zéro

&varname_ok.=0

Un message dans la log est affiché :

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle:
EARNING: (VARNAME_VALID) Valeur attendue: un nom de variable.

D’autres programmes peuvent être appelés après.

4.2 Violation pré-requis : plus d’un nom de variable est entré

Qu’est ce qui est testé : Plus d’une variable est entrée dans le paramètre de macro

Quel est le code à soumettre : %varname_valid(varname= ab cd );

Quel est le résultat attendu :

La macro variable prend la valeur zéro

&varname_ok.=0

Un message dans la log est affiché :

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle : ab cd
WARNING: (VARNAME_VALID) Valeur attendue : un seul nom de variable.

D’autres programmes peuvent être appelés après.

5. Test Cases : Les règles définies par SAS pour nommer une variable

5.1  Un nom de variable : Au maximum 32 caractères

Qu’est ce qui est testé : un variable avec plus de 32 caractères

Quel est le code à soumettre : %varname_valid(varname=abcdefghijklmnopqrstuvwxyz1234567890);

Quel est le résultat attendu :

La macro variable prend la valeur z éro

&varname_ok.=0

Un message dans la log est affiché :

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle : abcdefghijklmnopqrstuvwxyz1234567890
WARNING: (VARNAME_VALID) Valeur attendue : 32 caractères au maximum.

D’autres programmes peuvent être appelés après.

5.2 Un nom de variable : commence par une lettre de l’alphabet (a-z) ou un tiret bas

Qu’est ce qui est testés : Un premier caractère différent d’une lettre de l’alphabet ou d’un tiret bas

Quel est le code à soumettre : %varname_valid(varname=é);

Quel est le résultat attendu :

La macro variable prend la valeur zéro

&varname_ok.=0

Un message dans la log est affiché :

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle : é
WARNING: (VARNAME_VALID) Valeur attendue : La première lettre est une des 26 lettres ou un tiret bas.

D’autres programmes peuvent être appelés après.

5.3 Un nom de variable : Après le premier caractère on peut avoir des lettres (a-z), des chiffres (0-9) et des tirets bas.

Qu’est ce qui est testé : un caractère différent d’une lettre de l’alphabet, d’un chiffre ou d’un tiret bas parmi les autres caractères de l’alphabet

Quel est le code à soumettre : %varname_valid(varname=1é);

Quel est le résultat attendu :

La macro variable prend la valeur zéro

&varname_ok.=0

Un message dans la log est affiché :

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle : 1é
WARNING: (VARNAME_VALID) Valeur attendue : La première lettre est une des 26 lettres ou un tiret bas.

WARNING: (VARNAME_VALID) Nom de variable incorrect.
WARNING: (VARNAME_VALID) Valeur actuelle : 1é
WARNING: (VARNAME_VALID) Valeur attendue : A partir du deuxième caractères, seuls des lettres,
WARNING: (VARNAME_VALID) des chiffres et un tiret bas sont autorisés.

Lecture complémentaire

h1

Une petite histoire de macro : compter le nombre de mots dans un paramètre de macro

avril 11, 2010

Il est courant de devoir compter le nombre de mots dans un paramètre de macro. Il est par exemple possible de vouloir créer une boucle pour travailler chacun des termes contenu dans cette macro de manière séparée.

Voici donc l’histoire d’une mini macro qu’on nommera CNT_WRD qui crée une macro variable TOT_WRD renvoyant le nombre de mots contenu dans le paramètre TXT.

Ceci est pour vous l’occasion de voir ou revoir un raisonnement possible dans la construction d’une macro sous SAS.

1. Préciser ses besoins, une rapide « spécification »

La macro CNT_WRD composée d’un seul paramètre retournera dans une macro variable TOT_WRD le nombre de mots contenus dans le texte donné dans le paramètre de macro.

Ici on considérera comme mot, tout terme séparé par au moins un blanc.

Si le paramètre de macro est vide, la macro ne devra pas afficher de message d’erreur et la macro variable TOT_WRD sera égale à 1. Par défaut, aucune valeur ne sera entrée dans le paramètre TXT.

La macro variable doit pouvoir être utilisable à l’extérieur de la macro (macro variable globale).

2. Tester la fonction COUNT dans une étape data

La fonction COUNT permet de comptabiliser certains caractères et donc de répondre à ce type de besoin. En fait, cette fonction ne compte pas le nombre de mots mais compte le nombre de caractères définis par le second élément dans la fonction; dans notre cas, elle comptera le nombre de blancs. Il faut donc ajouter 1 au total.

Voici un exemple dans une étape data.

data _null_;
tot_wrd=1+count(‘mot1 mot2’,‘ ‘);
put tot_wrd=;
run;

Dans la log, vous pouvez voir que cnt_wrd=2.

Mais cela ne suffit pas pour gérer les blancs multiples et les blancs aux extrémités. Car si vous avez plus d’un blanc entre chaque mot, chacun sera compté. Il faut donc les enlever au préalable (avec la fonction COMPBL ici). Les blancs de début et fin peuvent s’enlever au moyen de la fonction STRIP.

data _null_;
tot_wrd=1+count(strip(compbl(‘ mot1 mot2 ‘)),‘ ‘);
put tot_wrd=;
run;

Mais que ce passe t-il si notre texte à compter est vide ? TOT_WRD sera égal à 1. Il faut donc ajouter le 1 au total que si le texte à analyser n’est pas vide.

data _null_;
length txt $200;
txt=;
if txt ne ‘ ‘ then tot_wrd=1+count(strip(compbl(txt)),‘ ‘);
put tot_wrd=;
run;

3. Créer la macro

Comme indiqué dans le dernier point, on travaille ici de manière conditionnelle. Si le paramètre de macro TXT est vide, la macro variable CNT_WRD nouvellement créée prend la valeur zéro. Sinon, On passe par la fonction COUNT.

Comme il n’existe pas d’équivalent aux fonctions COUNT et COMPBL en langage macro, il faut encadrer chacune d’elle dans une fonction macro SYSFUNC.

Ici on notera que la fonction STRIP n’apparaît pas. Les blancs de début et de fin en langage macro n’ont aucun impact.

%macro cnt_wrd(txt=);

%global tot_word;

%if &txt.= %then %let tot_wrd=0;
%else %let tot_wrd=%eval(1+%sysfunc(count(%sysfunc(compbl(&txt.)),%str( ))));

%mend cnt_wrd;

Pour représenter un blanc dans une étape data, il suffit d’utiliser des guillemets. En langage macro, on fait appel à la fonction %STR(). Il faudra ne pas oublier d’ajouter un blanc entre les parenthèses.

Afin d’ajouter 1 au résultat de la fonction COUNT, il faut utiliser la macro fonction %EVAL. Le contenu des macro variables sont sinon tous interprétés comme du texte, qu’il s’agisse de nombres ou pas.

Enfin, pour que cette macro variable TOT_WRD soit utilisable en dehors de la macro, il faut qu’elle soit globale. Hors par défaut, une macro variable créée dans une macro est locale, c’est-à-dire n’existe que le temps de la macro. L’instruction %GLOBAL TOT_WRD; résouds le problème.

4. Tester la macro dans le cadre de sa validation

Que se passe t-il quand on ne change pas la valeur par défaut du paramètre de macro ?

%cnt_wrd;
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il quand le paramètre de macro TXT est vide de texte ?
%put Valeur de TOT_WRD: &tot_wrd;

%cnt_wrd(txt=);
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il lorsqu’il n’y a qu’un mot?

%cnt_wrd(txt=mot1);
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il quand il y a plusieurs mots ?

%cnt_wrd(txt=mot1 mot2 mot3);
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il quand il y a des blancs multiples entre les mots, en début et à la fin ?

%cnt_wrd(txt= mot1 mot2 mot3 );
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il quand il y a des blancs multiples entre les mots, en début et à la fin ?

%cnt_wrd(txt=mot1 mot2);
%put Valeur de TOT_WRD: &tot_wrd;

Que se passe t-il quand la macro est appelée plusieurs fois ?

%cnt_wrd(txt=mot1 mot2);
%put Valeur de TOT_WRD: &tot_wrd;
%cnt_wrd(txt=mot1);
%put Valeur de TOT_WRD: &tot_wrd;

Lecture complémentaire

h1

Protégé : Une fonction LIBREF au résultat inattendu

mars 23, 2010

Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

h1

Protégé : Newsletter Mars : solution

mars 1, 2010

Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :

h1

Protégé : Newsletter Mars : Exercice

mars 1, 2010

Cet article est protégé par un mot de passe. Pour le lire, veuillez saisir votre mot de passe ci-dessous :