trying to get run the below macro only on first monday in any given month. Can anybody fix this macro?
options symbolgen;
data test;
format month date9.;
format firstmonday date9.;
month = intnx('month',today(),0);
firstmonday = intnx('week',month,1)+1;
if firstmonday= today() then
do;
call symput('MyMacroVariable','RunIt');
end;
run;
/*the below macro only run on first of the monday in any given month*/
%macro check2run;
%if &MyMacroVariable eq RunIt %then
%do;
%put hai;
%end;
%mend;
%check2run;
You could just do all of the assignments and check in the macro. e.g.:
%macro check2run;
%if %sysfunc(day(%sysfunc(today())))<=7 and
%sysfunc(mod(%sysfunc(today()),7))=3 %then %do;
%put hai;
%end;
%mend;
%check2run
/*
Note: The above macro was modified based on a better and easier to understand set of functions that were suggested by mkeintz
*/
Is it right?
options symbolgen;
data test;
format month date9.;
format firstmonday date9.;
format today date9.;
month = intnx('month',today(),0);
firstmonday = intnx('week',month,1)+1;
today=today();
if firstmonday eq today then
do;
call symput('MyMacroVariable','RunIt');
end;
else do;
call symput('MyMacroVariable','NoRunIt');
end;
run;
%macro check2run;
%if &MyMacroVariable eq RunIt %then
%do;
%put hai;
%end;
%else %do ;
%put no hai;
%end;
%mend;
%check2run;
sassharp: you asked a question about the code I posted but, as I was writing the response, you apparently deleted the post. Anyhow, I thought the answer was worthwhile sharing. You had asked what the purpose of the following code was:
%sysfunc(mod(%sysfunc(today()),7))=3
It is simply one of two ways to identify day of week. The two ways are probably easiest to show with a small SAS program. The following takes all of the dates from August1, 2012 to August 14, 2012 and identifies the day of the week by using two functions.
If you use the mod(date,7) function, Fridays are equal to 0, Saturdays=1, Sundays=2, Mondays=3, etc. thru 6
If you use the weekday(date) function, Sundays=1, Mondays=2, etc. thru 7
data test;
format i date9.;
do i=19206 to 19219;
x=mod(i,7);
y=weekday(i);
output;
end;
run;
·
Thanks for your explanation. I assumed this way.
Number of days between 01/01/1960 to 08/14/2012( todays date) = 19219
%sysfunc(mod(%sysfunc(today()),7))= mathematically mod(19219,7)= 4
so the statement
(%sysfunc(mod(%sysfunc(today()),7))= mathematically mod(19219,7)= 3) is not true .
So, the macro is not saying hai today.
But, first monday in August 2012 is on 08/06/2012
Number of days between 01/01/1960 to 08/06/2012 = 19211
%sysfunc(mod(%sysfunc(today()),7))= mathematically mod(19211,7)= 3
so this above one is true but the other logical statement %if %sysfunc(day(%sysfunc(today())))<=7 which is also true.(since day(today()) on 08/06/2012 is 6 which is less than 7)
so the macro said hai on 08/06/2012 and is going to say hai on first monday of every month.
I say thankful for all your(@Arthur) explanation.
Correct me If I was wrong.
thanks.
I (if 1=1) think you got it!
You might want to use the weekday function so that you don't have to keep explaining this to your co-workers. And, ArtC might want to add this to a new chapter in one of his employment security papers but, honestly (I think), both weekday and mod functions (in this case) both require an understanding of what one is attempting to accomplish and how SAS functions work.
You could just do all of the assignments and check in the macro. e.g.:
%macro check2run;
%if %sysfunc(day(%sysfunc(today())))<=7 and
%sysfunc(mod(%sysfunc(today()),7))=3 %then %do;
%put hai;
%end;
%mend;
%check2run
/*
Note: The above macro was modified based on a better and easier to understand set of functions that were suggested by mkeintz
*/
Here is another way. hth.
%*-- returns 1 (true) if the given date is the first monday of the month --*;
%macro isFMoM(date=%sysfunc(today()));
%local first i monday;
%let first = %sysfunc(intnx(month,&date,0,b));
%do i = 0 %to 6;
%let monday = %sysevalf(&first + &i);
%if %sysfunc(weekday(&monday)) = 2 %then %do;
%*;%sysevalf((&date - &monday) = 0)
%return;
%end;
%end;
%mend isFMoM;
That was clumsy! I like mkeintz's better, which in my translation, becomes:
%*-- returns 1 if date is the 1st monday of the month. 0 otherwise --*;
%macro isFMoM(date=%sysfunc(today()));
%sysevalf(%sysfunc(day(&date))<=7 & %sysfunc(weekday(&date))=2)
%mend isFMoM;
For returning the 1st monday of the month of a given date, I like patrick's:
%*-- returns date value of the first monday of the month of the given date --*;
%macro FMoM(date=%sysfunc(today()));
%sysfunc(intnx(week.3,%sysfunc(intnx(month,&date,0,b)),0,e))
%mend FMoM;
It is from Patrick.
%let year=2011; %let month=8; %let monday=%sysfunc(intnx(week.3,%sysfunc(mdy(&month,1,&year)),0,e),date9.); %put &monday ;
Ksharp
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.