検証環境: Excel 365 v2509 · Excel 2021 · Excel 2019 · 最終確認 2026-06-10
要点 — Format は値と書式コードを受け取り、指定どおりの見た目の文字列を返します。ファイル名・メッセージ・帳票のラベルを組み立てるには最高ですが、その結果をデータセルに書き込んだ瞬間に、静かなバグ工場になります。そのセルが保持するのはテキストで、数値でも日付でもなくなるからです。
Sub FormatDemo()
Debug.Print Format(1234.5, "#,##0.00") ' 1,234.50
Debug.Print Format(0.75, "0.0%") ' 75.0%
Debug.Print Format(Now, "yyyy/mm/dd") ' 2026/06/10
Debug.Print Format(Now, "m月d日(aaa)") ' 6月10日(水)
Debug.Print Format(38740, "¥#,##0") ' ¥38,740
End Sub
シグネチャ。ほとんどの人が忘れる 2 つの省略可能な引数つき。
Format(expression, [format], [firstDayOfWeek], [firstWeekOfYear])
' 値 コード 曜日計算用、めったに使わない
考え方の軸:Format は化粧であって、手術ではない
Format は値の見た目を変えるだけで、値が何であるかは変えません。日付シリアル値 46183 と コード "yyyy/mm/dd" を渡すと、文字列 "2026/06/10" が返ります。入っていく値は型を変えません — が、出てくるものは常に String です。これが Format について最も大事な 1 文です:出力はテキスト。
これを握れば、道具全体が腑に落ちます。出力先が文字列のときに Format を使う — メッセージ、シート名、"report_" & Format(Date, "yyyymmdd") & ".xlsx" というファイル名、連結しているラベル。出力先が数値や日付のままでいるべきセルのときは使わない。ブックの他の部分が計算しようとしている枠に、テキストを流し込むことになるからです。
唯一のルール:Format は String を返す — だから下流の計算を壊す
これが、最もよくある Format の惨事を説明するルールです。
cell.Value = Format(ある日付, "yyyy/mm/dd")と書いた瞬間、そのセルは日付であることをやめ、日付に見えるテキストになります。時系列で並べ替えられず、月でフィルターできず、「書式化された数値」の列に対する=SUMは0を返します。
罠を丸ごと組み上げると、こうです。
' ⚠ 間違い — 数値に見えるだけのテキストで列を埋める
Range("C2").Value = Format(1234.5, "#,##0.00") ' セルは今や文字列 "1,234.50" を保持する
' =SUM(C:C) は無視する。並べ替えは "1,234.50" をテキスト扱い。グラフは飛ばす。
本当にやりたいのが「桁区切りで表示しつつ、本物の数値のまま」なら、Format はまったく使いません — セルの表示形式を設定し、値はそのままにします。
' ✓ 正しい — 値は数値のまま、表示だけが変わる
Range("C2").Value = 1234.5
Range("C2").NumberFormat = "#,##0.00" ' SUM・並べ替え・グラフがすべて機能する
この区別 — Format はテキストを生む、NumberFormat は表示を変える — がすべてです。刻み込みましょう:文字列なら Format、セルなら NumberFormat。
第 2 の罠:m は月、ただし時々ちがう
日付コードと時刻コードは文字 m を共有していて、この曖昧さは誰でも一度はやられます。
- 単独の
"mm"は月:Format(Now, "mm")→06。 - 同じ
"mm"が"hh:"の直後にあると分として読まれます:Format(Now, "hh:mm")→09:05。時との隣接が意味を反転させます。 - 隣に時のない経過時間では、
"mm:ss"は月:秒になります — まず意図と違います。VBA 専用の分トークンnを使いましょう:Format(t, "nn:ss")。
Debug.Print Format(Now, "yyyy/mm/dd hh:mm:ss") ' 2026/06/10 09:05:30 (最初の mm = 月、2 つ目 = 分)
Debug.Print Format(Now, "mm:ss") ' 06:30 <- 月:秒、おなじみの不意打ち
Debug.Print Format(Now, "nn:ss") ' 05:30 <- 分、これが正解
プレースホルダの桁にも知っておくべき独自ルールがあります。0 は桁を強制(ゼロ埋め)、# は桁があるときだけ表示。Format(5, "00") → 05、Format(5, "##") → 5。請求番号をゼロ埋めしたり、整数をきれいに保ったりするのはこれです。
名前付き書式と Format* 兄弟
毎回ユーザー定義コードが要るわけではありません。VBA には名前付き書式と、地域設定に従う兄弟関数があります。
Debug.Print Format(1234.5, "Currency") ' ¥1,235 (PC の地域通貨を使う)
Debug.Print Format(Now, "Short Date") ' 2026/06/10 (地域の並び)
Debug.Print Format(0.75, "Percent") ' 75.00%
Debug.Print FormatCurrency(1234.5, 0) ' ¥1,235
Debug.Print FormatNumber(1234.5, 2) ' 1,234.50
Debug.Print FormatPercent(0.75, 1) ' 75.0%
Debug.Print FormatDateTime(Now, vbLongDate) ' 2026年6月10日
名前付き書式と Format* 兄弟は PC の地域設定に従います — ユーザー向け表示には利点、行き来させたいデータには危険です。"Short Date" は米国では 6/10/2026、日本では 2026/06/10 になります。固定でマシン非依存の文字列(ファイル名、CSV のキー、ISO タイムスタンプ)が必要なら、コードを明示的に書き下し — "yyyy-mm-dd" — "Short Date" は決して使わないこと。
どれをいつ使うか
| やりたいこと | 使うもの | 理由 |
|---|---|---|
| メッセージ・ファイル名・ラベル用の文字列 | Format(値, コード) |
出力はテキスト — まさに必要なもの |
| セルを書式付きで表示しつつ数値を保つ | Range.NumberFormat = コード |
値は数値のまま。SUM/並べ替え/グラフが機能 |
| 地域に従う通貨・数値の文字列 | FormatCurrency / FormatNumber |
地域設定に従う |
| 固定でマシン非依存の日付文字列 | Format(d, "yyyy-mm-dd") |
明示コードは地域の並びを無視 |
| テキストを実際に数値・日付へ戻す | CStr / CDate / Val | Format は値 → テキストの一方通行 |
意見:セルに入るなら Format ではなく NumberFormat
私が譲らない一線はこれです:Format はデータセルにはほぼ絶対に書き込むべきでない。 「SUM がゼロ」「日付が並ばない」案件の 9 割は、NumberFormat を使うべき場面で Format を使った誰かにたどり着きます。コード上ほぼ同じに見える — だからこのバグは多発し、レビューで見えないのです。
だから明確な切り分けを習慣にしましょう。文字列を組み立てる — シートのタブ名、ログの 1 行、ファイル名のスタンプ、MsgBox に連結するテキスト? Format。セルを正しく見せつつ、ブックが計算できる数値や日付に保つ? NumberFormat、値はそのまま。この切り分けを正せば、静かなデータバグの一群がまるごと消えます。そして一方通行を忘れずに:Format は値 → テキストだけ。逆方向 — 本物の数値や日付であるべきテキスト — には CStr・CDate・Val が要り、Format ではありません。
よくある Format のミス(と直し方)
| 症状 | 原因 | 直し方 |
|---|---|---|
列に対する =SUM が 0 を返す |
セルに Format()(テキスト)を書いた |
値 + Range.NumberFormat、Format は使わない |
| 日付が時系列で並ばない | セルが書式化テキストで、日付ではない | 本物の日付を保存し NumberFormat を設定 |
mm が分でなく月を表示する |
単独の mm は月 |
nn を使う、または mm を hh の隣に置く |
| 別の PC で日付の日/月が入れ替わる | "Short Date"(地域依存)を使った |
明示的な "yyyy-mm-dd" を使う |
| コードで先頭ゼロが欠ける | #(省略可能な桁)を使った |
0 で桁を強制:"00" |
| マクロ後に数値がテキストになる | Format の結果を .Value に代入した |
数値を代入し、NumberFormat で書式化 |
書式設定がマクロの半分を占めたら — 代わりに「結果」を伝える
書式設定は目的ではなく、帳票が目的です。あなたが欲しかったのは「金額は円、日付は ISO で表示され、合計はちゃんと合う月次シート」 — なのに、この mm は月か、この列はテキストか数値か、グラフがなぜ 1 行飛ばしたのか、と 3 層下に潜っている。ExcelMaster Agent なら、自然な日本語で結果をそのまま言えます — 「C 列を通貨、A 列を yyyy-mm-dd に書式化して、合計が効くよう数値のままにして」 — するとデータを文字列化せずに表示形式を設定する Python を、ファイルを先にバックアップしたうえで書き出します。無料で試す →
関連ガイド
- VBA Trim — 空白が消えない理由と Chr(160) の対処法
- VBA CStr・CDate・Val — 文字列を数値・日付へ正しく変換する
- VBA InStr — 文字列の中から文字を探す
- VBA Split — 1 つの文字列を配列に変える
- VBA For ループ — 実務の 8 例
よくある質問
VBA の Format 関数は何をする?
Format は書式コードを使って値を書式化した文字列に変換します — Format(1234.5, "#,##0.00") はテキスト "1,234.50" を返します。値の見た目を変えるだけで、値そのものは変えず、結果は常にテキストです。
VBA で日付を書式化するには?
明示コードを使います:Format(Now, "yyyy/mm/dd") は 2026/06/10、Format(Now, "dd/mm/yyyy") は日付が先。文字列がどの PC でも同じである必要があるなら、地域設定に従う名前付きの "Short Date" は避けましょう。
VBA の Format が分でなく月を表示するのはなぜ?
既定で m が月を意味するからです。単独の "mm" は月で、"hh:" の直後に置いたときだけ分になります。経過時間なら、VBA 専用の分トークンを使います:Format(t, "nn:ss")。
VBA で列を書式化したら SUM が 0 になるのはなぜ?
ほぼ確実に Format() の結果をセルに書き込み、数値に見えるだけのテキストを保存しています。本物の数値を保存し、見た目は代わりに Range.NumberFormat = "#,##0.00" で設定しましょう — そうすれば SUM・並べ替え・グラフがまた機能します。
VBA の Format と NumberFormat の違いは?
Format はテキスト文字列を返します。Range.NumberFormat はセルの表示を変える一方で、保存される値は本物の数値や日付のままです。文字列を組み立てるなら Format、計算を壊さずにセルを正しく見せるなら NumberFormat を使います。
