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;
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;
@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.
"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.
@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.
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
Ok, that's fine. I believe you can indeed know that you are in a situation where %BQUOTE works.
@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
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.
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.
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.
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!
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.
Ready to level-up your skills? Choose your own adventure.