VBA練習問題
VBA100本ノック 70本目:ステータスバーに1秒ごとに時刻が表示

VBAを100本の練習問題で鍛えます
公開日:2021-01-19 最終更新日:2021-09-22

VBA100本ノック 70本目:ステータスバーに1秒ごとに時刻が表示


ブックが開かれたら、ステータスバーに1秒ごとに時刻を表示する問題です。


ツイッター連動企画です。
ツイートでの見やすさを考慮して、ブック・シート指定等を適宜省略しています。

VBAテスト用のサンプルデータはご自身でご用意ください。


出題

出題ツイートへのリンク

#VBA100本ノック 70本目
ブックが開かれたら、自動的にステータスバーに1秒ごとに時刻が表示されるようにしてください。
ただし、1分後には時刻表示を終了してください。
※セル入力中は、時刻は更新されなくて構いません。


VBA作成タイム

この下に頂いた回答へのリンクと解説を掲載しています。
途中まででも良いので、できるだけ自分でVBAを書いてみましょう。


他の人の回答および解説を見て、書いたVBAを見直してみましょう。


頂いた回答

解説

「セル入力中は、時刻は更新されなくて構いません。」
つまりこれは時刻表示している間もセル入力出来なければならないという事です。
普通の方法としては2通りあります。
DoEvents関数
Application.OnTimeメソッド
まずはDoEvents関数から
時間計算と1秒ごとにする部分は様々だと思います。

Private Sub Workbook_Open()
  Dim dtStart As Date: dtStart = Now()
  Dim dtStop As Date: dtStop = DateAdd("s", 60, dtStart)
  Dim dtNext As Date: dtNext = dtStart
  
  Do While Now() <= dtStop
    If Now() >= dtNext Then
      dtNext = DateAdd("s", 1, dtNext)
      Application.StatusBar = Format(Now(), "hh:mm:ss")
    End If
    DoEvents
  Loop
  
  Application.StatusBar = False
End Sub


Application.OnTimeは、マクロが起動される時刻を指定します。
1秒ごとにマクロを起動することで時刻表示させることが出来ます。
DoEventsとOnTimeは、どちらも一長一短はあります。
OnTimeのサンプルVBAと若干の解説を記事補足に書きました。

※2021/09/21現在、Office365で上記が正しく動作しなくなっています。
補足の下に「追記」に対応VBAを掲載しました。


補足

時刻取得にはNow()を使っています。
TimeやTimerを使った回答も見受けられましたが、これらは午前0時からの時刻なので0時を挟む可能性がある場合は都合が悪いことになります。

DoEvents関数
Application.OnTimeメソッド
実行中の大きな違いとしては、
・CPU使用
・カーソルのちらつき
・セル編集中の時刻更新
・VBE編集可否

DoEvents
・CPUの1スレッドを占有
・カーソルはちらつかない
・セル編集中も時刻更新される
・VBE編集はできない

マクロ VBA 100本ノック

OnTime
・時刻表示する一瞬だけ
・カーソルがちらつく
・セル編集中は時刻更新されない
・VBE編集できる

環境により若干の違いがあるかもしれませんが、概ねこのような違いがあります。
一長一短はありますが、1秒ごとに1分間ということならどちらでも良いと思います。
もし1分ごとに1時間というような場合は、DoEventsでは1時間マクロが動きっぱなしになってしまいますので、いささか都合が緩いように思います。
このような場合は、Application.OnTimeを使ったほうが良いでしょう。

Application.OnTimeは、マクロが起動される時刻を指定するものです。
したがって、1秒後の指定は、
Now() + 1秒
このように指定します。
※1秒の書き方はいろいろあります。

ブックモジュール
Private Sub Workbook_Open()
  Call VBA100_70_01
End Sub

標準モジュール
Public Sub VBA100_70_01()
  Static dtStart As Date
  If dtStart = 0 Then dtStart = Now()
  If Now() > dtStart + DateSerial(0, 0, 60) Then
    Application.StatusBar = False
    Exit Sub
  End If
  Application.StatusBar = Format(Now(), "hh:mm:ss")
  Call Application.OnTime(Now() + TimeSerial(0, 0, 1), "VBA100_70_01")
End Sub

上記では、Static変数を使っていますが、モジュールレベル変数を使っても良いでしょう。


追記

マクロ VBA100本ノック
https://twitter.com/yamaoka_ss/status/1440344244267282453

現象確認しました。
最近のupdateで挙動が変化したようです。
本来、添付画像のようにOnTimeで切り離した方が良いのですが、本解答作成時には問題なかったので先の掲載のとうりとしていました。
※記事には本件を追記します。
※現在でも365以外(2019,2013,2010で確認)では問題なく動いています。

ThisWorkbook
Private Sub Workbook_Open()
  Application.OnTime [Now()+"0:0:0.1"], "VBA100_70_01"
End Sub

標準モジュール
Sub VBA100_70_01()
  Dim dtStart As Date: dtStart = Now()
  Dim dtStop As Date: dtStop = DateAdd("s", 60, dtStart)
  Dim dtNext As Date: dtNext = dtStart
 
  Do While Now() <= dtStop
    If Now() >= dtNext Then
      dtNext = DateAdd("s", 1, dtNext)
      Application.StatusBar = Format(Now(), "hh:mm:ss")
    End If
    DoEvents
  Loop
 
  Application.StatusBar = False
End Sub

上記の通りですが、もともと最初に掲載したVBAはWorkbook_Openの途中で停止させているので、あまりよろしくおりません。
Workbook_OpenでApplication.OnTimeを使うことにより次のプロシージャーを切り離しています。

Application.OnTimeは、そこで停止することなくプロージシャーの起動予約をするだけで次に進みます。
したがってWorkbook_Openを抜けて終了するので、期待した通りに動作するようになります。


サイト内関連ページ

第120回.OnTimeメソッド|VBA入門
・OnTimeメソッドの構文 ・OnTimeメソッドの使用例 ・OnTimeメソッドの実践例
時刻になったら音を鳴らして知らせる(OnTime)
・作成するシート ・標準モジュールのVBAコード ・VBAコードの解説 ・ビープ音を変更したい場合 ・時刻になったら音を鳴らして知らせる最後に
文字列としてのプロシージャー名を起動する方法(Run,OnTime)
文字列変数の中にプロシージャー名が入っていて、そのプロシージャーを起動したい場合になります、実際には、そのような構造が良いとは思えませんが、知っていればプログラミングの幅が広がります。使うのは、OnTimeメソッドorRunメソッドになります。
VBAでのタイマー処理(SetTimer,OnTime)
・Application.OnTime メソッド ・WindowsAPI:SetTimer関数 ・最後に




同じテーマ「VBA100本ノック」の記事

67本目:ComboBoxとListBox
68本目:全テキストボックスの転記
69本目:ダブルクリックでセル結合を解除
70本目:ステータスバーに1秒ごとに時刻が表示
71本目:パワーポイントへグラフを貼り付け
72本目:ITをDXに変換(文字列操作)
73本目:新規ブックにボタン作成しマクロ登録
74本目:1シート複数表をDB形式に変換
75本目:ログインフォームの作成
76本目:ボタンの表示名の位置へ移動
77本目:シート挿入イベント


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

AIは便利なはずなのに…「AI疲れ」が次の社会問題になる|生成AI活用研究(2026-02-16)
カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




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


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



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