Access
 sql >> Base de Dados >  >> RDS >> Access

Alquimia VBA:Transformando Métodos em Propriedades


Uma das melhores maneiras de acelerar a execução de código no Excel é desativar a atualização de tela usando o Application.ScreenUpdating propriedade. Você pode fazer a mesma coisa no Access usando o Application.Echo método.

Observe que me referi à versão do Excel como uma propriedade e a versão do Access como um método . Isso significa que podemos verificar o status da pintura de tela no Excel, mas não podemos fazer isso no Access. Isso acaba sendo uma diferença importante.

Eu tenho várias funções na minha biblioteca de código que desativam temporariamente a pintura de tela. A técnica geralmente não é usada para fornecer o tipo de aumento de desempenho que vemos no Excel. Em vez disso, ele melhora a interface, evitando o tipo de "intermitente de formulário" que ocorre se fizermos alterações rápidas na aparência de nossos formulários.

Um caso de uso simples


Eu tenho um módulo de classe que fornece recursos avançados para redimensionar controles de formulário individualmente quando o próprio formulário é redimensionado. Quando eu estava desenvolvendo este módulo pela primeira vez, o efeito visual era muito perturbador. Sempre que o formulário fosse redimensionado, cada controle individual seria redimensionado na tela, um de cada vez.
Public Sub weForm_Resize()
   '... loop through and resize controls based on their Tag property...
End Sub

Esta foi uma experiência de usuário chocante. Para melhorá-lo, eu desativaria a atualização da tela, faria minhas alterações e, em seguida, ativaria a atualização da tela novamente no final da função.
Public Sub weForm_Resize()
    Application.Echo False
    
    '... loop through and resize controls based on their Tag property...
    
    Application.Echo True
End Sub

Isso melhorou substancialmente a experiência do usuário. Comecei a usar essa técnica em todo o meu código que estava modificando a interface do usuário. E foi aí que comecei a ter problemas.

O problema surgiu quando eu chamava várias funções que desativavam a pintura de tela seguidas. A primeira função desativaria a pintura de tela, faria suas alterações e, em seguida, ativaria a pintura de tela novamente. A interface piscaria sua atualização, então a segunda função desligaria a pintura de tela novamente, faria suas alterações e, finalmente, ativaria a pintura de tela novamente.

Preservando o estado da pintura da tela


A melhor maneira de lidar com essa situação seria salvar o status de pintura de tela no início da rotina, desativar a pintura de tela e restaurar o status de pintura de tela original salvo no início da rotina. No Excel, isso era simples:
Sub ComplexExcelProcess()
    Dim SavePaintStatus As Boolean
    SavePaintStatus = Application.ScreenUpdating
    
    '...run some complex calculations...
    
    Application.ScreenUpdating = SavePaintStatus
End Sub

Talvez você já tenha percebido o problema no Access. O código para ativar e desativar a pintura de tela no Access é um método, o que significa que não há como verificar seu status atual. Escrever código como o exemplo acima é impossível no Access.

Como eu lidei com o problema? Eu criei um módulo de classe e envolvi o Application.Echo método dentro de uma propriedade de classe. Eu usei o padrão Singleton (sem perceber que era o que era na época) para manter esse estado do programa. Chamei esta classe de clsApp e criou uma única instância pública da classe declarada com o Novo palavra-chave para que ela esteja sempre disponível.

Código de amostra


Aqui está um trecho do meu clsApp aula:
'--== 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

Em um módulo padrão separado, declarei uma instância pública da classe assim:
Public App As New clsApp

Agora eu tinha uma maneira de verificar o status da pintura de tela do meu aplicativo. O único requisito era que eu nunca usaria Application.Echo diretamente em qualquer um dos meus códigos. Eu sempre uso o App.Echo para definir o sinalizador de pintura de tela agora.

Uso de amostra


Isso me permitiu alterar meu código de redimensionamento para isso, que se parece muito com meu exemplo do 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