dear all:
i wanna refer a macro variable in a macro like this:
%let a=%nrstr(%do i= 1 %to 3;);
%let b=%nrstr(%end;);
%macro linshi();
&a.;
%put &i.;
&b.;
%mend;
%linshi();
but the log shows :
NOTE: Line generated by the macro variable "A".
1 %do i= 1 %to 3;
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
WARNING: Apparent symbolic reference I not resolved.
&i.
NOTE: Line generated by the macro variable "B".
1 %end;
-
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
What should i do to make it work?
Thanks in advance !
Hello @duanzongran,
I think the error messages are due to the (invisible) macro quoting characters which you introduced by (correctly) using the %NRSTR function.
The deeper issue is that you want to create macro program text, then compile and finally execute this macro, but you mix the first two of these three steps. The compilation of the %MACRO, %PUT and %MEND statements must be deferred similarly to that of the %DO-%END statements. Here's how you can achieve this (and use the %UNQUOTE function to remove the macro quoting characters):
%let a=%nrstr(%do i= 1 %to 3;); %let b=%nrstr(%end;); %unquote( %nrstr(%macro linshi();) &a.; %nrstr(%put &i.;) &b.; %nrstr(%mend;) ) %linshi();
Hello @duanzongran,
I think the error messages are due to the (invisible) macro quoting characters which you introduced by (correctly) using the %NRSTR function.
The deeper issue is that you want to create macro program text, then compile and finally execute this macro, but you mix the first two of these three steps. The compilation of the %MACRO, %PUT and %MEND statements must be deferred similarly to that of the %DO-%END statements. Here's how you can achieve this (and use the %UNQUOTE function to remove the macro quoting characters):
%let a=%nrstr(%do i= 1 %to 3;); %let b=%nrstr(%end;); %unquote( %nrstr(%macro linshi();) &a.; %nrstr(%put &i.;) &b.; %nrstr(%mend;) ) %linshi();
Another working approach would be to create the macro variables A and B without quoting functions:
data _null_;
call symput('A', '%do i=1 %to 3;');
call symput('B', '%end;');
run;
Then you can use your macro as is.
Sounds like the old Doctor joke.
The patient says, "Doctor, it hurts when I do this." "Then don't do that!"
If you really need to dynamically generate code it is going to be much easier to dynamically generate SAS code instead of trying to dynamically generate macro code.
What is the actual problem you are trying to solve by creating that Rube Goldberg machine?
My thoughts, in sequence:
Really, what is the purpose of this?
I have had such thoughts many times about many posts. My tongue has permanent scars from the number and intensity of times I have bitten it. But not in this case.
To me, this is how you learn about macro language. Try things out, see what works and what doesn't. For the things that don't work, try to figure out why. Then re-test your conclusions.
Of course, I can't guarantee the intention here, but I look at this as a learning experience not application development.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.