sql >> Base de Datos >  >> RDS >> Access

Alquimia de VBA:convertir métodos en propiedades

Una de las mejores formas de acelerar la ejecución de código en Excel es desactivar la actualización de pantalla mediante Application.ScreenUpdating propiedad. Puede hacer lo mismo en Access usando Application.Echo método.

Tenga en cuenta que me referí a la versión de Excel como una propiedad y la versión de Access como método . Eso significa que podemos verificar el estado de la pintura de pantalla en Excel, pero no podemos hacerlo en Access. Esto resulta ser una diferencia importante.

Tengo varias funciones en mi biblioteca de códigos que desactivan temporalmente la pintura de pantalla. La técnica generalmente no se usa para proporcionar el tipo de aumento de rendimiento que vemos en Excel. En cambio, mejora la interfaz al evitar el tipo de "parpadeo de formulario" que ocurre si hacemos cambios rápidos en la apariencia de nuestros formularios.

Un caso de uso sencillo

Tengo un módulo de clase que proporciona funciones avanzadas para cambiar el tamaño de los controles de formulario individualmente cuando se cambia el tamaño del formulario. Cuando estaba desarrollando este módulo por primera vez, el efecto visual era muy inquietante. Cada vez que se cambiaba el tamaño del formulario, cada control individual cambiaba de tamaño en la pantalla uno a la vez.

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

Esta fue una experiencia de usuario discordante. Para mejorarlo, desactivaría la actualización de pantalla, haría mis cambios y luego volvería a activar la actualización de pantalla al final de la función.

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

Esto mejoró sustancialmente la experiencia del usuario. Empecé a usar esta técnica en todo mi código que modificaba la interfaz de usuario. Y fue entonces cuando comencé a tener problemas.

El problema surgió cuando invocaba varias funciones que desactivaban la pintura de pantalla seguidas. La primera función desactivaría la pintura de pantalla, haría sus cambios y luego volvería a activar la pintura de pantalla. La interfaz mostraría su actualización, luego la segunda función desactivaría la pintura de pantalla nuevamente, haría sus cambios y finalmente volvería a activar la pintura de pantalla para siempre.

Preservar el estado de pintura de pantalla

La mejor manera de manejar esta situación sería guardar el estado de pintura de pantalla al comienzo de la rutina, apagar la pintura de pantalla y luego restaurar el estado de pintura de pantalla original guardado al comienzo de la rutina. En Excel, esto fue sencillo:

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

Quizás ya haya detectado el problema en Access. El código para activar y desactivar la pintura de pantalla en Access es un método, lo que significa que no hay forma de verificar su estado actual. Escribir código como el ejemplo anterior es imposible en Access.

¿Cómo manejé el problema? Creé un módulo de clase y envolví el Application.Echo método dentro de una propiedad de clase. Usé el patrón Singleton (sin darme cuenta de lo que era en ese momento) para mantener esta parte del estado del programa. Llamé a esta clase clsApp y creó una sola instancia pública de la clase declarada con Nuevo palabra clave para que siempre esté disponible.

Código de muestra

Aquí hay un extracto de mi clsApp clase:

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

En un módulo estándar separado, declaré una instancia pública de la clase así:

Public App As New clsApp

Ahora tenía una manera de verificar el estado de la pintura de pantalla de mi aplicación. El único requisito era que nunca usaría Application.Echo directamente en cualquiera de mi código. Siempre uso App.Echo para configurar la bandera de pintura de pantalla ahora.

Uso de muestra

Esto me permitió cambiar mi código de cambio de tamaño a este, que se parece mucho a mi ejemplo de Excel anterior:

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