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-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 930 views
  • 7 likes
  • 5 in conversation