Tehokas tietojenkäsittely
Pyyhkäise näyttääksesi valikon
Kaikki tähän asti on toiminut solu kerrallaan — toimii viidelle tilaukselle, mutta on tuskallisen hidasta viidellekymmenelletuhannelle. Ratkaisu on lopettaa taulukon käsittely solu kerrallaan ja siirtää koko lohko muistiin taulukkoon, käsitellä sitä siellä ja kirjoittaa takaisin yhdellä kertaa.
Alueen lukeminen taulukkoon
Dim dataArr As Variant
dataArr = ws.Range("A2:I6").Value ' one read, not 45 individual reads
dataArr on nyt 2-ulotteinen taulukko muistissa: dataArr(1,1) on ORD1001, dataArr(1,4) on "Laptop Stand" ja niin edelleen — VBA-taulukot, jotka luetaan alueelta, ovat 1-pohjaisia, eivät 0-pohjaisia, mikä on yleinen kompastuskivi.
Taulukon käsittely
Tapahtuu tavallisilla silmukoilla — mutta nyt silmukoidaan muistissa, mikä on tuhansia kertoja nopeampaa kuin taulukossa:
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
Taulukon kirjoittaminen takaisin
Jälleen yksi operaatio:
ws.Range("A2:I6").Value = dataArr
Select- ja Activate-komentojen välttäminen
Tallennetut makrot käyttävät näitä usein (Range("A1").Select ja sitten Selection.Font.Bold = True), mutta ne ovat tarpeettomia ja hitaita — jokainen .Select pakottaa Excelin piirtämään näytön uudelleen. Viittaa suoraan alueeseen tai objektiin:
' Avoid:
ws.Range("A1").Select
Selection.Font.Bold = True
' Prefer:
ws.Range("A1").Font.Bold = True
Suorituskykytekijät
Näillä on merkitystä, kun dataa on satoja rivejä tai enemmän:
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
Palauta nämä asetukset aina lopuksi — ja käytä virheenkäsittelyä, jotta mahdollinen virhe ei jätä Exceliä näyttöpäivitys pois päältä -tilaan.
Työstetty esimerkki: Tilausten tarkistus
Tämä luku on johtanut tähän:
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
Suorita tämä esimerkkitaululle ja kaikkien viiden tilauksen summien pitäisi olla oikein — muuta ORD1002:n Total-arvo taulukossa vääräksi ja suorita uudelleen nähdäksesi hälytyksen.
Tehtävä
- Kopioi
VerifyOrderTotalstyökirjaasi ja suorita se viidelle esimerkkitilaukselle. - Riko yhden tilauksen
Total-arvo manuaalisesti taulukossa (kirjoita selvästi väärä luku) ja suorita makro uudelleen — varmista, että poikkeama raportoidaan oikeallaOrder ID:llä. - Lisää kymmenen uutta keksittyä tilausta rivin 6 alapuolelle ja varmista, että makro toimii edelleen ilman koodimuutoksia — tämä osoittaa
lastRow- ja taulukonkäsittelyn hyödyt.
Valinnainen apuohjelma, jos haluat mieluummin luoda kymmenen lisäriviä koodilla käsin kirjoittamisen sijaan:
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. VerifyOrderTotals-makron kopiointi
- Kirjoita
Subtäsmälleen kuten kohdassa 3.5 omaan työkirjaasi — muutoksia ei tarvita vielä. - Suorita makro kerran alkuperäisille viidelle riville ja varmista, että saat ilmoituksen "All 5 order totals check out."
2. Yhden Total-arvon tahallinen rikkominen
- Valitse minkä tahansa tilauksen Total-solu ja kirjoita siihen selvästi väärä arvo suoraan taulukkoon (ei koodin kautta).
- Suorita sama
Subuudelleen — virheilmoituksen pitäisi nimetä kyseinen Order ID sekä näyttää taulukon arvo ja makron laskema arvo. - Korjaa solu takaisin, jos haluat puhtaan taulukon seuraavaa vaihetta varten.
3. Kymmenen uuden rivin lisääminen
- Kirjoita uudet tilausrivit suoraan riveille 7–16 — samat yhdeksän saraketta, mitkä tahansa uskottavat arvot.
- Älä koske makroon lainkaan.
lastRowlaskee itsensä uudelleen joka kerta, kunSubsuoritetaan, ja taulukon luku (ws.Range("A2:I" & lastRow).Value) kasvaa automaattisesti — tämä on koko demonstroinnin ydin.
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
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme