Access
 sql >> Database >  >> RDS >> Access

Alchimia VBA:trasformare i metodi in proprietà

Uno dei modi migliori per accelerare l'esecuzione del codice in Excel è disattivare l'aggiornamento dello schermo utilizzando Application.ScreenUpdating proprietà. Puoi fare la stessa cosa in Access utilizzando Application.Echo metodo.

Si noti che ho indicato la versione di Excel come una proprietà e la versione Access come metodo . Ciò significa che possiamo controllare lo stato della pittura dello schermo in Excel, ma non possiamo farlo in Access. Questa risulta essere una differenza importante.

Ho diverse funzioni nella mia libreria di codici che disattivano temporaneamente la pittura dello schermo. La tecnica non viene generalmente utilizzata per fornire il tipo di aumento delle prestazioni che vediamo in Excel. Invece, migliora l'interfaccia impedendo il tipo di "form flashing" che si verifica se apportiamo modifiche rapide all'aspetto dei nostri moduli.

Un semplice caso d'uso

Ho un modulo di classe che fornisce funzionalità avanzate per il ridimensionamento individuale dei controlli dei moduli quando il modulo stesso viene ridimensionato. Quando stavo sviluppando questo modulo per la prima volta, l'effetto visivo era molto inquietante. Ogni volta che il modulo veniva ridimensionato, ogni singolo controllo veniva ridimensionato sullo schermo uno alla volta.

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

Questa è stata un'esperienza utente stridente. Per migliorarlo, disattivare l'aggiornamento dello schermo, apportare le modifiche, quindi riattivare l'aggiornamento dello schermo al termine della funzione.

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

Ciò ha migliorato notevolmente l'esperienza dell'utente. Ho iniziato a usare questa tecnica in tutto il mio codice che stava modificando l'interfaccia utente. Ed è allora che ho iniziato a riscontrare problemi.

Il problema è arrivato quando chiamavo più funzioni che disattivavano la pittura dello schermo di seguito. La prima funzione disattiva la pittura su schermo, apporta le sue modifiche, quindi riattiva la pittura su schermo. L'interfaccia eseguiva il flash del suo aggiornamento, quindi la seconda funzione disattivava di nuovo la pittura dello schermo, apportava le modifiche e infine riattivava definitivamente la pittura dello schermo.

Preservare lo stato della pittura dello schermo

Il modo migliore per gestire questa situazione consiste nel salvare lo stato della pittura dello schermo all'inizio della routine, disattivare la pittura dello schermo, quindi ripristinare lo stato della pittura dello schermo originale salvato all'inizio della routine. In Excel, questo era semplice:

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

Forse hai già individuato il problema in Access. Il codice per attivare e disattivare la pittura dello schermo in Access è un metodo, il che significa che non è possibile verificarne lo stato corrente. Scrivere codice come nell'esempio sopra è impossibile in Access.

Come ho gestito il problema? Ho creato un modulo di classe e ho eseguito il wrapping di Application.Echo metodo all'interno di una proprietà di classe. Ho usato il modello Singleton (senza rendermi conto che era quello che era in quel momento) per mantenere questo pezzo di stato del programma. Ho chiamato questa classe clsApp e creato una singola istanza pubblica della classe dichiarata con New parola chiave in modo che sia sempre disponibile.

Codice di esempio

Ecco un estratto dalla mia 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

In un modulo standard separato, ho dichiarato un'istanza pubblica della classe in questo modo:

Public App As New clsApp

Ora avevo un modo per controllare lo stato della pittura su schermo della mia applicazione. L'unico requisito era che non avrei mai usato Application.Echo direttamente in uno qualsiasi dei miei codici. Uso sempre App.Echo per impostare ora il flag per la pittura dello schermo.

Utilizzo del campione

Questo mi ha permesso di cambiare il mio codice di ridimensionamento in questo, che assomiglia molto al mio esempio Excel di prima:

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