【问题标题】:passing date variable to macro for sysfunc processing将日期变量传递给宏以进行 sysfunc 处理
【发布时间】:2018-02-15 21:21:50
【问题描述】:

下面是我创建宏并传入日期变量的小问题。不使用日期变量,它的结果如下。

%macro x();
%let i=-1;
%let dts = %sysfunc(today());
%put &dts; /*ok*/
%let yymm1 = %sysfunc(intnx(MONTH,&dts,&i));
%put &yymm1; /*ok*/

%let mth_beg = %sysfunc(intnx(MONTH,&dts,&i,B),date9.);
%let mth_end = %sysfunc(intnx(MONTH,&dts,&i,E),date9.);
%put &mth_beg &mth_end; /*01JAN2018 31JAN2018*/
/*** proc sql code below ** */
%mend;
%x();

日志: 21231 21185 01JAN2018 2018 年 1 月 31 日

现在我围绕它创建了一个宏并得到以下错误:

%macro x(dts1);

%let i=-1;
/*%let dts = %sysfunc(today());*/
%let dts = %sysfunc(&dts1);
%put &dts; /*ok*/
%let yymm1 = %sysfunc(intnx(MONTH,&dts,&i));
%put &yymm1; /*ok*/

%let mth_beg = %sysfunc(intnx(MONTH,&dts,&i,B),date9.);
%let mth_end = %sysfunc(intnx(MONTH,&dts,&i,E),date9.);
%put &mth_beg &mth_end; /*01JAN2018 31JAN2018*/
/*** proc sql code below ** */
%mend;
%x(16JAN2018);

错误:%SYSFUNC 或 %QSYSFUNC 宏函数引用中缺少函数名。 2018 年 1 月) 错误:未找到宏函数调用后预期的右括号。 )) 错误:未找到宏函数调用后预期的右括号。 错误:未找到宏函数调用后预期的右括号。 ,B),date9.) ,E),date9.)

我不确定如何让 SAS 将传入的日期视为公认日期。我知道我可能错误地使用了 sysfunc(&dts) 或者传递的日期需要遵守某种格式。我只想替换今天的日期()。你能帮我吗?我是 SAS 新手。

谢谢

【问题讨论】:

  • 您在调用宏时希望将哪些值传递给宏?你想传递看起来像日期16FEB2018的字符串吗?或者您想传入一个有效的 SAS 日期,例如日期文字 "16FEB2018"d,还是自 01JAN1960 以来的简单天数?
  • 我很灵活,因为我是决定传球的人。因为我会这样做,例如%x(2018 年 2 月 16 日); %x(16Jan2018);..等基本上我传递月度数据点来运行月度报告。所以只要 sas 接受我的价值观。
  • 因此,如果您传入 16FEB2018 之类的值,并且希望将其用作实际日期,则需要将其转换为宏主体中的日期文字。 "&mvar"d
  • 谢谢它的工作。但我想知道 btw %let dts = %sysfunc(today()); 的区别和 %let dts = "%dts1"d (即 "16jan2018"d。两个步骤都指向下面的步骤。%let yymm1 = %sysfunc(intnx(MONTH,&dts,&i));假设今天是 16jan2018,我知道 %let dts = %sysfunc(today()); 解析为 SAS 整数值。但是“16jan2018”D 不是 SAS 整数,对吧?我只是不确定为什么会有不同的处理方式。
  • 请参阅下面的答案。您可以将同一日期表示为整数或日期文字。只要确保你知道自己在做什么。

标签: sas sas-macro


【解决方案1】:

将日期包装在" 中,并以d 结尾。这将告诉 SAS 将字符串转换为日期:

%macro x(dts1);

%let i=-1;
/*%let dts = %sysfunc(today());*/
%let dts = "&dts1"d; /*Change here!*/
%put &dts; /*ok*/
%let yymm1 = %sysfunc(intnx(MONTH,&dts,&i));
%put &yymm1; /*ok*/

%let mth_beg = %sysfunc(intnx(MONTH,&dts,&i,B),date9.);
%let mth_end = %sysfunc(intnx(MONTH,&dts,&i,E),date9.);
%put &mth_beg &mth_end; /*01JAN2018 31JAN2018*/
/*** proc sql code below ** */
%mend;
%x(16JAN2018);

【讨论】:

  • 它有效。我可以知道 %sysfunc(today()) 和 "18jan2018"d 是否相同吗?我知道前者是一个 sas 整数(自 1960 年以来的天数),后者也一样吗?
  • 正确,假设 today() 是 2018 年 1 月 18 日。;-) SAS 中的所有日期都是您描述的整数。
【解决方案2】:

改变 %let dts = %sysfunc(&dts1);到

%let dts = %sysfunc(inputn(&dts1,date9. ));

【讨论】:

  • 甚至anydtdte. 以获得最大的兼容性!
  • 对于 %sysfunc(inputn(&dts1,date9. 我设置什么格式是否重要,即其他格式而不是 data9.?
  • 是的,您需要相应地使用格式作为宏变量。请使用 %let dts = %sysfunc(inputn(&dts1,anydtdte.));对于 user667849 建议的几乎任何日期
【解决方案3】:

SAS 将日期存储为自 1960 年 1 月 1 日以来的天数。因此,如果您不将日期格式附加到日期值,它将看起来像一个整数。

%let today=%sysfunc(today());

然后,您可以在任何需要使用日期值的地方使用该整数。

%let next_month=%sysfunc(intnx(month,&today,1,b));

您还可以使用日期文字来表示日期。要制作日期文字,您可以使用 DATE 信息可以读取的内容(如 16FEB2018、16feb18、16-FEB-2018 等)用引号括起来并附加字母 d 来表示日期值。

%let today="%sysfunc(today(),date9)"d ;
%let date_string=13FEB2018;
%let date_value="&date_string"d ;

因此,日期文字将在 SAS 代码中起作用,并且当您使用 %sysfunc() 宏函数调用 SAS 函数(如 INTNX)时,它们将在 %sysevalf() 宏函数中起作用。但是%eval() 宏函数将无法识别日期文字。因此,如果您想在宏逻辑中使用算术或比较日期文字,则需要使用 %sysevalf()

%if %sysevalf(&today > '01JAN2018'd) %then ....
%let tomorrow=%sysevalf(&today +1);

【讨论】:

    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多