So macro programming has always been a weakness for me, but I am trying to do something fairly simple to give it a go for date automation.
So what I want to happen is based on the run date, it will create the Quartercal for me based on my logic below. So I am missing something when running this macro but I am not sure what it is. I haven't done many of these if, then, do, else if, types before.
Thank you!
%macro Quarter_SAS(Quartercal);
%let Today_SAS = %sysfunc(date(),Date9.);
%LET Run_Date = %SYSFUNC(INPUTN(&Today_SAS., Date9.));
%LET Quarter_SAS = %SYSFUNC(INTNX(MONTH, &Run_Date., 0., B), Date9.);
%if &Quarter_SAS = ('01MAR2020') %then
%do;
%let Quartercal=('Q12020');
%end;
%else %if &Quarter_SAS = ('01AUG2020') %then
%do;
%let Quartercal=('Q22020');
%end;
%else %if &Quarter_SAS = ('01DEC2020') %then
%do;
%let Quartercal=('Q32020');
%end;
%else %if &Quarter_SAS = ('01JAN2021') %then
%do;
%let Quartercal=('Q42020');
%end;
%mend Quarter_SAS;
%put &Quarter_SAS;
I'm not going to re-write your entire macro code, but let me give you some general principles.
Macro variables should not be formatted (except for display in titles or labels or report). So
%let Today_SAS = %sysfunc(date(),Date9.);
really ought to be
%let Today_SAS = %sysfunc(date());
for any logical or arithmetical use, which is what you appear to be doing.
Next, macro variable values almost never need quotes around them, or parentheses around them. You spend a lot of time formatting and unformatting and adding quotes and then removing them. This is all unnecessary.
The exception is when you need to hard-code a specific date, such as you have 01MAR2020. Then you can use
%if &Quarter_SAS = %sysevalf('01MAR2020'd) %then %do;
Really, start from scratch, re-write your code without formatting and without quotes and parentheses, following the above principles, and it will work a lot better with a lot less effort.
Using the DATE9 format with the output of the %SYSFUNC() is going to generate a string that looks like:
01MAR2020
That is NEVER going to match a string that has quotes and parentheses in it like
('01MAR2020')
To add some detail to @Tom 's comment, this syntax is inaccurate:
%if &Quarter_SAS = ('01MAR2020') %then
%do;
%let Quartercal=('Q12020');
%end;
Macro language automatically treats characters as if they are characters. So this would be better:
%if &Quarter_SAS = 01MAR2020 %then
%do;
%let Quartercal=Q12020;
%end;
I'm not going to re-write your entire macro code, but let me give you some general principles.
Macro variables should not be formatted (except for display in titles or labels or report). So
%let Today_SAS = %sysfunc(date(),Date9.);
really ought to be
%let Today_SAS = %sysfunc(date());
for any logical or arithmetical use, which is what you appear to be doing.
Next, macro variable values almost never need quotes around them, or parentheses around them. You spend a lot of time formatting and unformatting and adding quotes and then removing them. This is all unnecessary.
The exception is when you need to hard-code a specific date, such as you have 01MAR2020. Then you can use
%if &Quarter_SAS = %sysevalf('01MAR2020'd) %then %do;
Really, start from scratch, re-write your code without formatting and without quotes and parentheses, following the above principles, and it will work a lot better with a lot less effort.
Thank you @Astounding, @PaigeMiller and @Tom. This macro logic is really interesting to me and I can see where formatting and characters can get in the way when trying to code the solution. Using a lot of these %put statements seem to help so I can see the output in my log to help formulate what I need.
Appreciate the help again! Thanks 😄
Adding to my above example
%let Today_SAS = %sysfunc(date());
If you want to see that this is correctly computing the date (and of course you can use this in more complicated date examples, such as with %sysfunc(intnx()) as well)
%put &=today_sas %sysfunc(putn(&today_sas,date7.));
Another question that may be worth considering is does this need be all macro code?
The comparisons and calculations may be easier in a DATA _NULL_ step that creates the needed macro values with call symputx.
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.