Макрос SAS, циклически проходящий через несколько форматов дат «гггг-мм-дд» с одинарными кавычками

#loops #date #sas-macro #single-quotes

Вопрос:

Мне нужно перебрать какой-то формат даты, например «гггг-мм-дд» в макросе SAS, поскольку в моем основном тексте запроса используется передача Teradata SQL, однако мой приведенный ниже код не работает там, где %let wk_first_dt не использует формат «гггг-мм-дд». Ошибка гласит

 %MACRO DO_APPEND;
%let first_dt_list = '2020-03-11' '2020-03-18';
%local i wk_first_dt;
%do i=1 %to %sysfunc(countw(amp;first_dt_list));
%let wk_first_dt = %scan(amp;first_dt_list, amp;i);

...
proc sql
...

where BILL_DT >= Date amp;wk_first_dt
AND SL_INVC.BILL_DT <= (Date amp;wk_first_dt   7)
...
quit;


...

%END;
%MEND; 
%DO_APPEND;
 
 ERROR: Literal contains unmatched quote.
ERROR: The macro DO_APPEND will stop executing.
 

Провел много исследований, и я считаю, что проблема возникла из-за одинарных кавычек в этом формате «гггг-мм-дд», поскольку в макросе SAS существует специальный режим, касающийся одинарных кавычек. однако наиболее популярные рекомендации, такие как

 %let first_dt_list = %str(%')yyyy-mm-dd.%str(%') 
 

в моем случае это не сработает. Пожалуйста, будьте добры указать мне правильное направление. Заранее спасибо!

Кстати, в приведенном выше коде, если я изменю %сканирования(amp;first_dt_list, amp;i) на «2020-03-11», весь макрос сработает, но мне просто нужно перебрать несколько дат. Это заставляет меня поверить, что как только «гггг-мм-дд» будет передано в %let wk_first_dt, проблема будет устранена.

Комментарии:

1. Вы включили опцию MPRINT, чтобы видеть в ЖУРНАЛЕ код SAS, который генерирует ваш макрос?

Ответ №1:

Ваш вызов функции %SCAN() неверен.

 75    %let list = '2020-03-11' '2020-03-18';
76    %put %qscan(amp;list,1);
'2020
 

Поскольку вы не указали %SCAN (), какой разделитель использовать, он использовал ЛЮБОЙ из набора разделителей по умолчанию, который включает дефис.

Попробуйте сказать ему, что в качестве разделителя следует использовать только пробел.

 %do i=1 %to %sysfunc(countw(amp;first_dt_list, %str( )));
%let wk_first_dt = %scan(amp;first_dt_list, amp;i,%str( ));