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
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.