【VBScript】PCの作業中に使えるキッチンタイマーをつくる

Windows PC

こんにちは、ふみです。みなさんは PC(パソコン)の作業中にカップラーメンを作ることはありますか?

カップラーメンはお湯を入れた後、3分間の待ち時間が必要です。しかし、その間も PC の作業を続けなければならないほど忙しかった場合、作業に集中しすぎて時間の経過を忘れてしまうとカップラーメンの麺がのびてしまいます。
また、場所によってはキッチンタイマーのアラームを出せない時もあると思います。

そこで、今回は PC の作業中のアプリケーション画面のさらに上に情報メッセージでお知らせするキッチンタイマーを VBScript で作る方法について紹介します。

キッチンタイマーは Excel等の VBA でも作れますが、VBScript で作ったほうが Excel等のアプリケーションの起動が不要な上、CPU の負荷が 0 なので使い勝手が良いです。

アプリケーション画面のさらに上にメッセージで表示する

音を鳴らさずに時間の経過を知らせるには、使用中のアプリケーション画面のさらに上にメッセージで表示するのが有効です。これができないと、作業中にメッセージが出ても気づけません。

使用中のアプリケーション画面のさらに上にメッセージボックスを表示させるには、MsgBox関数の引数buttons の定数を vbSystemModal に設定します
記述のしかたは次のとおりです。

MsgBox "領域展開", vbSystemModal

上記のコードを Windows 10 のアクセサリから開いたメモ帳へコピー&ペースト後、文字コードを「ANSI」に設定し、適当なファイル名に拡張子「.vbs」をつけてデスクトップ等に保存すると、すぐに動作確認できます。
保存した vbsファイルをダブルクリックすると、PC の画面上に「領域展開」が表示され、他のアプリケーションの画面を選択しても、「領域展開」のメッセージが画面の一番上にくるようになります。
キッチンタイマーの時間経過のお知らせは、このメッセージ表示を使うと効果的です。

もし「領域展開」が文字化けしてしまう場合、文字コードが「ANSI」になっていません。文字コードを「ANSI」に設定し、上書き保存してください。

このコードは Excel等の VBA でも動作します。

キッチンタイマーをつくる

キッチンタイマーのプログラムは次のとおりです。

サンプルコード

Option Explicit Dim strInput, sngMinute, strText Const c_strTitle = "キッチンタイマー", c_intLimit = 60, c_sngDefault = 3 Do     strInput = InputBox("時間(分)を数字で入力してください(最大" _         & c_intLimit & ")" & vbCrLf & vbCrLf _         & "次に「OK」をクリックしてください" & vbCrLf & vbCrLf _         & "指定した時間が経過するとメッセージでお知らせします" _         , c_strTitle, c_sngDefault)     If strInput = vbNullString Then 'キャンセル時         sngMinute = 0     ElseIf IsNumeric(strInput) = False Then '数字以外の入力時         sngMinute = c_intLimit + 1     Else         sngMinute = CSng(strInput)     End If     If sngMinute> c_intLimit Or sngMinute <0 Then         MsgBox "0~" & c_intLimit & "までの数字を入力してください" _             , vbExclamation, c_strTitle         sngMinute = -1     End If Loop Until sngMinute>= 0
If sngMinute > 0 Then
    WScript.Sleep Int(sngMinute * 60 * 1000)
    If sngMinute >= 1 Then strText = Int(sngMinute) & "分"
    
    If sngMinute <> Int(sngMinute) Then
        strText = strText & Int((sngMinute - Int(sngMinute)) * 60) & "秒"
    End If
    MsgBox strText & "経過しました", vbSystemModal + vbInformation, "お知らせ"
End If
WScript.Quit

上記のコードを Windows 10 のアクセサリから開いたメモ帳へコピー&ペースト後、文字コードを「ANSI」に設定し、適当なファイル名に拡張子「.vbs」をつけてデスクトップ等に保存すると、すぐに動作確認できます。
保存した vbsファイルをダブルクリックすると、あらかじめ「3」の数字が入力されているキッチンタイマーのインプットボックスが表示されます。(数字は0より大きい、60以下の数値に変更できます)

そのまま「OK」をクリックする(または数字を入力して Enter キーを押す)と、指定した時間(3分)後に時間経過をお知らせするメッセージが画面の一番上に表示されます。

「キャンセル」や右上の「×」をクリックすると、プログラムが終了します。

解説

3行目の定数c_intLimit はキッチンタイマーの設定できる最大の時間(分)です。この数値を変更するとキッチンタイマーの最大の時間を60分以外に変更できます。
同じ3行目の定数c_sngDefault はキッチンタイマーにあらかじめセットされる数値です。この数値を変更するとキッチンタイマーの最初の設定を3分以外に変更できます。

5~23行目はインプットボックスに指定した範囲の数値が入力されるまでループします。

6~10行目はダブルクリック時に最初に表示されるインプットボックスの設定です。インプットボックスに入力された数値は変数strInput に文字列として代入されます。

11行目の条件、インプットボックスの「キャンセル」、右上の「×」をクリックしたときは、12行目で変数sngMinute に「0」を代入します。

13行目の条件、インプットボックスに数値以外が入力されたときは、14行目で変数sngMinute に「キッチンタイマーの最大の時間 + 1」を代入します。ここで文字データを数値にしておかないと、次以降の処理でエラーが発生します。

16行目の CSng関数はインプットボックスに入力された数値の文字を単精度浮動小数点データ型に強制的に変換しています。この処理がないとインプットボックスで入力された数字が文字列として認識されてしまうので、18行目の数字の比較で不具合が発生します。

18行目の条件、変数sngMinute が定数c_intLimit(= 60)以上、または 0 未満の時は、19行目の MsgBox関数の引数を vbExclamation にして注意メッセージを表示した後、21行目で変数sngMinute を「-1」に変更します。
この場合、21行目のループを抜ける条件を満たせないので、11行目のインプットボックスからやり直しになります。

24行目の条件、変数sngMinute > 0 はインプットボックスに、0より大きい、60以下の数値が入力された時です。インプットボックスの「キャンセル」、右上の「×」をクリックした場合、変数sngMinute = 0 になるので、ここで処理が終了します。

25行目の WScript.Sleep はスクリプトのプロセスをミリ秒で指定された長さだけ非アクティブにした後、実行を再開します。インプットボックスで入力した値を代入した変数sngMinute の時間の単位は分なので、ミリ秒に換算しています。
変数sngMinute × 60 × 1000 の計算値に小数点以下を切り捨てた値がミリ秒です。
このSleepメソッドは、CPU の負荷がかからないので、キッチンタイマーの時間の計測にちょうど良いです。

26行目はインプットボックスで入力した値が1分以上の時、お知らせするメッセージに分表示を追加しています。(2021/04/15 表示不具合修正の為Int関数を追加しました)

28行目はインプットボックスで入力した値に小数点以下が含まれる場合、29行目の処理でお知らせするメッセージに秒表示を追加します。

31行目は指定したが経過したときにお知らせする情報メッセージです。
MsgBox関数の引数は vbSystemModal に設定しているので、使用中のアプリケーション画面のさらに上にメッセージが表示されます。その後に続く vbInformation は情報メッセージアイコンを表示すると共に、Beep音を鳴らします。

Visual Basic for Applications で使用する

上記の VBScript のサンプルコードを Excel等の VBA に転用する方法について解説します。

VBA で Sleepメソッドを使用する方法

Excel等の VBA で Sleepメソッドを使用する場合、モジュールの先頭に「Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)」を記述します。
次にSleepメソッドの記述は「WScript.Sleep」を「Sleep」に変更します。

これでExcel等の VBA でも Sleepメソッドが使用できます。
ただし、Excel等の VBA は Sleepメソッドで停止している時にVBAの実行を中断できなくなるので、注意が必要です。

キッチンタイマーを VBA で使用する方法(非推奨)

ここで紹介したサンプルコードを Excel等の VBA で使用する場合、モジュールには次のように記述します。

  • モジュールの先頭に「Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)」を記述する
  • 1行目の Option Explicit の下に「Sub (適当なプロシージャ名)()」を記述する
  • 25行目の 「WScript.Sleep」を「Sleep」に変更する
  • 最下行の「WScript.Quit」を「End Sub」に変更する

これで Excel等の VBA でもキッチンタイマーのサンプルコードが一応、動作します。
しかし、Excel等の VBAで利用するには、Excel等のアプリケーションを起動しないと使えません。
また、Excel等の VBA は Sleepメソッドで停止している時にVBAの実行を中断できなくなるので、タイマーが止まるまで Excel を終了できなくなります。したがって、このサンプルコードはVBAの転用をお勧めできません

Excel等の VBA でキッチンタイマーを作る場合、サンプルコードのようにSleepメソッドに直接時間を指定するのではなく、Timer 関数で経過時間を判定するループ内に、SleepメソッドとDoEvents関数を組み合わせて CPU の休止を短くして、VBA の実行を中断できるプログラムにしたほうが良いです。
しかし、キッチンタイマーは VBScript のほうが使い勝手が良いので、VBA でキッチンタイマーを作っても役に立つ機会がないと思います。

まとめ

  • キッチンタイマーは Excel等の VBA でも作れるが、VBScript で作ったほうが Excel等のアプリケーションの起動が不要な上、CPU の負荷が 0 なので使い勝手が良い
  • 使用中のアプリケーション画面のさらに上にメッセージボックスを表示させるには、MsgBox関数の引数を vbSystemModal にする
  • インプットボックスで入力された数字は文字列として認識される
  • WScript.Sleep はミリ秒で指定された長さだけ VBScript を非アクティブにした後、実行を再開する
  • Sleepメソッドは、CPU が開放されて負荷がかからなくなるで、キッチンタイマーの時間の計測にちょうど良い
  • Excel等の VBA は Sleepメソッドで停止している時に VBA の実行を中断できなくなる

ありがとうございました。

コメント

タイトルとURLをコピーしました