Bom dia/tarde/noite
Tudo bem?
Estava tentando fazer um exercício de encontrar o último dia útil através da data de hoje.
Acho que estou tendo dificuldade com a sintaxe dessa linguagem de programação.
Tentei o seguinte:
/* Defina a variável data como a data atual */
data _null_;
data_dia_util = today();
run;
/* Defina a lista de feriados */
data feriados;
input feriado date9.;
format feriado date9.;
datalines;
01JAN2023
15APR2023
21APR2023
01MAY2023
30MAY2023
09JUN2023
07SEP2023
12OCT2023
02NOV2023
15NOV2023
25DEC2023
;
run;
/* Calcule a data do último dia útil */
data _null_;
/* Subtraia 1 dia da data atual */
data_dia_util = intnx('day', data_dia_util, -1);
/* Enquanto a data não for um dia útil, subtraia 1 dia */
do while(weekday(data_dia_util) in (1,7) or feriados(feriado=data) ne 0);
data_dia_util = intnx('day', data_dia_util, -1, 'EXCLUDE=feriados');
end;
/* Exiba a data do último dia útil */
put data_dia_util= date9.;
run;
/* Cria tabela vazia com nome tabela_aaaammdd */
data tabela_&data_dia_util.;
run;
Estou tendo problema principalmente no while, acho que na parte de verificar se é feriado não coloquei a frase correta, mas n sei como fazer.
ola @reehfarias ,
Modifiquei seu código (veja abaixo), não sei se seria o resultado que esperado, mas imagino, o que você esta querendo fazer precise estudar um pouco de MACRO SAS. Espero que tenha ajudado, embora acho que não tenha chegado ao resultado que você esperava.
Abraços.
---código que modifiquei---
/* Defina a variável data como a data atual */
data _null_;
call symput('data_dia_util',today()); /* CRIEI COMO VARIAVEL MACRO */
run;
/* Defina a lista de feriados */
data feriados;
input feriado;
format feriado date9.;
informat feriado date9.; /* USEI INFORMAT PARA QUE A LEITURA FUNCIONASSE */
datalines;
01JAN2023
15APR2023
21APR2023
01MAY2023
30MAY2023
09JUN2023
07SEP2023
12OCT2023
02NOV2023
15NOV2023
25DEC2023
;
run;
/* Calcule a data do último dia útil */
data _null_;
/* Subtraia 1 dia da data atual */
set feriados;
%let data_dia_util = %eval(&data_dia_util-1); /* NOVAMENTE %let e %eval é SAS MACRO */
/* Enquanto a data não for um dia útil, subtraia 1 dia */
do while(weekday(&data_dia_util) in (1,7) or feriado=&data_dia_util); /* No loop aqui, uso macro substituição */
%let data_dia_util = %eval(&data_dia_util-1); /* NOVAMENTE %let e %eval é SAS MACRO */
end;
/* Exiba a data do último dia útil */
x=put(&data_dia_util,date9.);
y=put(x,$10.);
call symput('nome_tabela','tabela_' || y); /* gerei varíavel macro o nome da sua tabela, aproveitando o mesmo data step*/
put x;
run;
/* Cria tabela vazia com nome tabela_aaaammdd */
data &nome_tabela; /* fazendo a macro substituição */
run;
ola @reehfarias ,
Modifiquei seu código (veja abaixo), não sei se seria o resultado que esperado, mas imagino, o que você esta querendo fazer precise estudar um pouco de MACRO SAS. Espero que tenha ajudado, embora acho que não tenha chegado ao resultado que você esperava.
Abraços.
---código que modifiquei---
/* Defina a variável data como a data atual */
data _null_;
call symput('data_dia_util',today()); /* CRIEI COMO VARIAVEL MACRO */
run;
/* Defina a lista de feriados */
data feriados;
input feriado;
format feriado date9.;
informat feriado date9.; /* USEI INFORMAT PARA QUE A LEITURA FUNCIONASSE */
datalines;
01JAN2023
15APR2023
21APR2023
01MAY2023
30MAY2023
09JUN2023
07SEP2023
12OCT2023
02NOV2023
15NOV2023
25DEC2023
;
run;
/* Calcule a data do último dia útil */
data _null_;
/* Subtraia 1 dia da data atual */
set feriados;
%let data_dia_util = %eval(&data_dia_util-1); /* NOVAMENTE %let e %eval é SAS MACRO */
/* Enquanto a data não for um dia útil, subtraia 1 dia */
do while(weekday(&data_dia_util) in (1,7) or feriado=&data_dia_util); /* No loop aqui, uso macro substituição */
%let data_dia_util = %eval(&data_dia_util-1); /* NOVAMENTE %let e %eval é SAS MACRO */
end;
/* Exiba a data do último dia útil */
x=put(&data_dia_util,date9.);
y=put(x,$10.);
call symput('nome_tabela','tabela_' || y); /* gerei varíavel macro o nome da sua tabela, aproveitando o mesmo data step*/
put x;
run;
/* Cria tabela vazia com nome tabela_aaaammdd */
data &nome_tabela; /* fazendo a macro substituição */
run;
MUITO OBRIGADO! Consegue me dar só mais uma ajudinha?
O código estava criando a tabela com o nome tipo Tabela_19APR2023 então eu só fiz uma mudança no formato a fim de criar com o nome TABELA_20230419.
/* Defina a variável data como a data atual */
data _null_;
call symput('data_dia_util',today()); /* CRIEI COMO VARIAVEL MACRO */
run;
/* Defina a lista de feriados */
data feriados;
input feriado;
format feriado date9.;
informat feriado date9.; /* USEI INFORMAT PARA QUE A LEITURA FUNCIONASSE */
datalines;
01JAN2023
15APR2023
21APR2023
01MAY2023
30MAY2023
09JUN2023
07SEP2023
12OCT2023
02NOV2023
15NOV2023
25DEC2023
;
run;
/* Calcule a data do último dia útil */
data _null_;
/* Subtraia 1 dia da data atual */
set feriados;
/* Enquanto a data não for um dia útil, subtraia 1 dia */
do while(weekday(&data_dia_util) in (1,7) or feriado=&data_dia_util); /* No loop aqui, uso macro substituição */
%let data_dia_util = %eval(&data_dia_util-1); /* NOVAMENTE %let e %eval é SAS MACRO */
end;
/* Exiba a data do último dia útil */
x=put(&data_dia_util,yymmddn8.);
%let DATA_MOV=put(x,$10.);
call symput('nome_tabela','tabela_' || &DATA_MOV); /* gerei varíavel macro o nome da sua tabela, aproveitando o mesmo data step*/
put x;
run;
/* Cria tabela vazia com nome tabela_aaaammdd */
data &nome_tabela; /* fazendo a macro substituição */
run;
Na parte final do código, quando ele cria a tabela eu tentei colocar data tabela_&DATA_MOV; em vez de usar a variavel criada &nome_tabela. Não deu certo, sabe me explicar pq? sendo que na linha de cima : call symput('nome_tabela','tabela_' || &DATA_MOV) eu uso ela e ela me traz o resultado esperado.
Pergunto isso porque na verdade a tabela vazia era só pra testar a variável, o que eu preciso mesmo é dessa macro variável DATA_MOV com o valor de 20230419 (por exemplo)
Você primeiro precisava criar a varíavel macro já com o valor ao qual gostaria de substituir numa etapa anterior. (dentro de um data step).
para efeitos didáticos talvez eu criasse um data step sozinho desta forma:
data _null_;
x=put(&data_dia_util,yymmddn8.); /*convertendo o valor de data_dia_util para formato YYmmddn8. */
%let DATA_MOV=put(x,$10.); /* convertando o valor do x (está como data/numérico) para caracter/string */
call symput('nome_tabela','tabela_' || &DATA_MOV); /* aqui vc concatena duas string 'tabela_' com o conteúdo da string DATA_MOV */
run;
/* Somente no próximo data step vc já usa o conteúdo criado */
data &nome_tabela;
...
run;
Quando você fez "data tabela_&data_mov" --> ele ainda não entende que 'tabela_' é string e vc está substituindo uma parte.. e ainda faltou o || para concatenar as string. - Com certeza existe um jeito melhor de fazer do que eu fiz, mas isto é considerando o pouco que sei sobre SAS MACRO.
Abaixo tem um material básico sobre SAS Macros, tem cursos oficiais também pelo SAS.
SAS Tutorial | How to Create Macro Variables and Use Macro Functions - YouTube
How to create and use SAS macro functions - SAS Users
Estou aqui para tentar ajudar. A comunidade serve para isto.
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!