IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macro Discussion :

Paramétrage macro qui vérifie type de variables : A character operand was found IN the %EVAL FUNCTION


Sujet :

Macro

  1. #1
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut Paramétrage macro qui vérifie type de variables : A character operand was found IN the %EVAL FUNCTION
    Bonsoir,
    j'ai réussi à mettre en oeuvre la méthode

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    %macro verif_num_char(string);
    	DATA _NULL_;
    		var=input("&string" ,?? COMMA8.);
    		IF var=. then call symput('type','CHAR');
    		else call symput('type','NUM');
        run;
    	%put &type;
    %mend;
    exposée dans ce sujet

    Les calculs engendrés par cette méthode m'apparaissent néanmoins très longs car le data _null_ est exécuté pour un grand nombre de variables et plusieurs milliers d'enregistrements.

    J'essaie donc d'utiliser la macro suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    %Macro DataTyp_Numeric(MyVarIn) / store;
    	%Global Flag;
    	%local stVal;
     
    	/* Par convention, l'informat d'une valeur vide est correct */
    	%If &MyVarIn= %Then %Let Flag=1;
     
    	/* Cas d'une valeur non vide */
    	%If &MyVarIn ne %Then
    	%Do;
    		/* Cas d'une valeur constituée de blancs */
    		/* Strip enlève les blancs aux extrêmités */
    		%let stVal=%sysfunc(Strip(&MyVarIn));
     
    		/* Par convention, l'informat d'une valeur composée de blancs est correct */
    		%IF %LENGTH(&stVal)=0 %THEN %Let Flag=1;
     
    		%IF %LENGTH(&stVal)>0 %THEN %DO;
     
    			%let Flag=0;
     
    		    %Local j;
    			/* On ôte de MyvarIn passé en paramètre les caractères constitutifs d'un nombre */
    			/* i.e. espace, chiffres, virgule, point, +, - */
    			/* Ensuite on compte le nombre de caractères restants  */
    		    %let j = %sysfunc(compress(&myvarin.," 0123456789.,+-"));  
    		  	%IF %LENGTH(&j) eq 0 %THEN %let Flag=1;
    		%END;
    	%End;
    %Mend;
    que j'appelle grâce à un call execute dans une étape data :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If code_ ne &MyValueVide then do;CALL EXECUTE ('%DataTyp_Numeric('|| put(code, 3.) ||')'); %If &Flag ne 1 %Then %Do; code_=&MyFormatNok; %end; %Else %do; code_=&MyFormatOk; %end; end;
    Cet appel me génère le message suivant :

    ERREUR: A character operand was found in the %EVAL function or %IF condition where a numeric
    operand is required. The condition was: &MyVarIn=
    ERREUR: The macro DATATYP_NUMERIC will stop executing.
    J'ai essayé différentes syntaxes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    %STR(%')&MyString%STR(%')
    '&MyString'
    %eval(&MyString)
    Avec %eval le message est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ERREUR: A character operand was found in the %EVAL function or %IF condition where a numeric
            operand is required. The condition was: 1.00
    sans succès.

    Je tourne en rond pour essayer de trouver une syntaxe correcte.
    Si quelqu'un a une idée ça me dépannerait bien.

    Merci

  2. #2
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut


    La data _null_ et la macro doivent servir à tester de façon autonome le format d'une macro-variable.

    tu sembles vouloir utiliser cette méthode au sein d'une étape DATA pour tester l'un des ces champs. Est-ce cela ?

    Ensuite... je vois le message
    The condition was: &MyVarIn=
    mais je ne vois pas de dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    IF code_ ne &MyValueVide then do;
    CALL EXECUTE ('%DataTyp_Numeric('|| put(code, 3.) ||')'); 
    %IF &Flag ne 1 %Then %Do; code_=&MyFormatNok; %end; 
    %Else %do; 
    code_=&MyFormatOk; 
    %end; 
    end;

  3. #3
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut
    Bonjour et bonne année 2010, Datametric,
    Oui c'est bien ça.

    Le &MyVarIn est dans la macro %DataTyp_Numeric.


    En utilisant l'option SYMBOLGEN je vois que c'est la valeur +0000.00 de &MyVarIn qui cause l'erreur.

    SYMBOLGEN: Macro variable MYVARIN resolves to +0000.00
    ERREUR: A character operand was found in the %EVAL function or %IF condition where a numeric
    operand is required. The condition was: &MyVarIn=
    ERREUR: The macro DATATYP_NUMERIC will stop executing.

  4. #4
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Bonne année.

    mais tu testes le type au sein d'une étape DATA ?

  5. #5
    Membre éclairé Avatar de Filippo
    Homme Profil pro
    Statisticien
    Inscrit en
    Mai 2004
    Messages
    864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Statisticien

    Informations forums :
    Inscription : Mai 2004
    Messages : 864
    Points : 881
    Points
    881
    Par défaut
    Je n'utilise pas la macro %verif_num_char qui réutilise un data_null_; elle fonctionne mais c'est très long.

    Là j'ai contourné le problème en calculant la longueur de MyVarIn au lieu de la comparer à vide.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    %Macro DataTyp_Numeric(MyVarIn=) / store;
    	%Global Flag;
    	%local stVal;
    	%local longueur;
     
    	/* Par convention, l'informat d'une valeur vide est correct */
    	%let longueur=%LENGTH(&MyVarIn);
    	%If &longueur=0 %Then %Let Flag=1;
     
    	/* Cas d'une valeur non vide */
    	%If &longueur ne 0 %Then
    	%Do;
    		/* Cas d'une valeur constituée de blancs */
    		/* Strip enlève les blancs aux extrêmités */
    		%let stVal=%sysfunc(Strip(&MyVarIn));
     
    		/* Par convention, l'informat d'une valeur composée de blancs est correct */
    		%IF %LENGTH(&stVal)=0 %THEN %Let Flag=1;
     
    		%IF %LENGTH(&stVal)>0 %THEN %DO;
     
    			%let Flag=0;
     
    		    %Local j;
    			/* On ôte de MyvarIn passé en paramètre les caractères constitutifs d'un nombre */
    			/* i.e. espace, chiffres, virgule, point, +, - */
    			/* Ensuite on compte le nombre de caractères restants  */
    		    %let j = %sysfunc(compress(&myvarin.," 0123456789.,+-"));  
    		  	%IF %LENGTH(&j) eq 0 %THEN %let Flag=1;
    		%END;
    	%End;
    %Mend;

  6. #6
    Membre éprouvé
    Avatar de steelspirit
    Homme Profil pro
    SAS discute
    Inscrit en
    Janvier 2008
    Messages
    472
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : SAS discute
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2008
    Messages : 472
    Points : 916
    Points
    916
    Par défaut
    Hello Filippo & Datametric, Bonne année !

    Effectivement la première solution avec l'étape Data ne marche pas lorsque tu utilises CALL EXECUTE (tu ne peux pas appeler une étape data dans une étape data).

    Du coup ta solution de passer en langage macro est la bonne.

    Pour simplifier ton code, tu peux également utiliser la fonction ANYALPHA (nouveauté V9) qui retourne 0 quand on a que du numérique.

    Voici ce que ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    %Macro DataTyp_Numeric(MyVarIn) ;
    	%Global Flag;
    	/* Par convention, l'informat d'une valeur vide est correct */
    	%IF "&MyVarIn"="" %Then %Let Flag=1;
     
    	%else %do;
    		%if %sysfunc(anyalpha(&MyVarIn))=0 %then %Let Flag=1;
    	%end;
    	%put valeur de flag = &flag;
    %Mend;
     
    %DataTyp_Numeric(AB3C);
    %DataTyp_Numeric(123);
    %DataTyp_Numeric(123.4);
    Bon courage,

    Steel

  7. #7
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Bonne année steelspirit.

    Effectivement les fonctions ANYxx sont particulièrement bien adaptées dans ce cas. Mais la question autour de ce topic pour moi était de savoir pourquoi il fallait passer par une macro plutôt que d'utiliser directement un test dans l'étape DATA.

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/01/2010, 17h02
  2. Macro qui vérifie qu'une valeur est dans une table
    Par Filippo dans le forum Macro
    Réponses: 2
    Dernier message: 23/11/2009, 09h57
  3. Réponses: 1
    Dernier message: 18/09/2009, 19h37
  4. fonction qui indique qu'une variable est d'un type entier
    Par piotrr dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 21/06/2007, 16h05
  5. [Système] Variable qui vérifie un pseudonyme
    Par jojoquiasa dans le forum Langage
    Réponses: 1
    Dernier message: 08/04/2007, 12h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo