TL;DR — セルには 3 つの読みの顔があります。
.Value2は 生の 格納数値です(日付はシリアル 値46261として返り、変換なし — 最速)。.Valueはその数値を VBA の型に強制変換 したもの です — 日付セルならDate、通貨セルならCurrency(これは非常に大きな数値を丸めることがあり ます)。.Textは 表示される 文字列です —"$1,235"、列が狭すぎれば"###"— で、 読み取り専用 です。計算には.Value2を読みましょう。.Textを読んで数値を得るのが、あの 定番の静かなバグです。
' セル A1 は 1234.5 を保持し、通貨 "$#,##0" で書式設定されている
Debug.Print Range("A1").Value2 ' 1234.5 - 生の数値
Debug.Print Range("A1").Value ' 1234.5 - ここでは Currency に強制変換
Debug.Print Range("A1").Text ' "$1,235" - 表示文字列(丸め済み、読み取り専用)
誰もが最初に .Value を学び、それがセルの その 値だと思い込みます。実際にはそれは 3 つのうちの
1 つで、本記事が拠って立つ考え方は、セルには複数の顔があり、それぞれが違う問いに答える という
ことです。.Value2 は「どんな数値が格納されているか」を問い、.Value は「VBA から見てどんな型の
数値か」を問い、.Text は「画面に何が描かれているか」を問います。間違った顔に手を伸ばしても何も
エラーになりません — ただ静かに間違った答えを受け取るだけです。3 つを区別して押さえれば、「数値が
合わない」バグの一族まるごとが消えます。
この記事で学べること
- 考え方の軸 — 3 つの読みの顔を、Excel が答えをどれだけ加工するかの順に
- 最も大事なルール —
.Textは表示文字列であって値ではなく、読み取り専用 .Value対.Value2— Currency と Date の変換が数値を変える場所.Value2が一括読み込みの速くて損失のない既定である理由- 日付:
.ValueからはDate、.Value2からはシリアルのDouble - 毎回どの顔に手を伸ばすか
考え方の軸:生から表示までの 3 つの顔
格納された数値を、あなたに手渡す前に Excel がどれだけ処理するかで 3 つを並べましょう。
.Value2— 格納されたままの 数値。型変換は一切なし:整数はDouble、テキストはString、 日付はその下地のシリアル値(日付ではなく46261)です。「セルの中に本当にあるもの」に最も近い ものです。.Value— 格納された数値を 対応する VBA の型に強制変換 したもの。セルが日付として 書式 設定 されていれば.ValueはDateを返し、通貨として書式設定されていればCurrencyを返し ます。数値はたいていの場合同じですが、その VBA の型 — そしてときには精度 — は同じではありません。.Text— 表示される文字列:セルの数値書式を通した値で、画面に現れるとおりです。"$1,235"、"12.3%"、"1-Jan-2026"、あるいは列が狭すぎれば"###"。つねにStringで、つねに 読み取り専用 です。
3 つは互換ではなく、3 つの違う問いに答えます。以下のすべては、あなたが実際に問おうとしたのがどの 問いか、の帰結です。
最も大事なルール:.Text は表示であって値ではない
これは、再現できないバグを生むものです。書式と列幅に依存するからです。.Text は、セルの数値書式を
通した 画面が見せるもの を返します。
' A1 は 1234.5 を保持し、"$#,##0" で書式設定されている
Dim n As Double
n = Range("A1").Text ' n は "$1,235" を強制変換 -> 型不一致エラーか、または 1235
2 つのことが起きました。ドル記号とカンマがそれを 文字列 にするので、演算は壊れるか例外を投げ
ます。そして書式が 1234.5 を 1,235 に 丸めた ので、記号を取り除いても .5 は失われています。
さらに悪いことに、列が数値を表示するには狭すぎると、.Text は文字どおり "###" を返します — なので、
まったく同じコードが、あなたの画面では使える値を、ユーザーのより狭い画面ではゴミを読みます。そして
.Text は 読み取り専用 なので、Range("A1").Text = "5" はエラーになります — それを通して書き込む
ことはできません。ルールは無骨です。数値を得るために .Text を決して読まない。 .Text は、人が
見る書式済みの文字列が本当にほしいときだけ — 帳票のラベルやログ行のために — 使い、計算には決して
使いません。
.Value 対 .Value2:変換が数値を変える場所
.Value と .Value2 は、通常のデータでは同じ数値を返します。両者が分かれるのは 2 つの書式です。
通貨 と 日付 です。
通貨で書式設定された セルでは、.Value は Currency データ型を返します。これは 15 桁を、小数点
以下ちょうど 4 桁で保持します。お金には完璧で、浮動小数点のふらつきを避けます — しかし小数が 4 桁を
超える数値や、Currency の範囲を超える数値は、丸められるかオーバーフローします。
' A1 は 1234567.891234 を保持し、通貨で書式設定されている
Debug.Print Range("A1").Value ' 1234567.8912 - Currency、4 桁より後ろの端数は消える
Debug.Print Range("A1").Value2 ' 1234567.891234 - 完全な Double、何も失わない
教訓は、片方が正しく片方が間違っている、ではありません — 両者が違うニーズに答える、ということです。
お金 を扱っていて、正確な 4 桁小数の演算がほしいなら、.Value(Currency)が安全な顔です。生の
測定値や、精度を失ってはならない数値を読んでいるなら、.Value2(Double)です。静かなバグは、高精度の
数値に .Value を使い、端数を静かに落とすことです。
.Value2 が速くて損失のない既定である理由
.Value2 は 変換を一切しない ので、最も速い読み込みであり、型で驚かされることもない読み込みです。
配列への一括読み込み — VBA Cell Value の性能パターン — には、.Value2 が
プロの手を伸ばす既定です。
Dim arr As Variant
arr = Range("A1:Z100000").Value2 ' 生の Double と String — 最速、Date/Currency 変換なし
悩まなくてよい Date や Currency の型を隠し持たない、素の Double と String が得られ、大きな
範囲では読み込みがわずかに速くなります。トレードオフは、日付がシリアル値として届くことです。だから
データが日付で、それらを Date として型付けしたいなら .Value を使います。そうでなければ、読み込み
は .Value2 を既定にし、Date や Currency の型付けが具体的に必要なときだけ .Value に上げましょう。
日付:.Value からは Date、.Value2 からはシリアル値
日付は、.Value と .Value2 の分かれ目が最も強く噛む場所です。
' A1 は日付 2026-08-31 を保持している
Debug.Print Range("A1").Value ' 2026-08-31 - 本物の Date 値
Debug.Print Range("A1").Value2 ' 46265 - その下にあるシリアル値
日付の列を .Value2 で読んでから「日付の計算」をすると、実際にはシリアル値の演算をしています —
それと分かっていれば問題なく、分かっていなければ当惑します(+1 は 1 日ですが、値は日付ではなく
46266 と表示されます)。VBA にセルを日付として扱わせたいなら .Value を読み、生の数値を往復させて
あとで書式設定するなら .Value2 のほうがすっきりします。これは VBA Now, Date & Time
と VBA DateAdd の背後にある、「マスクをかぶった Double」という同じ考え方
です。
率直な結論:1 つのセル、4 つの顔、意図して選ぶ
セルは単一の値ではありません。4 つの顔を通して読み書きし、意図して選ぶことがスキルのすべてです。
.Formulaはレシピ — 中立な US-English の方言で書かれた生きた数式 (VBA Formula)。.Valueは型付きの答え — セルがそう書式設定されているときDateやCurrencyに強制変換された 数値。その型付けがほしいときに使い、Currency は 4 桁より後ろを丸めると知っておくこと。.Value2は生の答え — 素のDoubleやString、日付はシリアル値。読み込みと一括配列のための、 速くて損失のない既定。.Textは画面にあるもの — 書式済みの読み取り専用文字列。表示専用で、計算には決して使わず、列が 狭すぎるかもしれないときは決して信用できません。
間違った顔を読むとバグは静かです。.Value はお金を 4 桁より後ろで静かに丸め、.Text は数値の代わり
に "###" や "$1,235" を手渡し、.Formula はローカライズされた関数名を拒みます。どの顔を意図した
かを知れば、セルはもうあなたに嘘をつきません。
ExcelMaster の活用
値の顔のバグは、決して例外を投げないものです。Currency の変換で丸められたお金、シリアル値として読ま
れ「日付の計算」で壊された日付、他人のより狭い画面で "###" を返した .Text 読み込み。どれもあなたの
マシンでは全テストに通り、実データで静かに失敗します。
ExcelMaster は、各セルを正しい顔を
通して読みます。「生の金額を合計して」と頼めば損失のない Double のために .Value2 を読み、「請求書の
合計をお金として」と頼めば Currency の型付けのために .Value を使い、「表示どおりのラベル」と頼めば
.Text を取ります — そして .Text を演算には決して使いません。日付が .Value2 からはシリアル値
として、.Value からは Date として返ることを知っていて、それに応じて選びます。あなたはその数値が
何の ため かを説明するだけ。それを正しく保つ顔を読むのは、それがやります。
よくある質問
VBA の Value と Value2 の違いは?
.Value2 は型変換なしで格納された生の数値を返します — 日付はシリアルの Double として、通貨セルは
素の Double として返ります。.Value は同じ数値を、対応する VBA の型に強制変換して返します:日付
書式のセルなら Date、通貨書式のセルなら Currency です。通常の数値では一致しますが、.Value は
高精度の通貨値を 4 桁小数に丸めることがあり、一方 .Value2 は完全な Double を保ちます。
Excel VBA で Value と Value2 のどちらを使うべき?
読み込みは .Value2 を既定にしましょう。最速で、Date や Currency の型付けや精度の損失で驚かされる
ことがないので、配列への一括読み込みに理想的です。セルを Date として型付けしたいときや、お金のために
Currency の演算がほしいときは .Value を使います。計算に使う値には .Text を避けましょう — 書式
済みで読み取り専用の文字列を返すからです。
なぜ .Text でセルの値を読むべきでないのか?
.Text は、セルの数値書式を通した、画面に表示される文字列を返します — なので通貨セルは "$1,235"
(文字列で、しかも丸め済み)、パーセントは "12%"、狭すぎる列は文字どおり "###" として読まれます。
これは演算を失敗させるか間違った結果を生み、"###" の場合は同じコードがあなたの画面では動いてより
狭い画面では壊れることを意味します。.Text は読み取り専用でもあり、代入はできません。数値には
.Value2 か .Value を読み、.Text は表示だけに使いましょう。
VBA の日付が数値として返ってくるのはなぜ?
それを .Value2 で読んだからです。.Value2 は日付の下地にある生のシリアルの Double(例えば
46265)を、Date ではなく返します。Excel は日付をシリアル値として格納し、.Value2 はその数値を
変換なしで渡します。本物の Date 値を得るには、代わりに .Value を読みます。シリアル値がほしいとき —
例えばあとで書式設定する高速な一括読み込みのため — だけ .Value2 を使いましょう。
VBA で .Text を使ってセルの値を設定できますか?
いいえ。.Text は読み取り専用です — 画面に表示される書式済みの文字列を報告し、それへの代入、例えば
Range("A1").Text = "5" はエラーになります。セルに書き込むには .Value(または .Value2)に代入し、
見え方はフォーマット済み文字列を書き込むのではなく、セルの数値書式で制御しましょう。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-31。
関連ガイド: VBA Cell Value · VBA Formula · VBA Number Format · VBA Now, Date & Time · VBA Format
