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


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
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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

22 REPLIES 22
Astounding
PROC Star

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.


chang_y_chung_hotmail_com
Obsidian | Level 7

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
  */

PGStats
Opal | Level 21

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

PG

PG
Tom
Super User Tom
Super User

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

PGStats
Opal | Level 21

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
Tom
Super User Tom
Super User

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 */

PGStats
Opal | Level 21

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
Tom
Super User Tom
Super User

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

PGStats
Opal | Level 21

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

PG
Ksharp
Super User

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

Tom
Super User Tom
Super User

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*/

Linlin
Lapis Lazuli | Level 10

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.

Tom
Super User Tom
Super User

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.

Tom
Super User Tom
Super User

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;

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

How to Concatenate Values

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.

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
  • 22 replies
  • 1451 views
  • 7 likes
  • 6 in conversation