DATA Step, Macro, Functions and more

Immediate substitution in MACRO parameter

Accepted Solution Solved
Reply
Respected Advisor
Posts: 4,651
Accepted Solution

Immediate substitution in MACRO parameter


Hello,

how do I get parameter LIB in macro definition :

%MACRO myMacro(LIB=%scan(&SYSDSN,1));

...

%mend;

to be substituted immediately at macro invocation and not later during macro execution?

Thanks.

PG

PG

Accepted Solutions
Solution
‎05-17-2012 01:19 PM
Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

Here is the response from SAS Technical support about why 9.3 is different.

Apparently it has been broken for the last 30 years!

Starting in SAS V6.08 and continuing through SAS V9.2, the SAS Macro Facility was erroneously fully evaluating expressions at macro compilation time which defined the default value of keyword parameters.  This was a change from SAS V5.18.  At macro compilation time, the SAS Macro Facility should have only been evaluating %STR and %NRSTR quoting functions used in the default value expressions of keyword parameters.  The correct time for full resolution of default keyword parameter expressions is at macro execution time.  The change seen in SAS V9.3 is due to the correction to SAS Macro Facility to match the correct behavior of SAS V5.18.

Thank You,

Russ Tyndall

SAS Technical Support Analyst

SAS Certified Advanced Programmer for SAS 9

View solution in original post


All Replies
Super User
Posts: 5,085

Re: Immediate substitution in MACRO parameter

Depending on what is really needed, this approach might help.

When the program knows the right value to use, have it define a new macro.  Use FILE/PUT/%INCLUDE to define:

%macro myMacro2 (current_value=value_to_use_NOW);

   %myMacro (LIB=&current_value)

%mend myMacro2;

Then invoke %myMacro2 instead of %myMacro.


Regular Contributor
Posts: 241

Re: Immediate substitution in MACRO parameter

We can do an assignment in order to immediately evaluate a macro expression, meaning that it is easy to break the macro var, SYSDSN, being automatically updated. But macro compiler seems to keep the default values of the parameters as they are (ie, not resolved) -- which I think makes sense. hth

  %*-- macro definition when sysdsn has WORK ONE --*;
  data one; run;
  %let default = %scan(&sysdsn, 2);
  %macro test(mem=&default);
    %put mem=&mem;
  %mend  test;
 
  %*-- check --*;
  %test()
  /* ONE */
 
  data two; run;
  %test()
  /* ONE -- success! */
 
  %*-- but the macro arg^s default mem value is still &default --*;
  %let default = CRAZY;
  %test()
  /* CRAZY */
 
  %*-- what happens if we remove the mvar, default --*;
  %symdel default;
  %test()
  /*
  WARNING: Apparent symbolic reference DEFAULT not resolved.
  mem=&default
  */

Respected Advisor
Posts: 4,651

Re: Immediate substitution in MACRO parameter

Hi, your analysis was correct. You must be using V9.3.

PG

PG
Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

Use %unquote();

%let x=yvar;

%macro my(p=%unquote(%scan(&x,1)));

%put p=&p;

%mend;

218  %my;

p=yvar

219

220  %let x=xvar;

221  %my;

p=yvar

Respected Advisor
Posts: 4,651

Re: Immediate substitution in MACRO parameter

Thanks for all the suggestions. The only thing that seems to do what I want inspired by Astounding is to expand the macro parameter before it gets changed into a local variable. In wat follows, I wanted to get the word "better"  :

273  %let words=pretty awful;

274

275  %macro secondWord(w=%scan(&words,2));

276      %let words=pretty bad;

277      %put &w;

278  %mend secondWord;

279

280  %let words=much better;

281

282  %secondWord;

bad

283

284  %let words=pretty awful;

285

286  %macro secondWord(w=%unquote(%scan(&words,2)));

287      %let words=pretty bad;

288      %put &w;

289  %mend secondWord;

290

291  %let words=much better;

292

293  %secondWord;

bad

294

295  %let words=pretty awful;

296

297  %macro secondWord(w=%scan(%unquote(&words),2));

298      %let words=pretty bad;

299      %put &w;

300  %mend secondWord;

301

302  %let words=much better;

303

304  %secondWord;

bad

305

306  %let words=pretty awful;

307

308  %macro secondWord(w=%scan(&words,2));

309      %let myW=&w;

310      %let words=pretty bad;

311      %put &myW;

312  %mend secondWord;

313

314  %let words=much better;

315

316  %secondWord;

better

PG

PG
Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

Are you sure your session is ok?  Perhaps you should restart.  The %UNQUOTE() function works for me.

299   %let words=pretty awful;

300

301   %macro secondWord(w=%unquote(%scan(&words,2)));

302       %let words=pretty bad;

303       %put &w;

304   %mend secondWord;

305

306   %let words=much better;

307

308   %secondWord;

awful

309  /* bad */

Respected Advisor
Posts: 4,651

Re: Immediate substitution in MACRO parameter

Now, that's very strange. Fresh start :

NOTE: AUTOEXEC processing completed.

1    %let words=pretty awful;
2
3    %macro secondWord(w=%unquote(%scan(&words,2)));
4        %let words=pretty bad;
5        %put &w;
6    %mend secondWord;
7
8    %let words=much better;
9
10   %secondWord;
bad

I'm baffled! and worried...

PG

PG
Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

What version of SAS?  I get "awful" on both 9.2 and 8.2 on Unix.

Respected Advisor
Posts: 4,651

Re: Immediate substitution in MACRO parameter

I run my test on version 9.3 TS1M0, 32 bits on Windows 7.  - PG

PG
Super User
Posts: 9,682

Re: Immediate substitution in MACRO parameter

PGStats,

Very interesting .It looks like SAS resolve &w is not at the beginning of Macro , but at the very position it is appeared . If you change the order of %let and %put ,you will get the right answer. I am also confused and astounded.

  

   %let words=pretty awful;

   %macro secondWord(w=%qscan(&words,2) );
    %put Before: &w; 
    %let words=pretty bad;
    %put After: &w;
    %mend secondWord;

    %let words=much better;
   %secondWord()


Ksharp

Message was edited by: xia keshan

Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

What happens if you print the value of W using %SUPERQ?  I do not have 9.3 to test with.

Here is what I get with 8.2 or 9.2 on Unix or Windows.

12   %let words=pretty awful;

13

14    %macro secondWord(w=%unquote(%scan(&words,2)));

15        %put %superq(w);

16        %let words=pretty bad;

17        %put &w;

18    %mend secondWord;

19

20    %let words=much better;

21

22    %secondWord;

%unquote(awful)

awful

23   /*bad*/

Super Contributor
Posts: 1,636

Re: Immediate substitution in MACRO parameter

Hi Tom,

I ran you code on pc 9.3.

%let words=pretty awful;

   %macro secondWord(w=%unquote(%scan(&words,2)));

        %put %superq(w);

        %let words=pretty bad;

       %put &w;

    %mend secondWord;

  %let words=much better;

    %secondWord;

%unquote(awful)

log file:

13   %let words=pretty awful;

14      %macro secondWord(w=%unquote(%scan(&words,2)));

15           %put %superq(w);

16           %let words=pretty bad;

17          %put &w;

18       %mend secondWord;

19

20     %let words=much better;

21

22       %secondWord;

%unquote(%scan(&words,2))

bad

23   %unquote(awful)

NOTE: Line generated by the macro function "SCAN".

1     awful

      -----

      180

ERROR 180-322: Statement is not valid or it is used out of proper order.

Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

So in 9.3 the %SCAN() function it NOT evaluated during the compilation.

The last line was part of the output and not part of the program, so that is what generated the errors.

Super User
Super User
Posts: 6,502

Re: Immediate substitution in MACRO parameter

Try this version on SAS 9.3.  This time calling the DEQUOTE() function using %SYSFUNC().

%let words=pretty awful;

%macro secondWord(w=%sysfunc(dequote("%scan(&words,2)")));

  %put %superq(w);

  %let words=pretty bad;

  %put &w;

%mend secondWord;

%let words=much better;

%secondWord;

☑ This topic is SOLVED.

Need further help from the community? Please ask a new question.

Discussion stats
  • 22 replies
  • 571 views
  • 7 likes
  • 6 in conversation