Een van de beste manieren om de uitvoering van code in Excel te versnellen, is door schermupdates uit te schakelen met de Application.ScreenUpdating eigendom. U kunt hetzelfde doen in Access met behulp van de Application.Echo methode.
Merk op dat ik naar de Excel-versie verwees als een eigenschap en de Access-versie als een methode . Dat betekent dat we de status van schermschilderen in Excel kunnen controleren, maar dat kunnen we niet doen in Access. Dit blijkt een belangrijk verschil te zijn.
Ik heb verschillende functies in mijn codebibliotheek die het schilderen van schermen tijdelijk uitschakelen. De techniek wordt over het algemeen niet gebruikt om het soort prestatieverbetering te bieden dat we in Excel zien. In plaats daarvan verbetert het de interface door het type "formulierflitsen" te voorkomen dat optreedt als we snelle wijzigingen aanbrengen in het uiterlijk van onze formulieren.
Een eenvoudige use-case
Ik heb een klassenmodule die geavanceerde functies biedt voor het individueel wijzigen van het formaat van formulierbesturingselementen wanneer het formaat van het formulier zelf wordt gewijzigd. Toen ik deze module voor het eerst ontwikkelde, was het visuele effect erg verontrustend. Telkens wanneer het formaat van het formulier werd gewijzigd, werd het formaat van elk afzonderlijk besturingselement één voor één op het scherm gewijzigd.
Public Sub weForm_Resize()
'... loop through and resize controls based on their Tag property...
End Sub
Dit was een schokkende gebruikerservaring. Om het te verbeteren, zou ik het bijwerken van het scherm uitschakelen, mijn wijzigingen aanbrengen en het bijwerken van het scherm weer inschakelen aan het einde van de functie.
Public Sub weForm_Resize()
Application.Echo False
'... loop through and resize controls based on their Tag property...
Application.Echo True
End Sub
Dit verbeterde de gebruikerservaring aanzienlijk. Ik begon deze techniek te gebruiken in al mijn code die de gebruikersinterface aanpaste. En toen begon ik problemen te krijgen.
Het probleem kwam toen ik meerdere functies achter elkaar zou aanroepen die schermschilderen uitschakelden. De eerste functie zou schermschilderen uitschakelen, de wijzigingen aanbrengen en vervolgens schermschilderen weer inschakelen. De interface zou de update laten knipperen, waarna de tweede functie het schilderen van het scherm weer zou uitschakelen, de wijzigingen zou aanbrengen en ten slotte het schilderen van het scherm voorgoed weer zou inschakelen.
Behoud van schermschildering
De betere manier om met deze situatie om te gaan, is door de status van het schermschilderen aan het begin van de routine op te slaan, het schilderen van het scherm uit te schakelen en vervolgens de oorspronkelijke status van het schermschilderen te herstellen die aan het begin van de routine is opgeslagen. In Excel was dit eenvoudig:
Sub ComplexExcelProcess()
Dim SavePaintStatus As Boolean
SavePaintStatus = Application.ScreenUpdating
'...run some complex calculations...
Application.ScreenUpdating = SavePaintStatus
End Sub
Misschien heb je het probleem al opgemerkt in Access. De code om schermschildering in en uit te schakelen in Access is een methode, wat betekent dat er geen manier is om de huidige status te controleren. Het schrijven van code zoals het bovenstaande voorbeeld is onmogelijk in Access.
Hoe heb ik het probleem aangepakt? Ik heb een klassenmodule gemaakt en de Application.Echo
. ingepakt methode binnen een klasse-eigenschap. Ik gebruikte het Singleton-patroon (zonder te beseffen dat het destijds zo was) om dit stukje programmastatus te behouden. Ik noemde deze klas clsApp en een enkele openbare instantie gemaakt van de klasse die is gedeclareerd met de Nieuwe zoekwoord zodat het altijd beschikbaar is.
Voorbeeldcode
Hier is een fragment uit mijn clsApp klas:
'--== 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
In een aparte standaardmodule heb ik een openbare instantie van de klasse als volgt gedeclareerd:
Public App As New clsApp
Ik had nu een manier om de status van de schermafbeelding van mijn toepassing te controleren. De enige vereiste was dat ik Application.Echo
nooit zou gebruiken direct in een van mijn code. Ik gebruik altijd App.Echo
om de schermschilderingsvlag nu in te stellen.
Voorbeeld gebruik
Hierdoor kon ik mijn code voor het wijzigen van de grootte hierin wijzigen, die veel lijkt op mijn Excel-voorbeeld van eerder:
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