När dina Excel-makron blir allt mer robusta och komplexa kan du upptäcka att de förlorar prestanda. När man diskuterar makron är ordet prestanda vanligtvis synonymt med hastighet . Hastighet är hur snabbt dina VBA-procedurer utför sina avsedda uppgifter. Följande är tio sätt att hjälpa till att hålla dina Excel-makron igång på sin optimala prestandanivå.
Stoppa arkberäkningar
Visste du att varje gång en cell som påverkar en formel i ditt kalkylblad ändras eller manipuleras, räknar Excel om hela kalkylbladet? I kalkylblad som har en stor mängd formler kan detta beteende drastiskt sakta ner dina makron.
Du kan använda egenskapen Application.Calculation för att tala om för Excel att byta till manuellt beräkningsläge. När en arbetsbok är i manuellt beräkningsläge, kommer arbetsboken inte att räknas om förrän du uttryckligen utlöser en beräkning genom att trycka på F9-tangenten.
Placera Excel i manuellt beräkningsläge, kör din kod och växla sedan tillbaka till automatiskt beräkningsläge.
Sub Macro1()
Application.Calculation = xlCalculationManual
'Placera din makrokod här
Application.Calculation = xlCalculationAutomatic
Avsluta Sub
Att ställa tillbaka beräkningsläget till xlCalculationAutomatic kommer automatiskt att utlösa en omräkning av kalkylbladet, så det finns ingen anledning att trycka på F9-tangenten efter att ditt makro körs.
Inaktiverar uppdatering av arkskärm
Du kanske märker att när dina makron körs, flimrar din skärm en hel del. Detta flimrande är att Excel försöker rita om skärmen för att visa det aktuella tillståndet för kalkylbladet. Tyvärr tar det upp minnesresurser varje gång Excel ritar om skärmen.
Du kan använda egenskapen Application.ScreenUpdating för att inaktivera skärmuppdateringar tills ditt makro har slutförts. Att inaktivera skärmuppdatering sparar tid och resurser, vilket gör att ditt makro kan köras lite snabbare. När din makrokod har körts färdigt kan du aktivera skärmuppdateringen igen.
Sub Macro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falskt
'Placera din makrokod här
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Avsluta Sub
När du har ställt in egenskapen ScreenUpdating tillbaka till True, kommer Excel automatiskt att utlösa en omritning av skärmen.
Stänger av uppdateringar av statusfältet
Excel-statusfältet, som visas längst ner i Excel-fönstret, visar normalt förloppet för vissa åtgärder i Excel. Om ditt makro arbetar med mycket data kommer statusfältet att ta upp vissa resurser.
Det är viktigt att notera att inaktivering av skärmuppdatering är separat från att stänga av statusfältsvisningen. Statusfältet kommer att fortsätta att uppdateras även om du inaktiverar skärmuppdatering. Du kan använda egenskapen Application.DisplayStatusBar för att tillfälligt inaktivera alla statusfältsuppdateringar, vilket ytterligare förbättrar prestandan för ditt makro:
Sub Macro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falskt
Application.DisplayStatusBar = Falskt
'Placera din makrokod här
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
Avsluta Sub
Be Excel att ignorera händelser
Du kan implementera makron som händelseprocedurer och tala om för Excel att köra viss kod när ett kalkylblad eller arbetsbok ändras.
Ibland gör standardmakron ändringar som utlöser en händelseprocedur. Till exempel, om du har ett standardmakro som manipulerar flera celler på Sheet1, varje gång en cell på det arket ändras, måste ditt makro pausa medan Worksheet_Change-händelsen körs.
Du kan lägga till ytterligare en prestandahöjande nivå genom att använda egenskapen EnableEvents för att tala om för Excel att ignorera händelser medan ditt makro körs.
Ställ in egenskapen EnableEvents till False innan du kör ditt makro. När din makrokod är klar kan du ställa tillbaka egenskapen EnableEvents till True.
Sub Macro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falskt
Application.DisplayStatusBar = Falskt
Application.EnableEvents = False
'Placera din makrokod här
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
Application.EnableEvents = Sant
Avsluta Sub
Döljer sidbrytningar
Varje gång ditt makro ändrar antalet rader, ändrar antalet kolumner eller ändrar sidinställningarna för ett kalkylblad, tvingas Excel ta tid att räkna om sidbrytningarna som visas på bladet.
Du kan undvika detta beteende genom att helt enkelt dölja sidbrytningarna innan du startar ditt makro.
Ställ in egenskapen DisplayPageBreaks ark till False för att dölja sidbrytningar. Om du vill fortsätta att visa sidbrytningar efter att ditt makro har körts ställer du tillbaka egenskapen DisplayPageBreaks till True.
Sub Macro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falskt
Application.DisplayStatusBar = Falskt
Application.EnableEvents = False
Activesheet.DisplayPageBreaks = Falskt
'Placera din makrokod här
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
Application.EnableEvents = Sant
Activesheet.DisplayPageBreaks = Sant
Avsluta Sub
Avbryter pivottabelluppdateringar
Om ditt makro manipulerar pivottabeller som innehåller stora datakällor kan du uppleva dålig prestanda när du gör saker som att dynamiskt lägga till eller flytta pivotfält.
Du kan förbättra prestandan för ditt makro genom att avbryta omräkningen av pivottabellen tills alla ändringar av pivotfältet har gjorts. Ställ bara in egenskapen PivotTable.ManualUpdate till True för att skjuta upp omberäkningen, kör din makrokod och ställ sedan tillbaka egenskapen PivotTable.ManualUpdate till False för att utlösa omberäkningen.
Sub Macro1()
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=True
'Placera din makrokod här
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=False
Avsluta Sub
Undvik att kopiera och klistra in
Det är viktigt att komma ihåg att även om Macro Recorder sparar tid genom att skriva VBA-kod åt dig, skriver den inte alltid den mest effektiva koden. Ett utmärkt exempel är hur Macro Recorder fångar alla kopiera-och-klistra-åtgärder du utför under inspelning.
Du kan ge dina makron ett litet uppsving genom att klippa ut mellanhanden och utföra en direktkopiering från en cell till en destinationscell. Den här alternativa koden använder argumentet Destination för att kringgå urklipp och kopiera innehållet i cell A1 direkt till cell B1.
Range("A1").Copy Destination:=Range("B1")
Om du bara behöver kopiera värden (inte formatering eller formler) kan du förbättra prestandan ännu mer genom att undvika kopieringsmetoden. Ställ bara in värdet på målcellen till samma värde som finns i källcellen. Denna metod är ungefär 25 gånger snabbare än att använda kopieringsmetoden:
Range("B1").Value = Range("A1").Value
Om du bara behöver kopiera formler från en cell till en annan (inte värden eller formatering), kan du ställa in formeln för målcellen till samma formel som finns i källcellen:
Range("B1").Formel = Range("A1").Formel
Använda With-satsen
När du spelar in makron kommer du ofta att manipulera samma objekt mer än en gång. Du kan spara tid och förbättra prestandan genom att använda With-satsen för att utföra flera åtgärder på ett givet objekt i en tagning.
With-satsen som används i följande exempel talar om för Excel att tillämpa alla formateringsändringar på en gång:
Med Range("A1"). Teckensnitt
.Fet = Sant
.Kursiv = Sant
.Underline = xlUnderlineStyleSingle
Sluta med
Att ta för vana att lägga in åtgärder i With-satser kommer inte bara att hålla dina makron igång snabbare utan också göra det lättare att läsa din makrokod.
Undviker Select-metoden
Macro Recorder är förtjust i att använda Select-metoden för att explicit välja objekt innan du vidtar åtgärder på dem. Det finns i allmänhet inget behov av att välja objekt innan du arbetar med dem. Faktum är att du kan förbättra makroprestanda dramatiskt genom att inte använda Select-metoden.
När du har spelat in dina makron, gör det till en vana att ändra den genererade koden för att ta bort Select-metoderna. I det här fallet skulle den optimerade koden se ut så här:
Sheets("Sheet1"). Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet2").Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet3").Range("A1").FormulaR1C1 = "1000"
Observera att ingenting väljs. Koden använder helt enkelt objekthierarkin för att tillämpa de nödvändiga åtgärderna.
Begränsa resor till arbetsbladet
Ett annat sätt att snabba upp dina makron är att begränsa antalet gånger du refererar till kalkylbladsdata i din kod. Det är alltid mindre effektivt att hämta data från kalkylbladet än från minnet. Det vill säga, dina makron kommer att köras mycket snabbare om de inte behöver interagera med kalkylbladet upprepade gånger.
Till exempel tvingar följande enkla kod VBA att kontinuerligt återgå till Sheets(“Sheet1”). Range(“A1”) för att få det nummer som behövs för jämförelsen som utförs i If-satsen:
För rapportmånad = 1 till 12
If Range("A1").Value = ReportMonth Then
MsgBox 1000000 / ReportMonth
Avsluta om
Nästa rapportmånad
En mycket effektivare metod är att spara värdet i Sheets(“Sheet1”). Range(“A1”) till en variabel som heter MyMonth. På så sätt refererar koden till MyMonth-variabeln istället för kalkylbladet:
Dim MyMonth som heltal
MyMonth = Range("A1").Värde
För rapportmånad = 1 till 12
Om MyMonth = ReportMonth Då
MsgBox 1000000 / ReportMonth
Avsluta om
Nästa rapportmånad
Överväg att använda variabler för att arbeta med data i minnet i motsats till att direkt referera till kalkylblad.
Undvik överdriven referens
När du anropar en metod eller egenskap för ett objekt måste den gå igenom IDispatch-gränssnittet för OLE-komponenten. Anropen till dessa OLE-komponenter tar tid, så att minska antalet referenser till OLE-komponenter kan förbättra hastigheten på makrokoden.
För anropande av objektegenskaper eller metoder används vanligtvis representationsmetoden för Object.Method , det vill säga "." symbol används för att anropa egenskaper och metoder.
Därför kan antalet metod- eller egenskapsanrop bedömas enligt antalet symboler ".". Ju mindre "." symbol, desto snabbare körs koden.
Till exempel innehåller följande påstående 3 symboler ".".
ThisWorkbook.Sheet1.Range("A1").Value = 100
Följande påstående har bara en symbol ".".
Activewindow.Top = 100
Här är några knep för att minska antalet symboler "." att springa snabbare.
Först, när du behöver referera till samma objekt upprepade gånger, kan du ställa in objektet till en variabel för att minska antalet anrop. Till exempel kräver följande kod två samtal per linje.
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = 100
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = 200
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = 300
Eftersom Sheets("Sheet1") -objektet måste refereras upprepade gånger, kan det ställas in på en variabel sht först, så att varje kod bara behöver anropas en gång.
Set sht = ThisWorkbook.Sheets("Sheet1")
sht.Cells(1, 1) = 100
sht.Cells(2, 1) = 200
sht.Cells(3, 1) = 300
För det andra, om du inte vill deklarera en temporär variabel sht, kan du också använda With -satsen som nämndes tidigare. Som visas i följande exempel:
With ThisWorkbook.Sheets("Sheet1")
.Cells(1, 1) = 100
.Cells(2, 1) = 200
.Cells(3, 1) = 300
End With
För det tredje, när det finns många loopar, försök att hålla egenskaper och metoder utanför loopen. När du återanvänder ett egenskapsvärde för samma objekt i en loop kan du först tilldela egenskapsvärdet till en specificerad variabel utanför loopen och sedan använda variabeln i loopen, vilket kan uppnå snabbare hastighet. Som visas i följande exempel:
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = Cells(1, 2).Value
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = Cells(1, 2).Value
Next i
Varje slinga i detta exempel får egenskapen Value för cellen Cells(1,2). Om du tilldelar egenskapen Value för Cells(1.2) till en variabel innan loopen startar, kommer du att få en snabbare körning. Som visas i följande exempel:
tmp = Cells(1, 2).Value
For i = 1 To 1000
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = tmp
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = tmp
Next i
Ovanstående kod anropar ThisWorkbook.Sheets("Sheet1") varje gång den loopar. Du kan göra detta snabbare genom att använda With -satsen för att flytta anropet till ThisWorkbook.Sheets("Sheet1") utanför loopen. Som visas i följande exempel:
tmp = Cells(1, 2).Value
With ThisWorkbook.Sheets("Sheet1")
For i = 1 To 1000
.Cells(1, 1) = tmp
.Cells(2, 1) = tmp
.Cells(3, 1) = tmp
Next i
End With
Undvik att använda varianttyper
Nybörjare föredrar vanligtvis att använda Variant-variabler, vilket har fördelen att vara mindre komplicerat eftersom alla typer av data kan användas utan problem med minnesspill om data är för stora för datatyperna heltal eller långa. Varienmt-data kräver dock mer extra minnesutrymme än de andra specificerade typerna (2 byte för heltalsdata, 4 byte för långa data och 16 byte för variantdata), VBA kräver mer tid för att bearbeta data av varianttyp än andra specificerade typer av data. Som följande exempel visar.
Sub VariantTest()
Dim i As Long
Dim ix As Integer, iy As Integer, iz As Integer
Dim vx As Variant, vy As Variant, vz As Variant
Dim tm As Date
vx = 100: vy = 50
tm = Timer
For i = 1 To 1000000
vz = vx * vy
vz = vx + vy
vz = vx - vy
vz = vx / vy
Next i
Debug.Print "Variant types take " & Format((Timer - tm), "0.00000") & " seconds"
ix = 100: iy = 50
tm = Timer
For i = 1 To 1000000
iz = ix * iy
iz = ix + iy
iz = ix - iy
iz = ix / iy
Next i
Debug.Print "Integer types take " & Format((Timer - tm), "0.00000") & " seconds"
End Sub
I ovanstående kod gör raderna 8 till 13 1 miljon operationer med addition, subtraktion, multiplikation och division av Variantvariabler, och raderna 17 till 22 gör 1 miljon operationer med addition, subtraktion, multiplikation och division av heltalsvariabler. På min dator tog driften av Variantvariabeln cirka 0,09375 sekunder, medan operationen av Integer-variabeln tog cirka 0,03125 sekunder. Resultaten kan variera från dator till dator, men Variantvariabler är betydligt långsammare än heltalsvariabler .
Av denna anledning rekommenderas det att undvika att använda Variantvariabler när du uttryckligen kan använda den angivna datatypen .