IndigoChild
IndigoChild

Reputation: 844

Sas loop for start date and end date

I have a code here, where I take a start date and end date from the user and execute a macro for those 2 dates.

%let mon_last=31MAR2019;
%let mon_first=01JAN2019;
%macro call();
data _null_;
array datelist {2} "&mon_first"d "&mon_last"d;
%do i=1 %to 2;
    %let yrmon1=%sysfunc(inputn(datelist{i},mmddyy10.), date9.));
    %let yrmon=%sysfunc(putn(&yrmon1,date9.),yymmn6.);
    %let yr=%sysfunc(year(&yrmon1),4);
    %let mon=%sysfunc(month(&yrmon1),z2);
    %datapull(&yrmon., &yr., &mon.);
%end;
%mend;
%call();

But I end up getting the following error whichever way I try:

WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is out of range.
NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The result of the operations have been set 
      to a missing value.
ERROR: The function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function has too few arguments.

Upvotes: 0

Views: 393

Answers (1)

Tom
Tom

Reputation: 51621

The macro processor considers everything as a string. You cannot convert the string datelist{i} into a date value.

Looks like you want to have a macro that can take as input a list of strings that are in a format that can be converted into date values and use those to call another macro.

%macro call(date_list);
%local i yrmon yr mon;
%do i=1 %to %sysfunc(countw(&date_list));
    %let yrmon=%sysfunc(inputn(%scan(&date_list,&i),date11.),yymmn6.);
    %let yr=%substr(&yrmon,1,4);
    %let mon=%substr(&yrmon,5);
    %datapull(&yrmon., &yr., &mon.);
%end;
%mend;
%call(31MAR2019 01JAN2019);

If instead you wanted to process every month from start to end then you want a different macro with different inputs. In that case you just need two inputs that each can only have one value.

This time let's code it so that the burden of supplying valid date values falls onto the caller of the macro instead of accepting character strings that need to be converted into dates.

%macro call(start,end);
%local i yrmon yr mon;
%do i=0 %to %sysfunc(intck(month,&start,&end));
    %let yrmon=%sysfunc(intnx(month,&start,&i),yymmn6.);
    %let yr=%substr(&yrmon,1,4);
    %let mon=%substr(&yrmon,5);
    %datapull(&yrmon., &yr., &mon.);
%end;
%mend;
%call("01JAN2019"d,"31MAR2019"d);

Upvotes: 2

Related Questions