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
- Kopieer
VerifyOrderTotalsnaar je werkmap en voer het uit op de vijf voorbeeldorders. - Maak handmatig één
Totalvan een order fout op het blad (typ een duidelijk verkeerd getal) en voer opnieuw uit — bevestig dat de afwijking wordt gemeld met de juisteOrder ID. - 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
lastRowen array-verwerking.
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
1. Kopiëren van VerifyOrderTotals
- Typ de
Subexact 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
Subopnieuw 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.
lastRowwordt elke keer opnieuw berekend wanneer deSubwordt uitgevoerd, en het array-lezen (ws.Range("A2:I" & lastRow).Value) groeit automatisch mee — dat is precies het punt dat wordt gedemonstreerd.
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
Bedankt voor je feedback!
Vraag AI
Vraag AI
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
- Kopieer
VerifyOrderTotalsnaar je werkmap en voer het uit op de vijf voorbeeldorders. - Maak handmatig één
Totalvan een order fout op het blad (typ een duidelijk verkeerd getal) en voer opnieuw uit — bevestig dat de afwijking wordt gemeld met de juisteOrder ID. - 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
lastRowen array-verwerking.
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
1. Kopiëren van VerifyOrderTotals
- Typ de
Subexact 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
Subopnieuw 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.
lastRowwordt elke keer opnieuw berekend wanneer deSubwordt uitgevoerd, en het array-lezen (ws.Range("A2:I" & lastRow).Value) groeit automatisch mee — dat is precies het punt dat wordt gedemonstreerd.
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
Bedankt voor je feedback!