Ettersom Excel-makroene dine blir stadig mer robuste og komplekse, kan du oppleve at de mister ytelsen. Når man diskuterer makroer, er ordet ytelse vanligvis synonymt med hastighet . Hastighet er hvor raskt VBA-prosedyrene utfører de tiltenkte oppgavene. Følgende er ti måter å hjelpe deg med å holde Excel-makroene kjøre på sitt optimale ytelsesnivå.
Stoppe arkberegninger
Visste du at hver gang en celle som påvirker en formel i regnearket endres eller manipuleres, beregner Excel hele regnearket på nytt? I regneark som har en stor mengde formler, kan denne oppførselen drastisk bremse makroene dine.
Du kan bruke egenskapen Application.Calculation til å fortelle Excel om å bytte til manuell beregningsmodus. Når en arbeidsbok er i manuell beregningsmodus, vil ikke arbeidsboken beregnes på nytt før du eksplisitt utløser en beregning ved å trykke på F9-tasten.
Sett Excel i manuell beregningsmodus, kjør koden, og bytt deretter tilbake til automatisk beregningsmodus.
Sub Makro1()
Application.Calculation = xlCalculationManual
'Plasser makrokoden din her
Application.Calculation = xlCalculationAutomatic
End Sub
Å sette beregningsmodusen tilbake til xlCalculationAutomatic vil automatisk utløse en ny beregning av regnearket, så det er ikke nødvendig å trykke på F9-tasten etter at makroen er kjørt.
Deaktiverer oppdatering av arkskjerm
Du legger kanskje merke til at når makroene kjører, flimrer skjermen en god del. Denne flimringen er at Excel prøver å tegne skjermen på nytt for å vise den gjeldende tilstanden til regnearket. Dessverre tar den opp minneressurser hver gang Excel tegner skjermen på nytt.
Du kan bruke egenskapen Application.ScreenUpdating til å deaktivere skjermoppdateringer til makroen er fullført. Deaktivering av skjermoppdatering sparer tid og ressurser, slik at makroen din kan kjøre litt raskere. Etter at makrokoden er ferdig å kjøre, kan du slå på skjermoppdatering igjen.
Sub Makro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'Plasser makrokoden din her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
End Sub
Etter at du har satt egenskapen ScreenUpdating tilbake til True, vil Excel automatisk utløse en ny tegning av skjermen.
Slå av statuslinjeoppdateringer
Excel-statuslinjen, som vises nederst i Excel-vinduet, viser vanligvis fremdriften til visse handlinger i Excel. Hvis makroen din jobber med mye data, vil statuslinjen ta opp noen ressurser.
Det er viktig å merke seg at å slå av skjermoppdatering er atskilt fra å slå av statuslinjevisningen. Statuslinjen vil fortsette å bli oppdatert selv om du deaktiverer skjermoppdatering. Du kan bruke Application.DisplayStatusBar-egenskapen til å midlertidig deaktivere eventuelle statuslinjeoppdateringer, og forbedre ytelsen til makroen din ytterligere:
Sub Makro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
'Plasser makrokoden din her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
End Sub
Be Excel om å ignorere hendelser
Du kan implementere makroer som hendelsesprosedyrer, og fortelle Excel å kjøre bestemt kode når et regneark eller arbeidsbok endres.
Noen ganger gjør standardmakroer endringer som vil utløse en hendelsesprosedyre. For eksempel, hvis du har en standard makro som manipulerer flere celler på Ark1, hver gang en celle på det arket endres, må makroen din settes på pause mens Worksheet_Change-hendelsen kjører.
Du kan legge til et nytt nivå av ytelsesøkning ved å bruke EnableEvents-egenskapen for å fortelle Excel om å ignorere hendelser mens makroen kjører.
Sett EnableEvents-egenskapen til False før du kjører makroen. Etter at makrokoden er ferdig kjørt, kan du sette EnableEvents-egenskapen tilbake til True.
Sub Makro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
'Plasser makrokoden din her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
Application.EnableEvents = Sant
End Sub
Skjuler sideskift
Hver gang makroen din endrer antall rader, endrer antall kolonner eller endrer sideoppsettet til et regneark, blir Excel tvunget til å bruke tid på å beregne sideskiftene som vises på arket på nytt.
Du kan unngå denne oppførselen ved å skjule sideskiftene før du starter makroen.
Sett egenskapen DisplayPageBreaks ark til False for å skjule sideskift. Hvis du vil fortsette å vise sideskift etter at makroen er kjørt, setter du tilbake egenskapen DisplayPageBreaks til True.
Sub Makro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.EnableEvents = False
Activesheet.DisplayPageBreaks = False
'Plasser makrokoden din her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sant
Application.DisplayStatusBar = Sant
Application.EnableEvents = Sant
Activesheet.DisplayPageBreaks = Sant
End Sub
Suspender pivottabelloppdateringer
Hvis makroen din manipulerer pivottabeller som inneholder store datakilder, kan du oppleve dårlig ytelse når du gjør ting som å dynamisk legge til eller flytte pivotfelter.
Du kan forbedre ytelsen til makroen din ved å utsette omberegningen av pivottabellen til alle endringer i pivotfeltet er gjort. Sett ganske enkelt egenskapen PivotTable.ManualUpdate til True for å utsette omberegning, kjør makrokoden og sett deretter egenskapen PivotTable.ManualUpdate tilbake til False for å utløse nyberegningen.
Sub Makro1()
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=True
'Plasser makrokoden din her
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=False
End Sub
Unngå kopier og lim
Det er viktig å huske at selv om Macro Recorder sparer tid ved å skrive VBA-kode for deg, skriver den ikke alltid den mest effektive koden. Et godt eksempel er hvordan Macro Recorder fanger opp alle kopier-og-lim-handlinger du utfører mens du spiller inn.
Du kan gi makroene dine et lite løft ved å kutte ut mellommannen og utføre en direkte kopi fra én celle til en destinasjonscelle. Denne alternative koden bruker argumentet Destinasjon for å omgå utklippstavlen og kopiere innholdet i celle A1 direkte til celle B1.
Range("A1").Kopier Destinasjon:=Rekkevidde("B1")
Hvis du bare trenger å kopiere verdier (ikke formatering eller formler), kan du forbedre ytelsen enda mer ved å unngå kopieringsmetoden. Sett ganske enkelt verdien til målcellen til den samme verdien som finnes i kildecellen. Denne metoden er omtrent 25 ganger raskere enn å bruke kopieringsmetoden:
Range("B1"). Verdi = Område("A1"). Verdi
Hvis du bare trenger å kopiere formler fra én celle til en annen (ikke verdier eller formatering), kan du angi formelen for målcellen til den samme formelen i kildecellen:
Range("B1").Formel = Område("A1").Formel
Bruke With-setningen
Når du tar opp makroer, vil du ofte manipulere det samme objektet mer enn én gang. Du kan spare tid og forbedre ytelsen ved å bruke With-setningen til å utføre flere handlinger på et gitt objekt i ett skudd.
With-setningen brukt i følgende eksempel forteller Excel å bruke alle formateringsendringene på en gang:
With Range("A1"). Font
.Fet = Sant
.Kursiv = Sant
.Underline = xlUnderlineStyleSingle
Avslutt med
Å få en vane med å dele handlinger inn i With-utsagn vil ikke bare holde makroene kjøre raskere, men også gjøre det lettere å lese makrokoden.
Unngå Select-metoden
Macro Recorder er glad i å bruke Select-metoden for å eksplisitt velge objekter før du utfører handlinger på dem. Det er vanligvis ikke nødvendig å velge objekter før du arbeider med dem. Faktisk kan du forbedre makroytelsen dramatisk ved å ikke bruke Select-metoden.
Etter å ha registrert makroene dine, gjør det til en vane å endre den genererte koden for å fjerne Select-metodene. I dette tilfellet vil den optimaliserte koden se slik ut:
Sheets("Sheet1"). Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet2"). Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet3").Range("A1").FormulaR1C1 = "1000"
Merk at ingenting blir valgt. Koden bruker ganske enkelt objekthierarkiet for å bruke de nødvendige handlingene.
Begrense turer til arbeidsarket
En annen måte å øke hastigheten på makroene dine er å begrense antall ganger du refererer til regnearkdata i koden. Det er alltid mindre effektivt å hente data fra regnearket enn fra minnet. Det vil si at makroene dine vil kjøre mye raskere hvis de ikke må samhandle gjentatte ganger med regnearket.
For eksempel tvinger følgende enkle kode VBA til kontinuerlig å gå tilbake til Sheets(“Sheet1”). Range(“A1”) for å få tallet som trengs for sammenligningen som utføres i If-setningen:
For rapportmåned = 1 til 12
If Range("A1").Verdi = ReportMonth Then
MsgBox 1000000 / ReportMonth
Slutt om
Neste rapportmåned
En mye mer effektiv metode er å lagre verdien i Sheets(“Sheet1”). Range(“A1”) til en variabel kalt MyMonth. På denne måten refererer koden til MyMonth-variabelen i stedet for regnearket:
Dim MyMonth som heltall
MyMonth = Range("A1"). Verdi
For rapportmåned = 1 til 12
Hvis MyMonth = ReportMonth Then
MsgBox 1000000 / ReportMonth
Slutt om
Neste rapportmåned
Vurder å utnytte variabler for å arbeide med data i minnet i motsetning til å referere direkte til regneark.
Unngå overdreven referanse
Når du kaller en metode eller egenskap til et objekt, må det gå gjennom IDispatch-grensesnittet til OLE-komponenten. Anropene til disse OLE-komponentene tar tid, så å redusere antall referanser til OLE-komponenter kan forbedre hastigheten på makrokoden.
For påkalling av objektegenskaper eller metoder, brukes vanligvis representasjonsmetoden til Object.Method , det vil si "." symbol brukes til å påkalle egenskaper og metoder.
Derfor kan antallet metode- eller egenskapskall bedømmes i henhold til antall symboler ".". Jo mindre "." symbol, jo raskere kjører koden.
For eksempel inneholder følgende setning 3 symboler ".".
ThisWorkbook.Sheet1.Range("A1").Value = 100
Følgende setning har bare ett symbol ".".
Activewindow.Top = 100
Her er noen triks for å redusere antall symboler "." å løpe raskere.
Først, når du trenger å referere til det samme objektet gjentatte ganger, kan du sette objektet til en variabel for å redusere antall anrop. For eksempel krever følgende kode to anrop per linje.
ThisWorkbook.Sheets("Sheet1").Cells(1, 1) = 100
ThisWorkbook.Sheets("Sheet1").Cells(2, 1) = 200
ThisWorkbook.Sheets("Sheet1").Cells(3, 1) = 300
Fordi Sheets("Sheet1") -objektet må refereres gjentatte ganger, kan det settes til en variabel sht først, slik at hver kode bare trenger å bli kalt én gang.
Set sht = ThisWorkbook.Sheets("Sheet1")
sht.Cells(1, 1) = 100
sht.Cells(2, 1) = 200
sht.Cells(3, 1) = 300
For det andre, hvis du ikke vil deklarere en midlertidig variabel sht, kan du også bruke With- setningen nevnt tidligere. Som vist i følgende eksempel:
With ThisWorkbook.Sheets("Sheet1")
.Cells(1, 1) = 100
.Cells(2, 1) = 200
.Cells(3, 1) = 300
End With
For det tredje, når det er mange løkker, prøv å holde egenskaper og metoder utenfor løkken. Når du gjenbruker en egenskapsverdi for det samme objektet i en løkke, kan du først tilordne egenskapsverdien til en spesifisert variabel utenfor løkken, og deretter bruke variabelen i løkken, som kan oppnå høyere hastighet. Som vist i følgende eksempel:
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
Hver løkke i dette eksemplet får Verdi-egenskapen til cellen Cells(1,2). Hvis du tilordner Verdi-egenskapen til Cells(1.2) til en variabel før loopen starter, vil du få en raskere kjøring. Som vist i følgende eksempel:
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
Koden ovenfor kaller ThisWorkbook.Sheets("Sheet1") hver gang den går i loop. Du kan gjøre dette raskere ved å bruke With -setningen til å flytte kallet til ThisWorkbook.Sheets("Sheet1") utenfor løkken. Som vist i følgende eksempel:
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
Unngå å bruke varianttyper
Nybegynnere foretrekker vanligvis å bruke Variant-variabler, som har fordelen av å være mindre kompliserte fordi alle typer data kan brukes uten problemet med minneoverflyt hvis dataene er for store for datatypene heltall eller lange. Varienmt-data krever imidlertid mer ekstra minneplass enn de andre spesifiserte typene (2 byte for heltallsdata, 4 byte for lange data og 16 byte for variantdata), VBA krever mer tid for å behandle data av varianttypen enn andre spesifiserte typer av data. Som følgende eksempel viser.
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 koden ovenfor utfører linjene 8 til 13 1 million operasjoner med addisjon, subtraksjon, multiplikasjon og divisjon av Variantvariabler, og linjene 17 til 22 gjør 1 million operasjoner med addisjon, subtraksjon, multiplikasjon og divisjon av heltallsvariabler. På datamaskinen min tok operasjonen av Variant-variabelen omtrent 0,09375 sekunder, mens operasjonen av Integer-variabelen tok omtrent 0,03125 sekunder. Resultatene kan variere fra datamaskin til datamaskin, men variantvariabler er betydelig tregere enn heltallsvariabler .
Av denne grunn anbefales det å unngå å bruke Variantvariabler når du eksplisitt kan bruke den angitte datatypen .