首页 > 解决方案 > 开始日期和结束日期的 Sas 循环

问题描述

我在这里有一个代码,我从用户那里获取一个开始日期和结束日期,并为这两个日期执行一个宏。

%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();

但无论我尝试哪种方式,我最终都会收到以下错误:

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.

标签: arraysloopsdatesas

解决方案


宏处理器将所有内容都视为字符串。您不能将字符串datelist{i}转换为日期值。

看起来您想要一个宏,它可以将字符串列表作为输入,这些字符串的格式可以转换为日期值,并使用这些字符串调用另一个宏。

%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);

相反,如果您想从头到尾每个月进行处理,那么您需要一个具有不同输入的不同宏。在这种情况下,您只需要两个输入,每个输入只能有一个值。

这次让我们对其进行编码,以便提供有效日期值的负担落在宏的调用者身上,而不是接受需要转换为日期的字符串。

%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);

推荐阅读