I created a macro "marc" that has two parameters. I want to run it with many different number for each parameter. I tried this, but it doesn't work:
%Let years1= 2006 2007 2008 2009;
%Let years2= 2007 2008 2009 2010;
Data _Null_ ;
Retain years1 "&years1" ;
Retain years2 "&years2" ;
Do k = 1 to 4 ;
usevar1 = scan (years1, k) ;
usevar2 = scan (years2, k) ;
Call execute ('%Let usevar1 = ' || usevar1 || ';') ;
Call execute ('%Let usevar2 = ' || usevar2 || ';') ;
Call execute ('%macr (&usevar1 , &usevar2) ;') ;
End ;
Run ;
Knowing that this works,:
%macr(2006,2007);
%macr(2007,2008);
%macr(2008,2009);
%macr(2009,2010);
I guess the problem is not the macro, but the way I've called it. Do you see if there is any problem with the first lines? I'm not used to that kind of code.
Another method: write your own macro that contains a loop. From your original program, it seems you are willing to hard-code the values that should appear in a loop. In that case, here is a reasonably simple alternative:
%macro loop;
%local year;
%do year = 2006 %to 2009;
%macr (&year, %eval(&year+1))
%end;
%mend loop;
%loop
You don't show the definition of %macr, so we can't tell if it contains only DATA and PROC steps, or if it also contains macro language. If it does contain macro language, any loops generated by CALL EXECUTE become very tricky. The basic idea is that any macro language generated by CALL EXECUTE runs immediately (before the DATA _NULL_ step ends) but any DATA and PROC steps stack up and wait until the DATA _NULL_ step is over. While CALL EXECUTE can be a life saver, it does have its quirks.
Good luck.
If you named your macro MACR,
Assuming you always want year and year+1 as the parameter values to pass then this gets closer
data _null_;
do year = 2006 to 2009;
year2= year+1;
call execute ('%macr(' || year ||','|| year2||')');
end;
run;
Thank, but it still doesn't work. The error 22-322 occurs. I think when I call the number that way, there is a problem with the numeric/string format.
Post your code/log, the following should have worked.
data _null_;
do year = 2006 to 2009;
year2= year+1;
call execute ('%macr(' || years1 ||','|| years2||')');
end;
run;
Pretty close. There is no need to assign macro variables external to the macro calls. No need for RETAIN as you are only executing the data step once.
%let years1= 2006 2007 2008 2009;
%let years2= 2007 2008 2009 2010;
data _null_ ;
years1 = "&years1" ;
years2 = "&years2" ;
do k = 1 to countw(years1);
call execute ( '%macr(' || scan(years1,k) || ',' || scan(years2,k) || ');' ) ;
end ;
run ;
Another method is to write the code to a file instead of using CALL EXECUTE. This is much easier to debug as you can view the file to confirm you have generated the code properly before you execute it.
filename code temp;
data _null_ ;
file code ;
do year1 = 2006 ,2007 ,2008 ,2009 ;
year2 = year1 + 1;
put '%macr(' year1 ',' year2 ');' ;
end ;
run ;
%include code / source2 ;
Another method: write your own macro that contains a loop. From your original program, it seems you are willing to hard-code the values that should appear in a loop. In that case, here is a reasonably simple alternative:
%macro loop;
%local year;
%do year = 2006 %to 2009;
%macr (&year, %eval(&year+1))
%end;
%mend loop;
%loop
You don't show the definition of %macr, so we can't tell if it contains only DATA and PROC steps, or if it also contains macro language. If it does contain macro language, any loops generated by CALL EXECUTE become very tricky. The basic idea is that any macro language generated by CALL EXECUTE runs immediately (before the DATA _NULL_ step ends) but any DATA and PROC steps stack up and wait until the DATA _NULL_ step is over. While CALL EXECUTE can be a life saver, it does have its quirks.
Good luck.
Nice, it works.
I didn't post the definition of the macro because it's much too huge (maybe 1000 lines). Moreover, you point the problem: it also contains macro language.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.