BookmarkSubscribeRSS Feed
Quentin
Super User

Hi All,

Short question: Why does the open() function apparently unquote macro variables.

For example:

340  %put %sysfunc(open  (in(where=(var="%nrstr(%Something)"))));

WARNING: Apparent invocation of macro SOMETHING not resolved.

0

The user has quoted the value because %Something is a text string, not a macro invocation, but the open function is unmasking it, producing the warning message. (The result is still fine).

Compare the above result to the length() function, which does NOT unmask the value (expected behavior).

341  %put %sysfunc(length(in(where=(var="%nrstr(%Something)"))));

28

In this simple case of course user could change the code to use single quotes to hide the percent sign:

  %put %sysfunc(open(in(where=(var='%Something')));

But wondering if people agree that it is odd that open() is unquoting, and if there is a way to prevent this.  It feels like a bug to me, does it to you?

Longer version/background:

This came up because an autocall library had a %nobs macro, something like:

%macro nobs(data);   /*macro function in autocall library to return # obs in a dataset*/

%local nobs dsid rc;

%let dsid=%sysfunc(open(&data));

%let nobs=%sysfunc(attrn(&dsid,NLOBSF));

%let rc=%sysfunc(close(&dsid));

&nobs

%mend nobs;

User wrote a macro like:

%macro report(data=,type=);

%if %nobs(&data(where=(type="&type")))=0 %then %do;

  data _null_;  

  file print;  

  put "There were no records in &data with type=&type";

  run;

%end;

%else %do;

  title1 "Printout of &data where Type=&Type";

  proc print data=&data;

      where type="&type";

  run;

  title1;

%end;

%mend report;

And got the warning message when they ran:

data test;

input Year Type $14. Value;

cards;

2001 AbsoluteChange 10

2002 AbsoluteChange 20

2003 AbsoluteChange 30

2001 %Change        5

2002 %Change        10

2003 %Change        15

;

run;

%report(data=test,type=%nrstr(%Change))

So the user deduces that it is %nobs which is unmasking the percent sign in %Change, and calls the guy who maintains the autocall library and asks him to fix it.  But I don't see how %nobs can be fixed to avoid this problem.  Given the number of %nobs (and other) macro functions that are floating around autocall libraries that use the open function, was wondering if anyone had a good fix. If not, I guess I'm stuck adding a limitation to every macro that uses the open() function to say that it will unquote values, and telling the user to redesign %report.

Thanks,

--Quentin

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
4 REPLIES 4
RichardDeVen
Barite | Level 11

You can change your report code to use SYMGET in the argument constructed for the data parameter to nobs.  This will alleviate issues related to passing seemingly unmaskable characters in the chain of calls.

%macro report(data=, type=);
%if %nobs(&data(where=(type=symget('type'))))=0 %then %do;
...

The autocall maintainer of NOBS() should SUPERQ the data parameter to avoid unwanted interpretations.

%let dsid=%sysfunc(open(%superq(data)));

 

ballardw
Super User

Holy Necrothread Revival Batman!  The question was posed 10 years ago.

Quentin
Super User

Maybe even longer... this feels like a question from a job I was at more than 10 years ago.  But it's possible I was writing about myself as the user, in which case maybe 10 years is believable...

BASUG is hosting free webinars Next up: Mike Sale presenting Data Warehousing with SAS April 10 at noon ET. Register now at the Boston Area SAS Users Group event page: https://www.basug.org/events.
Tom
Super User Tom
Super User

See more recent discussion about the impact of macro quoting on arguments passed to %SYSFUNC().

 

If I remember the logic right it basically required double quoting. Something like.

%nrstr(%nrstr(%something))

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

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
  • 4 replies
  • 911 views
  • 5 likes
  • 4 in conversation