プロシージャを繰り返し実行する為に
OnTimeメソッドを使った方法を
記事「 一定時間ごとに繰り返し実行する 」で取り上げました。
上記の記事の方法だと
一番最初にプロシージャを実行した時間から
15分後に再度プロシージャが実行されます。
この繰り返しです。
実際は、ほかのプロシージャが実行中なら
それが終わってから実行されるため時間がずれることもあります。
また、実行するプロシージャ自身が時間がかかるため
ここでも時間がずれていきます。
ずれても問題がなければいいのですが
例えば1時間の内の0分から14分、15分から29分、30分から44分、45分から59分までの
それぞれの時間の間で1回づつ実行したい場合など
タイミングが悪いと実行できない時間帯が出てくるかもしれません。
そこで1時間の内で15分ごとに実行する方法を考えてみます。
プロシージャを繰り返し実行するのには
上記記事と同様にOnTimeメソッドを使います。
OnTimeメソッドの時間の指定を工夫します。
1時間のうちの15分ごとに実行すればよいので
テキトーに5分、20分、35分、50分に実行するようにします。
0分から14分、15分から29分、30分から44分、45分から59分の時間帯を
それぞれ時間帯0、時間帯1、時間帯2、時間帯3とします。
プロシージャを実行している時間帯で条件分岐して
次回の時刻を決定したいと思います。
具体的には、
0分から14分は、次回の実行時刻は20分
15分から29分、次回の実行時刻は35分
30分から44分、次回の実行時刻は50分
45分から59分、次回の実行時刻は5分
になります。
時間帯を区別するには次の式を使います。
Int(Minute(Now) / 15)
つまり、分を15で割った商です。
0分から14分は、Int(Minute(Now) / 15) = 0
15分から29分、Int(Minute(Now) / 15) = 1
30分から44分、Int(Minute(Now) / 15) = 2
45分から59分、Int(Minute(Now) / 15) = 3
になります。
下のプロシージャについての簡単な説明をします。
Dateは現在の日付を返します。
TimeSerial関数は引数で指定した時、分、秒に対応する時刻を返します。
例えば、
TimeSerial(12, 32, 08) = 12時32分8秒
詳細はVBAヘルプにあります。
コードはこちら
1時間の内で15分ごとに実行するコード1: Sub macro101106a() '1時間の内の15分ごとに実行する
Dim MyTime As Date '処理 Debug.Print "現在の時刻:" & Now '次回の実行時刻を設定 Select Case Int(Minute(Now) / 15) Case 0 MyTime = Date + TimeSerial(Hour(Now), 20, 0) Case 1 MyTime = Date + TimeSerial(Hour(Now), 35, 0) Case 2 MyTime = Date + TimeSerial(Hour(Now), 50, 0) Case 3 MyTime = Date + TimeSerial(Hour(Now), 65, 0) End Select 'MyTimeにmacro101106a自身を実行 Debug.Print "次の実行時間:" & MyTime Application.OnTime MyTime, "macro101106a"
End Sub |
さて、プログラムとしてこれで機能すると思いますが、
条件分岐なんか使わずに
1つの式でやっちゃいたい願望があるので
別の方法も考えてみます。
まずは時刻設定の説明用のプロシージャです。
i を Minute(Now) の代わりにしています。
「15分の区切り」とは15、30、45、60(0)のことです。
時刻設定の説明用のコード:Sub macro101106b() '1時間の内の15分ごとに実行する '時間を指定する式についての準備 'iを「分」とする (0 <= i <= 59)
Sheets.Add Dim i As Integer 'タイトル Cells(1, 1) = "i = 分" Cells(1, 2) = "Int(i / 15)" & Chr(10) & _ "=現在(分)の時間帯" Cells(1, 3) = "(Int(i / 15) + 1) * 15" & Chr(10) & _ "=現在(分)の次の15分の区切り" Cells(1, 4) = "(Int(i / 15) + 1) * 15 - i" & _ Chr(10) & "=現在(分)の次の15分の区切りまでの時間(分)" Cells(1, 5) = "(Int(i / 15) + 1) * 15 - i + 5" & _ Chr(10) & "=左に5分を足したもの(分後に実行)" For i = 0 To 59 Rows(2).Insert '現在(分) Cells(2, 1) = i '現在(分)は1時間のどの時間帯か Cells(2, 2) = Int(i / 15) '現在(分)の次の15分の区切り Cells(2, 3) = (Int(i / 15) + 1) * 15 '現在(分)の次の15分の区切りまでの時間(分) Cells(2, 4) = (Int(i / 15) + 1) * 15 - i '上に5分を足したもの Cells(2, 5) = (Int(i / 15) + 1) * 15 - i + 5 Next i Columns("A:E").ColumnWidth = 100 Columns("A:E").AutoFit Rows(1).AutoFit End Sub |
次が条件分岐なしで時間を設定する方法のプロシージャです。
コードはこちら
1時間の内で15分ごとに実行するコード2: Sub macro101106c() '1時間の内の15分ごとに実行する
Dim MyTime As Date '処理 Debug.Print "現在の時刻:" & Now '次回の現在からの実行時刻を設定 MyTime = TimeSerial(0, _ (Int(Minute(Now) / 15) + 1) * 15 - Minute(Now) + 5, _ -Second(Now)) '現在からMyTime後にmacro101106c自身を実行 Debug.Print "次の実行時間:" & Now + MyTime Application.OnTime Now + MyTime, "macro101106c" End Sub |
さらに柔軟性を高めて
固定した間隔ではなく
x 分ごとに実行する方法です。
説明用のコードはこちら
x 分ごとの時刻設定の説明用のコード: Sub macro101106d() '1時間の内のx分ごとに実行する '時間を指定する式についての準備 'iを「分」とする (0 <= i <= 59)
Sheets.Add Dim i As Integer Dim x As Integer '(1 < x) x = 10 'タイトル Cells(1, 1) = "i = 分" Cells(1, 2) = "Int(i / x)" & Chr(10) & _ "=現在(分)の時間帯" Cells(1, 3) = "(Int(i / x) + 1) * x" & Chr(10) & _ "=現在(分)の次のx分の区切り" Cells(1, 4) = "(Int(i / x) + 1) * x - i" & Chr(10) & _ "=現在(分)の次のx分の区切りまでの時間(分)" Cells(1, 5) = "(Int(i / x) + 1) * x - i + Int(x / 2)" & _ Chr(10) & "=左にInt(x/2)分を足したもの(分後に実行)" For i = 0 To 59 Rows(2).Insert '現在(分) Cells(2, 1) = i '現在(分)は1時間のどの時間帯か Cells(2, 2) = Int(i / x) '現在(分)の次のx分の区切り Cells(2, 3) = (Int(i / x) + 1) * x '現在(分)の次のx分の区切りまでの時間(分) Cells(2, 4) = (Int(i / x) + 1) * x - i '上にInt(x/2)分を足したもの Cells(2, 5) = (Int(i / x) + 1) * x - i + Int(x / 2) Next i Columns("A:E").ColumnWidth = 100 Columns("A:E").AutoFit Rows(1).AutoFit End Sub |
次が
x 分ごとの条件分岐なしで時間を設定する方法のプロシージャです。
コードはこちら
1時間の内で x 分ごとに実行するコード: Sub macro101106e() '1時間の内のx分ごとに実行する '条件、 1 < x <= 60 かつ xは60の約数
Dim MyTime As Date Dim x As Integer x = 10 '処理 Debug.Print "現在の時刻:" & Now '次回の現在からの実行時刻を設定 MyTime = TimeSerial(0, _ (Int(Minute(Now) / x) + 1) * x - Minute(Now) + Int(x / 2), _ -Second(Now)) '現在からMyTime後にmacro101106e自身を実行 Debug.Print "次の実行時間:" & Now + MyTime Application.OnTime Now + MyTime, "macro101106d" End Sub |
定数xで間隔を指定します。
ただし、x に条件があります。
コメント