DoEventsをうまく使う

AccessのVBAで時間のかかる処理をすると,画面が更新されなかったり,Windowsから(応答なし)扱いされたりします。それをさけるためには,DoEventsを呼び出すのですが,なにも考えずに呼び出すとパフォーマンスが大幅に低下します。これをなんとかしようという試みです。

まずは「DoEventsをパフォーマンスを下げずに使う方法」というページに紹介されていた手法を使ってみます。

Private Declare Function GetInputState Lib "USER32" () As Long
 
Public Sub CheckEvents()
    If GetInputState() Then
        DoEvents
    End If
End Sub

これは,GetInputState APIをコールして,待機中のイベントがあればDoEventsをコールするというものです。このCheckEventsプロシージャをDoEventsの代わりにコールすれば,パフォーマンスは低下せず,画面も更新されます。 

しかし,これでもしばらく(10秒ぐらい)Accessのウィンドウを放置しておくと,(応答なし)扱いになり,その後は画面更新もうまくされないようになってしまいます。そこで,一定時間がたったときには待機中のイベントがなくてもDoEventsをコールしてみます。

Private Declare Function GetInputState Lib "USER32" () As Long
Private m_Time As Variant
 
Public Sub CheckEvents()
    If GetInputState() Or (DateDiff("s", m_Time, Time) > 1) Then
        DoEvents
        m_Time = Time
    End If
End Sub

これは,待機中のイベントがあるか,前回の呼び出しより1秒以上経過しているか,いずれかであればDoEventsを呼び出します。モジュールレベル変数のm_Timeに前回呼び出し時の時間がセットされます。このプロシージャをDoEventsの代わりに呼び出せば,パフォーマンスと操作性の両立ができるのではないかと思います。

 

トラックバック


URL から "-MoIyadayo" を削除してトラックバックを送信してください。
トラックバックは承認後に表示されます。