Power Query – Como Incluir Feriados na Tabela Dimensão Calendário (Via API)

No meu blog já tem um post sobre como criar uma tabela dimensão calendário e agora venho fazer uma atualização de como é possível trazer os feriados nacionais a partir de API do site ANBIMA.

Eles não disponibilizam a API para isso, mas com a ajuda do Power Query conseguimos criar uma função para invocar os anos que desejamos, conforme imagem abaixo:

Neste caso eu defini o ano de início 2018 e o ano fim, para criar o calendário e invocar a função foram 5 anos a mais do que o ano atual.

Desta maneira, podemos deixar um padrão de anos futuros de acordo com o planejamento da empresa.

A intensão aqui não é mostrar como montar uma tabela calendário, isso você pode ver no post Tabela Calendário no Power Query.

O site também disponibiliza uma tabela em Excel para download e/ou conectar direto via Power Query.

Entretanto, eu acho arriscado depender de um arquivo, porque ele pode ser movido, removido ou alterado a sua estrutura.

Mas para quem tiver interesse em consumir os feriados via Excel, só clicar aqui para ter acesso.

Segue código utilizado no Power Query para criar a função fx_feriados e depois para criar a tabela com datas:

(ano as number) =>

let
    Fonte = 
        Web.Contents(
            "https://www.anbima.com.br/",
            [
                RelativePath= "feriados/fer_nacionais/"&Text.From(ano)&".asp"
            ]
            ),
    #"Tabela extraída de HTML" = Html.Table(Fonte, {{"Column1", "TABLE.interna > * > TR > :nth-child(1)"}, {"Column2", "TABLE.interna > * > TR > :nth-child(2)"}, {"Column3", "TABLE.interna > * > TR > :nth-child(3)"}}, [RowSelector="TABLE.interna > * > TR"]),
    #"Cabeçalhos Promovidos" = Table.PromoteHeaders(#"Tabela extraída de HTML", [PromoteAllScalars=true]),
    #"Tipo Alterado" = Table.TransformColumnTypes(#"Cabeçalhos Promovidos",{{"Data", type date}, {"Dia da Semana", type text}, {"Feriado", type text}})
in
    #"Tipo Alterado"
let
    anoFim = Date.Year(DateTime.LocalNow()) + 5, 
//----------- tabela feriados -----------
    
    feriados =
        List.Generate(
            () => [Consulta = try fx_feriados(anoInicio) otherwise null, ano = anoInicio],
            each [ano] <= anoFim,
            each [Consulta = try fx_feriados([ano]+1) otherwise null, ano = [ano]+1],
            each [Consulta]

        ),
    tabelaFeriados = Table.FromList(feriados, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    tabelaFeriadosExpandida = Table.ExpandTableColumn(tabelaFeriados, "Column1", {"Data", "Dia da Semana", "Feriado"}, {"Data", "Dia da Semana", "Feriado"}),
    tipoAlteradoTabFeriados = Table.Buffer(Table.TransformColumnTypes(tabelaFeriadosExpandida,{{"Data", type date}, {"Dia da Semana", type text}, {"Feriado", type text}})),

//----------- tabela calendário -----------
    
    listaDatas = 
        List.Generate(
            () => #date(anoInicio, 1, 1),
            each _ <= #date(anoFim, 12, 31),
            each Date.AddDays(_ , 1)
        ),
    tabelaData = Table.FromList(listaDatas, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
    colunaRenomeada = Table.RenameColumns(tabelaData,{{"Column1", "Data"}}),
    tipoAlteradoTabData = Table.TransformColumnTypes(colunaRenomeada,{{"Data", type date}}),
    consultaMescladas = Table.NestedJoin(tipoAlteradoTabData, {"Data"}, tipoAlteradoTabFeriados, {"Data"}, "Feriados", JoinKind.LeftOuter),
    tabDatasExpandida = Table.ExpandTableColumn(consultaMescladas, "Feriados", {"Feriado"}, {"Feriado"})
in
    tabDatasExpandida

No caso da última consulta, primeiro faço a requisição da função que traz os feriados para depois criar a tabela com as datas e na sequência faço a “mesclar” das tabelas.