Dans une Macro, tout est CHAÎNE DE CARACTÈRES.
L'utilisateur a tenté ceci :
%let i = '01Oct2007'd; /* &i contient le texte "'01Oct2007'd" */
%let i = %eval(&i + 7); /* ERREUR ! */
1
%let i = '01Oct2007'd;
2
/* &i contient le texte "'01Oct2007'd" */
3
%let i = %eval(&i + 7);
4
/* ERREUR ! */
La fonction %eval (calculatrice d'entiers macro) voit le texte '01Oct2007'd + 7. Elle ne sait pas convertir le littéral '...'d en nombre. Elle échoue donc à faire l'addition.
2. La Solution : Passer par la valeur numérique (%SYSFUNC)
Comme l'explique Linda (LAP), pour faire des maths en macro, vous devez travailler avec des nombres purs, pas des dates formatées.
Re-formater le nombre en date lisible uniquement pour l'affichage/utilisation finale.
Le Code Corrigé
Voici comment transformer la logique de l'utilisateur en macro fonctionnelle :
%macro loop;
/* 1. On convertit le littéral en nombre (ex: 17440) grâce à PUTN ou INPUTN */
/* Note: Ici on utilise l'astuce de formater le littéral en nombre brut '8.' */
%let i = %sysfunc(putn('01Oct2007'd, 8.));
/* On convertit aussi la borne de fin */
%let fin = %sysfunc(putn('31Dec2007'd, 8.));
/* 2. La boucle compare maintenant deux nombres entiers */
%do %until (&i >= &fin);
/* 3. L'incrémentation fonctionne car &i est un entier */
%let i = %eval(&i + 7);
/* 4. Pour l'affichage, on re-transforme le nombre en date lisible */
%put %sysfunc(putn(&i, date9.));
%end;
%mend loop;
%loop;
1
%macro loop;
2
/* 1. On convertit le littéral en nombre (ex: 17440) grâce à PUTN ou INPUTN */
3
/* Note: Ici on utilise l'astuce de formater le littéral en nombre brut '8.' */
4
%let i = %sysfunc(putn('01Oct2007'd, 8.));
5
6
/* On convertit aussi la borne de fin */
7
%let fin = %sysfunc(putn('31Dec2007'd, 8.));
8
9
/* 2. La boucle compare maintenant deux nombres entiers */
10
%DO %until (&i >= &fin);
11
12
/* 3. L'incrémentation fonctionne car &i est un entier */
13
%let i = %eval(&i + 7);
14
15
/* 4. Pour l'affichage, on re-transforme le nombre en date lisible */
16
%put %sysfunc(putn(&i, date9.));
17
18
%END;
19
%mend loop;
20
21
%loop;
3. L'Alternative : %SYSEVALF
L'expert Peter_C mentionne une fonction plus puissante : %sysevalf.
Contrairement à %eval (qui ne gère que les entiers), %sysevalf (System Evaluation Floating) gère les nombres à virgule, mais est aussi capable de mieux interpréter certains littéraux de date s'ils sont entre guillemets doubles.
Cependant, la méthode la plus robuste reste la conversion explicite en nombre via %sysfunc.
Règle d'or : Le processeur macro est "aveugle" aux types de données. Si vous voulez faire des maths, donnez-lui des nombres purs. Si vous voulez des dates, convertissez-les en nombres avant de les lui passer.
Important Disclaimer
The codes and examples provided on WeAreCAS.eu are for educational purposes. It is imperative not to blindly copy-paste them into your production environments. The best approach is to understand the logic before applying it. We strongly recommend testing these scripts in a test environment (Sandbox/Dev). WeAreCAS accepts no responsibility for any impact or data loss on your systems.
SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. ® indicates USA registration. WeAreCAS is an independent community site and is not affiliated with SAS Institute Inc.
This site uses technical and analytical cookies to improve your experience.
Read more.