1
votes

I'm trying to adjust the reporting period between 1 month and 3 months (full quarter) based on time of the month. Based on the date below, I should be getting the period between 1/1 and 3/31, but I'm getting a logic error when I run the following code, any advice on how to fix it?

ERROR: Expected close parathesis after macro function invocation not found. ERROR: Required operator not found in expression: 0 ) ERROR: SKipping to next %END statement.

%let obsdate = '31Mar2021'd;
%let current_qtr_first_day = intnx('month', &obsdate, -2, 'B');
%let current_qtr_last_day = intnx('month', &obsdate, 0, 'E');
%let current_month_first_day = intnx('month', &obsdate, 0, 'B');
%let current_month_last_day = intnx('month', &obsdate, 0, 'E');

%if %sysfunc(MOD(month(&obsdate),3)=0 ) %then %do;
    %let startdt = &obsdate_current_qtr_first_day;
    %let enddt = &obsdate_current_qtr_last_day;
%end;
%else %do;
    %let startdt = &obsdate_current_month_first_day;
    %let enddt = &obsdate_current_month_last_day;
%end;   
1
You're missing the %SYSFUNC() for your first set of %LET statements as well as some semicolons to end the %LET statements. You need one for every function in your macro code. I think once you fix that it'll workReeza
I have the %sysfunc() on the mod function, where else do I need it at?crlaoy
The sysfunc is not around MOD it's around the full comparison which isn't correct.Reeza
You know that INTNX() has a QTR interval so you can easily align a date to the start and end in a single statement? It may be more useful to provide your actual requirements here.Reeza

1 Answers

1
votes

A few more issues than I initially realized so listing all below but overall, you shouldn't be doing this in this manner. Use a data step and CALL SYMPUTX() to create the macro variable at the end instead - less buggy and infinitely easier to code.

  1. EVERY function call in a macro requires the %SYFUNC() wrapped around it - INTNX(), MOD(), MONTH()

  2. Missing semicolons (Line 2, 4, 7, 9)

  3. %DO is spelled incorrectly (DOL)

  4. I don't know what you would want here: &obsdate_current_qtr_first_day You have no macro variable shown with that name but you have two with each portion of the name? Did you want to concatenate those values?

  5. Functions used in macros should not have the parameters within quotes ('month' versus month)

  6. Use the options mprint; when writing/developing macros so you can see the values in the log and get more information to help you debug the issues at hand.

     options mprint;
     %let obsdate = '31Mar2021'd;
     %let current_qtr_first_day = %sysfunc(intnx(month, &obsdate, -2, B));
     %let current_qtr_last_day = %sysfunc(intnx(month, &obsdate, 0, E));
     %let current_month_first_day = %sysfunc(intnx(month, &obsdate, 0, B));
     %let current_month_last_day = %sysfunc(intnx(month, &obsdate, 0, E));
     %if %sysfunc(MOD(%sysfunc(month(&obsdate)), 3))=0 %then %do;
     %let startdt = &obsdate._&current_qtr_first_day;
     %let enddt = &obsdate._&current_qtr_last_day;
     %end;
     %else %do;
     %let startdt = &obsdate._&current_month_first_day;
     %let enddt = &obsdate._&current_month_last_day;
     %end;
    

EDIT: Here's a data step solution that can be simplified once you have it set up for what you want.

    %macro get_report_dates(obsdate=);
            data _null_;
            
            
            *determine if month or quarterly reporting is needed;
            if month(&obsdate) in (3, 6, 9, 12) then interval = 'QTR';
            else interval = 'MONTH';
            
            start_date = intnx(interval, &obsdate, 0, 'b');
            end_date = intnx(interval, &obsdate, 0, 'e');
            format start_date end_date date9.;
            
            *creates global macro variables available outside this macro;
            *change format here to have it displayed as desired (eg date9);
            call symputx('startdt', put(start_date, yymmddd10.), 'g');
            call symputx('enddt', put(end_date, yymmddd10.), 'g');
            run;
            
    %mend;
    
    *test for a quarter;
    %get_report_dates(obsdate="01Mar2021"d);
    %put &startdt.;
    %put &enddt.;
    
    *test for a month;
    %get_report_dates(obsdate="01Feb2021"d);
    %put &startdt.;
    %put &enddt.;