SAS:if循环中变量的定义

时间:2017-05-03 14:40:40

标签: sas sas-macro

我是SAS宏写作的新手,我一直在努力为以下实例编写代码。

%let DateOfInterest= "15jul2016"d;
%let yearyyyy=%sysfunc(putn(&DateOfInterest,year4.));
%let yearyyyy2=eval(yearyyyy+1);


data _null_;

if "01JAN2016"d<=&DateOfInterest<="31MAR2016"d then do; 
%let reportdate="31MAR2016"d;
%let reportdate2="01APR2016"d; 
%let reportdate3="01JAN2016"d;
%let QuarterOfInterest=Q1;

if "31MAR2016"d<&DateOfInterest<="30JUN2016"d then do;
%let reportdate="30JUN2016"d;
%let reportdate2="01JUL2016"d;
%let reportdate3="01APR2016"d;
%let QuarterOfInterest=Q2;

if "30JUN2016"d<&DateOfInterest<="30SEP2016"d then do;
%let reportdate="30SEP2016"d;
%let reportdate2="01OCT2016"d;
%let reportdate3="01JUL2016"d;
%let QuarterOfInterest=Q3;

if "30SEP2016"d<&DateOfInterest<="31DEC2016"d then do;
%let reportdate="31DEC2016"d;
%let reportdate2="01JAN2017"d;
%let reportdate3="01OCT2016"d;
%let QuarterOfInterest=Q4;
end;
end;
end;
end;
run;

代码运行没有任何问题。但是,无论我选择哪个DateOfInterest,reportdate变量都是最后一个if循环中指定的变量。有没有办法改变代码,以使reportdates变量符合DateOfInterest?

感谢。

1 个答案:

答案 0 :(得分:1)

您以一种不起作用的方式将宏与数据步骤相结合。宏语言和数据步骤语言基本无关:宏语言可以写入数据步骤代码,反之亦然,但一般不会相互影响。

特别是,在打开任何数据集或编译或执行任何数据步骤代码之前,首先编译和执行宏代码。这真的很重要 - 它可以让你编写datastep代码预编译。

所以

if ... then do;
  %let something
end;

这不起作用,因为首先发生宏%,然后发生数据步骤。

%if ... %then %do;
  %let something
%end;

这是有效的,因为它都是宏语言。一般来说,如果它一开始没有%,它就不是宏语句/函数,并且不会使用宏语言。

然而,你正在做的事情会有更多的复杂情况。你必须在宏中使用%if,但你也有范围问题。

所以像这样的一般小宏将是:

%let mval=1;
%macro set_things;

  %if &mval=1 %then %do;
    %let mval1=1;
  %end;

  %else %if &mval=2 %then %do;
     %let mval2=1;
  %end;

  %else %do;
     %let mval0=1;
  %end;
%mend;

%set_things();

%put &=mval &=mval0 &=mval1 &=mval2;

请注意,它不起作用:因为它不是全局的,所以你需要在宏中再添一行:

%global mval0 mval1 mval2;

告诉SAS让它们在全球范围内可用。