Werken met Excel-tabellen
Veeg om het menu te tonen
Een Excel-tabel — wat VBA een ListObject noemt — is een benoemd, zichzelf uitbreidend bereik met ingebouwde filterpijlen, afwisselend gekleurde rijen en gestructureerde kolomverwijzingen. Als je gegevens nog geen tabel zijn, selecteer dan een willekeurige cel erin en druk op Ctrl+T, of laat VBA er een maken met ListObjects.Add.
Een ListObject refereren
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
Het declareren van tbl As ListObject (in plaats van alleen As Range) ontsluit alle tabelspecifieke functies die in de rest van deze sectie worden gebruikt — ListRows, ListColumns en de Total Row zijn allemaal beschikbaar doordat het object correct getypt is. Let op het verschil tussen de twee Debug.Print-regels:
tbl.Range omvat de hele tabel inclusief de koprij, terwijl tbl.DataBodyRange alleen de gegevens eronder bevat.
Bijna alles wat je doet — een rij toevoegen, een kolom optellen, door records lopen — zou gebruik moeten maken van DataBodyRange, juist omdat je niet wilt dat de koptekst per ongeluk als gegevensrij wordt behandeld.
Rijen toevoegen
ListRows.Add voegt een nieuwe rij direct onder de tabel toe — en belangrijker nog, alle gestructureerde-verwijzingsformules in andere kolommen worden automatisch uitgebreid naar deze rij, wat een van de grootste praktische voordelen is van een tabel ten opzichte van een gewoon bereik.
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 maakt de lege rij aan en geeft deze terug als een ListRow-object, waardoor de volgende zes regels naar newRow schrijven in plaats van naar tbl. newRow.Range(1, 1) betekent "rij 1 van deze specifieke nieuwe rij, kolom 1" — de indexering begint opnieuw bij 1 voor de nieuwe rij zelf, het telt dus niet vanaf de bovenkant van de hele tabel. Dit is een duidelijk betere gewoonte dan handmatig de laatste rij van het werkblad opzoeken met End(xlUp) en er een kolom naast schrijven: ListRows.Add plaatst de rij altijd correct binnen de grenzen van de tabel, zodat elke Total Row, gestructureerde-verwijzingsformule of voorwaardelijke opmaakregel die op de tabel is toegepast automatisch wordt uitgebreid.
Records bijwerken
Om een bestaande rij bij te werken, loop je door DataBodyRange en zoek je op een sleutelkolom — hier wordt het Target-bedrag van de regio Central in februari bijgewerkt na een budgetherziening:
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
Dit is hetzelfde van boven naar beneden, stoppen bij de eerste match-patroon als bij voorwaardelijke logica, toegepast op echte rijen in plaats van hardgecodeerde waarden: de lus controleert Maand en Regio samen met And, en zodra beide overeenkomen, wordt de Target-kolom bijgewerkt en wordt Exit For aangeroepen zodat de resterende rijen niet onnodig worden doorzocht. Door tbl.DataBodyRange.Cells(r, 1) te gebruiken in plaats van een werkbladniveau Cells-verwijzing blijft de rijnummering beperkt tot de gegevens van de tabel — rij 1 betekent hier de eerste gegevensrij, ongeacht op welke fysieke werkbladrij de tabel begint.
Tabelkolommen refereren
Gestructureerde verwijzingen — ListColumns("Name") — zijn leesbaarder en robuuster dan kolommen tellen op nummer, vooral als een tabel wordt bewerkt en kolommen verschuiven:
Dim profitCol As Range
Set profitCol = tbl.ListColumns("Profit").DataBodyRange
Debug.Print Application.WorksheetFunction.Sum(profitCol)
Debug.Print Application.WorksheetFunction.Average(profitCol)
ListColumns("Profit") zoekt de kolom op basis van de koptekst in plaats van op positie, zodat de code blijft werken, zelfs als Profit later van kolom E naar kolom F verschuift — handmatig Cells(r, 5) tellen zou in dat geval ongemerkt fout gaan. Application.WorksheetFunction is de brug waarmee VBA gewone Excel-functies zoals SUM en AVERAGE direct op een Range-object kan toepassen, in plaats van dat je een handmatige lus met een lopend totaal moet schrijven, wat zowel minder code is als minder kans op een telfout.
Taak
- Open
Section_4_Reports.xlsx, sla deze op alsSection_4_Reports.xlsmen controleer of de gegevens op het tabblad Reports een tabel zijn met de naamtblReports(klik op een willekeurige cel in de tabel — het tabblad Tabelontwerp zou moeten verschijnen). - Schrijf een macro die voor elk van de vijf regio's een rij voor april toevoegt met
ListRows.Add(in totaal vijf nieuwe rijen, verzonnen cijfers zijn prima). - Schrijf een tweede macro die met
ListColumns("Sales").DataBodyRangeenWorksheetFunction.Sumde totale Sales over alle rijen afdrukt in het Direct Venster.
1. Openen en bevestigen van de tabel
- Sla het bestand opnieuw op via Bestand → Opslaan als en kies "Excel-werkmap met macro's (*.xlsm)" in het formaat dropdownmenu — voor dit deel is geen code nodig.
- Klik op een willekeurige cel in de Reports-gegevens en controleer of het lint het tabblad Tabelontwerp toont — dat bevestigt dat het een echte Excel-tabel is en geen gewoon bereik dat er alleen zo uitziet.
2. Vijf april-rijen toevoegen met ListRows.Add
- Je hebt een
ListObject-variabele nodig die verwijst naartblReports, en roept vervolgens.ListRows.Addaan voor elke regio — vijf afzonderlijke aanroepen, of één lus die vijf keer draait. - Elke nieuwe rij heeft zes waarden nodig: Month, Region, Sales, Expenses, Profit, Target — verwijs naar deze via hun positie (
newRow.Range(1, 1),(1, 2), enz.), op dezelfde manier als het uitgewerkte voorbeeld in hoofdstuk 4. - Een array met de vijf regiobenamingen maakt de lusversie overzichtelijker dan vijf bijna identieke blokken handmatig schrijven.
3. Sales optellen met WorksheetFunction
ListColumns("Sales")zoekt de kolom op basis van de koptekst —.DataBodyRangebeperkt dit tot alleen de gegevenscellen, zonder koptekst.Application.WorksheetFunction.Sum(...)neemt dat bereik direct — er is geen lus nodig.Debug.Printstuurt het resultaat naar het Direct Venster (Ctrl+G) in plaats van een 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
Voer eerst AddAprilRows uit en daarna PrintTotalSales — het totaal moet automatisch de vijf nieuwe april-rijen bevatten, omdat DataBodyRange altijd de huidige grootte van de tabel weergeeft.
Bedankt voor je feedback!
Vraag AI
Vraag AI
Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.
Werken met Excel-tabellen
Een Excel-tabel — wat VBA een ListObject noemt — is een benoemd, zichzelf uitbreidend bereik met ingebouwde filterpijlen, afwisselend gekleurde rijen en gestructureerde kolomverwijzingen. Als je gegevens nog geen tabel zijn, selecteer dan een willekeurige cel erin en druk op Ctrl+T, of laat VBA er een maken met ListObjects.Add.
Een ListObject refereren
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
Het declareren van tbl As ListObject (in plaats van alleen As Range) ontsluit alle tabelspecifieke functies die in de rest van deze sectie worden gebruikt — ListRows, ListColumns en de Total Row zijn allemaal beschikbaar doordat het object correct getypt is. Let op het verschil tussen de twee Debug.Print-regels:
tbl.Range omvat de hele tabel inclusief de koprij, terwijl tbl.DataBodyRange alleen de gegevens eronder bevat.
Bijna alles wat je doet — een rij toevoegen, een kolom optellen, door records lopen — zou gebruik moeten maken van DataBodyRange, juist omdat je niet wilt dat de koptekst per ongeluk als gegevensrij wordt behandeld.
Rijen toevoegen
ListRows.Add voegt een nieuwe rij direct onder de tabel toe — en belangrijker nog, alle gestructureerde-verwijzingsformules in andere kolommen worden automatisch uitgebreid naar deze rij, wat een van de grootste praktische voordelen is van een tabel ten opzichte van een gewoon bereik.
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 maakt de lege rij aan en geeft deze terug als een ListRow-object, waardoor de volgende zes regels naar newRow schrijven in plaats van naar tbl. newRow.Range(1, 1) betekent "rij 1 van deze specifieke nieuwe rij, kolom 1" — de indexering begint opnieuw bij 1 voor de nieuwe rij zelf, het telt dus niet vanaf de bovenkant van de hele tabel. Dit is een duidelijk betere gewoonte dan handmatig de laatste rij van het werkblad opzoeken met End(xlUp) en er een kolom naast schrijven: ListRows.Add plaatst de rij altijd correct binnen de grenzen van de tabel, zodat elke Total Row, gestructureerde-verwijzingsformule of voorwaardelijke opmaakregel die op de tabel is toegepast automatisch wordt uitgebreid.
Records bijwerken
Om een bestaande rij bij te werken, loop je door DataBodyRange en zoek je op een sleutelkolom — hier wordt het Target-bedrag van de regio Central in februari bijgewerkt na een budgetherziening:
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
Dit is hetzelfde van boven naar beneden, stoppen bij de eerste match-patroon als bij voorwaardelijke logica, toegepast op echte rijen in plaats van hardgecodeerde waarden: de lus controleert Maand en Regio samen met And, en zodra beide overeenkomen, wordt de Target-kolom bijgewerkt en wordt Exit For aangeroepen zodat de resterende rijen niet onnodig worden doorzocht. Door tbl.DataBodyRange.Cells(r, 1) te gebruiken in plaats van een werkbladniveau Cells-verwijzing blijft de rijnummering beperkt tot de gegevens van de tabel — rij 1 betekent hier de eerste gegevensrij, ongeacht op welke fysieke werkbladrij de tabel begint.
Tabelkolommen refereren
Gestructureerde verwijzingen — ListColumns("Name") — zijn leesbaarder en robuuster dan kolommen tellen op nummer, vooral als een tabel wordt bewerkt en kolommen verschuiven:
Dim profitCol As Range
Set profitCol = tbl.ListColumns("Profit").DataBodyRange
Debug.Print Application.WorksheetFunction.Sum(profitCol)
Debug.Print Application.WorksheetFunction.Average(profitCol)
ListColumns("Profit") zoekt de kolom op basis van de koptekst in plaats van op positie, zodat de code blijft werken, zelfs als Profit later van kolom E naar kolom F verschuift — handmatig Cells(r, 5) tellen zou in dat geval ongemerkt fout gaan. Application.WorksheetFunction is de brug waarmee VBA gewone Excel-functies zoals SUM en AVERAGE direct op een Range-object kan toepassen, in plaats van dat je een handmatige lus met een lopend totaal moet schrijven, wat zowel minder code is als minder kans op een telfout.
Taak
- Open
Section_4_Reports.xlsx, sla deze op alsSection_4_Reports.xlsmen controleer of de gegevens op het tabblad Reports een tabel zijn met de naamtblReports(klik op een willekeurige cel in de tabel — het tabblad Tabelontwerp zou moeten verschijnen). - Schrijf een macro die voor elk van de vijf regio's een rij voor april toevoegt met
ListRows.Add(in totaal vijf nieuwe rijen, verzonnen cijfers zijn prima). - Schrijf een tweede macro die met
ListColumns("Sales").DataBodyRangeenWorksheetFunction.Sumde totale Sales over alle rijen afdrukt in het Direct Venster.
1. Openen en bevestigen van de tabel
- Sla het bestand opnieuw op via Bestand → Opslaan als en kies "Excel-werkmap met macro's (*.xlsm)" in het formaat dropdownmenu — voor dit deel is geen code nodig.
- Klik op een willekeurige cel in de Reports-gegevens en controleer of het lint het tabblad Tabelontwerp toont — dat bevestigt dat het een echte Excel-tabel is en geen gewoon bereik dat er alleen zo uitziet.
2. Vijf april-rijen toevoegen met ListRows.Add
- Je hebt een
ListObject-variabele nodig die verwijst naartblReports, en roept vervolgens.ListRows.Addaan voor elke regio — vijf afzonderlijke aanroepen, of één lus die vijf keer draait. - Elke nieuwe rij heeft zes waarden nodig: Month, Region, Sales, Expenses, Profit, Target — verwijs naar deze via hun positie (
newRow.Range(1, 1),(1, 2), enz.), op dezelfde manier als het uitgewerkte voorbeeld in hoofdstuk 4. - Een array met de vijf regiobenamingen maakt de lusversie overzichtelijker dan vijf bijna identieke blokken handmatig schrijven.
3. Sales optellen met WorksheetFunction
ListColumns("Sales")zoekt de kolom op basis van de koptekst —.DataBodyRangebeperkt dit tot alleen de gegevenscellen, zonder koptekst.Application.WorksheetFunction.Sum(...)neemt dat bereik direct — er is geen lus nodig.Debug.Printstuurt het resultaat naar het Direct Venster (Ctrl+G) in plaats van een 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
Voer eerst AddAprilRows uit en daarna PrintTotalSales — het totaal moet automatisch de vijf nieuwe april-rijen bevatten, omdat DataBodyRange altijd de huidige grootte van de tabel weergeeft.
Bedankt voor je feedback!