ExcelマクロVBA技術解説
VBAでのタイマー処理(SetTimer,OnTime)

ExcelマクロVBAの問題点と解決策、エクセルVBAの技術的解説
最終更新日:2019-04-03

VBAでのタイマー処理(SetTimer,OnTime)


マクロ VBA Timer


VBAでタイマー処理(一定時間間隔で処理)を行う方法についての解説です。


最も一般的な方法は、Application.OnTimeを使う方法になりますが、
今回の主題としては、WindowsAPIのSetTimerを紹介します。


まずはApplication.OnTimeの確認してから、
次にWindowsAPIのSetTimerを紹介します。

以下のサンプルを実行するときは、他のExcelブックは閉じておいてください。
特にSetTimerの実行時は、Excel強制終了に巻き込まれないように注意してください。
そういう危険性もあるということを承知の上で実行してください。


Application.OnTime メソッド

基本的な使い方については以下を参照してください。
第120回.OnTimeメソッド
指定された時刻にマクロを実行させたい時、今から一定時間後にマクロを実行させたい時、このような時に使うのが、OnTimeメソッドです。お昼になったらExcelが教えてくれたり、1時間経ったらExcelが教えてくれるといったことが、このメソッドで実現出来ます。

文字列としてのプロシージャー名を起動する方法(Run,OnTime)
文字列変数の中にプロシージャー名が入っていて、そのプロシージャーを起動したい場合になります、実際には、そのような構造が良いとは思えませんが、知っていればプログラミングの幅が広がります。使うのは、OnTimeメソッドorRunメソッドになります。

時刻になったら音を鳴らして知らせる(OnTime)

では、サンプルになります。

Option Explicit

Public mOnTime As Date

Sub TimerProc()
 Range("A1") = Now()
End Sub

Sub OnTimeStart()
  Call TimerProc
  mOnTime = Now() + TimeSerial(0, 0, 1)
  Call Application.OnTime(mOnTime, "OnTimeStart")
End Sub

Sub OnTimeStop()
  '同一のProcedureとEarliestTimeがないとエラーになる
  On Error Resume Next
  Call Application.OnTime(mOnTime, "OnTimeStart", , False)
End Sub 

プロハージャー「OnTimeStart」を実行すると、
アクティブシートのA1セルに日時が1秒ごとに更新されて表示されます。
普通のデジタル時計です。
これが実行されている間も、他のExcel作業は普通に行えます。

ただし、注意深く良く見てください。
カーソルがチカチカしていないでしょうか。
僅かで一瞬ですがウエイトカーソルになっているのが確認できるはずです。
どうも嫌ですよね。(まあ、気分の問題ですけど…)

確認したら、プロハージャー「OnTimeStop」でタイマー処理を終了しておいてください。


WindowsAPI:SetTimer関数

まずはサンプルコードから

Option Explicit

Public Declare PtrSafe Function SetTimer Lib "USER32" _

                    (ByVal hwnd As Long, _
                    ByVal nIDEvent As Long, _
                    ByVal uElapse As Long, _
                    ByVal lpTimerFunc As LongPtr) As Long
Public Declare PtrSafe Function KillTimer Lib "USER32" _
                    (ByVal hwnd As Long, _
                    ByVal nIDEvent As Long) As Long

Public mTimerID As Long

Sub TimerProc()
  If mTimerID = 0 Then End '終了できない時の対策
  On Error Resume Next 'デバッグ出すとExcelが固まるので
  Range("A1") = Now()
End Sub

Sub TimerStart()
  If mTimerID <> 0 Then
    MsgBox "起動済です。"
    Exit Sub
  End If
  mTimerID = SetTimer(0&, 1&, 1000&, AddressOf TimerProc)
End Sub

Sub TimerStop()
  Call KillTimer(0&, mTimerID)
  mTimerID = 0
End Sub

引数の説明
hWnd タイマーに関連付けるウィンドウのハンドル
nIDEvent タイマーID(任意の値、0以外)
uElapse タイマーの間隔(ミリ秒単位1/1000秒)
lpTimerFunc タイマーのコールバック関数のポインタを指定
戻り値
戻り値は関数が成功すると新しいタイマIDが返され、失敗すると 0 が返ります。
注意点
Aイマー起動したプロシージャーでデバッグが出てしまうような事があると、
エクセルが操作不能になったり、
Excelそのものを終了しても勝手にExcelが立ち上がってしまったり、
いろいろとめんどうな事が起こったりします。

上記掲載のコードでは、これらに対応して、
If mTimerID = 0 Then End '終了できない時の対策
On Error Resume Next 'デバッグ出すとExcelが固まるので
これらを一応入れていますが、テスト過程では決して過信しないでください。
最悪、Windowsを終了しても良いくらいのつもりで実行してもらえれば問題ありませんが、
少なくとも、Excelはタスクを終了しても良いつもりで実行してください。。
もちろん、ちゃんとVBAを書けばちゃんと動きます。
Application.OnTimeと違い、そもそもタイマー処理機能のAPI関数ですので、
1回起動すると、その後は指定間隔ごとにプロシージャーが起動されます。
このタイマーを止めるものが、KillTimer関数になります。

プロシージャー「TimerStart」を実行すると、
アクティブシートのA1セルに日時が1秒ごとに更新されて表示されます。
OnTimeと違って、カーソルがチカチカしないはずです。
動いていることを意識できないくらいスムーズに動作している事が確認できると思います。


最後に

今回は、タイマー処理をVBAに実装する場合のごく簡単な紹介でした。

さすがに、サンプルコードのようなセルに時刻を出力することは無いとは思いますが、、、
タイマー処理自体はプログラミングとしては普通の事ですので、知識としては覚えておくこと良いでしょう。

いつかタイマー処理が必要になった時に本記事を思い出してもらえれば良いと思います。





同じテーマ「マクロVBA技術解説」の記事

画像サイズ(横x縦)の取得について
文字種(ひらがな、全半角カタカナ、半角英大文字等々)の判定
オブジェクトとプロパティの真実
オブジェクト式について
オブジェクトの探索方法
条件付きコンパイル(32ビット64ビットの互換性)
ドキュメントプロパティ(BuiltinDocumentProperties,CustomDocumentProperties)
VBAでファイルを規定のアプリで開く方法
Excelアドインの作成と登録について
VBAでのタイマー処理(SetTimer,OnTime)
マクロでShift_JIS文字コードか判定する

新着記事NEW ・・・新着記事一覧を見る

Withステートメントの実行速度と注意点|VBA技術解説(6月6日)
VBA+SeleniumBasicで検索順位チェッカー(改)|VBA技術解説(6月2日)
マクロでShift_JIS文字コードか判定する|VBA技術解説(6月1日)
Shift_JISのテキストファイルをUTF-8に一括変換|VBAサンプル集(5月31日)
「VBAによる解析シリーズその2 カッコ」をやってみた|エクセル(5月21日)
VBA+SeleniumBasicで検索順位チェッカー作成|VBA技術解説(5月18日)
テーブル操作のVBAコード(ListObject)|VBA入門(5月12日)
テーブル操作の概要(ListObject)|VBA入門(5月12日)
VBAのスクレイピングを簡単楽にしてくれるSelenium|VBA技術解説(5月6日)
Excelワークシート関数一覧(2010以降)|VBAリファレンス(4月22日)

アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|ExcelマクロVBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数とデータ型(Dim)|ExcelマクロVBA入門
6.ひらがな⇔カタカナの変換|エクセル基本操作
7.繰り返し処理(For Next)|ExcelマクロVBA入門
8.マクロって何?VBAって何?|ExcelマクロVBA入門
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.ExcelマクロVBAの基礎を学習する方法|エクセルの神髄



  • >
  • >
  • >
  • VBAでのタイマー処理(SetTimer,OnTime)

    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。






    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。

    本文下部へ