SAS 宏变量

问题描述 投票:0回答:1

我正在尝试创建一个需要引用 2 个日期的宏,我希望它成为 do 循环的一部分,这样我就不必输入 36 次日期。

这是我到目前为止所拥有的:

PROC SQL NOPRINT;
SELECT MMMYY INTO : mmmyy1 -
FROM USE_DATES;
%LET T=&SQLOBS.;
QUIT;

PROC SQL NOPRINT;
SELECT _YEAR_ INTO : yy1 -
FROM USE_DATES;
%LET T=&SQLOBS.;
QUIT;

PROC SQL NOPRINT;
SELECT mm INTO : mm1 -
FROM USE_DATES;
%LET T=&SQLOBS.;
QUIT;


%MACRO MATS(DATE, NUM);
%let j=%eval(&i+1);
%let month = &mm&&j.;
%let year_x = &yy&&j.;

PROC SQL;
CREATE TABLE TEST AS 
SELECT 
PRODUCT_EXPIRY_DATE, 
COUNT(*)
FROM DATA.AGGREGATE_ACCOUNTS_&mmmyy&&i.
WHERE YEAR(PRODUCT_EXPIRY_DATE) = &year_x. AND MONTH(PRODUCT_EXPIRY_DATE) = &month.

;
QUIT;
%MEND;

%MACRO apply_MATS;
%DO i = 1 %to 1  %by 1;
%MATS(&mmmyy&&i.,&i.);
%end;
%mend;

%apply_MATS;

问题是它没有分配year_x,因此代码失败并显示错误代码:

错误 22-322:语法错误,需要以下之一:名称、;、(、'、'、ANSIMISS、AS、 交叉、除外、完整、分组、具有、内部、相交、连接、左、自然、 NOMISS、ORDER、OUTER、RIGHT、UNION、WHERE。

错误 200-322:该符号无法识别,将被忽略。

我无法弄清楚我做错了什么?有人可以帮忙吗?

sas macros sas-macro do-loops macro-variable
1个回答
1
投票

您没有在正确的位置使用 &&。如果 &J=1 并且想要 YY1 的值,那么你应该这样做:

%let year_x = &&yy&j;

第一遍会将 && 转换为 &,并将 &J 转换为 1,得到 &yy1。第二遍将转换为 YY1 的值。

但你把事情搞得太难了。如果目标是按 YEAR 和 MONTH 选择,则以这种方式构造内部宏。

%MACRO MATS(year, month, NUM);
PROC SQL;
CREATE TABLE TEST&num. AS 
  SELECT PRODUCT_EXPIRY_DATE
       , COUNT(*)
  FROM DATA.AGGREGATE_ACCOUNTS_&year.&month.
  WHERE YEAR(PRODUCT_EXPIRY_DATE) = &year
    AND MONTH(PRODUCT_EXPIRY_DATE) = &month.
;
QUIT;
%MEND;

然后你可以为YYMM的每个值调用一次宏

data _null_;
   set USE_DATES;
   call execute(cats('%nrstr(%MATS)(',yy,',',mm,',',_n_,')'));
run;
© www.soinside.com 2019 - 2024. All rights reserved.