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