【Excel】VBAによるタイマーの作り方

スポンサーリンク
Excel
スポンサーリンク

ExcelVBAでカウントダウンするタイマーを作る

世界的なテレワーク化が進んだことで「通勤時間は減ったけど会議が増えた・・・」というのは意外とメジャーな悩みの様子。
会議を円滑に進めるために会議目的を常に表示しつつ、カウントダウンするタイマーを昔VBAで作っていたので紹介する。↓こんなやつ

完成イメージ

機能要件

機能として以下を具備する。

  • ExcelVBAで実装する。Excelバージョンは2013以上を想定する。
  • 時・分・秒単位での指定を可能にする。ミリ秒は考慮しない。
  • 会議目的を指定セルに記入してもらい、それをユーザーフォームに反映する
  • 常時最前面表示するかしないかを選べるようにする
  • タイマーのストップも可能にする

画面

タイマー実行中
終了後は会議終了を通知

作り方

順序と前提(Excel開発タブの有効化)

このVBAは大きく3つの枠組みで出来ている。

  • ユーザーフォーム(実際タイマーとして表示されるGUI)
  • Excelブックの入力部分(時分秒とか会議目的)
  • スタートボタン(標準モジュールの動作)

どれから作ってもいいのだが、変数指定の問題があるので上から順番に作ることをおすすめする。
ただ大前提として、Excelの開発タブが有効になっている必要がある。
これは通常無効化されているので、有効化されていなければ以下記事を参考にまず有効化しておくこと。

ユーザーフォーム(実際タイマーとして表示されるGUI)の作り方

まず、実際にタイマーとして表示する枠組みをユーザーフォームにて作成していく。

「開発」タブより「コードの表示」をクリックする。

続いて、ツールバーより「ユーザーフォームの挿入」をクリックしてユーザーフォームを作成する。

ユーザーフォームの挿入
ユーザーフォーム編集画面

本タイマーでは機能要件に合わせて以下4つの要素(オブジェクト)を作成する。

  • タイマー表示用テキストボックス
  • 会議目的表示用テキストボックス(とラベル)
  • 最前面表示ON/OFFボタン
  • タイマーストップボタン

テキストボックスは、ツールボックスの「テキストボックス」より選択しデザインする。
また、会議目的注記はツールボックスの「ラベル」より選択しデザインする。

テキストボックス
ラベル

ここまでのデザインイメージはこんな感じ。

ボタンについては、ツールボックスの「コマンドボタン」より選択しデザインする。

コマンドボタン

ボタンデザイン後はこんな感じ。
なおボタンのCaption(表示名)については別途指定するのでここではデフォルトのCommandButton1、2のままでよい。

ガワのデザインが完了したので、ここからはボタン等の挙動により動作変更するようにコードを編集する。

ここまで、特に指定していなければそれぞれのオブジェクト名は以下となっているはず。
本記事でも以下オブジェクト名を前提にコードを記載する。

タイマー表示用テキストボックス:TextBox1
会議目的表示用テキストボックス:TextBox2
最前面表示ON/OFFボタン(ボタン左):CommandButton1
タイマーストップボタン(ボタン右):CommandButton2

プロジェクトプロパティから「フォーム」→「UserForm1」を右クリックし「コードの表示」を選択する。

「General」「Declarations」が選択されている状態で、以下のコードを記載(上書きコピー)する。

Private Declare Function FindWindow Lib "USER32" Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function SetWindowPos Lib "USER32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, _
ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long

''hWndInsertAfterの設定
Private Const TEMAE_SET = 0 '手前にセット
Private Const USIRO_SET = 1 '後ろにセット
Private Const TUNENI_TEMAE_SET = -1 '常に手前にセット
Private Const KAIJYO = -2 '解除
''wFlagsの設定
Private Const HYOUZI_SURU = &H40 '表示する
Private Const NO_SIZE = &H1 'サイズを設定しない
Private Const NO_MOVE = &H2 '位置を設定しない

Private Sub TextBox1_Change()

End Sub

Private Sub TextBox2_Change()

End Sub

Private Sub UserForm_Initialize()
CommandButton1.Caption = "[最前面]"
CommandButton2.Caption = "[ストップ]"
End Sub

Private Sub CommandButton1_Click()
Dim FORMHANDORU As Long
FORMHANDORU = FindWindow("ThunderDFrame", Me.Caption)
If CommandButton1.Caption = "[最前面解除]" Then
Call SetWindowPos(FORMHANDORU, KAIJYO, 0, 0, 0, 0, HYOUZI_SURU Or NO_MOVE Or NO_SIZE)
CommandButton1.Caption = "[最前面]"
ElseIf CommandButton1.Caption = "[最前面]" Then
Call SetWindowPos(FORMHANDORU, TUNENI_TEMAE_SET, 0, 0, 0, 0, HYOUZI_SURU Or NO_MOVE Or NO_SIZE)
CommandButton1.Caption = "[最前面解除]"
End If
End Sub

Private Sub CommandButton2_Click()
  Dim rng_s As Date
 
  rng_s = Time 'ストップボタンを押した時刻を取得
  Call MsgBox("再開する場合はボタンを押してください", vbSystemModal)  'メッセージボックス
 
  rng = rng + DateDiff("s", rng_s, Time) 'ストップしていた間の秒数を取得して上書き
End Sub
 
Private Sub UserForm_Terminate()
  End '終了時にDoを抜ける
End Sub

Private Sub 会議目的_Click()

End Sub

これでユーザーフォーム関連の設定は終了である。

Excelブックの入力部分(時分秒とか会議目的)の作り方

続いて、Excelブックで入力させる時分秒や会議目的の入力箇所、及びタイマー起動のためのスタートボタン作成を行っていく。

入力箇所の作成については好みである(あとで参照させる場所指定をしてやればいいだけなので)
本記事では、以下セルにそれぞれの入力箇所を作成する。
 B2:時 D2:分 F2:秒
 K2:会議目的

時分秒及び会議目的入力箇所。わかりやすいように背景色を変えるとよい

短いが、これでExcelブック入力部分の作成完了である。

スタートボタン(標準モジュールの動作)の作り方

最後に、タイマーを起動させるためのスタートボタン、及びスタートボタン押下時の挙動(標準モジュール)のコーディングを行う。

スタートボタンの作成は、Excelの「開発」タブ→「挿入」から「ボタン(フォームコントロール)」を選択し、ボタンを配置したい場所へデザインする。

スタートボタンを設置すると「マクロの登録」画面が出てくるので好きなマクロ名を記入し「新規作成」をクリックする。本記事ではマクロ名を「Timer」とする。
※この後のコードでは、Timerと命名していることを前提とする。

手順に沿って実施した場合、Module1のコード入力画面が開くので、以下のコードを記載(上書きコピー)する。
なお、時分秒や会議目的用テキストボックスの参照セルについては前述[Excelブックの入力部分(時分秒とか会議目的)の作り方]で決めた内容に合わせること。

Public rng As Double '一時停止時間格納用
 
Sub timer()
  Dim limit As Date, cnt_d As Double
 
  limit = DateAdd("s", Range("F2"), Time) '現在時刻に指定秒を足す
  limit = DateAdd("n", Range("D2"), limit) '現在時刻に指定分を足す
  limit = DateAdd("h", Range("B2"), limit) '現在時刻に指定時を足す
  rng = 0 '一時停止の時間リセット
 
  userForm1.Show vbModeless 'タイマーをモードレス表示
  userForm1.Repaint '強制表示
  
  
 
  Do
    cnt_d = DateDiff("s", Time, limit) + rng '指定時刻 - 現在時刻 (+ 一時停止)
    userForm1.TextBox1 = Format(TimeSerial(0, 0, cnt_d), "hh:nn:ss") '時:分:秒 で表示
    userForm1.TextBox2 = Workbooks(Application.ThisWorkbook.Name).Worksheets("Sheet1").Range("K2")
    If userForm1.TextBox1 = "00:00:00" Then
        userForm1.TextBox1 = ("会議終了") '0になったら会議終了を伝える
        userForm1.TextBox1.ForeColor = RGB(255, 0, 0) '時刻ボックスの文字色を赤にする
        userForm1.TextBox1.BackColor = RGB(255, 255, 0) '時刻ボックスの背景色を黄にする
        Call MsgBox("予定していた会議時間が経過しました", vbSystemModal)  '0になったら会議終了を伝える
        Exit Do 'Doを抜ける
    End If
    DoEvents 'イベントを実行
  Loop
 
End Sub

続いて、Excelブック画面に戻り、作成したボタンのラベルを変更する。
※この時点では「ボタン1」のように表示されてしまっていると思われるため

こんな感じ

以上でスタートボタン(標準モジュールの動作)は作成完了である。

テスト実行と文字サイズ等の微調整

ここまで手順どおりに出来たなら、作成したスタートボタンを押下し想定通り動作するか確認する。
おそらく、文字の大きさなどが小さかったりすると思うので、作成したユーザーフォームサイズに合わせてフォントサイズ変更やユーザーフォームのリデザインなどしてほしい。

フォントサイズを適当に作るとこんなにアンバランスに!

参考までに、ユーザーフォームのテキストボックスのフォントサイズの変更手順は以下の通り

  1. 「開発」タブよりユーザーフォームを表示する
  2. フォントサイズを変更したいテキストボックスをクリックし、オブジェクトプロパティの「Font」の右端にある「…」ををクリックする
  3. 「サイズ」から好みの大きさを選択し、OKをクリックする

使い方

作り方の説明が終わったところで、以下に基本的な使い方を記載する。

①設定したい時間を入力する。(B2:時 D2:分 F2:秒)
②会議の目的をK2に入力する。
③スタートボタンをクリックすると、以下の画面が表示されカウントダウンが始まる。

④最前面ボタンをクリックすると、常に前面に表示されるようになる(パワポプレゼン中など)
 最前面解除ボタンをクリックすると解除される。

⑤ストップボタンを押すとカウントダウンが停止し、以下の画面が表示される。
 OKをクリックするとカウントが再開される。

⑥会議時間が過ぎると、以下の画面が表示される。
 右上の「×」をクリックすることでウィンドウが閉じられる。

kかかいかいgかいぎ会議会議会議終了通知ポップアップ
会議終了が強調される

注意事項

本VBAには型Typeなどにより以下の注意事項がある。
※本ツールを作成し他者に配布する場合、注意事項としてどこかに記載しておくこと推奨。

  1. 分及び秒の有効設定範囲は0~59です。それ以上の値を設定すると差分値またはエラーとなります。
  2. 時の有効設定範囲は0~9です。それ以上の値を設定するとエラーとなります。
  3. 設定可能な範囲は9時6分7秒までです。それ以上の時間を設定するとオーバーフローでエラーとなります。
  4. タイマー画面を最前面にした状態でストップを押すとストップ画面が見えづらくなる場合があります。万が一OKをクリックできない状態になったら Enter を押してください。
  5. Ecxelのブックグループを他のExcelと同じにしていると、最前面モードのときの同ブックの他Ecxelを操作できません。本ファイルのみ単独のブックとして開くことを推奨します。

余談「なぜExcelVBAでタイマー?」

タイマーなんて今どきJavaでも何でもいくらでもフリーツールがある。
なぜわざわざExcelVBAで・・・?というのが多くの方の疑問と思われるが、単純に私のいた会社ではフリーウェアのダウンロードが許可されていなかったためである。
※そういう会社は多いのではないだろうか?

また、本ツールは多くの人に配布を想定していたため、変にPowerShellなどのスクリプトではなく使い慣れているExcelのほうが抵抗なく導入してもらえるかな、と思ったのが理由である。

改版履歴

2021/02/22 初版公開

コメント

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