Hello
In this example the user enter two dates (start and end in format YYMM) .
The target is to get all end of quarter months between start and end.
for example:
start=1612
end=1808
We should get 1612 1703 1706 1709 1712 1803 1806
In the following code the problem is that we get also 1809 (which is bigger than end )
One more problem is that when I run %PUT &&m&n..; I get warning "WARNING: Apparent symbolic reference M not resolved."
%let start=1612; /*Must start from end of quarter :Dec March June Sep*/
%let end=1807;
%let date_start=%sysfunc(inputn(&start.,yymmn4.));
%let date_end=%sysfunc(inputn(&end.,yymmn4.));
%put &date_start.;
%put &date_end.;
Data want_month;
do j=0 to intck('QUARTER',&date_start.,&date_end.) ;
ddate=intnx('QUARTER', &date_start., j, 's');
char_ddate = put(ddate, YYMMn4.);
/*Var_Macro_name=compress('m'||put(J,2.));*/
Var_Macro_name='m'||strip(put(J,2.));
call symputx('m'||strip(put(J,2.)), char_ddate);
output;
end;
Run;
PROC SQL Noprint;
select count(*) INTO:n
from want_month
;
QUIT;
%put &n.;
%put &m0;
%put &m1;
%PUT &&m&n..;
please try the below i applied the filter
new=%sysfunc(inputn(&end.,best.));
if input(char_ddate,best.)<new;
%let start=1612; /*Must start from end of quarter :Dec March June Sep*/
%let end=1807;
%let date_start=%sysfunc(inputn(&start.,yymmn4.));
%let date_end=%sysfunc(inputn(&end.,yymmn4.));
%put &date_start.;
%put &date_end.;
Data want_month;
do j=0 to intck('QUARTER',&date_start.,&date_end.) ;
ddate=intnx('QUARTER', &date_start., j, 's');
char_ddate = put(ddate, YYMMn4.);
/*Var_Macro_name=compress('m'||put(J,2.));*/
Var_Macro_name='m'||strip(put(J,2.));
call symputx('m'||strip(put(J,2.)), char_ddate);
new=%sysfunc(inputn(&end.,best.));
if input(char_ddate,best.)<new;
output;
end;
format ddate date9.;
Run;
PROC SQL Noprint;
select count(*) INTO:n
from want_month
;
QUIT;
Use a do while loop, it is simpler to read:
%let start=1612;
%let end=1807;
data want_month (keep=quarter);
length quarter $4;
quarterdate = intnx('quarter',input("20&start.01",yymmdd8.),0,'e');
n = 1;
do while (quarterdate le input("20&end.01",yymmdd8.));
quarter = put(quarterdate,yymmn4.);
call symputx('m'||strip(put(n,2.)),quarter);
output;
quarterdate = intnx('quarter',quarterdate,1,'e');
n + 1;
end;
run;
%put _global_;
PROC SQL Noprint;
select count(*) INTO:n
from want_month
;
QUIT;
%let n=&n; * removes leading blanks;
%put &m1;
%put &&m&n;
Note how to fix the problem with &&m&n. Without the %let n=&n, you see this in the log:
53 %put &&m&n; WARNING: Apparent symbolic reference M not resolved. &m 7
The blanks between the letter m and the numeric value in &n are clearly visible.
Note that it is usually simpler to create dynamic code off a dataset than off a bunch of macro variables.
Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!
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.
Ready to level-up your skills? Choose your own adventure.