Hello experts,
I'm struggling to get a value from the macro variable with %eval function:
%macro test2;
data test;
k=1;
l=.;
call symputx('k',k);
call symputx('l',l);
run;
%if %eval(&l.)=. %then %do;
%put "TEST MACRO";
%end;
%mend;
%test2;
The error is: ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was:
.
ERROR: The macro TEST2 will stop executing.
In fact, I would like to execute the code conditionally (in the case of empty value of numeric macro variable).
Thank you very much for your help!
Best regards,
Marie
%eval is for integer arithmetic or evaluating comparisons (which return integer values). And Macro value of . is not an integer.
So you get that error.
To see if the value of l is . use this code. WARNING: if you change the system option of missing from the default this will behave differently.
%macro test2; data test; k=1; l=.; call symputx('k',k); call symputx('l',l); run; %if &l.=. %then %do; /* or %if %eval(&l. = .) %then %do; */ %put "TEST MACRO"; %end; %mend; %test2;
You might describe how you intend to use this in a bit more detail as missing values and macro variables can be a bit tricky.
%eval is for integer arithmetic or evaluating comparisons (which return integer values). And Macro value of . is not an integer.
So you get that error.
To see if the value of l is . use this code. WARNING: if you change the system option of missing from the default this will behave differently.
%macro test2; data test; k=1; l=.; call symputx('k',k); call symputx('l',l); run; %if &l.=. %then %do; /* or %if %eval(&l. = .) %then %do; */ %put "TEST MACRO"; %end; %mend; %test2;
You might describe how you intend to use this in a bit more detail as missing values and macro variables can be a bit tricky.
@SASdevAnneMarie wrote:
Thank you very much!
Does it work if I test &l.^=. (case of non-empty value)?
Why not just try it and see? Set the macro variable and then evaluate your test. 1 is TRUE and 0 is FALSE.
854 %let x=.; 855 %put %eval(&x=.); 1 856 %put %eval(&x=); 0 857 %let x=; 858 %put %eval(&x=.); 0 859 %put %eval(&x=); 1 860 %let x=0; 861 %put %eval(&x=.); 0 862 %put %eval(&x=); 0 863 %let x=text; 864 %put %eval(&x=.); 0 865 %put %eval(&x=); 0
I took a slightly different approach from @Tom. I'm not sure that it's necessarily better, but perhaps it will be of value in some circumstances. It's a little macro that will detect character or numeric missing values in a macro variable including special missing values. The MISSING option should matter less, at least that's the idea.
Here's the macro:
%MACRO Test_For_Missing(Var, Debug=NO) / MINOPERATOR MINDELIMITER=',';
%LOCAL lCmnt;
%IF %QUPCASE(&Debug) = YES %THEN
%DO;
%LET lCmnt = ;
%PUT NOTE: Debug is on in &Sysmacroname;
%PUT NOTE- &Var is >&&&Var<;
%END;
%ELSE
%DO;
%LET lCmnt = ;
%END;
%IF %BQUOTE(&&&Var) = %BQUOTE() %THEN
%DO;
%PUT NOTE: &Var is missing. Value is >&&&Var<;
%END;
%ELSE
%IF (%QUPCASE(&&&Var) IN (._,.,%STR(),%STR( ),.A,.B,.C,.D,.E,
.F,.G,.H,.I,.J,.K,.L,.M,.N,.O,.P,
.Q,.R,.S,.T,.U,.V,.W,.X,.Y,.Z)) %THEN
%DO;
%PUT NOTE: &Var is missing. Value is >&&&Var<;
%END;
%ELSE
%DO;
%PUT NOTE: &Var is NOT missing. Value is >&&&Var<;
%END;
%MEND Test_For_Missing;
And here's some test code:
%LET Char_Missing = ;
%LET Num_Missing = .;
%LET Spcl_Missing = .E;
%LET Char_Var = Ham Sandwich;
%LET Num_Var = 07292020;
%LET Save_Options = %SYSFUNC(GETOPTION(SOURCE)) %SYSFUNC(GETOPTION(SOURCE2)) PS=%SYSFUNC(GETOPTION(PS)) ;
OPTIONS NOSOURCE NOSOURCE2 PS=MAX;
%Test_For_Missing(Char_Missing, Debug=NO);
%Test_For_Missing(Num_Missing, Debug=NO);
%Test_For_Missing(Spcl_Missing, Debug=NO);
%Test_For_Missing(Char_Var, Debug=NO);
%Test_For_Missing(Num_Var, Debug=NO);
OPTIONS &Save_Options;
Which yields the following:
NOTE: Char_Missing is missing. Value is >< NOTE: Num_Missing is missing. Value is >.< NOTE: Spcl_Missing is missing. Value is >.E< NOTE: Char_Var is NOT missing. Value is >Ham Sandwich< NOTE: Num_Var is NOT missing. Value is >07292020<
I hope that is of some use.
Jim
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.