Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 9
Accepted Solution

Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

[ Edited ]

 

I'm trying to create a read-only macro variable.  I can create a non-read-only macro variable that does what I need to do, but I prefer that the variable be read-only.  This is what I have that works:

 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 55         
 56         *works;
 57         %LET path1=%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete
 57       ! Guide to the SAS Macro Language);
 58         %LET path1test=&path1/test/location;
 59         %PUT &=path1test;
 PATH1TEST=/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro 
 Language/test/location
 60         
 61         OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 73         

I'm unable to create a read-only variable using the following %GLOBAL statement however:

 

 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 55         
 56         *doesn't work;
 57         %GLOBAL / READONLY path2=%STR(%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS
 57       ! 9/Carpenter's Complete Guide to the SAS Macro Language));
 58         %LET path2test=&path2/test/location;
 59         %PUT &=path2test;
 60         
 61         OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 62         ODS HTML CLOSE;
 63         &GRAPHTERM; ;*';*";*/;RUN;QUIT;
 64         QUIT;RUN;
 65         ODS HTML5 (ID=WEB) CLOSE;
 66         
 67         ODS RTF (ID=WEB) CLOSE;
 68         ODS PDF (ID=WEB) CLOSE;
 69         FILENAME _GSFNAME;
 70         DATA _NULL_;
 71         RUN;
 72         OPTIONS NOTES STIMER SOURCE SYNTAXCHECK;

Does anybody know what I'm doing wrong?

 

Vic


Accepted Solutions
Solution
‎02-11-2017 02:05 PM
Super User
Super User
Posts: 6,502

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

[ Edited ]

It is definitely NOT storing the macro quoting. You can see this for yourself by looking at the value you can see in the dictionary tables.

 

%let x=%bquote(Don't);
%global /readonly y=%bquote(Don't);
data _null_;
  set sashelp.vmacro;
  where scope='GLOBAL' and name in ('X','Y');
  put name= value = $hex20. ;
run;

Results

name=X value=04446F6E117408202020
name=Y value=446F6E27742020202020

You will need to just be careful where you REFERENCE the value of the global macro variable you have created that has unbalanced quotes.

Or you could take more care in defining the global macro variable so that the stored value does not require macro quoting.

1    %global /readonly a=%qsysfunc(dequote('%bquote(Don''t)')) ;
2    %put Actual value = |%superq(a)| ;
Actual value = |%bquote(Don't)|
3    %put Resolves to  = |&a| ;
Resolves to  = |Don't|

 

View solution in original post


All Replies
Occasional Contributor
Posts: 9

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

PS I'm running SAS University Edition.

Super User
Posts: 6,946

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

There is no readonly option for macro variables. Macro variables can be set anytime/anywhere.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Occasional Contributor
Posts: 9

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Super User
Posts: 6,946

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement


rararayayayay wrote:

See:  https://support.sas.com/resources/papers/proceedings15/SAS1575-2015.pdf


I stand corrected. Well, we're finally upgrading from 9.2 to 9.4 next month. READONLY was introduced with 9.3, so I never encountered it.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
PROC Star
Posts: 1,233

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

When you make a macro variable read only, after that you cannot change the value of that macro variable. 

 

But in your test code, you are not testing whether you can change the value of of a read only macro variable.  First you make PATH2 and it is read only.  Then you make PATH2TEST and happen to resolve PATH2 in that assignment statement.  That is all allowed.  If you tried to change the value of PATH2, it should error.

 

So, this works:

33         %GLOBAL / READONLY path2=/some/location ;
34         %LET path2test=&path2/with/subdirectory ;
35         %put &=Path2 &=Path2test ;
PATH2=/some/location PATH2TEST=/some/location/with/subdirectory

But if you try to assign a new value to path2 it fails:

 

37         %let path2=/some/other/location ;
ERROR: The variable PATH2 was declared READONLY and cannot be modified or re-declared.
Occasional Contributor
Posts: 9

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Sorry, I didn't make my problem easy to reproduce.

 

No, I'm not trying to change the value of a read-only variable, and I can get the %GLOBAL statement with the READONLY option to work for most strings.  But when I use a particaular string that has an unmatched apostrophe, I have problems.  The string in question is

 

/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro Language 

 

 

What's strange is that I don't have any problems when using a %LET statement.  I mask the string with a macro quoting function and it works.

%LET path1=%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro Language);
%PUT &=path1;
%LET path1test=&path1/test/location;
%PUT &=path1test;

 

yields

 

56         %LET path1=%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete
 56       ! Guide to the SAS Macro Language);
 57         %PUT &=path1;
 PATH1=/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro Language
 58         %LET path1test=&path1/test/location;
 59         %PUT &=path1test;
 PATH1TEST=/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro Language/test/location

But if I use the same string with a %GLOBAL / READONLY macro-variable=value; statement 

 

%GLOBAL / READONLY path2=%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro Language);
%PUT &=path2;
%LET path2test=&path2/test/location;
%PUT &=path2test;

 

it doesn't work, and I get this junk:

 

 56         %GLOBAL / READONLY path2=%NRBQUOTE(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS
 56       ! 9/Carpenter's Complete Guide to the SAS Macro Language);
 57         %PUT &=path2;
 58         %LET path2test=&path2/test/location;
 59         %PUT &=path2test;
 60         
 61         OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 62         ODS HTML CLOSE;
 63         &GRAPHTERM; ;*';*";*/;RUN;QUIT;
 PATH2=/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter's Complete Guide to the SAS Macro 
 Language;%LET path2test=&path2/test/location;%PUT &=path2test;OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;ODS HTML 
 CLOSE;&GRAPHTERM; ;*'
 64         QUIT;RUN;
 65         ODS HTML5 (ID=WEB) CLOSE;
 66         
 67         ODS RTF (ID=WEB) CLOSE;
 68         ODS PDF (ID=WEB) CLOSE;
 NOTE: ODS PDF(WEB) printed no output. 
       (This sometimes results from failing to place a RUN statement before the ODS PDF(WEB) CLOSE statement.)
 69         FILENAME _GSFNAME;
 NOTE: Fileref _GSFNAME has been deassigned.
 70         DATA _NULL_;
 71         RUN;
 
 NOTE: DATA statement used (Total process time):
       real time           0.01 seconds
       cpu time            0.01 seconds
       
 
 72         OPTIONS NOTES STIMER SOURCE SYNTAXCHECK;
 73  

 

Does that make any sense to you?

 

Vic

 

PROC Star
Posts: 1,233

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Sorry,missed your point. Does it work with:
%GLOBAL / READONLY path2=%Str(/folders/myfolders/sasuser.v94/2 SAS Certified Advanced Programmer for SAS 9/Carpenter%'s Complete Guide to the SAS Macro Language);

?
I think %str is the proper quoting function to use outside of a macro definition, even though it requires marking the quote with a %. But agree %nrbquote() should work. 
Apparently something about readonly  is unquoting the value, which seems bad. So you end up with an unmatched single quote mark.  I'm away from sas but will play with this later. 

PROC Star
Posts: 1,233

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Okay, came back to playing with it, and I think you should send this in to tech support.  Looks like /readonly is not honoring the macro quoting.

 

I ran this in EG with SAS 9.4M3, and didn't work:

%global /readonly y=%str(Carpenter%'s) ;
%put y=&y ;

Reaching for straws, I tried %SUPERQ, but it didn't help:

%let x=%str(Carpenter%'s) ;
%put x=&x ;
%global /readonly y=%superq(x);
%put y=&y ;

 

 

And trying it in a macro caused an ugly "CALL tech support" error:

%macro try(dummy) ;
 %global /readonly Z=%str(Carpenter%'s) ;
%mend try ;

%try()

Perhaps because EG gets tripped up by the unmatched quote and then not seeing the %mend and even EG's magic string doesn't save it.

 

Seems buggy to me.  Unless of course it's documented somewhere that you can't use quoting functions with /readonly.

Occasional Contributor
Posts: 9

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Good morning Quentin, thanks for your help. I'm going to submit the macro quoting issue to tech support right now. The last error you're getting appears to be a known issue -- http://support.sas.com/kb/58/357.html. Bye 👋.
Solution
‎02-11-2017 02:05 PM
Super User
Super User
Posts: 6,502

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

[ Edited ]

It is definitely NOT storing the macro quoting. You can see this for yourself by looking at the value you can see in the dictionary tables.

 

%let x=%bquote(Don't);
%global /readonly y=%bquote(Don't);
data _null_;
  set sashelp.vmacro;
  where scope='GLOBAL' and name in ('X','Y');
  put name= value = $hex20. ;
run;

Results

name=X value=04446F6E117408202020
name=Y value=446F6E27742020202020

You will need to just be careful where you REFERENCE the value of the global macro variable you have created that has unbalanced quotes.

Or you could take more care in defining the global macro variable so that the stored value does not require macro quoting.

1    %global /readonly a=%qsysfunc(dequote('%bquote(Don''t)')) ;
2    %put Actual value = |%superq(a)| ;
Actual value = |%bquote(Don't)|
3    %put Resolves to  = |&a| ;
Resolves to  = |Don't|

 

Occasional Contributor
Posts: 9

Re: Question About Macro Quoting in a %GLOBAL / READONLY macro-variable=value; Statement

Thank you Tom.
☑ This topic is SOLVED.

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

Discussion stats
  • 11 replies
  • 270 views
  • 4 likes
  • 4 in conversation