BookmarkSubscribeRSS Feed
mansour_ib_sas
Pyrite | Level 9

 

Hello,

I have this macro that creates me variables macros.

I can't understand why on the outside of the macro tt(), variables macros created by call symputx do not display with the semicolon.

In the vmacro table, variables macros are created with semicolon.

The addition of % SUPERQ, to indeed, allows the display of these variables macros with  semicolon (;).

Thank you in advance for your help.

 

 

%macro tt();

data _null_;
set sashelp.class;
call symputx ('name'||left(_n_),catt(name,';') );
call symput ('nbr',_n_);
run;
%put name_in = &name1;
%do i=1 %to &nbr;
%global  nname&i;
%let nname&i=%SUPERQ(name&i);

%end;

%mend;

%tt;
%put &name1;
%put &nname1;

 

11 REPLIES 11
Reeza
Super User
It has nothing to do with SUPERQ and has to do with the GLOBAL statement. Macro variables within a macro are local and exist only within the macro. In comparison, a global variable is available almost anywhere in your session. Check the documentation for CALL SYMPUTX. The third parameter allows you to specify a macro variable as global or local.
mansour_ib_sas
Pyrite | Level 9

The variables macros are created with the semicolon.

Their display outside the macro requires% SUPERQ.

I tried again with the third parameter and the result is the same

%macro tt();

data _null_;
set sashelp.class;
call symputx ('name'||left(_n_),catt(name,';'),'G' );
run;
%end;
%mend;
%tt;
PaigeMiller
Diamond | Level 26

@mansour_ib_sas wrote:

The variables macros are created with the semicolon.

Their display outside the macro requires% SUPERQ.

I tried again with the third parameter and the result is the same

%macro tt();

data _null_;
set sashelp.class;
call symputx ('name'||left(_n_),catt(name,';'),'G' );
run;
%end;
%mend;
%tt;

Actually, no, it does not require %SUPERQ

 

You can display the semicolon using 

%put %bquote(&name1);

The unanswered question is: why doesn't %put &name1; print the result with the semi-colon on the end? I don't have a complete explanation, but it seems like %put does not consider the semicolon at the end to be text, it considers it a character with special meaning, and so doesn't print it. However %bquote removes the special meaning from the semi-colon and treats the semi-colon as ordinary text.

--
Paige Miller
novinosrin
Tourmaline | Level 20

"Actually, no, it does not require %SUPERQ"

 

I'm afraid, if a macrovar were to have & in the resolved value, %bquote will throw warnings/errors, so %superq is the right way to go

Although not in OPs case but just pure diligence.

 

Example:

 


%let j=%str(&abc;);

%put %bquote(&j);


%put %superq(j);

 

 

 

 

 

 


@PaigeMiller wrote:

@mansour_ib_sas wrote:

The variables macros are created with the semicolon.

Their display outside the macro requires% SUPERQ.

I tried again with the third parameter and the result is the same

%macro tt();

data _null_;
set sashelp.class;
call symputx ('name'||left(_n_),catt(name,';'),'G' );
run;
%end;
%mend;
%tt;

Actually, no, it does not require %SUPERQ

 

You can display the semicolon using 

%put %bquote(&name1);

The unanswered question is: why doesn't %put &name1; print the result with the semi-colon on the end? I don't have a complete explanation, but it seems like %put does not consider the semicolon at the end to be text, it considers it a character with special meaning, and so doesn't print it. However %bquote removes the special meaning from the semi-colon and treats the semi-colon as ordinary text.


 

PaigeMiller
Diamond | Level 26

@novinosrin wrote:

"Actually, no, it does not require %SUPERQ"

 

I'm afraid, if a macrovar were to have & in the resolved value, %bquote will throw warnings/errors, so %superq is the right way to go

 


Which simply doesn't apply here. So YES, it does not require %SUPERQ.

 

In the case where the value of &name1 contains a semicolon, %SUPERQ is not required, other functions work as well. If you know your data, and we do know it in this case, we can choose the proper function.

 

It also sounds as if you are arguing to always use %SUPERQ even in situation where %BQUOTE will work because you never know when the value of the macro variable, which again is not the case.

--
Paige Miller
novinosrin
Tourmaline | Level 20

No not arguing at all. 🙂 Just feels that %superq is most ideal and safe 

 

And trust me , I ran into the very same issue without knowing a macro trigger (& %) to expect in a resolved value and the warnings/errors in the log warranted so much escalation and I was almost told off. I recall that situation and honestly feels to play safe in prod code. That's all

 

My apologies, if the tone of the writing was mistaken

PaigeMiller
Diamond | Level 26

Ok, that's fine. I believe you can indeed know that you are in a situation where %BQUOTE works. 

--
Paige Miller
novinosrin
Tourmaline | Level 20

@mansour_ib_sas  Brilliant question who wants to understand macro quoting and it's nothing to do with symbol table in this case 

 

Correction:

%put %superq(name1);
%put &nname1;

Full code:

 


%macro tt();

data _null_;
set sashelp.class;
call symputx ('name'||left(_n_),catt(name,';') );
call symput ('nbr',_n_);
run;
%put name_in = &name1;
%do i=1 %to &nbr;
%global  nname&i;
%let nname&i=%SUPERQ(name&i);

%end;

%mend;

%tt;
%put %superq(name1);
%put &nname1;

 

NOTES:

First off, it's smart of you to quote aka make macro processor treat the semicolon as text rather than as step boundary for the statement. So when you resolved the quoted one, your resolution was perfect.

Secondly, WRT call symputx, you did not do that. The macro processor processes your resolved &name1 as %put Alfred;; and writes Alfred to the log. The first semicolon which was resolved from &name1 ended the %put statement as the tokenisation was complete and sent to the compiler for execution. 

So to counter this quote the unquoted value at the time of macro execution with the same %superq and you are done 🙂 HTH

 

novinosrin
Tourmaline | Level 20

To add some spice and to confirm your understanding, try using some other char besides semicolon and execute without %superq. Your code will do fine. This will essentially help in understanding the tokenisation process and step boundaries for the compiler to execute sections of code queued in the input stack. In SAS, it's far more slick and exquisite than many other programming languages.  

Astounding
PROC Star

Consider the key statement both inside and outside of a macro:

 

%put name_in = &name1;

 

Inside a macro, as part of the compilation process that defines the contents of the macro, SAS interprets the semicolon that it can see as ending the %PUT statement.  Whatever value is assigned to &NAME1 get printed, as you noticed.

 

Outside a macro, there is no compilation process.  SAS just replaces &name1 with its value, and executes the generated statements, which are:

 

%put Amy;;

 

(or whatever the value of &NAME1 is).  So outside of a macro, the first semicolon (generated by resolving &NAME1) ends the %PUT statement.  The second semicolon is just a null SAS statement.

PaigeMiller
Diamond | Level 26

I did not know this (maybe I should have known it), thank you @Astounding.

 

But if the second semicolon is treated as a null SAS statement, wouldn't I still see the second semi-colon and the null SAS statement in the LOG? I looked for it, and don't see it.

--
Paige Miller

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 11 replies
  • 5215 views
  • 3 likes
  • 5 in conversation