Hello,
when running this code:
%MACRO test(bla=);
options minoperator mindelimiter=',';
%PUT %lowcase(&bla);
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in year,month);
options nominoperator mindelimiter=%STR(' ');
%mend;
%test(bla=year);
I am expecting to get the value "1" in case bla equals "year" or "month";
This is unfortunately not the case. What am I missing?
My goal is to validate the macro parameter values which are set by the user....
Cheers,
FK
@FK1 wrote:
@yabwon: thank's for the side note. I was thinking about this as well.... But same question here:
Are the parenthesis needed or not?
%MACRO test(bla=) / minoperator mindelimiter=','; %PUT %lowcase(&bla); %PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (year,month)); %mend; %test(bla=year);
You might consider what happens to readability when you start passing the values that are needed in the IN as macro variables such as
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (&yearparm. , &monthparm. ));
Since Yearparm and Monthparm could resolve to almost anything the ( ) around both is quite helpful in letting you see that both are intended as being evaluated with IN. if the code looks like:
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in &yearparm. , &monthparm. );
it is not quite as obvious. And the parentheses may help diagnose issues when you pass a complex constructed macro value that blows up the IN operator.
Hi @FK1 You are missing a parenthesis
Correction
%MACRO test(bla=);
options minoperator mindelimiter=',';
%PUT %lowcase(&bla);
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (year,month));
options nominoperator mindelimiter=%STR(' ');
%mend;
%test(bla=year)
LOG:
2686 options minoperator mindelimiter=',';
2687
2688 %PUT %lowcase(&bla);
2689 %PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (year,month));
2690
2691 options nominoperator mindelimiter=%STR(' ');
2692
2693 %mend;
2694 %test(bla=year)
year
Evaluation value = 1
@novinosrin: okay, it seems, we need parenthesis. I am confused, though, as in the SAS documentation, it is not written that you have to use parenthesis:
https://documentation.sas.com/?docsetId=mcrolref&docsetTarget=n0vc5y2nyi55dvn1agla9j658kwh.htm&docse...
option minoperator;
%put %eval(a in d,e,f,a,b,c); /* should print 0 */
%put %eval(a in d e f a b c); /* should print 1 */
option mindelimiter=',';
%put %eval(a in d,e,f,a,b,c); /* should print 1 */
%put %eval(a in d e f a b c); /* should print 0 */
Oh I didn't look at the documentation. The standard IN operator across RDBMS languages will require the list to be within parenthesis. Feel free to report to SAS to correct the documentation
You don't need parentheses when using the IN operator in macro logic, but if you use them they need to be balanced.
So if you have a closing parenthesis without an opening one then the extra one becomes part of the value returned.
2106 options minoperator mindelimiter=' '; 2107 %put %eval( y in x y ); 1 2108 %put %eval( y in (x y)); 1 2109 %put %eval( y in x y)); 1)
Hi @FK1 ,
One side note.
Why not to use %macro statement options to have the use of the operator macro-specific?
Like that:
%MACRO test(bla=) / minoperator mindelimiter=',';
%PUT %lowcase(&bla);
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in year,month);
%mend;
%test(bla=year);
All the best
Bart
@yabwon: thank's for the side note. I was thinking about this as well.... But same question here:
Are the parenthesis needed or not?
%MACRO test(bla=) / minoperator mindelimiter=',';
%PUT %lowcase(&bla);
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (year,month));
%mend;
%test(bla=year);
From my log, without parenthesis.
3595 %MACRO test(bla=) / minoperator mindelimiter=',';
3596
3597 %PUT %lowcase(&bla);
3598 %PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in year,month);
3599
3600 %mend;
3601 %test(bla=year);
year
Evaluation value = 1
But, as a good programming practice improving readability, I would use: x in (...)
Bart
@FK1 wrote:
@yabwon: thank's for the side note. I was thinking about this as well.... But same question here:
Are the parenthesis needed or not?
%MACRO test(bla=) / minoperator mindelimiter=','; %PUT %lowcase(&bla); %PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (year,month)); %mend; %test(bla=year);
You might consider what happens to readability when you start passing the values that are needed in the IN as macro variables such as
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in (&yearparm. , &monthparm. ));
Since Yearparm and Monthparm could resolve to almost anything the ( ) around both is quite helpful in letting you see that both are intended as being evaluated with IN. if the code looks like:
%PUT Evaluation value = %eval(%CMPRES(%lowcase(&bla)) in &yearparm. , &monthparm. );
it is not quite as obvious. And the parentheses may help diagnose issues when you pass a complex constructed macro value that blows up the IN operator.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.