BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Demographer
Pyrite | Level 9

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

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.

View solution in original post

6 REPLIES 6
ballardw
Super User

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;

Demographer
Pyrite | Level 9

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.

Reeza
Super User

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;

Tom
Super User Tom
Super User

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 ;


Astounding
PROC Star

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.

Demographer
Pyrite | Level 9

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: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 1197 views
  • 7 likes
  • 5 in conversation