代码之家  ›  专栏  ›  技术社区  ›  IndigoChild

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

  •  0
  • IndigoChild  · 技术社区  · 5 年前

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

    %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.
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   Tom    5 年前

    宏处理器将所有内容都视为字符串。不能转换字符串 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);