Effektiv Databehandling
Sveip for å vise menyen
Alt hittil har jobbet med én celle om gangen — greit for fem ordre, men smertefullt tregt for femti tusen. Løsningen er å slutte å behandle regnearket celle for celle, og i stedet flytte hele blokken inn i et array i minnet, jobbe med det der, og skrive det tilbake i én operasjon.
Lese et område inn i et array
Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value ' one read, not 45 individual reads
dataArr er nå et 2D-array i minnet: dataArr(1,1) er ORD1001, dataArr(1,4) er "Laptop Stand", og så videre — VBA-arrays som leses fra et område er 1-baserte, ikke 0-baserte, noe som ofte fører til feil.
Behandle arrayet
Dette gjøres med vanlige løkker — men nå løkker du over minnet, som er tusenvis av ganger raskere enn å løkke over regnearket:
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
Skrive arrayet tilbake
Igjen én enkelt operasjon:
ws.Range("A2:I6").Value = dataArr
Unngå Select og Activate
Opptaksmakroer bruker ofte disse (Range("A1").Select deretter Selection.Font.Bold = True), men de er unødvendige og trege — hver .Select tvinger Excel til å tegne skjermen på nytt. Referer direkte til området eller objektet i stedet:
' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
' Prefer:
ws.Range("A1").Font.Bold = True
Ytelseshensyn
Disse blir viktige når datamengden overstiger noen hundre rader:
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
Gjenopprett alltid disse innstillingene til slutt — og pakk gjenopprettingen inn i feilhåndtering slik at et krasj underveis ikke etterlater Excel med skjermoppdatering avslått.
Gjennomgangseksempel: Order Integrity Checker
Dette kapittelet har bygget opp mot dette:
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
Kjør dette mot eksempel-tabellen og det skal rapportere at alle fem summer er korrekte — prøv å endre Total for ORD1002 på arket til noe feil og kjør på nytt for å se varslingen.
Oppgave
- Kopier
VerifyOrderTotalsinn i arbeidsboken din og kjør den mot de fem eksempelordrene. - Endre manuelt én ordres
Totalpå arket (skriv inn et åpenbart feil tall) og kjør på nytt — bekreft at avviket rapporteres med riktigOrder ID. - Legg til ti nye rader med fiktive ordredata under rad 6, og bekreft at makroen fortsatt fungerer uten endringer i koden — dette viser fordelen med
lastRowog array-behandling.
Valgfri hjelper hvis du heller vil generere de ti ekstra radene i kode i stedet for å skrive dem inn manuelt:
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. Kopiere VerifyOrderTotals
- Skriv inn
Sub-rutinen nøyaktig som vist i seksjon 3.5 i modularket ditt — ingen endringer nødvendig ennå. - Kjør den én gang på de fem opprinnelige radene og bekreft at du får "All 5 order totals check out."
2. Med vilje ødelegge én Total
- Velg en hvilken som helst ordres Total-celle og skriv inn et åpenbart feil tall direkte i regnearket (ikke via kode).
- Kjør samme
Subpå nytt — feilmeldingen skal vise nøyaktig den Order ID-en, sammen med hva arket viser og hva makroen har rekalkulert. - Rett opp cellen etterpå hvis du ønsker et rent ark til neste steg.
3. Legge til ti nye rader
- Skriv inn nye ordredata direkte i radene 7–16 — samme ni kolonner, bruk troverdige verdier.
- Ikke rør makroen i det hele tatt.
lastRowberegnes på nytt hver gangSub-rutinen kjøres, og array-lesingen (ws.Range("A2:I" & lastRow).Value) vokser automatisk — det er hele poenget som demonstreres.
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
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
Effektiv Databehandling
Alt hittil har jobbet med én celle om gangen — greit for fem ordre, men smertefullt tregt for femti tusen. Løsningen er å slutte å behandle regnearket celle for celle, og i stedet flytte hele blokken inn i et array i minnet, jobbe med det der, og skrive det tilbake i én operasjon.
Lese et område inn i et array
Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value ' one read, not 45 individual reads
dataArr er nå et 2D-array i minnet: dataArr(1,1) er ORD1001, dataArr(1,4) er "Laptop Stand", og så videre — VBA-arrays som leses fra et område er 1-baserte, ikke 0-baserte, noe som ofte fører til feil.
Behandle arrayet
Dette gjøres med vanlige løkker — men nå løkker du over minnet, som er tusenvis av ganger raskere enn å løkke over regnearket:
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
Skrive arrayet tilbake
Igjen én enkelt operasjon:
ws.Range("A2:I6").Value = dataArr
Unngå Select og Activate
Opptaksmakroer bruker ofte disse (Range("A1").Select deretter Selection.Font.Bold = True), men de er unødvendige og trege — hver .Select tvinger Excel til å tegne skjermen på nytt. Referer direkte til området eller objektet i stedet:
' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
' Prefer:
ws.Range("A1").Font.Bold = True
Ytelseshensyn
Disse blir viktige når datamengden overstiger noen hundre rader:
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
Gjenopprett alltid disse innstillingene til slutt — og pakk gjenopprettingen inn i feilhåndtering slik at et krasj underveis ikke etterlater Excel med skjermoppdatering avslått.
Gjennomgangseksempel: Order Integrity Checker
Dette kapittelet har bygget opp mot dette:
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
Kjør dette mot eksempel-tabellen og det skal rapportere at alle fem summer er korrekte — prøv å endre Total for ORD1002 på arket til noe feil og kjør på nytt for å se varslingen.
Oppgave
- Kopier
VerifyOrderTotalsinn i arbeidsboken din og kjør den mot de fem eksempelordrene. - Endre manuelt én ordres
Totalpå arket (skriv inn et åpenbart feil tall) og kjør på nytt — bekreft at avviket rapporteres med riktigOrder ID. - Legg til ti nye rader med fiktive ordredata under rad 6, og bekreft at makroen fortsatt fungerer uten endringer i koden — dette viser fordelen med
lastRowog array-behandling.
Valgfri hjelper hvis du heller vil generere de ti ekstra radene i kode i stedet for å skrive dem inn manuelt:
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. Kopiere VerifyOrderTotals
- Skriv inn
Sub-rutinen nøyaktig som vist i seksjon 3.5 i modularket ditt — ingen endringer nødvendig ennå. - Kjør den én gang på de fem opprinnelige radene og bekreft at du får "All 5 order totals check out."
2. Med vilje ødelegge én Total
- Velg en hvilken som helst ordres Total-celle og skriv inn et åpenbart feil tall direkte i regnearket (ikke via kode).
- Kjør samme
Subpå nytt — feilmeldingen skal vise nøyaktig den Order ID-en, sammen med hva arket viser og hva makroen har rekalkulert. - Rett opp cellen etterpå hvis du ønsker et rent ark til neste steg.
3. Legge til ti nye rader
- Skriv inn nye ordredata direkte i radene 7–16 — samme ni kolonner, bruk troverdige verdier.
- Ikke rør makroen i det hele tatt.
lastRowberegnes på nytt hver gangSub-rutinen kjøres, og array-lesingen (ws.Range("A2:I" & lastRow).Value) vokser automatisk — det er hele poenget som demonstreres.
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
Takk for tilbakemeldingene dine!