Version = Release: 3.7 (Enterprise Edition)
Hi, suppose I have this Macro:
%macro test(p1,p2);
%put &p1.;
%put &p2.;
%mend test;
And sometimes when I call it, the value of p2 depends on p1:
%test(p1=peas,p2=&p1. and carrots);
This works fine but I receive a warning:
WARNING: Apparent symbolic reference P1 not resolved.
68
69 %test(p1=peas,p2=&p1. and carrots);
P1=peas
P2=peas and carrots
Is there a way to suppress this warning?
Thank you
It works because the macro call has caused the macro parser to treat the && and your macro call as two separate tokens. Normally if you type &&p1 the macro processor will convert && to & and then continue to resolve the token and try to resolve &p1. But adding the macro call around p1 it does not do that second round of evaluation. So the &p1 is passed into the macro as the value of P2.
Note that you should use the %UPCASE() function instead of calling the SAS supplied %LOWCASE() macro.
Use %UPCASE() instead because that is macro function (part of the actual SAS language).
Also the SAS supplied macro %LOWCASE is not that well written. It will cause errors if try to call it with values that contain commas.
567 %put %lowcase(a,b); ERROR: More positional parameters found than defined.
Here is a replacement for the limited %LOWCASE() macro that SAS sends.
%macro lowcase/parmbuff;
%if %length(&syspbuff)>2 %then %sysfunc(lowcase&syspbuff);
%mend;
570 %macro lowcase/parmbuff; 571 %if %length(&syspbuff)>2 %then %sysfunc(lowcase&syspbuff); 572 %mend; 573 574 575 %put %lowcase; 576 %put %lowcase(); 577 %put %lowcase(a,b); a,b
When you call the macro via
%test(p1=peas,p2=&p1. and carrots);
then at this point, &p1 is not defined. So the WARNING is correct.
You could, if you want, do something like this:
%let word=peas;
%test(p1=&word,p2=&word and carrots)
And sometimes when I call it, the value of p2 depends on p1:
If it is only sometimes then make that happen in the process of generating the call.
%let x=peas;
%test(p1=&x,p2=&x and carrots)
You can get that effect if you reference another parameter's value in the default values assigned in DEFINITION of the macro.
%macro test(p1=peas,p2=&p1 and carrots);
%put ACTUAL P1=%superq(p1) P2=%superq(p2);
%put RESULT &=p1 &=p2;
%mend test;
276 %test; ACTUAL P1=peas P2=&p1 and carrots RESULT P1=peas P2=peas and carrots
But if you try to use macro quoting to pass in the &p1 then your macro will have to do something to remove the macro quoting.
%macro test(p1,p2);
%put ACTUAL P1=%superq(p1) P2=%superq(p2);
%put RESULT &=p1 &=p2;
%let p1=%unquote(&p1);
%let p2=%unquote(&p2);
%put AFTER &=p1 &=p2;
%mend test;
300 %test(peas,%nrstr(&p1) and carrots); ACTUAL P1=peas P2=&p1 and carrots RESULT P1=peas P2=&p1 and carrots AFTER P1=peas P2=peas and carrots
Thanks for the answers. I think creating another macrovariable before the macro call is going to be the best approach.
I also tried this, which seems to work:
%macro test(p1,p2);
%put &=p1.;
%put &=p2.;
%mend;
%test(p1=peas,p2=&&%lowcase(p1) and carrots);
69 %macro test(p1,p2); 70 %put &=p1.; 71 %put &=p2.; 72 %mend; 73 74 %test(p1=peas,p2=&&%lowcase(p1) and carrots); P1=peas P2=peas and carrots
But why does it work? And why shouldn't I use it?
It works because the macro call has caused the macro parser to treat the && and your macro call as two separate tokens. Normally if you type &&p1 the macro processor will convert && to & and then continue to resolve the token and try to resolve &p1. But adding the macro call around p1 it does not do that second round of evaluation. So the &p1 is passed into the macro as the value of P2.
Note that you should use the %UPCASE() function instead of calling the SAS supplied %LOWCASE() macro.
Use %UPCASE() instead because that is macro function (part of the actual SAS language).
Also the SAS supplied macro %LOWCASE is not that well written. It will cause errors if try to call it with values that contain commas.
567 %put %lowcase(a,b); ERROR: More positional parameters found than defined.
Here is a replacement for the limited %LOWCASE() macro that SAS sends.
%macro lowcase/parmbuff;
%if %length(&syspbuff)>2 %then %sysfunc(lowcase&syspbuff);
%mend;
570 %macro lowcase/parmbuff; 571 %if %length(&syspbuff)>2 %then %sysfunc(lowcase&syspbuff); 572 %mend; 573 574 575 %put %lowcase; 576 %put %lowcase(); 577 %put %lowcase(a,b); a,b
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.