Access
 sql >> Datenbank >  >> RDS >> Access

VBA-Alchemie:Methoden in Eigenschaften umwandeln

Eine der besten Möglichkeiten, die Codeausführung in Excel zu beschleunigen, besteht darin, die Bildschirmaktualisierung mithilfe von Application.ScreenUpdating zu deaktivieren Eigentum. Sie können dasselbe in Access tun, indem Sie Application.Echo verwenden Methode.

Beachten Sie, dass ich die Excel-Version als Eigenschaft bezeichnet habe und die Access-Version als Methode . Das bedeutet, dass wir den Status der Bildschirmmalerei in Excel überprüfen können, aber das können wir in Access nicht. Dies stellt sich als wichtiger Unterschied heraus.

Ich habe mehrere Funktionen in meiner Codebibliothek, die das Bildschirmzeichnen vorübergehend deaktivieren. Die Technik wird im Allgemeinen nicht verwendet, um die Art von Leistungssteigerung bereitzustellen, die wir in Excel sehen. Stattdessen verbessert es die Benutzeroberfläche, indem es die Art des "Form-Blinkens" verhindert, das auftritt, wenn wir das Erscheinungsbild unserer Formulare schnell ändern.

Ein einfacher Anwendungsfall

Ich habe ein Klassenmodul, das erweiterte Funktionen zum individuellen Ändern der Größe von Formularsteuerelementen bietet, wenn die Größe des Formulars selbst geändert wird. Als ich dieses Modul zum ersten Mal entwickelte, war der visuelle Effekt sehr beunruhigend. Wenn die Größe des Formulars geändert wurde, änderte sich die Größe jedes einzelnen Steuerelements einzeln auf dem Bildschirm.

Public Sub weForm_Resize()
   '... loop through and resize controls based on their Tag property...
End Sub

Dies war eine erschütternde Benutzererfahrung. Um es zu verbessern, würde ich die Bildschirmaktualisierung deaktivieren, meine Änderungen vornehmen und dann die Bildschirmaktualisierung am Ende der Funktion wieder einschalten.

Public Sub weForm_Resize()
    Application.Echo False
    
    '... loop through and resize controls based on their Tag property...
    
    Application.Echo True
End Sub

Dies verbesserte die Benutzererfahrung erheblich. Ich fing an, diese Technik in meinem gesamten Code zu verwenden, der die Benutzeroberfläche modifizierte. Und da fing ich an, auf Probleme zu stoßen.

Das Problem trat auf, als ich mehrere Funktionen hintereinander aufrief, die das Bildschirmmalen deaktivierten. Die erste Funktion würde die Bildschirmmalerei ausschalten, ihre Änderungen vornehmen und dann die Bildschirmmalerei wieder einschalten. Die Schnittstelle würde ihr Update flashen, dann würde die zweite Funktion das Screen Painting wieder deaktivieren, ihre Änderungen vornehmen und schließlich das Screen Painting für immer wieder einschalten.

Bildschirmdarstellungszustand beibehalten

Der bessere Weg, mit dieser Situation umzugehen, wäre, den Bildschirmmalstatus zu Beginn der Routine zu speichern, das Bildschirmmalen auszuschalten und dann den ursprünglichen Bildschirmmalstatus wiederherzustellen, der zu Beginn der Routine gespeichert wurde. In Excel war dies einfach:

Sub ComplexExcelProcess()
    Dim SavePaintStatus As Boolean
    SavePaintStatus = Application.ScreenUpdating
    
    '...run some complex calculations...
    
    Application.ScreenUpdating = SavePaintStatus
End Sub

Vielleicht haben Sie das Problem bereits in Access entdeckt. Der Code zum Ein- und Ausschalten des Screen Painting in Access ist eine Methode, was bedeutet, dass es keine Möglichkeit gibt, den aktuellen Status zu überprüfen. Das Schreiben von Code wie im obigen Beispiel ist in Access nicht möglich.

Wie bin ich mit dem Problem umgegangen? Ich habe ein Klassenmodul erstellt und Application.Echo umschlossen Methode innerhalb einer Klasseneigenschaft. Ich habe das Singleton-Muster verwendet (ohne zu wissen, dass es damals so war), um diesen Programmzustand aufrechtzuerhalten. Ich habe diese Klasse clsApp genannt und eine einzelne öffentliche Instanz der mit New deklarierten Klasse erstellt Schlüsselwort, damit es immer verfügbar ist.

Beispielcode

Hier ein Auszug aus meiner clsApp Klasse:

'--== 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 einem separaten Standardmodul habe ich eine öffentliche Instanz der Klasse wie folgt deklariert:

Public App As New clsApp

Ich hatte jetzt eine Möglichkeit, den Status der Bildschirmdarstellung meiner Anwendung zu überprüfen. Die einzige Bedingung war, dass ich niemals Application.Echo verwenden würde direkt in einem meiner Codes. Ich verwende immer App.Echo um jetzt das Screenpainting-Flag zu setzen.

Beispielnutzung

Dadurch konnte ich meinen Größenänderungscode wie folgt ändern, der meinem Excel-Beispiel von früher sehr ähnlich sieht:

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