Durante toda a minha vida, não consigo descobrir como corrigir esses formatos para uma macro de data utilizável. Tenho duas informações que desejo usar para criar variáveis de macro de data. O primeiro é um ano e o segundo é uma tag que me informa se eu crio as variáveis para um determinado ano ou para o ano anterior. Por exemplo, se eu definir o ano como 2025 e o período como PREV, quero criar as variáveis de data para 2024. As datas que desejo são o início do ano, o final do ano, 6 meses antes do início e 6 meses depois. o fim. Estou procurando que todos tenham o formato 01JAN2024.
Tenho rastreado fóruns e o site de ajuda do SAS e tentei mil combinações. Não consigo encontrar nada que funcione e nem sei como imprimir corretamente os resultados para verificar. Aqui está o que tentei mais recentemente:
%let year = 2025;
%let period = PREV;
%let start_date = %sysfunc(mdy(1, 1, &meas_yr));
%macro set_dates;
%if &period = PREV
%then %do;
%let p_start = %sysfunc(intnx(year, &start_date, -1, beg));
%let p_end = %sysfunc(intnx(year, &start_date, -1, end));
%let period_start = %sysfunc(putn(&p_start, date9.));
%let period_end = %sysfunc(putn(&p_end, date9.));
%end;
%else %do;
%let p_start = %sysfunc(intnx(year, &start_date, 0, beg));
%let p_end = %sysfunc(intnx(year, &start_date, 0, end));
%let period_start = %sysfunc(putn(&p_start, date9.));
%let period_end = %sysfunc(putn(&p_end, date9.));
%end;
%mend set_dates;
%set_dates;
%let period_lkbk = %sysfunc(intnx(month, &p_start., -6, beg), date9.);
%put &period_lkbk;
%let period_lkfw = %sysfunc(intnx(month, &p_end., 6, end), date9.);
%put &period_lkfw;
A seguir está meu código para testar o que está sendo definido:
%put Date_Test_1 : %sysfunc(putn(&p_start, date9.));
%put Date_Test_2 : &period_start;
%put Date_Test_3 : %sysfunc(putn(&p_end, date9.));
%put Date_Test_4 : &period_end;
%put Date_Test_5 : &period_lkbk;
E os resultados que obtenho são:
SYMBOLGEN: Macro variable P_START resolves to 23376
27
28 %put Date_Test_1 : %sysfunc(putn(&p_start, date9.));
Date_Test_1 : 01JAN2024
29 %put Date_Test_2 : &period_start;
SYMBOLGEN: Macro variable PERIOD_START resolves to 01JAN2024
Date_Test_2 : 01JAN2024
30 %put Date_Test_3 : %sysfunc(putn(&p_end, date9.));
WARNING: Apparent symbolic reference P_END not resolved.
WARNING: Apparent symbolic reference P_END not resolved.
ERROR: Argument 1 to function PUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is not a number.
ERROR: Invalid arguments detected in %SYSCALL, %SYSFUNC, or %QSYSFUNC argument list. Execution of %SYSCALL statement or %SYSFUNC
or %QSYSFUNC function reference is terminated.
Date_Test_3 :
31 %put Date_Test_4 : &period_end;
SYMBOLGEN: Macro variable PERIOD_END resolves to 31DEC2024
Date_Test_4 : 31DEC2024
32 %put Date_Test_5 : &period_lkbk;
SYMBOLGEN: Macro variable PERIOD_LKBK resolves to 01JUL2023
Date_Test_5 : 01JUL2023
33 %put Date_Test_6 : &period_lkfw;
SYMBOLGEN: Macro variable PERIOD_LKFW resolves to .
Date_Test_6 : .
Eventualmente eu quero usar isso em uma instrução dentro do proc sql assim:
WHERE startdate >= "&period_lkbk."d and enddate <= "&period_lkfw."d;
Por que p_end não está resolvendo? Sinto que estou perto, mas não consigo chegar à linha de chegada.
Sua macro atribui um valor a PERIOD_END (e P_START etc.), mas não há nenhum código que garanta que PERIOD_END foi definido fora da macro, ao contrário de START_DATE, onde há uma instrução %LET em código aberto para criá-lo na macro GLOBAL escopo antes de começar a executar a macro. Como as variáveis da macro ainda não existem, as instruções %LET dentro de uma definição de macro criarão variáveis de macro LOCAL, que desaparecerão quando a macro terminar.
Como não há nada no código que precise de uma macro, você pode tentar eliminar a definição da macro.
Resultados
Dica:
Para tornar sua programação de macro mais fácil de entender e manter, não use variáveis de macro "mágicas" dentro de sua definição de macro. Com isso quero dizer que você precisa ter um propósito ao projetar se as variáveis de macro que você faz referência (e aquelas que você cria) serão LOCAIS para a macro (para que desapareçam quando a execução da macro terminar) ou EXTERNAS para a macro (para que elas permanecem após a conclusão da macro). Você nem tem comentários que ajudem o próximo usuário (que provavelmente será seu) a entender qual era o seu plano.
Então talvez você queira uma macro como esta que receba duas entradas e gere 5 variáveis de macro GLOBAIS.
Que você pode usar assim: