Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Efficiënte Gegevensverwerking | Werken met Excel-gegevens
Excel VBA voor Bedrijfsautomatisering

Efficiënte Gegevensverwerking

Veeg om het menu te tonen

Tot nu toe is alles cel voor cel uitgevoerd — prima voor vijf bestellingen, maar pijnlijk traag voor vijftigduizend. De oplossing is om te stoppen met het cel-voor-cel benaderen van het werkblad en in plaats daarvan het hele blok in één keer in een array in het geheugen te plaatsen, daar te bewerken en vervolgens in één keer terug te schrijven.

Een bereik inlezen in een array

Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value    ' one read, not 45 individual reads

dataArr is nu een 2D-array in het geheugen: dataArr(1,1) is ORD1001, dataArr(1,4) is "Laptop Stand", enzovoort — VBA-arrays die uit een bereik worden gelezen zijn 1-gebaseerd, niet 0-gebaseerd, wat vaak verwarring veroorzaakt.

De array verwerken

Dit gebeurt met gewone lussen — maar nu loop je door het geheugen, wat duizenden keren sneller is dan door het werkblad:

Dim i As Long
Dim recalculated As Double
 
For i = 1 To UBound(dataArr, 1)
    recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
    If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
        Debug.Print "Mismatch on row " & i & ": sheet says " & dataArr(i, 8) & _
                    ", recalculated " & Format(recalculated, "0.00")
    End If
Next i

De array terugschrijven

Opnieuw één enkele bewerking:

ws.Range("A2:I6").Value = dataArr

Select en Activate vermijden

Opgenomen macro's maken hier veel gebruik van (Range("A1").Select gevolgd door Selection.Font.Bold = True), maar ze zijn overbodig en traag — elke .Select dwingt Excel om het scherm opnieuw te tekenen. Verwijs direct naar het bereik of object:

' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
 
' Prefer:
ws.Range("A1").Font.Bold = True

Prestatieoverwegingen

Deze worden belangrijk zodra je gegevens meer dan een paar honderd rijen bevatten:

Application.ScreenUpdating = False   ' stop redrawing while the macro runs
Application.Calculation = xlCalculationManual   ' pause recalculation
Application.EnableEvents = False     ' suppress other macros triggering mid-run
 
' ... your fast array-based code here ...
 
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

Herstel deze instellingen altijd aan het einde — en plaats het herstel in foutafhandeling zodat een crash tijdens uitvoering Excel niet achterlaat met uitgeschakelde schermverversing.

Voorbeeld: de Order Integrity Checker

Dit hoofdstuk werkt hier naartoe:

Option Explicit
 
Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String
 
    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
    Application.ScreenUpdating = False
 
    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""
 
    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i
 
    Application.ScreenUpdating = True
 
    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub

Voer dit uit op de voorbeeldtabel en het zou moeten melden dat alle vijf totalen kloppen — probeer de Total van ORD1002 op het blad te wijzigen naar een foutief getal en voer opnieuw uit om de waarschuwing te zien.

Opdracht

  1. Kopieer VerifyOrderTotals naar je werkmap en voer het uit op de vijf voorbeeldorders.
  2. Maak handmatig één Total van een order fout op het blad (typ een duidelijk verkeerd getal) en voer opnieuw uit — bevestig dat de afwijking wordt gemeld met de juiste Order ID.
  3. Voeg tien extra rijen verzonnen ordergegevens toe onder rij 6 en controleer of de macro nog steeds werkt zonder codewijzigingen — dit is het voordeel van lastRow en array-verwerking.
Helper
expand arrow

Optionele helper als je liever de tien extra rijen via code genereert in plaats van ze handmatig te typen:

Sub AddTestOrders()
    Dim ws As Worksheet
    Dim i As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Orders")
    r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    For i = 1 To 10
        ws.Cells(r, 1).Value = "ORD" & (1005 + i)
        ws.Cells(r, 2).Value = Date
        ws.Cells(r, 3).Value = "Test Customer " & i
        ws.Cells(r, 4).Value = "Sample Product"
        ws.Cells(r, 5).Value = i
        ws.Cells(r, 6).Value = 20 + i
        ws.Cells(r, 7).Value = 0.05
        ws.Cells(r, 8).Value = i * (20 + i) * (1 - 0.05)
        ws.Cells(r, 9).Value = "Pending"
        r = r + 1
    Next i
End Sub
Hint
expand arrow

1. Kopiëren van VerifyOrderTotals

  • Typ de Sub exact zoals weergegeven in sectie 3.5 in het module van je werkmap — nog geen aanpassingen nodig.
  • Voer deze één keer uit op de vijf oorspronkelijke rijen en controleer of je "Alle 5 ordertotalen kloppen." krijgt.

2. Opzettelijk één Totaal breken

  • Kies een willekeurige Totaal-cel van een order en typ een duidelijk foutief getal direct in het werkblad (niet via code).
  • Voer dezelfde Sub opnieuw uit — het foutbericht moet precies dat Order ID noemen, samen met wat er op het blad staat versus wat de macro heeft herberekend.
  • Herstel de cel daarna als je een schoon blad wilt voor de volgende stap.

3. Tien extra rijen toevoegen

  • Typ gewoon nieuwe ordergegevens direct in rijen 7–16 — dezelfde negen kolommen, willekeurige geloofwaardige waarden.
  • Raak de macro helemaal niet aan. lastRow wordt elke keer opnieuw berekend wanneer de Sub wordt uitgevoerd, en het array-lezen (ws.Range("A2:I" & lastRow).Value) groeit automatisch mee — dat is precies het punt dat wordt gedemonstreerd.
Oplossing
expand arrow
Option Explicit

Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String

    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Application.ScreenUpdating = False

    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""

    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i

    Application.ScreenUpdating = True

    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub
Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 5

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Efficiënte Gegevensverwerking

Tot nu toe is alles cel voor cel uitgevoerd — prima voor vijf bestellingen, maar pijnlijk traag voor vijftigduizend. De oplossing is om te stoppen met het cel-voor-cel benaderen van het werkblad en in plaats daarvan het hele blok in één keer in een array in het geheugen te plaatsen, daar te bewerken en vervolgens in één keer terug te schrijven.

Een bereik inlezen in een array

Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value    ' one read, not 45 individual reads

dataArr is nu een 2D-array in het geheugen: dataArr(1,1) is ORD1001, dataArr(1,4) is "Laptop Stand", enzovoort — VBA-arrays die uit een bereik worden gelezen zijn 1-gebaseerd, niet 0-gebaseerd, wat vaak verwarring veroorzaakt.

De array verwerken

Dit gebeurt met gewone lussen — maar nu loop je door het geheugen, wat duizenden keren sneller is dan door het werkblad:

Dim i As Long
Dim recalculated As Double
 
For i = 1 To UBound(dataArr, 1)
    recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
    If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
        Debug.Print "Mismatch on row " & i & ": sheet says " & dataArr(i, 8) & _
                    ", recalculated " & Format(recalculated, "0.00")
    End If
Next i

De array terugschrijven

Opnieuw één enkele bewerking:

ws.Range("A2:I6").Value = dataArr

Select en Activate vermijden

Opgenomen macro's maken hier veel gebruik van (Range("A1").Select gevolgd door Selection.Font.Bold = True), maar ze zijn overbodig en traag — elke .Select dwingt Excel om het scherm opnieuw te tekenen. Verwijs direct naar het bereik of object:

' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
 
' Prefer:
ws.Range("A1").Font.Bold = True

Prestatieoverwegingen

Deze worden belangrijk zodra je gegevens meer dan een paar honderd rijen bevatten:

Application.ScreenUpdating = False   ' stop redrawing while the macro runs
Application.Calculation = xlCalculationManual   ' pause recalculation
Application.EnableEvents = False     ' suppress other macros triggering mid-run
 
' ... your fast array-based code here ...
 
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

Herstel deze instellingen altijd aan het einde — en plaats het herstel in foutafhandeling zodat een crash tijdens uitvoering Excel niet achterlaat met uitgeschakelde schermverversing.

Voorbeeld: de Order Integrity Checker

Dit hoofdstuk werkt hier naartoe:

Option Explicit
 
Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String
 
    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
 
    Application.ScreenUpdating = False
 
    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""
 
    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i
 
    Application.ScreenUpdating = True
 
    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub

Voer dit uit op de voorbeeldtabel en het zou moeten melden dat alle vijf totalen kloppen — probeer de Total van ORD1002 op het blad te wijzigen naar een foutief getal en voer opnieuw uit om de waarschuwing te zien.

Opdracht

  1. Kopieer VerifyOrderTotals naar je werkmap en voer het uit op de vijf voorbeeldorders.
  2. Maak handmatig één Total van een order fout op het blad (typ een duidelijk verkeerd getal) en voer opnieuw uit — bevestig dat de afwijking wordt gemeld met de juiste Order ID.
  3. Voeg tien extra rijen verzonnen ordergegevens toe onder rij 6 en controleer of de macro nog steeds werkt zonder codewijzigingen — dit is het voordeel van lastRow en array-verwerking.
Helper
expand arrow

Optionele helper als je liever de tien extra rijen via code genereert in plaats van ze handmatig te typen:

Sub AddTestOrders()
    Dim ws As Worksheet
    Dim i As Long
    Dim r As Long

    Set ws = ThisWorkbook.Worksheets("Orders")
    r = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1

    For i = 1 To 10
        ws.Cells(r, 1).Value = "ORD" & (1005 + i)
        ws.Cells(r, 2).Value = Date
        ws.Cells(r, 3).Value = "Test Customer " & i
        ws.Cells(r, 4).Value = "Sample Product"
        ws.Cells(r, 5).Value = i
        ws.Cells(r, 6).Value = 20 + i
        ws.Cells(r, 7).Value = 0.05
        ws.Cells(r, 8).Value = i * (20 + i) * (1 - 0.05)
        ws.Cells(r, 9).Value = "Pending"
        r = r + 1
    Next i
End Sub
Hint
expand arrow

1. Kopiëren van VerifyOrderTotals

  • Typ de Sub exact zoals weergegeven in sectie 3.5 in het module van je werkmap — nog geen aanpassingen nodig.
  • Voer deze één keer uit op de vijf oorspronkelijke rijen en controleer of je "Alle 5 ordertotalen kloppen." krijgt.

2. Opzettelijk één Totaal breken

  • Kies een willekeurige Totaal-cel van een order en typ een duidelijk foutief getal direct in het werkblad (niet via code).
  • Voer dezelfde Sub opnieuw uit — het foutbericht moet precies dat Order ID noemen, samen met wat er op het blad staat versus wat de macro heeft herberekend.
  • Herstel de cel daarna als je een schoon blad wilt voor de volgende stap.

3. Tien extra rijen toevoegen

  • Typ gewoon nieuwe ordergegevens direct in rijen 7–16 — dezelfde negen kolommen, willekeurige geloofwaardige waarden.
  • Raak de macro helemaal niet aan. lastRow wordt elke keer opnieuw berekend wanneer de Sub wordt uitgevoerd, en het array-lezen (ws.Range("A2:I" & lastRow).Value) groeit automatisch mee — dat is precies het punt dat wordt gedemonstreerd.
Oplossing
expand arrow
Option Explicit

Sub VerifyOrderTotals()
    Dim ws As Worksheet
    Dim dataArr As Variant
    Dim lastRow As Long
    Dim i As Long
    Dim recalculated As Double
    Dim issues As String

    Set ws = ThisWorkbook.Worksheets("Orders")
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Application.ScreenUpdating = False

    dataArr = ws.Range("A2:I" & lastRow).Value
    issues = ""

    For i = 1 To UBound(dataArr, 1)
        recalculated = dataArr(i, 5) * dataArr(i, 6) * (1 - dataArr(i, 7))
        If Abs(recalculated - dataArr(i, 8)) > 0.01 Then
            issues = issues & dataArr(i, 1) & ": sheet=" & dataArr(i, 8) & _
                      ", expected=" & Format(recalculated, "0.00") & vbNewLine
        End If
    Next i

    Application.ScreenUpdating = True

    If issues = "" Then
        MsgBox "All " & UBound(dataArr, 1) & " order totals check out."
    Else
        MsgBox "Discrepancies found:" & vbNewLine & issues
    End If
End Sub
Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 3. Hoofdstuk 5
some-alt