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

Him I would like to  be able to pass a numeric range such as 2013:2017 into a macro and then iterate over it through it with a do loop.

 

It would look something like what I have below.  I have wrote ....... where I am not sure of what to do.

 

%some_macro(year);
   %do .........    ;

      %let year_i = ............    ; 

      %put year_I;
   %end;

%mend some_macro;

I would like it to work with a range.

%some_macro(2013:2017);

 

But I also would like it to work with a single number.

%some_macro(2013);

 

Or with a list of numbers.

%some_macro(2013 2015 2018)

 

Not sure if this is possible or practical SAS, but i thought it would be interesting to try. 

 

Thanks for the help.

 

-Bill

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

So you want to take space delimited list of values. Where each value is either a single number or a pair of numbers separated by a colon.

Scan the list. Then scan/parse the items in the list.

%macro some_macro(yearlist);
%local index token year;
%do index=1 %to %sysfunc(countw(&yearlist,%str( )));
  %let token=%scan(&yearlist,&index,%str( ));
  %do year=%scan(&token,1,:) %to %scan(&token,-1,:) ;
    %put &=index &=token &=year ;
  %end;
  %put ;
%end;
%mend ;

%some_macro(2000  2010:2013  2015);
INDEX=1 TOKEN=2000 YEAR=2000

INDEX=2 TOKEN=2010:2013 YEAR=2010
INDEX=2 TOKEN=2010:2013 YEAR=2011
INDEX=2 TOKEN=2010:2013 YEAR=2012
INDEX=2 TOKEN=2010:2013 YEAR=2013

INDEX=3 TOKEN=2015 YEAR=2015

 

View solution in original post

2 REPLIES 2
ballardw
Super User
%macro dummy (parm= );
%do i=1 %to %sysfunc(countw(&parm));
   %let value = %scan(&parm, &i);
   %put Value for &i. is &value.;
%end;
%mend;

%dummy(parm= a b 234 q)

First thing to remember: MACRO VARIABLES ARE ALWAYS TEXT.

If you really want a "range" instead of an explicit list then use a separate parameter for the lower and upper bound (makes it clear what you are doing which could be masked by using one parameter with two values).

%macro dummy2 (lower= , upper= );
%do i=&lower. %to &upper. ;
   %put Value is &i.; 
%end;
%mend;

%dummy2(lower= 123, upper=127)

If you go this route I strongly suggest doing some error check coding to insure that lower is less than upper AND that the values are integers. Macro do loops aren't going to perform well with decimal values.

Tom
Super User Tom
Super User

So you want to take space delimited list of values. Where each value is either a single number or a pair of numbers separated by a colon.

Scan the list. Then scan/parse the items in the list.

%macro some_macro(yearlist);
%local index token year;
%do index=1 %to %sysfunc(countw(&yearlist,%str( )));
  %let token=%scan(&yearlist,&index,%str( ));
  %do year=%scan(&token,1,:) %to %scan(&token,-1,:) ;
    %put &=index &=token &=year ;
  %end;
  %put ;
%end;
%mend ;

%some_macro(2000  2010:2013  2015);
INDEX=1 TOKEN=2000 YEAR=2000

INDEX=2 TOKEN=2010:2013 YEAR=2010
INDEX=2 TOKEN=2010:2013 YEAR=2011
INDEX=2 TOKEN=2010:2013 YEAR=2012
INDEX=2 TOKEN=2010:2013 YEAR=2013

INDEX=3 TOKEN=2015 YEAR=2015

 

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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
  • 2 replies
  • 1105 views
  • 2 likes
  • 3 in conversation