Ett av de bästa sätten att påskynda kodexekveringen i Excel är att stänga av skärmuppdateringen med Application.ScreenUpdating fast egendom. Du kan göra samma sak i Access genom att använda Application.Echo metod.
Lägg märke till att jag hänvisade till Excel-versionen som en egendom och Access-versionen som en metod . Det betyder att vi kan kontrollera statusen för skärmmålning i Excel, men vi kan inte göra det i Access. Detta visar sig vara en viktig skillnad.
Jag har flera funktioner i mitt kodbibliotek som tillfälligt stänger av skärmmålning. Tekniken används vanligtvis inte för att ge den typ av prestandahöjning vi ser i Excel. Istället förbättrar det gränssnittet genom att förhindra den typ av "blankettblinkande" som uppstår om vi gör snabba ändringar av utseendet på våra formulär.
Ett enkelt användningsfall
Jag har en klassmodul som ger avancerade funktioner för individuell storleksändring av formulärkontroller när själva formuläret ändras. När jag först utvecklade den här modulen var den visuella effekten mycket oroande. Närhelst formulärets storlek ändrades, ändrades storleken på varje enskild kontroll på skärmen en i taget.
Public Sub weForm_Resize()
'... loop through and resize controls based on their Tag property...
End Sub
Detta var en skakande användarupplevelse. För att förbättra det skulle jag stänga av skärmuppdatering, göra mina ändringar och sedan slå på skärmuppdatering igen i slutet av funktionen.
Public Sub weForm_Resize()
Application.Echo False
'... loop through and resize controls based on their Tag property...
Application.Echo True
End Sub
Detta förbättrade användarupplevelsen avsevärt. Jag började använda den här tekniken i all min kod som modifierade användargränssnittet. Och det var då jag började stöta på problem.
Problemet kom när jag skulle ringa flera funktioner som stängde av skärmmålning i rad. Den första funktionen skulle stänga av skärmmålning, göra sina ändringar och sedan slå på skärmmålning igen. Gränssnittet skulle blinka sin uppdatering, sedan skulle den andra funktionen stänga av skärmmålning igen, göra sina ändringar och slutligen slå på skärmmålning igen för gott.
Bevara skärmmålningsstatus
Det bättre sättet att hantera denna situation skulle vara att spara skärmmålningsstatusen i början av rutinen, stänga av skärmmålning och sedan återställa den ursprungliga skärmmålningsstatusen som sparades i början av rutinen. I Excel var detta enkelt:
Sub ComplexExcelProcess()
Dim SavePaintStatus As Boolean
SavePaintStatus = Application.ScreenUpdating
'...run some complex calculations...
Application.ScreenUpdating = SavePaintStatus
End Sub
Du kanske redan har upptäckt problemet i Access. Koden för att slå på och av skärmmålning i Access är en metod, vilket innebär att det inte finns något sätt att kontrollera dess nuvarande status. Att skriva kod som exemplet ovan är omöjligt i Access.
Hur hanterade jag problemet? Jag skapade en klassmodul och slog in Application.Echo
metod inuti en klassegenskap. Jag använde Singleton-mönstret (utan att inse att det var vad det var vid den tiden) för att bibehålla denna del av programtillståndet. Jag döpte den här klassen till clsApp och skapade en enda offentlig instans av klassen som deklarerades med Ny sökord så att det alltid är tillgängligt.
Exempelkod
Här är ett utdrag från min clsApp klass:
'--== clsApp class module ==--
Option Explicit
Option Compare Database
Private m_bEcho As Boolean
Private Sub Class_Initialize()
Application.Echo True
m_bEcho = True
End Sub
Public Property Get Echo() As Boolean
Echo = m_bEcho
End Property
Public Property Let Echo(ByVal bEcho As Boolean)
Application.Echo bEcho
m_bEcho = bEcho
End Property
I en separat standardmodul deklarerade jag en offentlig instans av klassen så här:
Public App As New clsApp
Jag hade nu ett sätt att kontrollera statusen för min applikations skärmmålning. Det enda kravet var att jag aldrig skulle använda Application.Echo
direkt i någon av mina koder. Jag använder alltid App.Echo
för att ställa in skärmmålningsflaggan nu.
Exempel på användning
Detta gjorde att jag kunde ändra min storleksändringskod till denna, som liknar mitt Excel-exempel från tidigare:
Public Sub weForm_Resize()
Dim SaveEcho As Boolean
SaveEcho = App.Echo 'Save the current screen painting state
App.Echo = False
'... loop through and resize controls based on their Tag property...
App.Echo = SaveEcho 'Restore the screen painting state
End Sub