Access
 sql >> Base de données >  >> RDS >> Access

VBA Alchemy :transformer des méthodes en propriétés

L'un des meilleurs moyens d'accélérer l'exécution du code dans Excel consiste à désactiver la mise à jour de l'écran à l'aide de Application.ScreenUpdating biens. Vous pouvez faire la même chose dans Access en utilisant Application.Echo méthode.

Notez que j'ai fait référence à la version Excel en tant que propriété et la version Access comme méthode . Cela signifie que nous pouvons vérifier l'état de la peinture d'écran dans Excel, mais nous ne pouvons pas le faire dans Access. Cela s'avère être une différence importante.

J'ai plusieurs fonctions dans ma bibliothèque de codes qui désactivent temporairement la peinture d'écran. La technique n'est généralement pas utilisée pour fournir le type d'amélioration des performances que nous voyons dans Excel. Au lieu de cela, il améliore l'interface en empêchant le type de "clignotement de formulaire" qui se produit si nous apportons des modifications rapides à l'apparence de nos formulaires.

Un cas d'utilisation simple

J'ai un module de classe qui fournit des fonctionnalités avancées pour redimensionner individuellement les contrôles de formulaire lorsque le formulaire lui-même est redimensionné. Lorsque j'ai commencé à développer ce module, l'effet visuel était très troublant. Chaque fois que le formulaire était redimensionné, chaque contrôle individuel se redimensionnait à l'écran un par un.

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

Ce fut une expérience utilisateur choquante. Pour l'améliorer, je désactiverais la mise à jour de l'écran, apporterais mes modifications, puis réactiverais la mise à jour de l'écran à la fin de la fonction.

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

Cela a considérablement amélioré l'expérience utilisateur. J'ai commencé à utiliser cette technique dans tout mon code qui modifiait l'interface utilisateur. Et c'est là que j'ai commencé à rencontrer des problèmes.

Le problème est survenu lorsque j'appelais plusieurs fonctions qui désactivaient la peinture d'écran à la suite. La première fonction désactiverait la peinture d'écran, apporterait ses modifications, puis réactiverait la peinture d'écran. L'interface flasherait sa mise à jour, puis la deuxième fonction désactiverait à nouveau la peinture d'écran, apporterait ses modifications, et enfin réactiverait la peinture d'écran pour de bon.

Préserver l'état de peinture de l'écran

La meilleure façon de gérer cette situation serait d'enregistrer l'état de peinture d'écran au début de la routine, de désactiver la peinture d'écran, puis de restaurer l'état de peinture d'écran d'origine enregistré au début de la routine. Dans Excel, c'était simple :

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

Peut-être avez-vous déjà repéré le problème dans Access. Le code pour activer et désactiver la peinture d'écran dans Access est une méthode, ce qui signifie qu'il n'y a aucun moyen de vérifier son état actuel. L'écriture de code comme l'exemple ci-dessus est impossible dans Access.

Comment ai-je géré le problème ? J'ai créé un module de classe et enveloppé le Application.Echo méthode à l'intérieur d'une propriété de classe. J'ai utilisé le modèle Singleton (sans me rendre compte que c'était ce qu'il était à l'époque) pour maintenir cet état de programme. J'ai nommé cette classe clsApp et créé une seule instance publique de la classe déclarée avec le Nouveau mot clé afin qu'il soit toujours disponible.

Exemple de code

Voici un extrait de mon clsApp classe :

'--== 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

Dans un module standard séparé, j'ai déclaré une instance publique de la classe comme suit :

Public App As New clsApp

J'avais maintenant un moyen de vérifier l'état de la peinture d'écran de mon application. La seule exigence était que je n'utiliserais jamais Application.Echo directement dans n'importe lequel de mes codes. J'utilise toujours App.Echo pour définir le drapeau de peinture d'écran maintenant.

Exemple d'utilisation

Cela m'a permis de changer mon code de redimensionnement en celui-ci, qui ressemble beaucoup à mon exemple Excel précédent :

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