SAS: определение переменных в цикле if

Я новичок в написании макросов 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 ответ

Вы комбинируете макрос с шагом данных таким образом, что это не работает. Язык макросов и язык шагов данных в основном не связаны: язык макросов может писать код шагов данных, и наоборот, но не может влиять друг на друга в целом.

В частности, макрокод компилируется и выполняется первым, прежде чем открывается какой-либо набор данных или любой код шага данных компилируется или выполняется. В этом-то и дело - это позволяет вам писать прекомпиляцию кода шага данных.

Так

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

Это не работает, потому что сначала выполняется макрос%let, а затем шаг данных.

%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 сделать их доступными в глобальном масштабе.

Другие вопросы по тегам