BookmarkSubscribeRSS Feed
hellohere
Pyrite | Level 9
Need to exit one macro but without ending sas session[other macros]?! %return seems end the session, so does %abort.
6 REPLIES 6
SASKiwi
PROC Star

%RETURN terminates the current macro, not your SAS session. You need to post your code so we can figure out what is happening.

sbxkoenk
SAS Super FREQ

The %RETURN Macro Statement indeed.

 

I also use the %GOTO Macro Statement (%GOTO label;) a lot:

 

Example: Providing Exits in a Large Macro
(The %GOTO statement is useful in large macros when you want to provide an exit if an error occurs.)
This example can be found on this SAS doc page:
%GOTO Macro Statement: SAS Help Center

 

Ciao,
Koen

hellohere
Pyrite | Level 9

%macro loop_a(x, xtest);
	%do i=1 %to 50;
		%put "i=&i. x=&x. xtest=&xtest.";
		%if &x.> %sysfunc(floor(&xtest.)) %then %return;
	%end;
%mend;

%macro loop_b();
	%do i=1 %to 10;
		%let y=%sysfunc(ranuni(&i.))*100;
		%put "y=&y.";
		%loop_a(&i., &y.);
	%end;
%mend;

%loop_b();

When run, how many loops loop_b() do?! 

Quentin
Super User

@hellohere wrote:

%macro loop_a(x, xtest);
	%do i=1 %to 50;
		%put "i=&i. x=&x. xtest=&xtest.";
		%if &x.> %sysfunc(floor(&xtest.)) %then %return;
	%end;
%mend;

%macro loop_b();
	%do i=1 %to 10;
		%let y=%sysfunc(ranuni(&i.))*100;
		%put "y=&y.";
		%loop_a(&i., &y.);
	%end;
%mend;

%loop_b();

When run, how many loops loop_b() do?! 


This would be better as a new question.  loop_b will only iterate once, because in the definition of loop_a (and loop_b), you forgot to create the macro variable &i as a local macro variable.  Therefore when %loop_a executes, instead of creating its own macro variable &i, it will use the existing macro variable &i that is owned by %loop_b.

 

On the first iteration of %loop_b, %loop_a is called one time and iterates 50 times, and after that &i will have the value 51.  %loop_b will not iterate a second time, because 51 is greater than 10.

 

Test code:

 

%macro loop_a();
  %* local i ;
  %do i=1 %to 50;
    %put &=sysmacroname &=i ;
    %put _user_ ;
  %end;
%mend;

%macro loop_b();
  %* local i ;
  %do i=1 %to 10;
    %put &=sysmacroname &=i ;
    %loop_a()
  %end;
%mend;

%loop_b()
The Boston Area SAS Users Group is hosting free webinars!

Register now at https://www.basug.org/events.
hellohere
Pyrite | Level 9

thanks for the point. 

 

So, if not explicitly decleared as local, the i/j variable at different macro will interfere?!

 

Quentin
Super User

@hellohere wrote:

thanks for the point. 

 

So, if not explicitly decleared as local, the i/j variable at different macro will interfere?!

 


Yes, exactly, this is a macro variable "collision". Luckily your collision resulted in a loop that ends prematurely.  If you had done it the other way around, it would have created an infinite loop.  

 

You should "always" declare macro variables you create inside a macro to be local.  Unless you have a very good reason not to do so (which is rare).

The Boston Area SAS Users Group is hosting free webinars!

Register now at https://www.basug.org/events.

CFC_SAS_Communities_400x225.jpg

Call for content now open!

It's your turn to help shape SAS Innovate 2027. Share your expertise and inspire the SAS community.

Submit your proposal →

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
  • 6 replies
  • 118 views
  • 4 likes
  • 4 in conversation