Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Effektiv Databehandling | Arbejde med Excel-data
Excel VBA til Forretningsautomatisering

Effektiv Databehandling

Stryg for at vise menuen

Alt hidtil har arbejdet én celle ad gangen — fint til fem ordrer, men ekstremt langsomt til halvtreds tusinde. Løsningen er at undgå at arbejde celle for celle på regnearket og i stedet flytte hele blokken ind i et array i hukommelsen, bearbejde det der, og skrive det tilbage på én gang.

Læsning af et område ind i et array

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

dataArr er nu et 2D-array i hukommelsen: dataArr(1,1) er ORD1001, dataArr(1,4) er "Laptop Stand", og så videre — VBA-arrays læst fra et område er 1-baserede, ikke 0-baserede, hvilket ofte forvirrer.

Bearbejdning af arrayet

Foregår med almindelige løkker — men nu looper du over hukommelsen, hvilket er tusindvis af gange hurtigere end at loope 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

Skrivning af arrayet tilbage

Igen en enkelt operation:

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

Undgå Select og Activate

Optagede makroer bruger ofte disse (Range("A1").Select efterfulgt af Selection.Font.Bold = True), men de er unødvendige og langsomme — hver .Select tvinger Excel til at opdatere skærmen. Henvis i stedet direkte til området eller objektet:

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

Ydelsesmæssige overvejelser

Disse bliver vigtige, når dine data overstiger et par hundrede rækker:

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

Gendan altid disse indstillinger til sidst — og indpak gendannelsen i fejlhåndtering, så et nedbrud undervejs ikke efterlader Excel med skærmopdatering slået fra.

Gennemarbejdet eksempel: Order Integrity Checker

Dette kapitel har bygget op til 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

Kør dette mod eksempeltabellen, og det bør rapportere, at alle fem totaler er korrekte — prøv at ændre ORD1002's Total på arket til noget forkert og kør igen for at se advarslen.

Opgave

  1. Kopiér VerifyOrderTotals ind i din projektmappe og kør den på de fem eksempelordrer.
  2. Ødelæg manuelt én ordres Total på arket (indtast et åbenlyst forkert tal) og kør igen — bekræft at uoverensstemmelsen rapporteres med det korrekte Order ID.
  3. Tilføj ti ekstra rækker med fiktive ordredata under række 6, og bekræft at makroen stadig fungerer uden ændringer i koden — dette er fordelen ved lastRow og array-baseret behandling.
Hjælper
expand arrow

Valgfri hjælper, hvis du hellere vil generere de ti ekstra rækker i koden i stedet for at indtaste dem 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
Tip
expand arrow

1. Kopiering af VerifyOrderTotals

  • Indtast Sub-proceduren nøjagtigt som vist i afsnit 3.5 i din projektmappes modul — ingen ændringer nødvendige endnu.
  • Kør den én gang på de fem oprindelige rækker og bekræft, at du får "All 5 order totals check out."

2. Bevidst ødelæggelse af én Total

  • Vælg en vilkårlig ordres Total-celle og indtast et åbenlyst forkert tal direkte i regnearket (ikke via kode).
  • Kør den samme Sub igen — fejlmeddelelsen bør nævne det præcise Order ID samt hvad arket viser i forhold til, hvad makroen har genberegnet.
  • Ret cellen tilbage bagefter, hvis du ønsker et rent ark til næste trin.

3. Tilføjelse af ti ekstra rækker

  • Indtast blot nye ordredata direkte i rækkerne 7–16 — samme ni kolonner, alle troværdige værdier.
  • Rør ikke makroen overhovedet. lastRow genberegnes automatisk hver gang Sub-proceduren køres, og array-læsningen (ws.Range("A2:I" & lastRow).Value) vokser automatisk — det er hele pointen, der demonstreres.
Løsning
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
Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 3. Kapitel 5

Spørg AI

expand

Spørg AI

ChatGPT

Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat

Sektion 3. Kapitel 5
some-alt