Hello,
I have a macro variable yearlist.
Is there a way to define / upgrade it until the current year ?
%let yearlist=2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023;
I would like to have:
some thing like %let yearlist2=2001--year(date());
I am using the yearlist in a loop like this one below. I am using this approach because the other loop use a list of define cie subfolder and so on.
%let yearlist=2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025;
%macro test;
%do k=1 %to %sysfunc(countw(&yearlist.));
%put %scan(&yearlist.,&k);
%end;
%mend test;
%test;
So I am looking for a way to generate the yearlist.
This one seems a good way
data _null_;
length yearlist $500;
do year=2001 to year(date());
yearlist=catx(' ',yearlist,year);
end;
call symputx('yearlist',yearlist);
run;
other idea ?
Let's start simple:
%macro makeList(s,e);
%do s=&s. %to &e.; &s.%end;
%mend makeList;
%let yearlist=%makeList(2001,2025);
%put &yearlist.;
Bart
And here is some update:
%macro makeListDT(s,e);
%do s=&s. %to %sysfunc(year(&e.)); &s.%end;
%mend makeListDT;
%let yearlist2=%makeListDT(2001,"11jun2025"d);
%put &yearlist2.;
%let yearlist3=%makeListDT(2001,%sysfunc(today()));
%put &yearlist3.;
Bart
I would say that in my experience, such a macro variable like &yearlist with 23 consecutive years listed is rarely needed.
If you have macro variables &startyear and &endyear, you could use these in a DATA step. Example:
where year between &startyear and &endyear;
Something very similar would work in SQL
Use a DO loop.
data _null_;
length yearlist $500;
do year=2001 to year(date());
yearlist=catx(' ',yearlist,year);
end;
call symputx('yearlist',yearlist);
run;
You could do it in macro code, but you would need to define a macro and then call it to be able to run a %DO loop.
But why do you want that list?
If you plan to use it to generate SAS code like
year in (2001 2002 ... 2024 2025)
Then why not just generate
year in (2001:2025)
instead?
That you could put into a macro variable pretty easily. If you just want the last year to be the year your SAS session started you could use last four characters of the SYSDATE9 automatic macro variable.
%let yearlist=2001:%substr(&sysdate9,6);
If instead you need to actual current year (in case your SAS session started last year) then use
%let yearlist=2001:%sysfunc(date(),year4.);
In data step you can go without loop:
data _null_;
array Y[2001:%sysfunc(date(),year4.)] (2001:%sysfunc(date(),year4.));
call symputx('yearlist',catx(" ", of Y[*]));
run;
%put &=yearlist;
or with a bit less keystrokes:
%let y=2001:%sysfunc(date(),year4.);
data _null_;
array Y[&y.] (&y.);
call symputx('yearlist',catx(" ", of Y[*]));
run;
%put &=yearlist;
Bart
I am using the yearlist in a loop like this one below. I am using this approach because the other loop use a list of define cie subfolder and so on.
%let yearlist=2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025;
%macro test;
%do k=1 %to %sysfunc(countw(&yearlist.));
%put %scan(&yearlist.,&k);
%end;
%mend test;
%test;
So I am looking for a way to generate the yearlist.
This one seems a good way
data _null_;
length yearlist $500;
do year=2001 to year(date());
yearlist=catx(' ',yearlist,year);
end;
call symputx('yearlist',yearlist);
run;
other idea ?
If you already have a %DO loop you are using for something else you could just use arithmetic to calculate the year.
Say you already needed to extract a value for the MYVAR macro variable from the space delimited set of values stored in the MYLIST macro variable. You could use the same looping index to calculate the YEAR value. You just need to base year.
%let baseyear=2001;
....
%do i=1 %to &nyears;
%let myvar = %scan(&mylist,&i,%str( ));
%let year=%eval(&baseyear + &i - 1);
....
%end;
@alepage wrote:
I am using the yearlist in a loop like this one below. I am using this approach because the other loop use a list of define cie subfolder and so on.
%let yearlist=2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025; %macro test; %do k=1 %to %sysfunc(countw(&yearlist.)); %put %scan(&yearlist.,&k); %end; %mend test; %test;
So I am looking for a way to generate the yearlist.
Why does it have to be a LIST of years? Why not this:
%macro test;
%do yr=&startyear %to &endyear;
%put &yr;
%end;
%mend;
%test
But looking at the big picture, we see many people creating macro loops when that is completely unnecessary and it is an unneeded complication to the code. Could you also achieve something similar with much similar coding using
by year;
in one or more places in your analysis? The BY statement essentially creates a loop for you, without any complicated programming. Please @alepage convince me that the BY statement won't work in your situation.
I am a SQL guy, just for having some fun .
data x; do year=2001 to year(date()); output; end; run; proc sql noprint; select year into :yearlist separated by ' ' from x; quit; %put &=yearlist.;
Check out this tutorial series to learn how to build your own steps in SAS Studio.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.