BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
muhuri
Obsidian | Level 7
options nonotes nodate nonumber nosource nosymbolgen;
/* Source: Carpenter's Complete Guide to the SAS Macro Language (pp 133-134) */
/* The author's original code is slightly modified here */
%let dsn = class;

%let p   = %nrstr(proc print data=sashelp.&dsn; run;);
%let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn; run;));

%put The macro variable dsn contains the correct text: &=dsn;
%put;
%put The macro variable p contains the correct text: &=p;
%put;
%put The macro variable p_x contains the incorrect  (?) text: %superq(p_x);

The macro variable dsn contains the correct text: DSN=class
 
The macro variable p contains the correct text: P=proc print data=sashelp.&dsn; run;
 
The macro variable p_x contains the incorrect  (?) text: proc print data=sashelp.class
Question: Why is some part [; run;] of the inetnded text of the macro variable p_x truncated? 
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Second question first.  The RUN;; is not "truncated".  It just comes AFTER the end of the %LET statement.  And that is because the %UNQUOTE() function did what you asked it to do.  It REMOVED all of the macro quoting that was hiding the semi-colons from the SAS code interpreter.

 

I am not exactly sure how it works, but it I think that basically the %NRSTR() protects the triggers in the text, but only temporarily.  So by nesting them you basically end up stopping the %UNQUOTE() from unquoting all the way down to plain text.  So even though you ran %UNQUOTE() the value stored in the macro variable still has macro quoting in it.  You can see this if you look at the value using the SASHELP.VMACRO view.

%let p4 = %unquote(%nrstr(%nrstr(proc print data=sashelp.&dsn; run;)));

filename text temp;

data _null_;
  set sashelp.vmacro;
  where name='P4';
  file text;
  length=length(value);
  put value $varying100. length ;
run;

data _null_;
  infile text;
  input;
  list;
run;

Results

 RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0                      
 
 1   CHAR  .proc print data.sashelp..dsn. run.. 36
     ZONE  077662776672667617676667206760277600
     NUMR  102F30029E404141C31385C0EF43EE025EE2
 NOTE: 1 record was read from the infile TEXT.
       The minimum record length was 36.
       The maximum record length was 36.

So those bytes with values like '01'x , '1C'x , '0F'x, '0E'x and '02'x are how the macro processor stores the macro quoting into the macro variables.

 

Contrast that to what is stored in the macro variable when you use SAS code to make instead of MACRO code.

data _null_;
  call symputx('p4','proc print data=sashelp.&dsn; run;');
run;
 RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0                      
 1         proc print data=sashelp.&dsn; run; 34
 NOTE: 1 record was read from the infile TEXT.
       The minimum record length was 34.
       The maximum record length was 34.

View solution in original post

9 REPLIES 9
Ksharp
Super User

If you put %unquote() around a macro variable, that macro variable would be displayed or interpreted .

Therefore, macro variable &p_x would translate &dsn into 'class', check the following . that is to say %superq() doesn't make any sense.

 

You will see &p_x is already truncated in my code(check the bottom).

 

Actually, your code would look like this if you are using %unquote():

%let p_x = proc print data=sashelp.class; run;

the sas only know the first semicolon,  and 'run;' is a validate statement in sas. so the line above is actually two line or code.

%let p_x = proc print data=sashelp.class;

run;

 

 

options nonotes nodate nonumber nosource nosymbolgen;
/* Source: Carpenter's Complete Guide to the SAS Macro Language (pp 133-134) */
/* The author's original code is slightly modified here */
%let dsn = class;

%let p   = %nrstr(proc print data=sashelp.&dsn; run;);
%let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn; run;));

%put The macro variable dsn contains the correct text: &=dsn;
%put The macro variable p=&p ;
%put The macro variable p contains the correct text: &=p;
%put The macro variable p_x=&p_x ;
%put The macro variable p_x contains the incorrect  (?) text: %superq(p_x);

 

The macro variable dsn contains the correct text: DSN=class
The macro variable p=proc print data=sashelp.&dsn; run;
The macro variable p contains the correct text: P=proc print data=sashelp.&dsn; run;
The macro variable p_x=proc print data=sashelp.class
The macro variable p_x contains the incorrect  (?) text: proc print data=sashelp.class
muhuri
Obsidian | Level 7

Now, my revised code (below) is:

%put The macro variable p_x contain the incorrect (?) text: &=p_x;

Output:  

The macro variable p_x contain the incorrect  (?) text: P_X=proc print data=sashelp.class

What changes would I make to the SAS code to get the desired output of the macro variable p_x as follows?

proc print data=sashelp.class; run;

 

/**************************************************************************************************************/

ods html close;
options nonotes nodate nonumber nosource nosymbolgen;
/* Source: Carpenter's Complete Guide to the SAS Macro Language (pp 133-134) */
/* The code is slightly modified */
%let dsn = class;

%let p = %nrstr(proc print data=sashelp.&dsn; run;);
%let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn; run;));

%put The macro variable dsn contains the correct text: &=dsn;
%put;
%put The macro variable p contains the correct text: &=p;
%put;
%put The macro variable p_x contain the incorrect (?) text: &=p_x;

Kathryn_SAS
SAS Employee

Try the following revised code:

117  %let dsn = class;
118
119  %let p = %nrstr(proc print data=sashelp.&dsn; run;);
120  %let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn))%str(; run;);
121
122  %put The macro variable dsn contains the correct text: &=dsn;
The macro variable dsn contains the correct text: DSN=class
123  %put;

124  %put The macro variable p contains the correct text: &=p;
The macro variable p contains the correct text: P=proc print data=sashelp.&dsn; run;
125  %put;

126  %put The macro variable p_x contain the incorrect (?) text: &=p_x;
The macro variable p_x contain the incorrect (?) text: P_X=proc print data=sashelp.class; run;
Tom
Super User Tom
Super User

To get that %UNQUOTE() to work inside the %LET statement you need to add %NRSTR().

 

Are you trying to resolve DSN when making P?  If so then use %STR() instead of %NRSTR().

Are you trying to resolve DSN when making P_X?

 

Example:

 75         %let p   = %str(proc print data=sashelp.&dsn; run;);
 76         %put &=p;
 P=proc print data=sashelp.class; run;
 77         %let p2  = %nrstr(proc print data=sashelp.&dsn; run;);
 78         %put &=p2;
 P2=proc print data=sashelp.&dsn; run;
 79         %let p3 =  %unquote(%nrstr(%str(proc print data=sashelp.&dsn; run;)));
 80         %put &=p3;
 P3=proc print data=sashelp.class; run;
 81         %let p4 =  %unquote(%nrstr(%nrstr(proc print data=sashelp.&dsn; run;)));
 82         %put &=p4;
 P4=proc print data=sashelp.&dsn; run;
 83         

 

Ksharp
Super User
options nonotes nodate nonumber nosource nosymbolgen;
/* Source: Carpenter's Complete Guide to the SAS Macro Language (pp 133-134) */
/* The author's original code is slightly modified here */
%let dsn = class;

%let p   = %nrstr(proc print data=sashelp.&dsn ; run;);
%let p_x = %str(proc print data=sashelp.)&dsn%str(;run;);

%put The macro variable dsn contains the correct text: &=dsn;
%put ;
%put The macro variable p contains the correct text: &=p;
%put ;
%put The macro variable p_x contains the incorrect  (?) text: &p_x ;
The macro variable dsn contains the correct text: DSN=class

The macro variable p contains the correct text: P=proc print data=sashelp.&dsn ; run;

The macro variable p_x contains the incorrect  (?) text: proc print data=sashelp.class;run;
Tom
Super User Tom
Super User

If you want the reference to DSN to resolve there is no need for TWO calls to %STR().

%str(proc print data=sashelp.&dsn;run;);
Tom
Super User Tom
Super User

The answer is clear when you run that code in open code.  Be your own macro processor and process this line of code:

%let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn; run;));

First resolve the %NRSTR() function to get:

%let p_x = %unquote(proc print data=sashelp.&dsn; run;);

Which will then become the following THREE statements:

%let p_x = proc print data=sashelp.class; run;;

First an assignment statement.

Then the RUN; statement.

Then an empty statement.

 

What exactly are you trying to learn how to do?

If you want to get text into macro variables without any macro quoting then it is easiest to do it with SAS code instead of MACRO code.

data _null_;
  call symputx('p_x',"proc print data=sashelp.&dsn; run;");
run;

This will but the two statements:

proc print data=sashelp.class; 
run;

into the macro variable P_X.

 

Which you could then execute by just expanding the macro variable:

&p_x.

 

Notice that if you use single quotes in the SAS code 

data _null_;
  call symputx('p_x','proc print data=sashelp.&dsn; run;');
run;

Then you instead of the value of DSN being in the macro variable P_X a reference to is there instead. So you could change the value of the macro variable DSN  to print a different dataset.

%let dsn=cars;
&p_x.

 

 

 

 

muhuri
Obsidian | Level 7

 

Thank you, Tom SUPER USER, for resolving the issue with my original code.  Some pointers on the following questions would be  greatly appreciated.

 

%let p4 = %unquote(%nrstr(%nrstr(proc print data=sashelp.&dsn; run;)));

 

Question 1: I understand that the inner %nrstr above protects everything inside parentheses. What does the outer %nrstr do?

 

%let p_x = %unquote(%nrstr(proc print data=sashelp.&dsn; run;));

%put p_x;

 

P_X=proc print data=sashelp.class

Question 2:  Why do these parts [; run;] above get truncated?

Tom
Super User Tom
Super User

Second question first.  The RUN;; is not "truncated".  It just comes AFTER the end of the %LET statement.  And that is because the %UNQUOTE() function did what you asked it to do.  It REMOVED all of the macro quoting that was hiding the semi-colons from the SAS code interpreter.

 

I am not exactly sure how it works, but it I think that basically the %NRSTR() protects the triggers in the text, but only temporarily.  So by nesting them you basically end up stopping the %UNQUOTE() from unquoting all the way down to plain text.  So even though you ran %UNQUOTE() the value stored in the macro variable still has macro quoting in it.  You can see this if you look at the value using the SASHELP.VMACRO view.

%let p4 = %unquote(%nrstr(%nrstr(proc print data=sashelp.&dsn; run;)));

filename text temp;

data _null_;
  set sashelp.vmacro;
  where name='P4';
  file text;
  length=length(value);
  put value $varying100. length ;
run;

data _null_;
  infile text;
  input;
  list;
run;

Results

 RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0                      
 
 1   CHAR  .proc print data.sashelp..dsn. run.. 36
     ZONE  077662776672667617676667206760277600
     NUMR  102F30029E404141C31385C0EF43EE025EE2
 NOTE: 1 record was read from the infile TEXT.
       The minimum record length was 36.
       The maximum record length was 36.

So those bytes with values like '01'x , '1C'x , '0F'x, '0E'x and '02'x are how the macro processor stores the macro quoting into the macro variables.

 

Contrast that to what is stored in the macro variable when you use SAS code to make instead of MACRO code.

data _null_;
  call symputx('p4','proc print data=sashelp.&dsn; run;');
run;
 RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0                      
 1         proc print data=sashelp.&dsn; run; 34
 NOTE: 1 record was read from the infile TEXT.
       The minimum record length was 34.
       The maximum record length was 34.

Catch up on SAS Innovate 2026

Nearly 200 sessions are now available on demand with the SAS Innovate Digital Pass.

Explore 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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 9 replies
  • 832 views
  • 4 likes
  • 4 in conversation