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.
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
- On Error Resume Next combinado com a alternância de
DisplayAlertse.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 = Falsesuprime o pop-up de confirmação do Excel "tem certeza de que deseja excluir esta planilha?"; - O
Error GoTo 0logo em seguida reativa a exibição normal de erros — deixarOn Error Resume Nextativo pelo restante doSubfaria com que erros posteriores e não relacionados fossem ignorados silenciosamente, o que é uma armadilha a ser evitada; ThisWorkbook.PivotCaches.Createfaz 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.CreatePivotTabletransforma 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 = xlRowFielde 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
- Execute
BuildProfitPivotexatamente como mostrado e confirme que uma nova planilha "Pivot" aparece com Region nas linhas e Month nas colunas. - Adicione manualmente uma nova linha de March em
tblReportspara uma sexta região fictícia, depois execute apenas a linha RefreshTable — confirme que a Pivot é atualizada sem ser reconstruída do zero. - Modifique
BuildProfitPivotpara resumir Sales em vez de Profit, e troque Region e Month para que Month fique nas Linhas e Region nas Colunas.
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.
1. Executando BuildProfitPivot como está
- Copie a
Subexatamente 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
tblReportse 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
RefreshTabledo 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 ptprecisam ser alteradas: qual campo éxlRowField, qual éxlColumnFielde para qual campo oAddDataFieldaponta. - Dê a essa versão modificada um nome de
Subdiferente e umTableNamediferente — 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.
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.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo