ExcelVBAに時間指定処理を組み込む(OnTimeメソッド)


今回はExcelVBAで利用できる”時間指定処理”の解説です。

名前を「OnTime(オンタイム)メソッド」と言います。

このメソッドを用いる事で、「○時○分に実行」や「○時間(○分、○秒も可)後に実行」といった処理を実装する事ができます。

元々メルカリ用出品補助ツールに組み込んで『完全自動再出品』!

というのをやりたかったんですが、色々懸念があったので実装していませんでした。

先日ツールの一部の機能について質問を受けた際にこの処理の事を思い出したので、ちょっと紹介しておきます。

メソッドについて

■OnTime( EarliestTime, Procedure, LatestTime, Schedule )

上記の形式で記述します。

それぞれのパラメータについては以下の通り。

名前必須データ型説明
EarliestTimeVariantプロシージャを実行する時刻を指定。
ProcedureString実行するプロシージャ名を指定。
LatestTime×Variantプロシージャを実行できる最終時刻を指定します。たとえば、引数 LatestTime に、引数 EarliestTime で設定した値 + 30 を設定します。引数 EarliestTime に指定した時刻にはほかのプロシージャを実行しているため、Excel は待機、コピー、切り取り、または検索のいずれのモードでもないとします。その場合、Excel は実行中のプロシージャが終了するまで 30 秒間待ちます。30 秒以内に Excel が待機モードにならないとき、指定したプロシージャは実行されません。この引数を省略すると、Excel はプロシージャが実行できるまで待ちます。
Schedule×Variant新しい OnTime プロシージャを設定するには、 True を指定します。直前のプロシージャの設定を解除するには、 False を指定します。既定値は True です
※ × = 引数省略可

LatestTimeは少し分かり難いかもしれませんが、簡単に言うと

「EarliestTimeで指定した時間になっても処理が実行できない(他の処理が行われている)場合、LatestTimeに指定した時間まではProcedureの実行開始を待ちますよ。」

という事です。

例えばEarliestTimeに12:00と指定します。そしてLatestTimeに12:30と指定した場合、以下の様になります。


ケース① – 12:00になった時点で実行可能 ⇒ Procedure実行

ケース② – 12:00になった時点で実行不可 ⇒ 実行待機

ケース③ – 12:15に実行可能状態になった ⇒ Procedure実行

ケース④ – 12:30を過ぎた ⇒ Procedureは実行されずに終了


中々使い所のイメージが湧きませんが・・・いずれ何かの役に立つかもしれません。

ちなみにLatestTimeを指定しない場合は、実行可能になるまでずっと待ち続けます。それはそれで困るってシーンはありそうですね。

Scheduleは主にOnTimeで指定した予約を解除するために使用します。

引数に「False」を渡す事で予約を解除することができますが、当初EarliestTimeに指定した時間と同じもので無ければ解除できない点は注意が必要です。

例えば日時が固定とならない以下の様な場合、

「Now() + TimeValue(“00:01:00”)」
※TimeValue … 時刻を表す文字列からDate型へ値を変換する関数

と指定すると現在の時刻から1分後に実行となりますが、解除する際にこの現在の時刻(Nowの値)を保持していないと解除できなくなります。

条件によって取消を行う必要がある様な処理を組む場合は、シートなどに保存しておくといった対応が必要ですね。

スポンサーリンク

記述について

OnTime処理を使う場合は以下の様に記述します。

Sub SetAlarm()
    Application.OnTime Now() + TimeValue("00:00:05"), "alarm"
End Sub

Sub alarm()
    MsgBox "指定した時間になりました!"
End Sub

上記コードをコピーしてSetAlarmを実行すると、5秒後にalarm関数が実行されてメッセージボックスが表示されます。

また、呼び出す際に引数を渡したい場合は以下の様な記述となります。

Sub SetAlarm2()
    Application.OnTime Now() + TimeValue("00:00:05"), _
                       "'alarm """ & 10 & """'"
End Sub

Sub alarm(i As Integer)
    MsgBox "指定した時間になりました!" & i
End Sub
[実行結果]

Procedureとして記述する部分の全体をシングルクォーテーション(’)で囲み、引数をそれぞれダブルクォーテーション(”)で囲む形ですね。

「”‘alarm “”” & 10 & “””‘”」を分かり易くすると

alarm 10」こんな感じです。(分かりづらい…)

スポンサーリンク

ループさせてみる

さて・・・このOnTimeですが、処理を予約してその処理が終了した段階で更に次の予約を入れて・・・という風にすれば完全自動化が実現できるのでは!?

と思った方もいると思います。

それでは試してみましょうか。

Sub SetAlarm()
    Application.OnTime Now() + TimeValue("00:00:05"), "dispNow"
End Sub

Sub dispNow()
    Debug.Print Now()
    SetAlarm
End Sub

こんな感じの処理を作り、5秒おきにイミディエイトウィンドウに現在時刻を吐き出す処理を作りました。

早速実行してみると・・・

無事ループすることを確認しました!(*´∀`*)

これがあれば日中仕事をしていても自宅で出品ツールをガシガシ回していける様になりますね。

ところでこれ勝手に止まらないので、

手動でブレークポイント入れたり・・・

時間を判定してループ処理するタイミングを分岐させておいたり・・・

If Time() < TimeValue("12:00:00") Then
    'ループ
Else
    '終了処理
End If

といった対応が必要になると思います。

後、グローバル変数の値もそのまま保持している様なのでループ回数とかで判定するのもありですね。

いかがでしたでしょうか?

スタートアップフォルダに入れておいてPC起動と同時に立ち上げ。

更にWorkbook_Open関数と組み合わせて立ち上げと同時に予約なんて仕組みを作っておけば、毎日行っている単純作業なんてもうPC起動するだけでおっけー!

なんて環境も目指せそうですよね!

html処理と組み合わせれば「毎日○時に某サイトから○○のデータを取得して、そのまま自分のお店の価格更新」なんて事もVBAでできちゃう!

利用シーンを想像しただけでワクワクしますねー。

まぁ、今の所そんな感じの機能を作る予定は無いんですが・・・

とりあえず今作っている出品ツールには組み込んでいきたいですね。

関連記事と広告