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

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

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


マクロ VBA Timer

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


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

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

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

Application.OnTime メソッド

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

文字列としてのプロシージャー名を起動する方法(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 が返ります。
注意点
タイマー起動したプロシージャーでデバッグが出てしまうような事があると、
エクセルが操作不能になったり、
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技術解説」の記事

ドキュメントプロパティ(BuiltinDocumentProperties,CustomDocumentProperties)
VBAでファイルを規定のアプリで開く方法
Excelアドインの作成と登録について
VBAでのタイマー処理(SetTimer,OnTime)
マクロでShift_JIS文字コードか判定する
Byte配列と文字コード関数について
VBA+SeleniumBasicで検索順位チェッカー(改)
Applicationを省略できるApplicationのメソッド・プロパティ一覧
PowerQueryの強力な機能をVBAから利用する方法
ShapesとDrawingObjectsの相違点と使い方
新規挿入可能なシート名の判定


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

SQL関数と演算子|SQL入門(12月1日)
データの取得:集約集計、並べ替え(DISTINKT,GROUP BY,ORDER BY)|SQL入門(11月30日)
データの取得:条件指定(SELECT,WHERE)|SQL入門(11月29日)
データの挿入:バルクインサート|SQL入門(11月28日)
データの挿入(INSERT)と全削除|SQL入門(11月26日)
テーブル名変更と列追加(ALTER TABLE)とテーブル自動作成|SQL入門(11月25日)
テーブルの作成/削除(CREATE TABLE,DROP TABLE)|SQL入門(11月24日)
データベースに接続/切断|SQL入門(11月23日)
SQLiteのインストール|SQL入門(11月22日)
SQL入門:VBAでデータベースを使う|エクセルの神髄(11月22日)


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

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



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

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


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



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