Efterhånden som dine Excel-makroer bliver mere og mere robuste og komplekse, kan du opleve, at de mister ydeevne. Når man diskuterer makroer, er ordet ydeevne normalt synonymt med hastighed . Hastighed er, hvor hurtigt dine VBA-procedurer udfører deres tilsigtede opgaver. Følgende er ti måder, du kan hjælpe med at holde dine Excel-makroer kørende på deres optimale ydeevne.
Standsning af arkberegninger
Vidste du, at hver gang en celle, der påvirker en formel i dit regneark, ændres eller manipuleres, genberegner Excel hele regnearket? I regneark, der har en stor mængde formler, kan denne adfærd drastisk bremse dine makroer.
Du kan bruge egenskaben Application.Calculation til at fortælle Excel om at skifte til manuel beregningstilstand. Når en projektmappe er i manuel beregningstilstand, genberegnes projektmappen ikke, før du eksplicit udløser en beregning ved at trykke på F9-tasten.
Sæt Excel i manuel beregningstilstand, kør din kode, og skift derefter tilbage til automatisk beregningstilstand.
Undermakro1()
Application.Calculation = xlCalculationManual
'Placer din makrokode her
Application.Calculation = xlCalculationAutomatic
Slut Sub
Indstilling af beregningstilstanden tilbage til xlCalculationAutomatic vil automatisk udløse en genberegning af regnearket, så der er ingen grund til at trykke på F9-tasten, efter at din makro er kørt.
Deaktiverer opdatering af arkskærm
Du bemærker måske, at når dine makroer kører, flimrer din skærm en del. Dette flimrende er, at Excel forsøger at tegne skærmen igen for at vise regnearkets aktuelle tilstand. Desværre optager den hukommelsesressourcer, hver gang Excel gentegner skærmen.
Du kan bruge egenskaben Application.ScreenUpdating til at deaktivere skærmopdateringer, indtil din makro er fuldført. Deaktivering af skærmopdatering sparer tid og ressourcer, så din makro kan køre lidt hurtigere. Når din makrokode er færdig med at køre, kan du slå skærmopdatering til igen.
Undermakro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falsk
'Placer din makrokode her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sand
Slut Sub
Når du har sat egenskaben ScreenUpdating tilbage til True, udløser Excel automatisk en gentegning af skærmen.
Deaktiverer statuslinjeopdateringer
Excel-statuslinjen, som vises nederst i Excel-vinduet, viser normalt fremskridtene for visse handlinger i Excel. Hvis din makro arbejder med masser af data, vil statuslinjen optage nogle ressourcer.
Det er vigtigt at bemærke, at deaktivering af skærmopdatering er adskilt fra at slukke for statuslinjens visning. Statuslinjen vil fortsat blive opdateret, selvom du deaktiverer skærmopdatering. Du kan bruge egenskaben Application.DisplayStatusBar til midlertidigt at deaktivere eventuelle statuslinjeopdateringer, hvilket yderligere forbedrer ydeevnen af din makro:
Undermakro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falsk
Application.DisplayStatusBar = Falsk
'Placer din makrokode her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sand
Application.DisplayStatusBar = Sand
Slut Sub
Beder Excel om at ignorere begivenheder
Du kan implementere makroer som hændelsesprocedurer og bede Excel om at køre bestemt kode, når et regneark eller projektmappe ændres.
Nogle gange foretager standardmakroer ændringer, der vil udløse en hændelsesprocedure. For eksempel, hvis du har en standardmakro, der manipulerer flere celler på Ark1, skal din makro, hver gang en celle på det ark ændres, holde pause, mens hændelsen Worksheet_Change kører.
Du kan tilføje endnu et niveau af ydelsesforøgelse ved at bruge egenskaben EnableEvents til at bede Excel om at ignorere hændelser, mens din makro kører.
Indstil egenskaben EnableEvents til False, før du kører din makro. Når din makrokode er færdig med at køre, kan du indstille egenskaben EnableEvents tilbage til True.
Undermakro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falsk
Application.DisplayStatusBar = Falsk
Application.EnableEvents = Falsk
'Placer din makrokode her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sand
Application.DisplayStatusBar = Sand
Application.EnableEvents = Sand
Slut Sub
Skjuler sideskift
Hver gang din makro ændrer antallet af rækker, ændrer antallet af kolonner eller ændrer sideopsætningen af et regneark, er Excel tvunget til at tage tid på at genberegne sideskiftene vist på arket.
Du kan undgå denne adfærd ved blot at skjule sideskiftene, før du starter din makro.
Indstil arkegenskaben DisplayPageBreaks til False for at skjule sideskift. Hvis du vil fortsætte med at vise sideskift, efter at din makro er kørt, skal du sætte egenskaben DisplayPageBreaks-ark tilbage til True.
Undermakro1()
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = Falsk
Application.DisplayStatusBar = Falsk
Application.EnableEvents = Falsk
Activesheet.DisplayPageBreaks = Falsk
'Placer din makrokode her
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = Sand
Application.DisplayStatusBar = Sand
Application.EnableEvents = Sand
Activesheet.DisplayPageBreaks = Sand
Slut Sub
Suspendering af pivottabelopdateringer
Hvis din makro manipulerer pivottabeller, der indeholder store datakilder, kan du opleve dårlig ydeevne, når du gør ting som dynamisk tilføjelse eller flytning af pivotfelter.
Du kan forbedre ydeevnen af din makro ved at suspendere genberegningen af pivottabellen, indtil alle pivotfeltændringer er foretaget. Indstil blot egenskaben PivotTable.ManualUpdate til True for at udskyde genberegning, kør din makrokode, og sæt derefter egenskaben PivotTable.ManualUpdate tilbage til False for at udløse genberegningen.
Undermakro1()
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=True
'Placer din makrokode her
ActiveSheet.PivotTables("PivotTable1").ManualUpdate=False
Slut Sub
Undgå at kopiere og indsætte
Det er vigtigt at huske, at selvom Macro Recorder sparer tid ved at skrive VBA-kode for dig, skriver den ikke altid den mest effektive kode. Et godt eksempel er, hvordan Macro Recorder fanger enhver kopi-og-indsæt-handling, du udfører, mens du optager.
Du kan give dine makroer et lille løft ved at fjerne mellemmanden og udføre en direkte kopi fra én celle til en destinationscelle. Denne alternative kode bruger argumentet Destination til at omgå udklipsholderen og kopiere indholdet af celle A1 direkte til celle B1.
Range("A1").Kopiér Destination:=Range("B1")
Hvis du kun har brug for at kopiere værdier (ikke formatering eller formler), kan du forbedre ydeevnen endnu mere ved at undgå kopieringsmetoden. Indstil blot værdien af destinationscellen til den samme værdi, som findes i kildecellen. Denne metode er cirka 25 gange hurtigere end at bruge kopieringsmetoden:
Range("B1").Value = Range("A1").Værdi
Hvis du kun skal kopiere formler fra én celle til en anden (ikke værdier eller formatering), kan du indstille formlen for destinationscellen til den samme formel, som er indeholdt i kildecellen:
Range("B1").Formel = Range("A1").Formel
Brug af With-erklæringen
Når du optager makroer, vil du ofte manipulere det samme objekt mere end én gang. Du kan spare tid og forbedre ydeevnen ved at bruge With-sætningen til at udføre flere handlinger på et givet objekt i ét skud.
With-sætningen brugt i følgende eksempel fortæller Excel at anvende alle formateringsændringer på én gang:
Med Range("A1"). Skrifttype
.Fed = Sand
.Kursiv = Sand
.Underline = xlUnderlineStyleSingle
Slut med
At vænne sig til at dele handlinger ind i With-sætninger vil ikke kun holde dine makroer kørende hurtigere, men også gøre det nemmere at læse din makrokode.
Undgå Select-metoden
Macro Recorder er glad for at bruge Select-metoden til eksplicit at vælge objekter, før der foretages handlinger på dem. Der er generelt ingen grund til at vælge objekter, før du arbejder med dem. Faktisk kan du dramatisk forbedre makroydelsen ved ikke at bruge Select-metoden.
Efter at have optaget dine makroer, gør det til en vane at ændre den genererede kode for at fjerne Select-metoderne. I dette tilfælde vil den optimerede kode se sådan ud:
Sheets("Sheet1").Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet2").Range("A1").FormulaR1C1 = "1000"
Sheets("Sheet3").Range("A1").FormelR1C1 = "1000"
Bemærk, at intet er ved at blive valgt. Koden bruger blot objekthierarkiet til at anvende de nødvendige handlinger.
Begrænsning af ture til arbejdsarket
En anden måde at fremskynde dine makroer på er at begrænse antallet af gange, du refererer til regnearksdata i din kode. Det er altid mindre effektivt at hente data fra regnearket end fra hukommelsen. Det vil sige, at dine makroer kører meget hurtigere, hvis de ikke gentagne gange skal interagere med regnearket.
For eksempel tvinger følgende simple kode VBA til løbende at vende tilbage til Sheets(“Sheet1”). Range(“A1”) for at få det tal, der er nødvendigt for sammenligningen, der udføres i If-sætningen:
For rapportmåned = 1 til 12
If Range("A1").Value = ReportMonth Then
MsgBox 1000000 / ReportMonth
Afslut Hvis
Næste rapportmåned
En meget mere effektiv metode er at gemme værdien i Sheets(“Sheet1”). Range(“A1”) til en variabel kaldet MyMonth. På denne måde refererer koden til MyMonth-variablen i stedet for arbejdsarket:
Dim MyMonth som heltal
MyMonth = Range("A1").Værdi
For rapportmåned = 1 til 12
Hvis MyMonth = ReportMonth Then
MsgBox 1000000 / ReportMonth
Afslut Hvis
Næste rapportmåned
Overvej at udnytte variabler til at arbejde med data i hukommelsen i modsætning til at referere direkte til regneark.
Undgå overdreven reference
Når du kalder en metode eller egenskab for et objekt, skal den gå gennem OLE-komponentens IDispatch-grænseflade. Opkaldene til disse OLE-komponenter tager tid, så en reduktion af antallet af referencer til OLE-komponenter kan forbedre makrokodens hastighed.
Til påkaldelse af objektegenskaber eller -metoder bruges repræsentationsmetoden for Object.Method generelt, det vil sige "." symbol bruges til at påberåbe egenskaber og metoder.
Derfor kan antallet af metode- eller egenskabskald bedømmes efter antallet af symboler ".". Jo mindre "." symbol, jo hurtigere kører koden.
For eksempel indeholder følgende sætning 3 symboler ".".
ThisWorkbook.Sheet1.Range("A1").Value = 100
Følgende sætning har kun ét symbol ".".
Activewindow.Top = 100
Her er nogle tricks til at reducere antallet af symboler "." at løbe hurtigere.
For det første, når du skal henvise til det samme objekt gentagne gange, kan du indstille objektet til en variabel for at reducere antallet af opkald. For eksempel kræver følgende kode to opkald pr. 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 skal refereres gentagne gange, kan det sættes til en variabel sht først, så hver kode kun skal kaldes én gang.
Set sht = ThisWorkbook.Sheets("Sheet1")
sht.Cells(1, 1) = 100
sht.Cells(2, 1) = 200
sht.Cells(3, 1) = 300
For det andet, hvis du ikke ønsker at erklære en midlertidig variabel sht, kan du også bruge With- sætningen nævnt 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 der er mange løkker, så prøv at holde egenskaber og metoder uden for løkken. Når du genbruger en egenskabsværdi for det samme objekt i en løkke, kan du først tildele egenskabsværdien til en specificeret variabel uden for løkken og derefter bruge variablen i løkken, som kan opnå hurtigere hastighed. 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 sløjfe i dette eksempel får egenskaben Værdi for cellen Cells(1,2). Hvis du tildeler egenskaben Værdi for Celler(1.2) til en variabel, før løkken starter, vil du få en hurtigere kørsel. 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
Ovenstående kode kalder ThisWorkbook.Sheets("Sheet1") hver gang den looper. Du kan gøre dette hurtigere ved at bruge With -sætningen til at flytte opkaldet til ThisWorkbook.Sheets("Sheet1") uden for 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
Undgå at bruge varianttyper
Begyndere foretrækker normalt at bruge Variant-variabler, som har den fordel, at de er mindre komplicerede, fordi enhver type data kan bruges uden problemet med hukommelsesoverløb, hvis dataene er for store til datatyperne Integer eller Long. Varienmt-typedata kræver dog mere ekstra hukommelsesplads end de andre specificerede typer (2 bytes for heltaldata, 4 bytes for lange data og 16 bytes for variantdata), VBA kræver mere tid at behandle data af varianttypen end andre specificerede typer af data. Som det 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 ovenstående kode udfører linje 8 til 13 1 million operationer med addition, subtraktion, multiplikation og division af Variantvariabler, og linje 17 til 22 udfører 1 million operationer med addition, subtraktion, multiplikation og division af heltalsvariable. På min computer tog driften af Variant-variablen omkring 0,09375 sekunder, mens operationen af Integer-variablen tog omkring 0,03125 sekunder. Resultaterne kan variere fra computer til computer, men variantvariabler er betydeligt langsommere end heltalsvariabler .
Af denne grund anbefales det at undgå at bruge Variantvariabler, når du eksplicit kan bruge den angivne datatype .