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

 

Develop Code with SAS Studio

Get started using SAS Studio to write, run and debug your SAS programs.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

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