我试图进行日期比较,但我没有得到正确的结果。有谁知道发生了什么?
%macro ttt;
%let check_start = 28APR2014;
%if "&check_start."d < "25may2014"d %then %let true = 1;
%else %if "&check_start."d > "25may2014"d %then %let true = 2;
%put &true;
%mend;
%ttt;
14 %macro ttt;
15 %let check_start = 28APR2010;
16 %if "&check_start."d < "25may2014"d %then %let true = 1;
17 %else %if "&check_start."d > "25may2014"d %then %let true = 2;
18 %put &true;
19 %mend;
20 %ttt;
true = 2
宏变量true应等于1
答案 0 :(得分:5)
在这种情况下,您需要使用%sysevalf()来评估比较。以下作品。
%macro ttt;
%let check_start = 28APR2015;
%if %sysevalf("&check_start"d < '25may2014'd) %then %let true=1;
%else %if %sysevalf("&check_start."d > '25may2014'd) %then %let true=2;
%put &true.;
%mend;
%ttt;
答案 1 :(得分:2)
Reeza提供了一个很好的解决方案,但我想我也会添加一些建议。
您遇到的问题是我建议在使用宏语言时不要使用日期文字的原因。相反,日期文字(即"01jan2000"d
)我建议使用包含日期值的宏变量(即%let start_of_21st_century = %sysfunc(mdy(1,1,2000));
)。通过使用宏变量,您不仅可以避免上述问题,而且还可以自行记录代码。
目前我不知道您的代码在2014年5月25日有什么意义,但是如果你有这一行:
%let product_launch_date = %sysfunc(mdy(5,25,2014));
......那么任何读它的人都会清楚其重要性。
您的代码将成为:
%macro ttt;
%local check_start compare_date;
%let check_start = %sysfunc(mdy(4,28,2014));
%let compare_date = %sysfunc(mdy(5,25,2014));
%if &check_start < &compare_date %then %let true = 1;
%else %if &check_start > &compare_date %then %let true = 2;
%put &true;
%mend;
还有一些我认为会改变的事情。我注意到的一件事是,如果2个日期值相等,则不会为true
分配值。所以这应该可以补救。
此外,在SAS中,典型的真/假概念通常表示如下:
因此,如果一个名为true
的宏变量值为1或2(这两个值通常表示值为true)可能会让某些人感到困惑。我会考虑重命名宏变量,或使用值0和1(或其他非零数字)。
结合所有这些,宏将变成类似:
%macro check_dates;
%local check_start compare_date;
%let check_start = %sysfunc(mdy(4,28,2014));
%let compare_date = %sysfunc(mdy(5,25,2014));
%let check_start_compared_higher = &check_start > &compare_date;
%if &check_start_compared_higher %then %do;
%put It was higher =) ;
%end;
%else %do;
%put It was equal to or lower =( ;
%end;
%mend;
%check_dates;
对最终宏的一些评论......名为true
的宏变量已被替换为名为check_start_compared_higher
的更具描述性的变量。因为我们只需要一个存储在其中的布尔值,我们可以简单地为它分配评估表达式&check_start > &compare_date
的结果,它将返回0(如果为假)或1(如果为真)。这比使用%if...%else...
语句进行赋值更容易阅读,因为很明显代码行只是执行赋值而已。
行%if &check_start_compared_higher %then %do;
显示了我们如何使用新保存的值来控制程序流。因为&check_start_compared_higher
中的值解析为TRUE或FALSE,所以我们可以通过这种方式轻松地使用它来生成易于读取的if语句。