使用 CALL SYMPUT 做循环

Do Loop using CALL SYMPUT

Do 循环概念有一些问题。我有一个用 -

定义的静态日期(可以是任何日期)
%LET DATE = %SYSFUNC(TODAY());
%PUT &DATE;

我需要创建一系列宏变量来保存该日期 (&DATE) 增加 10 天的值,所以我使用了一个简单的数据步骤来实现这个 -

DATA _NULL_;
CALL SYMPUT('DATE10',&DATE+10);
CALL SYMPUT('DATE20',&DATE+20);
CALL SYMPUT('DATE30',&DATE+30);
RUN;

此方法适用于 &DATE 初始值后最多 30 天的 10 增量。我现在的任务是将报告扩展到从 &DATE 的值延长到 250 天(增加 10 天)的日期。假设 DO LOOP 是最有效的执行方法,我无法理解循环如何 "create" 循环内的新宏变量(例如 &Date150)。假设下面的语法是正确的,我不确定 next/correct 步骤是什么:

DATA _NULL_;
DO I=10 TO 150 BY 10;
CALL SYMPUT('DATE10',&DATE);
END;
RUN;

在执行基于 10 天增量的宏变量创建时,我如何 "increment" 循环中宏变量的实际名称 (&DATE10,&Date20...&Date150)?

非常简单 - 将变量作为第一个参数传递给 call symput,其中包含您要创建的宏变量的名称。

通过串联函数使用 I 变量作为变量名称的一部分,cats() 可能是合适的。另外,个人喜好,但我更喜欢调用 SymputX,因为它会删除任何额外的空格。

DATA _NULL_;
DO I=10 TO 150 BY 10;
CALL SYMPUTX(cats('DATE', i), &DATE+i);
END;
RUN;

考虑将这些值放入单个宏变量中。只要列表不超过宏变量的最大长度。

DATA _NULL_;
  length dates 767 ;
  date=today();
  DO I=10 TO 150 BY 10;
    dates=catx(' ',dates,date+i);
  end;
  CALL SYMPUTx('dates',dates);
RUN;

然后在您的报告代码中,您可以只使用日期列表。

proc report ;
  where date in (&dates);
 ...
run;

或者如果你有宏,你可以使用 %DO 循环。

%do i=1 %to %sysfunc(countw(&dates));
  %let date=%scan(&dates,&i);
  proc report;
    where date=&date;
    ....
%end;