Hello,
I am running creating reports based on the month and year. The way my code is set (below) I have to manually enter each month and year combination in for the variable "newdata", "dateyear", "rcenvar" and "data_remove". My question is it possible to create a macro of this so I could put a starting and ending month and the macro would run my macros for each combination between the time frame. Ideally, it will produce the data sets aug17, sep17, oct17 and so on like I have below but without having to manually do that for each. Thank you
*AUG17;
%report_my(olddata=forreports, newdata=aug17, dateyear=01AUG2017, rcenvar = aug17_rcen)
%report_data_update(data_remove=aug17, data_update= forreports)
*SEP17;
%report_my(olddata=forreports, newdata=sep17, dateyear=01SEP2017, rcenvar = sep17_rcen)
%report_data_update(data_remove=sep17, data_update= forreports)
*OCT17;
%report_my(olddata=forreports, newdata=oct17, dateyear=01OCT2017, rcenvar = oct17_rcen)
%report_data_update(data_remove=oct17, data_update= forreports)
*NOV17;
%report_my(olddata=forreports, newdata=NOV17, dateyear=01NOV2017, rcenvar = NOV17_rcen)
%report_data_update(data_remove=NOV17, data_update= forreports)
Show what those macros do, i.e. the code.
Example data would be helpful.
For reporting purposes there is likely no reason to create separate data sets if you have proper date variable(s) in your existing data set.
Agreeing with @ballardw — without strong justification to use macros here, you would be better off keeping all data sets together (i.e. as one large data set with many months) and using a BY statement to produce the analysis and reports, and then macros are not needed.
I'd be happy to help with the non-macro solution. Let's discuss further.
If I am understanding you properly:
This can all be done with a BY statement in your analysis and reporting. Which is an awful lot simpler to program than a macro to do this. SAS has already done the hard work to make its code dynamic, so you don't have to.
Periods that appear to be selected with this
* IF YOU WANT THE FULL, LEAVE THE FOLLOWING COMMENTED OUT */ /* Annual only - include the following: if &rcenvar in('6 week','3 month','6 month') then delete; */ /* Annual for 1,2,3 year only (arbitrarily chosen) - include the following: if &rcenvar ~in('1 year','2 year','3 year') then delete; */ /* All time points except for 6 week (they don't collect that anymore) - include the following: */ if &rcenvar in('6 week') then delete; /* Minimum 2 year - include the following: if &rcenvar in('6 week','3 month','6 month', '1 year') then delete; */ run;
might be better accomplished with 2 parameters, number of intervals and the interval (or parse this not nice one).
The Function INTNX can calculate a new date using those values such as Intnx("year",somedatevar,3,'E') would return 31 Dec (the 'E' is end) 3 years after the value of the Somedatevar (assuming it is a valid date value).
If you need to select Prior then the interval would be negative, -3, instead of 3.
So if you pass a macro variable like Interval with value of week, month or year that becomes the first parameter in the INTNX function and then the appropriate number of intervals. You can get different alignments of 'B', begin if the interval, 'S', same day (as close as practical).
So you could create a filter like:
Where intnx("&interval.",&somedate., &numintervals.,"B") le datevariable le &somedate. ;
to select values of your datavariable in the data set and a range of values from a parameter date. (the above assumes you a calculating an earlier variable than Somedate, change direction by using GE (or GT) depending on want.
Given any desired data value you can get a lot things you might need with either the INTNX function, the INTCK function (to count intervals between dates (times or datetimes), the various functions such as Year, Month, Day to extract bits and formatting dates to create groups
You can do your loop with next code, just edit the first two lines:
%let from_mm = AUG2017;
%let upto_mm = NOV2017;
data _null_;
from_dt = input("01&from_mm",date9.);
upto_dt = input("01&upto_mm",date9.);
put from_dt= date9. upto_dt= date9.;
do until(from_dt > upto_dt);
dtx = upcase(put(from_dt,date9.));
mmy2 = lowcase(substr(dtx,3,5));
call symput('DTX',strip(dtx));
call symput('MMy2', strip(mmy2));
call execute("%report_my(olddata=forreports, newdata=&mmy2, dateyear=&dtx, rcenvar = &mmy2._rcen);" ||
"%report_data_update(data_remove=&mmy2, data_update= forreports);" ||
"run;");
from_dt = intnx('month',from_dt,1,'b');
end;
run;
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!
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.