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が教えてくれるといったことが、このメソッドで実現出来ます。Excelマクロの基礎と応用

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

時刻になったら音を鳴らして知らせる(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技術解説」の記事

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

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

クラスとCallByNameとポリモーフィズム(多態性)|VBA技術解説(4月6日)
VBAでのタイマー処理(SetTimer,OnTime)|VBA技術解説(4月3日)
クラスとイベントとマルチプロセス並列処理|VBA技術解説(4月2日)
エクセルの日付と時刻のまとめ|エクセル関数超技(3月6日)
Excelシートの複雑な計算式を解析するVBA|VBAサンプル集(2月18日)
VBAクラスの作り方:独自Rangeっぽいものを作ってみた|VBA技術解説(2月16日)
VBAクラスの作り方:列名のプロパティを自動作成する|VBA技術解説(2月14日)
VBAクラスの作り方:列名の入力支援と列移動対応|VBA技術解説(2月11日)
クラスを使って他ブックのイベントを補足する|VBA技術解説(2月6日)
Excelアドインの作成と登録について|VBA技術解説(2月3日)

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

1.ひらがな⇔カタカナの変換|エクセル基本操作
2.最終行の取得(End,Rows.Count)|VBA入門
3.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.RangeとCellsの使い方|ExcelマクロVBA入門
6.変数とデータ型(Dim)|ExcelマクロVBA入門
7.マクロって何?VBAって何?|ExcelマクロVBA入門
8.繰り返し処理(For Next)|ExcelマクロVBA入門
9.とにかく書いて見よう(Sub,End Sub)|VBA入門
10.セルに文字を入れるとは(Range,Value)|VBA入門



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

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


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






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

    本文下部へ