Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Criando Tabelas Dinâmicas com VBA | Automatizando Tabelas e Relatórios
VBA do Excel para Automação Empresarial

Criando Tabelas Dinâmicas com VBA

Deslize para mostrar o menu

Uma Tabela Dinâmica resume uma tabela ao arrastar campos para Linhas, Colunas e Valores — e cada uma dessas ações de arrastar e soltar possui um equivalente direto em VBA, o que significa que todo um relatório de Tabela Dinâmica pode ser reconstruído do zero por uma macro sempre que novos dados chegarem.

Figura 4.3

Construindo uma Tabela Dinâmica

Sub BuildProfitPivot()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable
 
    Set wsData = ThisWorkbook.Worksheets("Reports")
    Set tbl = wsData.ListObjects("tblReports")
 
    ' start clean: remove an existing Pivot sheet if this has run before
    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("Pivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0
 
    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "Pivot"
 
    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)
 
    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptProfitByRegion")
 
    With pt
        .PivotFields("Region").Orientation = xlRowField
        .PivotFields("Month").Orientation = xlColumnField
        .AddDataField .PivotFields("Profit"), "Sum of Profit", xlSum
    End With
End Sub
Explicação linha por linha
expand arrow
  • On Error Resume Next combinado com a alternância de DisplayAlerts e .Delete é um padrão seguro de "excluir se existir": excluir uma planilha que não existe normalmente geraria um erro e interromperia a macro, mas On Error Resume Next instrui o VBA a continuar silenciosamente após esse erro específico; DisplayAlerts = False suprime o pop-up de confirmação do Excel "tem certeza de que deseja excluir esta planilha?";
  • O Error GoTo 0 logo em seguida reativa a exibição normal de erros — deixar On Error Resume Next ativo pelo restante do Sub faria com que erros posteriores e não relacionados fossem ignorados silenciosamente, o que é uma armadilha a ser evitada;
  • ThisWorkbook.PivotCaches.Create faz uma captura dos dados da Tabela — o PivotCache, não a própria PivotTable — que é o objeto a partir do qual toda PivotTable é realmente construída nos bastidores;
  • pc.CreatePivotTable transforma essa captura em uma PivotTable visível, posicionada a partir da célula A3 na nova planilha Pivot e recebe o nome ptProfitByRegion para que códigos posteriores (como RefreshTable, por exemplo) possam encontrá-la pelo nome;
  • PivotFields("Region").Orientation = xlRowField e a linha de Month logo abaixo são o equivalente direto em código de arrastar Region para a caixa de Linhas e Month para a caixa de Colunas na Lista de Campos;
  • AddDataField é o que preenche a área de Valores — o segundo argumento ("Sum of Profit") é apenas o rótulo exibido pelo Excel como título da coluna, e xlSum indica que os valores devem ser somados em vez de fazer média ou contagem.

Atualizando Relatórios

Depois que uma PivotTable existe, não é necessário reconstruí-la toda vez que chegam novos dados — basta atualizá-la, o que é mais rápido e preserva quaisquer ajustes manuais de layout feitos pelo usuário:

ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable

Essa única linha relê o PivotCache a partir do estado atual de tblReports e atualiza todos os números da PivotTable para corresponderem — mas mantém o layout exatamente como está, incluindo larguras de coluna, formatação de números ou organização de campos que o usuário tenha ajustado manualmente após a criação inicial da Pivot. Essa é a principal vantagem em relação a chamar BuildProfitPivot novamente: reconstruir do zero recriaria a planilha e apagaria qualquer ajuste manual feito.

Atualizando PivotCharts

Um PivotChart criado a partir de uma PivotTable atualiza seus dados automaticamente sempre que a PivotTable é atualizada — portanto, atualizar a tabela geralmente é tudo o que uma macro de relatório precisa fazer para manter um gráfico vinculado sempre atualizado:

Dim pt As PivotTable
Set pt = ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion")
pt.RefreshTable
' any PivotChart based on pt updates automatically — no extra code needed

Vale a pena comparar com os gráficos comuns abordados na próxima seção: um gráfico comum precisa de uma chamada explícita SetSourceData para apontar para os novos dados, enquanto um PivotChart está permanentemente vinculado à sua PivotTable e simplesmente acompanha automaticamente. Se um dashboard precisa de um gráfico que sempre reflita os números mais recentes da PivotTable com o mínimo de código, construí-lo como PivotChart em vez de gráfico independente geralmente é a melhor escolha.

Tarefa

  1. Execute BuildProfitPivot exatamente como mostrado e confirme que uma nova planilha "Pivot" aparece com Region nas linhas e Month nas colunas.
  2. Adicione manualmente uma nova linha de March em tblReports para uma sexta região fictícia, depois execute apenas a linha RefreshTable — confirme que a Pivot é atualizada sem ser reconstruída do zero.
  3. Modifique BuildProfitPivot para resumir Sales em vez de Profit, e troque Region e Month para que Month fique nas Linhas e Region nas Colunas.
Ajuda
expand arrow

Aqui está o código para adicionar uma sexta região como uma nova linha de março em tblReports, usando ListRows.Add em vez de digitá-la manualmente:

Sub AddSixthRegion()
    Dim tbl As ListObject
    Dim newRow As ListRow

    Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
    Set newRow = tbl.ListRows.Add

    newRow.Range(1, 1).Value = "March"        ' Month
    newRow.Range(1, 2).Value = "Southwest"    ' Region
    newRow.Range(1, 3).Value = 41500          ' Sales
    newRow.Range(1, 4).Value = 28200          ' Expenses
    newRow.Range(1, 5).Value = 13300          ' Profit
    newRow.Range(1, 6).Value = 39000          ' Target
End Sub

Execute isso uma vez e, em seguida, execute a Sub RefreshProfitPivot mencionada anteriormente — a tabela dinâmica agora deve exibir "Southwest" como uma nova linha junto com North, South, East, West e Central, sem que você tenha alterado a macro de criação da tabela dinâmica.

Dica
expand arrow

1. Executando BuildProfitPivot como está

  • Copie a Sub exatamente como está escrita no capítulo para o seu módulo e execute uma vez.
  • Verifique o Project Explorer ou as abas da planilha — uma nova planilha chamada literalmente "Pivot" deve aparecer, com Region listada nas linhas e Month distribuído nas colunas, somando Profit.

2. Adicionando uma sexta região e apenas atualizando

  • Digite a nova linha diretamente na planilha (não via código) — vá até o final de tblReports e adicione uma linha de março para uma região fictícia, por exemplo, "Southwest".
  • Não execute novamente o BuildProfitPivot — isso excluiria e reconstruiria toda a planilha Pivot do zero, o que vai contra o objetivo deste exercício.
  • Em vez disso, execute apenas a instrução de uma linha RefreshTable do capítulo — será necessário referenciar a PivotTable existente pelo nome, da mesma forma que o exemplo de atualização do capítulo.

3. Trocando campos e alterando o valor resumido

  • Três linhas dentro do bloco With pt precisam ser alteradas: qual campo é xlRowField, qual é xlColumnField e para qual campo o AddDataField aponta.
  • Dê a essa versão modificada um nome de Sub diferente e um TableName diferente — reutilizar os mesmos nomes do original pode causar erro ou sobrescrever silenciosamente a primeira tabela dinâmica.
  • O rótulo passado para o AddDataField (o segundo argumento, como "Sum of Profit") é apenas texto de exibição — atualize para corresponder ao que está sendo resumido agora.
Solução
expand arrow

Ponto 2 — após adicionar manualmente a linha da sexta região, execute apenas isto:

Sub RefreshProfitPivot()
    ThisWorkbook.Worksheets("Pivot").PivotTables("ptProfitByRegion").RefreshTable
End Sub

Ponto 3 — uma versão modificada separada:

Sub BuildSalesPivotByMonth()
    Dim wsData As Worksheet, wsPivot As Worksheet
    Dim tbl As ListObject
    Dim pc As PivotCache
    Dim pt As PivotTable

    Set wsData = ThisWorkbook.Worksheets("Reports")
    Set tbl = wsData.ListObjects("tblReports")

    On Error Resume Next
    Application.DisplayAlerts = False
    ThisWorkbook.Worksheets("SalesPivot").Delete
    Application.DisplayAlerts = True
    On Error GoTo 0

    Set wsPivot = ThisWorkbook.Worksheets.Add
    wsPivot.Name = "SalesPivot"

    Set pc = ThisWorkbook.PivotCaches.Create( _
        SourceType:=xlDatabase, SourceData:=tbl.Range)

    Set pt = pc.CreatePivotTable( _
        TableDestination:=wsPivot.Range("A3"), _
        TableName:="ptSalesByMonth")

    With pt
        .PivotFields("Month").Orientation = xlRowField
        .PivotFields("Region").Orientation = xlColumnField
        .AddDataField .PivotFields("Sales"), "Sum of Sales", xlSum
    End With
End Sub

Execute BuildSalesPivotByMonth e você deverá obter uma nova planilha "SalesPivot" com Month nas linhas, Region nas colunas e totais de Sales no corpo — o espelho do layout original.

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 4. Capítulo 3

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Seção 4. Capítulo 3
some-alt