BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
reehfarias
Calcite | Level 5

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.

1 ACCEPTED SOLUTION

Accepted Solutions
wilkoba
SAS Employee

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;

View solution in original post

3 REPLIES 3
wilkoba
SAS Employee

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;

reehfarias
Calcite | Level 5

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)

wilkoba
SAS Employee

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: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

Discussion stats
  • 3 replies
  • 1169 views
  • 1 like
  • 2 in conversation