Trabalhando com Tabelas do Excel
Deslize para mostrar o menu
Uma Tabela do Excel — chamada de ListObject no VBA — é um intervalo nomeado e autoexpansível com setas de filtro integradas, linhas em faixas e referências estruturadas de colunas. Se seus dados ainda não forem uma Tabela, selecione qualquer célula dentro deles e pressione Ctrl+T, ou deixe o VBA criar uma usando ListObjects.Add.
Referenciando um ListObject
Dim ws As Worksheet
Dim tbl As ListObject
Set ws = ThisWorkbook.Worksheets("Reports")
Set tbl = ws.ListObjects("tblReports")
Debug.Print tbl.Range.Address ' full table including header
Debug.Print tbl.DataBodyRange.Rows.Count ' data rows only, no header
Declarar tbl As ListObject (em vez de apenas As Range) é o que libera todos os recursos específicos de Tabela usados no restante desta seção — ListRows, ListColumns e a Total Row vêm do objeto estar tipado corretamente. Observe a distinção entre as duas linhas de Debug.Print:
tbl.Range cobre toda a Tabela, incluindo a linha de cabeçalho, enquanto tbl.DataBodyRange cobre apenas os dados abaixo dela.
Quase tudo o que você faz — adicionar uma linha, somar uma coluna, percorrer registros — deve usar DataBodyRange, justamente porque você não quer que o texto do cabeçalho seja tratado acidentalmente como uma linha de dados.
Adicionando Linhas
ListRows.Add adiciona uma nova linha diretamente abaixo da tabela — e, de forma crucial, quaisquer fórmulas de referência estruturada em outras colunas se estendem automaticamente para ela, o que é uma das maiores vantagens práticas de uma Tabela em relação a um intervalo comum.
Dim newRow As ListRow
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "April"
newRow.Range(1, 2).Value = "North"
newRow.Range(1, 3).Value = 45200
newRow.Range(1, 4).Value = 30750
newRow.Range(1, 5).Value = 14450
newRow.Range(1, 6).Value = 41000
tbl.ListRows.Add cria a linha em branco e a retorna como um objeto ListRow, por isso as próximas seis linhas escrevem em newRow em vez de tbl. newRow.Range(1, 1) significa "linha 1 desta nova linha específica, coluna 1" — a indexação reinicia em 1 para a nova linha, não conta a partir do topo da tabela inteira. Esse é um hábito significativamente melhor do que encontrar a última linha da planilha com End(xlUp) e escrever manualmente uma coluna além dela: ListRows.Add sempre insere corretamente dentro do limite da Tabela, então qualquer Linha de Total, fórmula de referência estruturada ou regra de formatação condicional aplicada à Tabela se estende automaticamente para incluí-la.
Atualizando Registros
Para atualizar uma linha existente, percorra o DataBodyRange e faça a correspondência em uma coluna-chave — aqui, atualizando a meta da região Central de fevereiro após uma revisão orçamentária:
Dim r As Long
For r = 1 To tbl.DataBodyRange.Rows.Count
If tbl.DataBodyRange.Cells(r, 1).Value = "February" And _
tbl.DataBodyRange.Cells(r, 2).Value = "Central" Then
tbl.DataBodyRange.Cells(r, 6).Value = 52000 ' revised Target
Exit For
End If
Next r
Esse é o mesmo padrão de cima para baixo, parando na primeira correspondência, da lógica condicional, aplicado a linhas reais em vez de valores fixos: o loop verifica Mês e Região juntos com And, e no momento em que ambos correspondem, ele atualiza a coluna Target e chama Exit For para não continuar verificando as linhas restantes desnecessariamente. Usar tbl.DataBodyRange.Cells(r, 1) em vez de uma referência Cells no nível da planilha mantém a numeração das linhas restrita aos dados da Tabela — linha 1 aqui significa a primeira linha de dados, independentemente de em qual linha física da planilha a Tabela começa.
Referenciando Colunas da Tabela
Referências estruturadas — ListColumns("Name") — são mais legíveis e mais resilientes do que contar colunas por número, especialmente quando uma tabela é editada e as colunas mudam de posição:
Dim profitCol As Range
Set profitCol = tbl.ListColumns("Profit").DataBodyRange
Debug.Print Application.WorksheetFunction.Sum(profitCol)
Debug.Print Application.WorksheetFunction.Average(profitCol)
ListColumns("Profit") encontra a coluna pelo texto do cabeçalho em vez de pela posição, então o código continua funcionando mesmo que Profit depois mude da coluna E para a coluna F — contar Cells(r, 5) manualmente quebraria silenciosamente nesse cenário. Application.WorksheetFunction é a ponte que permite ao VBA chamar funções comuns do Excel como SOMA e MÉDIA diretamente em um objeto Range, em vez de você escrever um loop manual com um total acumulado, o que resulta em menos código e menos chance de erro de contagem.
Tarefa
- Abra o arquivo
Section_4_Reports.xlsx, salve-o comoSection_4_Reports.xlsme confirme que os dados da planilha Reports estão em uma Tabela chamadatblReports(clique em qualquer célula dentro dela — a guia Design da Tabela deve aparecer). - Escreva uma macro que adicione uma linha de abril para cada uma das cinco regiões usando
ListRows.Add(cinco novas linhas no total, valores fictícios podem ser usados). - Escreva uma segunda macro utilizando
ListColumns("Sales").DataBodyRangeeWorksheetFunction.Sumpara imprimir o total de Sales de todas as linhas na Janela Imediata.
1. Abrindo e confirmando a Tabela
- Basta salvar novamente com Arquivo → Salvar Como, escolhendo "Pasta de Trabalho Habilitada para Macro do Excel (*.xlsm)" no menu de formatos — não é necessário código para esta parte.
- Clique em qualquer célula dentro dos dados de Reports e verifique se a faixa de opções exibe a guia Design da Tabela — isso confirma que é uma Tabela do Excel de verdade, não apenas um intervalo comum com aparência semelhante.
2. Adicionando cinco linhas de abril com ListRows.Add
- É necessário uma variável
ListObjectapontando paratblReports, depois chamar.ListRows.Adduma vez para cada região — cinco chamadas separadas ou um loop que execute cinco vezes. - Cada nova linha precisa de seis valores preenchidos: Month, Region, Sales, Expenses, Profit, Target — referencie-os pela posição (
newRow.Range(1, 1),(1, 2), etc.), da mesma forma que o exemplo prático do Capítulo 4. - Um array com os nomes das cinco regiões torna o loop mais limpo do que escrever cinco blocos quase idênticos manualmente.
3. Somando Sales com WorksheetFunction
ListColumns("Sales")localiza a coluna pelo texto do cabeçalho —.DataBodyRangerestringe apenas às células de dados, sem incluir o cabeçalho.Application.WorksheetFunction.Sum(...)aceita esse intervalo diretamente — não é necessário loop.Debug.Printenvia o resultado para a Janela Imediata (Ctrl+G) em vez de exibir um pop-up.
Option Explicit
Sub AddAprilRows()
Dim tbl As ListObject
Dim newRow As ListRow
Dim regions As Variant
Dim i As Long
Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
regions = Array("North", "South", "East", "West", "Central")
For i = 0 To 4
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "April"
newRow.Range(1, 2).Value = regions(i)
newRow.Range(1, 3).Value = 46000 + i * 500 ' Sales — invented
newRow.Range(1, 4).Value = 31000 + i * 300 ' Expenses — invented
newRow.Range(1, 5).Value = 15000 + i * 200 ' Profit — invented
newRow.Range(1, 6).Value = 41000 ' Target — invented
Next i
End Sub
Sub PrintTotalSales()
Dim tbl As ListObject
Dim salesCol As Range
Set tbl = ThisWorkbook.Worksheets("Reports").ListObjects("tblReports")
Set salesCol = tbl.ListColumns("Sales").DataBodyRange
Debug.Print "Total Sales: " & Application.WorksheetFunction.Sum(salesCol)
End Sub
Execute primeiro AddAprilRows e depois PrintTotalSales — o total já incluirá automaticamente as cinco novas linhas de abril, pois DataBodyRange sempre reflete o tamanho atual da Tabela.
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo