Précédent   Forum des professionnels en informatique > Logiciels > Solutions d'entreprise > Business Intelligence > SAS > Macro
Macro Forum d'entraide sur le langage Macro de SAS
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 12/05/2011, 14h16   #1
Membre du Club
 
Inscription : novembre 2003
Messages : 142
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 142
Points : 58
Points : 58
Par défaut Taille de paramètre dans une macro

Bonjour,
Le code suivant :
Code :
1
2
3
4
5
6
7
8
9
%macro ESSAI;
   %let MOT=;
   %do i=1 %TO 19;
      %IF &i < 10 %then %let j=&i; %else %let j=%substr(&i,2,1);
      %let MOT=&MOT.&j;
      %IF &MOT ne %then %put &MOT;
   %end;
%mend ESSAI;
%essai;
Donne comme résultat :

Citation:
1
12
123
1234
12345
123456
1234567
12345678
123456789
1234567890
12345678901
123456789012
1234567890123
12345678901234
123456789012345
1234567890123456
12345678901234567
123456789012345678
1234567890123456789
Si on incrémente i au-delà de 19, on obtient une erreur :

Citation:
ERREUR: Dépassement ; évaluation stoppée.
ERREUR: L'exécution de la macro ESSAI va s'arrêter
C'est au moment de l'exécution du test sur la variable MOT que le problème se pose.

Quelqu'un saurait-il comment procéder pour dépasser cette limite ?
enicnath est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 14h40   #2
Membre confirmé
 
Inscription : janvier 2010
Messages : 185
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 185
Points : 250
Points : 250
Essaie cette écriture :
Code :
1
2
 
 %IF ^%sysevalf(%superq(MOT)=,BOOLEAN) ne %then %put &MOT;
J'utilise cette macro pour tester si un paramètre macro est vide :

Code :
1
2
3
%macro Blanc(param);
   %sysevalf(%superq(param)=,BOOLEAN)
%mend;
C'est le moyen le plus sûr car param peut contenir des parenthèses ou d'autres caractères interprétés normalement comme du code SAS ou macro.


Citation:
source: Paper 022-2009
IS THIS MACRO PARAMETER BLANK?
Chang Y. Chung, Princeton University, Princeton, NJ
John King, Ouachita Clinical Data Services, Mount Ida, AR
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/05/2011, 18h00   #3
Expert Confirmé
 
Avatar de olivier.decourt
 
Homme Olivier Decourt
Formateur en informatique
Inscription : avril 2008
Messages : 1 467
Détails du profil
Informations personnelles :
Nom : Homme Olivier Decourt
Âge : 34
Localisation : France

Informations professionnelles :
Activité : Formateur en informatique
Secteur : Conseil

Informations forums :
Inscription : avril 2008
Messages : 1 467
Points : 2 823
Points : 2 823
Comme le souligne SASADM, le souci ne vient que de la ligne
Il faut savoir que %IF est une instruction assez "spéciale". Quand on lui envoie une condition, elle cherche à lui trouver une valeur logique en s'aidant des fonctions d'évaluation comme %EVAL et %SYSEVALF, celles qui transforment les chaînes de caractères qu'on trouve dans les macro-variables en nombres. Quand le compilateur macro voit arriver ta condition
Citation:
12345678901234567890 NE
(c'est la valeur de &mot quand ça plante), il prend peur car il croit qu'on veut lui demander si cette valeur est supérieure ou inférieure à une autre. Or cette valeur est un NOMBRE que SAS ne peut pas manipuler car il est trop gros.
En revanche, la chaîne de caractères, elle, ne pose aucun souci, et il faut donc rédiger le %IF autrement.
La proposition de SASADM est bonne, mais elle risque d'effrayer le commun des codeurs. Je te propose une alternative toute bête qui fonctionne dans de nombreux cas (pas tous) et ici aussi : si la longueur de &mot est supérieure à 1 (il y a au moins 1 caractère non vide dans &mot).
Code :
1
2
3
4
5
6
7
8
9
%macro ESSAI (max) ;
   %let MOT=;
   %do i=1 %TO &max;
      %IF &i < 10 %then %let j=&i; %else %let j=%substr(&i,2,1);
      %let MOT=&MOT.&j;
      %IF %LENGTH(&MOT)>0 %then %put &MOT;
   %end;
%mend ESSAI;
%essai (50) ;
Bon courage.
Olivier
olivier.decourt est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 10h06   #4
Membre du Club
 
Inscription : novembre 2003
Messages : 142
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 142
Points : 58
Points : 58
Merci SASADM et Olivier, ça résoud tout à fait mon problème !
par contre Olivier, tu dis que ta solution ne fonctionne pas dans tous les cas. Pourrais-tu me préciser, sauf le cas où MOT est vide, dans quels autres cas elle ne fonctionne pas et pourquoi ?
enicnath est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/05/2011, 10h21   #5
Membre confirmé
 
Inscription : janvier 2010
Messages : 185
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 185
Points : 250
Points : 250
Dans ton cas ça fonctionnera toujours car tu manipules des chiffres et donc des caractères qui ne seront pas confondus par le compilateur SAS avec des éléments du langage macro.

La technique du length atteint ses limites quand il s'agit de tester la valeur d'un paramètres dont tu ne maitrises pas la forme. Dans le traitement de formulaire WEB par exemple où la saisie des champs est laissée libre à l'utilisateur. Là, la valeur du paramètre peut "casser" le code macro comme dans l'exemple ci-dessous :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
%macro ESSAI ( ) ;
   %let MOT=);
	%IF %LENGTH(&MOT)>0 %then %put &MOT;
%mend ESSAI;
 
%essai ( ) ;
 
 
%macro ESSAI2 ( ) ;
    %let MOT=);
	%IF ^%sysevalf(%superq(MOT)=,BOOLEAN) ne %then %put &MOT;
%mend ESSAI2;
 
%essai2 ( ) ;
sasadm est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 20/05/2011, 16h50   #6
Membre du Club
 
Inscription : novembre 2003
Messages : 142
Détails du profil
Informations forums :
Inscription : novembre 2003
Messages : 142
Points : 58
Points : 58
Merci !
enicnath est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h36.


 
 
 
 
Partenaires

Hébergement Web