BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
pepegalleta
Fluorite | Level 6

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

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

 

View solution in original post

4 REPLIES 4
PaigeMiller
Diamond | Level 26

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)
--
Paige Miller
Tom
Super User Tom
Super User

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
pepegalleta
Fluorite | Level 6

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?

 

Tom
Super User Tom
Super User

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

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
SAS Enterprise Guide vs. SAS Studio

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 4 replies
  • 582 views
  • 0 likes
  • 3 in conversation