Arrays 开始日期和结束日期的Sas循环

Arrays 开始日期和结束日期的Sas循环,arrays,loops,date,sas,Arrays,Loops,Date,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 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.

宏处理器将所有内容视为字符串。无法将字符串
日期列表{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);

宏处理器将所有内容视为字符串。无法将字符串
日期列表{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);

为什么在%do循环之前有那个数据语句?您的%DO循环未生成任何数据步骤语句。未定义宏的作用是什么?它是否只生成宏代码?它是否生成单个SAS语句的一部分?多个SAS语句?一个或多个SAS步骤?因此,目的是从以年和月为字段的文件中获取数据。因此出现了未定义的宏%datapull。为什么在%do循环之前有那个DATA语句?您的%DO循环未生成任何数据步骤语句。未定义宏的作用是什么?它是否只生成宏代码?它是否生成单个SAS语句的一部分?多个SAS语句?一个或多个SAS步骤?因此,目的是从以年和月为字段的文件中获取数据。因此,未定义的宏%datapull.%调用作为宏名称似乎也是一个坏主意。SAS对例程使用CALL,所以我不建议这样使用。你可能不会遇到问题,但风格/设计不好。谢谢你的意见。我使用数组是为了运行宏%datapull,只运行2个日期-由用户指定。通过执行循环步骤,宏似乎将在开始日期和结束日期之间的所有月份运行。有没有办法只在开始和结束日期运行宏?有两个版本。使用符合您需要的名称。%CALL作为宏名称似乎也是个坏主意。SAS对例程使用CALL,所以我不建议这样使用。你可能不会遇到问题,但风格/设计不好。谢谢你的意见。我使用数组是为了运行宏%datapull,只运行2个日期-由用户指定。通过执行循环步骤,宏似乎将在开始日期和结束日期之间的所有月份运行。有没有办法只在开始和结束日期运行宏?有两个版本。使用一个符合你需要的。