【VBA】現在時刻を取得する方法|Time・Nowの違いと実務での使い分け
VBAで現在時刻を取得する基本
VBAで現在時刻を取得する処理は、TimeまたはNowを使えば数行で書けます。大切なのは、取得方法そのものより、時刻だけが必要なのか、日付を含む実行日時まで必要なのかを先に決めることです。
・Timeで現在時刻だけを取得する
VBAで「いま何時か」を取得したいだけなら、最初に覚えるのはTimeです。Microsoft Learnでは、Time関数は現在のシステム時刻を示すVariantのDate値を返すと説明されています。時刻だけを扱いたい処理では、日付まで持たせる必要がないため、用途と返される情報が一致します。
基本形は Dim currentTime As Date と currentTime = Time の2行で十分です。取得した値をメッセージで確認するなら MsgBox currentTime、イミディエイトウィンドウへ出すなら Debug.Print currentTime と続けます。関数に引数はなく、実行した時点のコンピューターのシステム時刻が基準になります。
変数をStringではなくDateとして持つ理由は、あとで比較や計算に使いやすいからです。時刻を最初から「13:45:30」のような文字列にすると、人には読みやすくても、時間差の計算や時刻順の比較をするときに再変換が必要になります。表示とデータ保持を分けると、後から仕様が増えても扱いやすくなります。
たとえば処理の開始時刻を記録するなら Dim processStartTime As Date、続けて processStartTime = Time とします。単に現在時刻を取得するだけなら短いコードですが、変数名に役割を入れておくと「何の時刻なのか」が一目で分かります。
Timeが参照するのはPCのシステム時刻です。したがって、端末側の時計がずれていれば、VBAが取得する時刻もそのずれを引き継ぎます。VBAが独自に標準時を問い合わせているわけではないため、業務ログに厳密な時刻が必要な環境では、端末の時刻同期が前提になります。
Timeは「現在時刻を読む関数」であり、Timeステートメントとは役割が異なります。Microsoft LearnではTimeステートメントはシステム時刻を設定するための構文として分けて説明されています。現在時刻を取得する記事では、誤って Time = … のような設定処理を書かないことが重要です。
初心者が確認しやすい最小例は、Sub GetCurrentTime()、Dim currentTime As Date、currentTime = Time、MsgBox currentTime、End Sub という流れです。まず値を取得し、その後で表示や記録へ使うという順番にすると、処理の役割を追いやすくなります。
時刻だけで条件分岐したい場面にもTimeは使えます。たとえば営業時間内だけ処理を許可する、特定時刻以降に別処理へ切り替える、といった判断です。ただし日付をまたぐ条件では単純な大小比較だけでは読みづらくなるため、条件の対象が「時刻だけ」なのか「日時」なのかを先に決める必要があります。
Timeを使うか迷ったら、記録の寿命を考えると判断しやすくなります。その日の処理中だけ使い、日付は別の情報から分かるならTimeで十分です。反対に、ファイルを翌日以降に開いて記録だけを見ても意味が通じる必要があるなら、時刻単独では情報不足になりやすいためNowを検討します。
条件判定へTimeを使う場合は、比較対象も時刻としてそろえることが重要です。日付付きのNowと時刻だけの基準値を無理に比較すると、日付部分の影響が入り、式の意味が読み取りにくくなります。比較したい情報の粒度を合わせることが、誤判定を避ける基本です。
また、現在時刻を何度も参照する処理では「同じ瞬間の値を使いたいか」を考えます。同一の処理単位で同じ時刻を記録したいなら、最初にTimeを変数へ1回だけ格納して再利用します。各行でTimeを呼ぶと、処理中に秒が変わり、同じイベントの記録なのに値が少しずれることがあります。
・セルに現在時刻を入力する
現在時刻をセルへ残したい場合は、RangeのValueへTimeを代入します。たとえば ThisWorkbook.Worksheets(“Sheet1”).Range(“A2”).Value = Time とすれば、マクロを実行した時点の時刻をA2セルへ値として書き込めます。
Range(“A2”).Value = Time だけでも動く場合がありますが、実務ではブックとシートを明示する方が安全です。ActiveSheetに依存すると、利用者が別シートを表示した状態でマクロを実行したとき、意図しないセルへ書き込む可能性があります。
書き込み先を変数にしておく方法もあります。Dim targetCell As Range、Set targetCell = ThisWorkbook.Worksheets(“Sheet1”).Range(“A2”)、targetCell.Value = Time とすれば、対象セルと値の処理を分けて読めます。
セルへTimeを書き込むと、値と表示形式は別々に管理されます。内部に秒まで含まれていても、セルの表示形式が h:mm なら画面上は「13:45」のように見えます。秒が見えないからといって、Timeが秒を取得していないとは限りません。
秒まで見せたいなら、値を書いた後で targetCell.NumberFormat = “hh:mm:ss” と設定できます。Microsoft LearnのRange.NumberFormatの説明でも、セルの表示形式を取得・設定するプロパティとしてNumberFormatが定義されています。
この考え方は「値を変える処理」と「見せ方を変える処理」を分離することにつながります。Timeは現在時刻の値を取得し、NumberFormatはExcel上の見え方を決めます。両者を分けて理解すると、時刻が正しく保存されているのに表示だけが想定と違う、といったトラブルを切り分けやすくなります。
複数行へ履歴を追加する場合も基本は同じです。最終行を求めて次の行へTimeを書けば、作業開始時刻や受付時刻などを連続して記録できます。ただし日をまたいで後日確認する履歴では、時刻だけでは日付が分からないため、次のH2で説明するNowの方が適する場合があります。
セルへ直接書く方法は簡単ですが、既存値を上書きしてよいかも確認が必要です。履歴用途では固定セルを毎回上書きするのか、最終行の次へ追記するのかで設計が変わります。最終更新時刻なら固定セル、操作履歴なら追記型というように、保存目的とセル配置を合わせます。
複数のセルへ同じ時刻を入れる場合は、各セルでTimeを呼び出すより、1度取得したDate値を複数セルへ書く方が整合しやすくなります。たとえば recordedTime = Time としてからA列とD列へ同じrecordedTimeを書けば、同一イベントの記録時刻が一致します。
セルへ値を入れた後で利用者が表示形式を変更しても、元のDate値が保持されていれば別形式で再表示できます。これは、最初から文字列として保存する方法との大きな違いです。後から「秒も見たい」「12時間表記にしたい」といった要望が出ても、値を取り直さず表示だけ変えられます。
VBAのTimeとNowで取得できる値の違い
TimeとNowの違いは、取得できる情報の範囲です。見た目が似ていても、Timeは時刻、Nowは日付と時刻を扱うため、記録を後からどう使うかによって選択が変わります。
・Timeは現在の時刻を取得する
TimeとNowはどちらも現在の情報を取得しますが、返される範囲が違います。Timeは現在の時刻、Nowは現在の日付と時刻です。Microsoft Learnでも、Timeはcurrent system time、Nowはcurrent date and timeを返す関数として明確に分けられています。
Timeを選ぶ代表例は、処理開始時刻、受付時刻、現在の時間帯、時刻だけを使う条件判定です。後から「何月何日の記録か」を確認する必要がないなら、時刻だけを扱う方が意図を読み取りやすくなります。
Date型は日付と時刻を扱える型ですが、Timeから受け取った値では時刻部分が目的になります。Date型の内部では日付・時刻が数値として扱われるため、文字列の見た目だけで判断せず、値として保持することが大切です。
たとえば Dim checkTime As Date、checkTime = Time としておけば、後続のHour、Minute、Secondなどで構成要素を取り出す処理にもつなげられます。この記事の中心は現在時刻の取得ですが、Date型で受けることで拡張しやすい状態を保てます。
一方、ログを翌日以降も確認するならTimeだけでは情報が不足します。「15:30に実行」と分かっても、それが今日なのか昨日なのか、1週間前なのか判断できないからです。履歴の保存期間が長いほど、この不足は大きくなります。
時刻だけを記録する設計は、目的が本当に時刻だけに限定されている場合に向いています。たとえば当日のシフト内で開始・終了を管理し、日付が別の列で既に管理されているなら、Timeでも十分です。必要な情報が別列にあるかどうかも判断材料になります。
Timeのメリットは、扱う情報が時刻に絞られることです。たとえば午前と午後で処理を切り替える、受付締切時刻を過ぎたか確認する、といった条件では、日付を含まない方が意図を説明しやすいことがあります。情報が少ないことは欠点ではなく、目的と一致していればコードを簡潔にする要素になります。
一方、日付をまたぐ可能性がある処理ではTimeの単独利用に注意します。23時台に開始して0時台に終了した処理で単純に時刻だけを見ると、終了の方が小さい値に見えるためです。日付またぎが仕様上あり得るなら、開始と終了をNowで日時として持つ方が自然です。
Timeは現在時刻を取得するためのもので、処理の実行速度を厳密に測るための専用関数ではありません。Microsoftのキーワード一覧ではTimerが処理時間の計測用途として別に示されています。目的が「何時に始めたか」か「何秒かかったか」かを分けて考えると、関数選択を誤りにくくなります。
・Nowは現在の日付と時刻をまとめて取得する
Nowは、コンピューターのシステム日付と時刻に基づいて現在日時を返します。Dim currentDateTime As Date、currentDateTime = Now とすれば、実行した瞬間の年月日と時刻を1つのDate値として保持できます。
更新履歴、実行ログ、最終処理日時、エラー発生日時など、「いつ起きたか」を後から確認する情報にはNowが向いています。時刻だけでは日付を特定できませんが、Nowなら日付と時刻をまとめて残せます。
セルへ記録するなら ThisWorkbook.Worksheets(“Log”).Range(“A2”).Value = Now のように書けます。表示を yyyy/mm/dd hh:mm:ss にしたい場合は、値の代入とは別にNumberFormatを設定します。ここでも、値と表示を分ける考え方が有効です。
TimeよりNowの方が情報量は多いものの、常にNowを使えばよいわけではありません。たとえば「現在が17時を過ぎたか」のような時刻だけの判定へ日時をそのまま持ち込むと、日付部分を意識した式になり、コードの意図が分かりにくくなることがあります。
判断の基準は、後から日付が必要になるかです。時刻だけを使う一時的な判断ならTime、後から記録として見返すならNow、と考えると選びやすくなります。
TimeとNowはどちらもPCのシステム時計を基準にします。したがって、複数PCで同じブックを使う場合、各端末の時計がずれているとログの並びに違和感が出る可能性があります。共有運用では時刻同期の状態も確認しておくと安心です。
用途を表にすると、現在時刻だけならTime、現在日時ならNow、当日だけの開始時刻ならTime、長期保存する更新履歴ならNow、という整理になります。関数名の覚え方よりも、保存後に何を判断したいかから逆算する方が実務では迷いにくくなります。
Nowが向くのは、値を見ただけで出来事の発生日時を特定したい場面です。最終更新、承認、取込、出力、エラー記録などは、時刻だけでは履歴の証拠として弱いため、年月日を含むNowの方が情報として完結しやすくなります。
Nowで記録した値を別シートへコピーしたり並べ替えたりする場合も、Date型のまま扱うと日付と時刻を一体として並べられます。表示だけを整えているなら、見た目が変わっても基礎となる日時値は同じです。履歴一覧では、この性質を活かして新しい順や古い順に整理できます。
ただし、Nowも端末のシステム日時をそのまま使います。時刻の正確性が契約や監査に直結する業務では、PCローカル時刻だけを正式記録としてよいかを確認してください。一般的な社内管理では十分でも、厳格な証跡では別の時刻源が必要になることがあります。
VBAで現在時刻を記録するときの実務的な使い分け
実務では、関数名だけで選ぶのではなく、記録の保存期間と利用目的でTimeとNowを使い分けます。開始時刻のような一時的な情報と、更新履歴のような長期記録では必要な情報が異なります。
・処理開始時刻をTimeで記録する
処理開始時刻だけを把握したいなら、Timeを変数へ入れてから必要な場所へ記録すると扱いやすくなります。Dim processStartTime As Date、processStartTime = Time としておけば、その変数名から「処理開始時刻」であることが分かります。
同じ値を画面表示とセル記録の両方に使う場合も、1度変数へ格納しておくと一貫します。取得のタイミングがずれると、非常に短い差ではありますが、表示した時刻と保存した時刻が異なる可能性があるためです。
開始時刻をB2へ記録するなら targetSheet.Range(“B2”).Value = processStartTime とします。終了時刻も必要なら別の変数 processEndTime を用意し、処理終了直前でTimeを取得します。変数名を分けることで、どちらが開始でどちらが終了かを見失いにくくなります。
処理時間を求めたい場合は、単純な開始・終了時刻の記録だけでなく、日付をまたぐ可能性を考える必要があります。深夜をまたぐ長時間処理ではTimeだけを引き算すると意図どおりにならないケースがあるため、日時全体を扱うNowや、目的に応じたTimerなどを検討します。
MicrosoftのVBA日付・時刻キーワードの概要では、現在の日付または時刻の取得にDate、Now、Time、処理時間の計測にTimerが挙げられています。したがって、Timeは「現在時刻の記録」には適しますが、高精度な経過時間計測の専用手段として考えない方が安全です。
短い処理で開始時刻を人が確認するだけならTimeで十分です。一方、性能測定や秒未満の精度まで必要なベンチマークでは、この記事の範囲を超えて計測方法そのものを選び直す必要があります。
実務では、ログ列名も「開始時刻」「終了時刻」「実行日時」のように目的に合わせます。コード側だけ正しくても、シート上の見出しが曖昧だと利用者が意味を取り違えるため、データ設計とコードを揃えることが大切です。
開始時刻を残すときは、終了時刻や処理結果との関係も設計しておくと実務で使いやすくなります。開始だけ記録しても、処理が完了したかは分かりません。終了時刻や成功・失敗の列を合わせて持てば、処理の状況を後から確認できます。
同じマクロの中で開始時刻を何度も上書きしないことも重要です。開始直後に取得したprocessStartTimeは、その処理が終わるまで保持します。途中でTimeを再代入すると「開始時刻」という変数名と実際の値が一致しなくなり、経過時間の計算やログ確認で混乱します。
日をまたぐ可能性がなく、人が開始時刻を確認するだけならTimeは分かりやすい選択です。夜間バッチなど日またぎがあり得る処理ではNowで開始日時を持つ、短時間の性能計測ならTimer系を検討するなど、処理の実行条件によって選び分けます。
・更新履歴にはNowで実行日時を残す
データ更新や集計の履歴を残すなら、Nowで日付と時刻をまとめて記録する方が後から確認しやすくなります。Dim updatedAt As Date、updatedAt = Now と取得し、管理シートの「最終更新日時」セルへ書き込むのが基本形です。
履歴は実行直後ではなく数日後、数週間後に確認されることがあります。そのとき「14:20」だけではいつの更新か判断できません。Nowなら年月日と時刻が同じ値に含まれるため、履歴としての意味が残ります。
管理シートへ書くなら managementSheet.Range(“B2”).Value = updatedAt とし、見せ方は managementSheet.Range(“B2”).NumberFormat = “yyyy/mm/dd hh:mm:ss” のように分けます。記録値をDateのまま保持すれば、後で日付順に並べたり、一定期間より古いデータを判定したりする処理へつなげやすくなります。
複数の処理が同じログ表へ書き込む場合は、日時だけでなく処理名や結果も別列に残すと実務で役立ちます。たとえばA列を実行日時、B列を処理名、C列を結果とすれば、Nowで記録した日時が何のイベントなのか分かります。
履歴の用途では、値をFormatで文字列化してから保存するより、Date値を保存してNumberFormatで見せる方が柔軟です。文字列化すると、並べ替えや日付計算の前に変換が必要になることがあり、後工程の手間が増えます。
また、ワークブックを複数人で共有する環境では、誰のPCで実行したかによってシステム時刻が異なる可能性があります。厳密な監査ログが必要な業務では、VBAのNowだけで要件を満たせるかを別途確認し、必要ならサーバー側の記録なども検討します。
一般的なExcel業務の更新履歴であれば、NowをDate型で保持し、見やすい表示形式を設定する設計が分かりやすいでしょう。「いつ更新したか」を残す目的と、取得する情報の範囲が一致するためです。
最終更新日時を1セルへ保存する方法と、更新のたびに履歴行を追加する方法では、得られる情報が違います。1セル方式は「最後にいつ更新したか」をすぐ確認でき、履歴行方式は過去の実行を追跡できます。必要な追跡粒度に合わせて保存先を決めます。
履歴行へNowを書き込む場合は、日時だけでなく処理名、対象、結果などを同じ行へ保存すると原因調査がしやすくなります。たとえば「2026/08/20 19:30:15」「売上集計」「完了」のようにイベント単位でまとまっていれば、後からログを読む人が状況を復元しやすくなります。
更新日時を固定値として残したいときは、セルにVBAのNowの結果をValueとして書き込む方法が適しています。ワークシートの =NOW() は再計算で変化するため、過去の更新時刻を固定する用途とは性質が異なります。ここを取り違えると「履歴が勝手に現在時刻へ変わった」という問題につながります。
VBAでTime・Nowを使うときに注意したいポイント
TimeやNowは簡単に使えますが、値と表示、Date型と文字列を混同すると、後で比較や計算をするときに扱いにくくなります。取得、保持、表示の役割を分けて考えることが重要です。
・セルの表示形式と取得した時刻を混同しない
TimeやNowで取得した値と、セルに見えている文字列は同じものではありません。Excelは日付・時刻を計算可能な値として保持し、NumberFormatなどの表示形式で見せ方を変えます。
たとえば値が13時45分30秒を含んでいても、セルの表示形式が h:mm なら「13:45」としか表示されません。秒を確認したいなら hh:mm:ss、日付と時刻を確認したいなら yyyy/mm/dd hh:mm:ss のような形式を指定します。
Microsoft LearnのRange.NumberFormatでは、セルの表示形式を表す値を取得または設定すると説明されています。つまり、TimeやNowが返す値を変更するのではなく、表示だけを変更する役割です。
不具合調査では、まずセルを選択して数式バーや表示形式を確認し、値が想定どおり入っているかを切り分けます。見た目だけを見て「Timeで秒が取れない」と判断すると、関数側を不要に変更してしまう可能性があります。
セルへ時刻を書いた後に表示形式を設定する例は、targetCell.Value = Time、targetCell.NumberFormat = “hh:mm:ss” です。日時なら targetCell.Value = Now、targetCell.NumberFormat = “yyyy/mm/dd hh:mm:ss” と分ければ、意図が明確です。
表示形式は地域設定の影響も受ける場合があります。固定した見せ方が必要な帳票ではNumberFormatを明示し、利用者の環境に任せてよい場合は標準表示を利用するなど、出力目的に合わせます。
もう1つの注意点は、セル幅です。日時を含む長い表示形式では列幅が不足し、値が入っていても見え方が崩れることがあります。取得処理、表示形式、列幅は別の問題として確認すると、原因を切り分けやすくなります。
トラブル対応では「値」「表示形式」「列幅」の順に確認すると効率的です。まずDate値が正しく入っているかを確認し、次にNumberFormat、最後に列幅や表示上の問題を見ます。取得コードを直す前に表示側を確認すれば、不必要な修正を避けられます。
日付と時刻を表示する書式では、yyyy/mm/dd hh:mm:ss のように年月日と時分秒を明示すると、履歴として読みやすくなります。時刻だけなら hh:mm:ss が分かりやすいでしょう。見せ方は利用者が判断しやすい粒度に合わせ、内部値を文字列へ変えて対応しないことが基本です。
Excel上で日時が数値のように見える場合も、値が壊れたとは限りません。日付・時刻は内部的に数値で扱われるため、標準表示へ戻すとシリアル値のように見えることがあります。適切な日付・時刻形式を設定すれば、人が読める日時として表示できます。
・日時をすぐ文字列に変換しない
Format(Time, “hh:mm:ss”) のように書けば、表示用の文字列を作れます。帳票やメッセージへ出すだけなら便利ですが、その時点で「計算しやすいDate値」から「表示用の文字列」へ役割が変わります。
後から比較や時間差計算をする可能性があるなら、Dim currentTime As Date としてTimeを保持し、表示するときだけFormatを使う方が安全です。データの型を途中で不要に変えないため、処理の流れを追いやすくなります。
文字列で保存すると、見た目は 09:05:03 のように整っていても、Excelが日時として扱わない場合があります。そのまま並べ替えや計算をすると、期待した結果にならず、変換処理を追加することになります。
「保存はDate、表示はFormatまたはNumberFormat」という役割分担を基本にすると、用途が広がっても修正が少なく済みます。特に実行履歴では、最初から文字列にしてしまうより、日時値を残しておく方が再利用しやすいです。
一方、CSVへ出力する、メール本文へ埋め込む、ファイル名の一部へ使うなど、最終的に文字列が必要な場面ではFormatが適しています。重要なのは、文字列化するタイミングを「取得直後」ではなく「文字列が必要になった時点」に寄せることです。
Format関数の既定書式や時刻書式はシステム設定の影響を受ける部分があります。外部システムへ渡す形式が厳密に決まっている場合は、必要な形式を明示して、想定外の表記にならないか確認します。
Time・Nowの問題に見えて、実際には型変換や表示の問題というケースは少なくありません。値の取得、型の保持、表示、外部出力の4段階を分けて考えると、トラブルの原因を特定しやすくなります。
文字列化が問題になる典型例は、時系列の並べ替えです。表示が同じ桁数なら文字列でも順番が合うことがありますが、書式が混在すると正しい日時順にならない可能性があります。Date値で保持しておけば、Excelは日時として比較できます。
もう1つは加減算です。30分後を求める、2つの日時の差を求める、といった処理ではDate値の方が自然です。表示用文字列へ変換した後に計算しようとすると、再び日時へ戻す処理が必要になり、エラー要因が増えます。
したがって、Formatは保存のためではなく、最終表示のために使うと整理しやすくなります。メッセージボックス、帳票の見出し、CSVの出力文字列など、人や外部仕様に合わせる段階で変換するのが基本です。内部処理ではできるだけ元のDate値を保ちます。
VBAで現在時刻を取得する処理を保守しやすくする考え方
現在時刻を取得する1行は短くても、実務マクロの中では何のための日時か分からなくなることがあります。変数名、コメント、保存先、Excel関数との違いまで含めて整理すると保守しやすくなります。
・用途が分かる変数名とコメントを使う
TimeやNowは1行で書けるため、つい t = Time や dt = Now のような短い変数名にしがちです。しかし、コードが長くなるほど、その値が「開始時刻」「終了時刻」「更新日時」のどれなのか分かりにくくなります。
開始時刻なら processStartTime、終了時刻なら processEndTime、最終更新日時なら lastUpdatedAt のように、用途を名前へ含めると読み返しやすくなります。英語名にこだわる必要はありませんが、同じプロジェクト内で命名の方針をそろえることが大切です。
コメントも「Timeで現在時刻を取得」のようにコードを読み上げるだけではなく、「集計処理の開始時刻を保持」のように目的を残す方が役立ちます。関数の意味はコードを見れば分かりますが、なぜその時刻が必要なのかは仕様を知らないと分からないからです。
セルへ直接 Range(“A1”).Value = Now と書く箇所が増えると、どの日時を記録しているのか追いにくくなります。必要に応じて対象シートや対象セル、日時変数を分け、処理単位で意味を明確にします。
ただし、短いコードを何でも関数化・共通化すればよいわけではありません。TimeやNowの取得だけを専用関数に隠すと、かえって呼び出し先を追う必要が出ることもあります。重複量と再利用性を見ながら、読みやすさを優先します。
保守で重要なのは、値の意味、取得タイミング、保存先の3点が分かることです。processStartTime = Time の直後に対象セルへ記録するなら意図は明確ですが、取得してから長い処理を挟む場合は「いつの時刻なのか」が曖昧になりやすいため注意します。
複数人で改修するマクロでは、変数名だけでなく列見出しやコメントもそろえると理解しやすくなります。コード上はupdatedAt、シート上は「処理時刻」、仕様書では「更新日」のように表現がばらばらだと、同じデータかどうか判断しづらくなります。
変数名には、値の種類だけでなく役割を含めると効果的です。currentTimeは現在時刻という意味までは分かりますが、processStartTimeなら処理開始、lastUpdatedAtなら最終更新という業務上の意味まで伝わります。保守ではこの差が大きくなります。
コメントは、将来の担当者が判断に迷う理由を残す場所として使います。たとえば「履歴を翌日以降も確認するためNowを使用」のように選択理由を書けば、後からTimeへ変更してよいか判断できます。単に「Nowで日時を取得」と書くだけでは、コードから読み取れる情報を繰り返すだけです。
同じ時刻処理を複数のプロシージャへ追加するときは、命名とセル配置の規則を合わせます。一方ではupdatedAt、別の場所ではlastTime、さらに別の場所ではdtとすると、同じ概念かどうか判断しにくくなります。小さな処理ほど規則をそろえると、全体の理解が速くなります。
・Excel関数のNOWとVBAのNowを混同しない
Excelにはワークシート関数の =NOW() があり、VBAにはNowがあります。どちらも現在の日付と時刻を扱いますが、実行される場所と更新の仕組みが違います。
ワークシートのNOW関数はセルの数式として使います。Microsoft Supportでは、NOWは現在の日付と時刻に対応するシリアル値を返し、ワークシートが再計算されたときなどに結果が更新されると説明されています。
一方、VBAのNowはマクロ内で実行した瞬間の現在日時を取得します。currentDateTime = Now として値をセルへ書けば、そのセルにはマクロ実行時点の値が記録され、数式として自動更新されるわけではありません。
したがって「ブックを開いている間、現在日時を表示し続けたい」ならワークシートのNOW関数が候補になります。「ボタンを押した瞬間の日時を履歴として固定したい」ならVBAのNowで値を書き込む方が目的に合います。
混同しやすいのは、どちらも画面上では同じような日時に見えるからです。セルに =NOW() が入っているのか、VBAでNowの結果を値として書いたのかを確認すれば、後から日時が変わるかどうかの違いを理解できます。
更新履歴として残したいセルへ =NOW() を入れると、再計算のたびに時刻が変わり、履歴として固定できません。逆に、常に現在日時を見せたいセルへVBAでNowを1回だけ書くと、その後は更新されません。目的と更新タイミングを合わせることが重要です。
初心者が迷ったら「数式として現在日時を表示したいのか」「マクロ実行時点の日時を固定値として残したいのか」と問い直します。この2択で整理すると、ExcelのNOW関数とVBAのNowを使い分けやすくなります。
ExcelのNOW関数は数式なので、再計算というExcel側の仕組みに従います。Microsoft Supportでも、NOWの結果はワークシートが計算されたときなどに更新され、時間経過だけで連続更新されるものではないと説明されています。常時時計のように秒ごと更新されるわけではない点にも注意が必要です。
VBAのNowは、コードがその行を実行した瞬間の値を返します。その値をセルのValueへ代入すれば、数式ではなく値として残ります。つまり、同じ「現在日時」でも、Excel NOWは再計算される数式、VBA Nowはコード実行時に取得できる値という違いがあります。
既存ファイルを調査するときは、セルを選択して数式バーを確認します。=NOW() が入っていればワークシート関数、日時だけが値として入っていればVBAや手入力などで固定値が書かれた可能性があります。更新タイミングの問題を調べる際は、この確認が有効です。
まとめ:VBAで現在時刻を取得するならTimeとNowを目的別に使い分けよう
VBAで現在時刻を取得する基本はシンプルです。時刻だけが必要ならTime、日付と時刻をまとめて残したいならNowを使います。どちらもコンピューターのシステム時計を基準にしたDate値として扱えるため、まずは文字列へ変換せず、値として保持するのが扱いやすい方法です。
セルへ記録するときは、取得した値と表示形式を分けて考えます。TimeやNowで値を入れ、必要に応じてNumberFormatで hh:mm:ss や yyyy/mm/dd hh:mm:ss のような見せ方を指定します。表示が短いからといって、取得値そのものが欠けているとは限りません。
実務では、当日の開始時刻など時刻だけで意味が通じる情報はTime、更新履歴や実行ログなど後日確認する情報はNowが分かりやすい選択です。処理時間の計測が目的ならTimerなど別の手段も含めて検討し、現在時刻の記録と経過時間の計測を混同しないようにします。
また、Excelワークシートの =NOW() とVBAのNowは別物です。数式として再計算時に更新したいならExcelのNOW、マクロ実行時点の日時を固定値として残したいならVBAのNow、と目的で選びます。
TimeとNowの使い分けで迷ったときは、「保存した後に日付まで必要か」を基準にしてください。必要な情報だけを適切な型で持ち、表示は別に整えるだけで、時刻処理のコードは読みやすく、後から変更しやすくなります。
現在時刻を取得した結果が想定と違うときは、TimeやNowの書き方だけを見るのではなく、PCのシステム時計、変数の型、セルの表示形式、値を書き込むタイミングを順に確認してください。関数自体は単純なので、周辺条件を切り分ける方が原因へ早くたどり着けます。
とくに「秒が表示されない」「日時が数値に見える」「翌日になると履歴の意味が分からない」といった問題は、それぞれ表示形式、内部値、保存情報の不足という別の原因があります。症状ごとに原因を分けて考えることで、TimeをNowへ変えるだけの場当たり的な修正を避けられます。
既存マクロへ追加する場合は、まずその日時を誰が、いつ、何のために見るのかを確認すると設計しやすくなります。実行中だけ参照するならTimeで足りることが多く、後日確認する記録ならNowの方が自然です。保存期間と利用者を基準にすると、必要な情報量を決めやすくなります。
また、同じイベントの時刻を複数箇所へ記録する場合は、TimeやNowを何度も呼ばず、1回取得した値を使い回すと記録の一貫性を保てます。処理の途中で秒が変わっても、同一イベントとして扱いたいセルには同じ値が残るため、ログを見たときの違和感を減らせます。
VBAの日時処理では、短いコードほど「動けば終わり」と考えがちですが、履歴や条件判定へ使い始めると設計の差が表れます。Date型で保持し、用途が分かる名前を付け、表示はNumberFormatや必要時のFormatで整えるという基本を守るだけでも、後からの変更に強くなります。
最終的には、TimeとNowのどちらを使うかは「取得できる情報の多さ」ではなく「必要な情報と一致しているか」で決めます。時刻だけで十分な処理にNowを使う必要はなく、履歴に日付が必要なのにTimeだけで済ませるべきでもありません。目的に合った最小限の情報を選ぶことが、読みやすく扱いやすいVBAにつながります。
もし処理仕様が変わり、「開始時刻だけ」から「開始日時を履歴として残す」要件へ広がった場合は、TimeからNowへ切り替えるだけでなく、既存データとの整合も確認します。過去データが時刻だけ、新しいデータが日時という混在になると、一覧の並べ替えや比較条件へ影響するためです。
反対に、Nowで保存している既存処理から時刻だけを表示したい場合は、値そのものをTimeへ置き換えず、表示形式で時刻だけ見せる方法もあります。保持する情報と画面に見せる情報を分ければ、将来の再利用性を落とさず、利用者には必要な部分だけを提示できます。
迷ったときは「取得」「保持」「表示」「履歴」の4つに処理を分解してください。TimeやNowは取得、Date型は保持、NumberFormatやFormatは表示、セルやログ表は履歴というように役割を整理すると、どこを直すべきか判断しやすくなります。
この基本を押さえておけば、現在時刻をセルへ記録するだけの小さなマクロから、更新履歴や実行ログを管理する処理まで、同じ考え方で安全に拡張できます。コードを短くすることより、取得した値の意味が後から分かる設計を優先してください。
実務ではこの整理が保守性を高めます。
現在時刻の処理をレビューするときは、コードだけでなく保存されたセルも実際に確認してください。想定どおりのDate値が入り、表示形式が目的に合い、翌日以降に見ても意味が通じるかを確認すれば、TimeとNowの選択が適切かを実データで判断できます。
マクロを他の担当者へ引き継ぐ場合は、「なぜTimeなのか」「なぜNowなのか」が変数名やコメントから分かる状態にしておくと安心です。取得方法は簡単でも、履歴の意味や更新タイミングは業務ルールに依存するため、選択理由をコード上に残す価値があります。
さらに、セルへ書き込む日時がユーザー操作の証跡なのか、単なる画面表示なのかでも必要な厳密さは変わります。証跡なら日付を含むNowや時刻同期を重視し、一時表示ならTimeで十分なことがあります。用途に応じて必要な精度と情報量を決めることが重要です。