TL;DR —
IsEmptyはセルを見ていません。Variant について、ひとつの狭い問いを投げているだけです。一度でも値が入れられたことがあるか? 誰も触っていないセルの答えは「はい」です。""を返す数式、スペース、アポストロフィだけが入ったセルの答えは「いいえ」で、三つとも見た目は空白なのにそうなります。複数セルの範囲も常に「いいえ」で、String型の変数も同じです。ですから「空」を判定する前に、どの空を意味しているのかを決めてください。一度も入力されていない(IsEmpty)、何も表示されていない(エラーのセルを除外したうえで、前後の空白を除いた長さを調べる)、範囲全体に何も入っていない(CountAまたはCountBlank)のどれかです。
If IsEmpty(Range("A2").Value) Then
Debug.Print "Nothing was ever entered in A2"
End If
この記事は、値に「あなたは何者か」を尋ねる シリーズの第一回です。今回の IsEmpty、続いて VarType と TypeName、そして IsNull を扱います。シリーズを貫く考え方は、VBA の値は中身とは別に型のタグを持っていて、これらの判定はどれも見た目ではなくタグを読んでいる ということです。Empty、Null、Nothing、"" はどれも「何もない」ように見えますが、四つとも別々のタグです。
この記事で学べること
- 考え方の軸:Empty は見た目ではなくタグ
- IsEmpty が空ではないと判定する、空に見える三つのセル
- 範囲や String 型の変数で IsEmpty が常に False になる理由
- 0 と等しくなる空のセルと、エラーで止まるセル
- 「空」の意味ごとに使うべき判定方法
- Empty、Null、Nothing、空文字列の比較
考え方の軸:Empty は見た目ではなくタグ
Variant は二つのものを持っています。どんな種類の値を保持しているかを示すタグと、値そのものです。Empty はそのタグのひとつです。 意味は ここには一度も値が入れられていない ということです。宣言しただけで一度も代入していない Variant は Empty で、誰も入力していないセルの .Value も Empty です。
IsEmpty が読むのはタグだけです。セルに何が表示されているか、どんな書式が設定されているか、背後に数式があるかどうかは一切見ません。だからこそ判定は正確で、同時に人を驚かせもします。セルは空のセルとまったく同じに見えながら、String のタグを持っていることがあるのです。
IsEmpty が空ではないと判定する、空に見える三つのセル
A2、A3、A4 に次の内容を入れ、A5 には何もせず、四つすべてを判定してみます。
| セル | 内容 | 見た目 | IsEmpty(.Value) |
.Value = "" |
|---|---|---|---|---|
| A2 | =IF(B2="","",B2) |
空白 | False | True |
| A3 | スペース 1 文字 | 空白 | False | False |
| A4 | アポストロフィ ' だけ |
空白 | False | True |
| A5 | 何もない | 空白 | True | True |
A2 には結果が長さゼロの String になる数式が入っているので、タグは Empty ではなく String です。A3 には 1 文字の String が入っています。A4 には長さゼロの文字列定数が入っています。アポストロフィはセルの接頭辞文字であり、セルは空ではありません。一度も値が入れられていないのは A5 だけです。
これが「IsEmpty が効かない」という定番の質問の正体です。IsEmpty は正しく動いていて、問いのほうが間違っていたのです。ワークシート関数も同じ区別をします。ISBLANK は A2 ~ A4 で False になり、COUNTA は三つとも数えます。
最終行を探すときにも同じタグが顔を出します。End(xlUp) は "" を返す数式のところで止まります。そのセルは空ではないからです。このケースは 最終行のガイド で扱っています。
範囲や String 型の変数で IsEmpty が常に False になる理由
IsEmpty が意味を持つのは、単一の Variant に対してだけです。よく見かける次の二つの使い方は、決して True を返しません。
' 複数セルの範囲:.Value は配列で、配列は Empty ではない
If IsEmpty(Range("A2:A100").Value) Then ' すべて空白でも True にならない
' 型付きの変数:String は ""、Long は 0 から始まり、Empty にはならない
Dim name As String
If IsEmpty(name) Then ' 決して True にならない
範囲の場合、.Value は Variant の二次元配列を返すので、タグは「配列」であって Empty にはなりません。String、Long、Date 型の変数は、最初から実際の値(""、0、1899 年 12 月 30 日の午前 0 時)を持っているので、Empty になる余地がありません。Empty になれるのは Variant だけで、v = Empty でリセットできます。型付きの変数が空の状態から始まらない理由は データ型のガイド で説明しています。
0 と等しくなる空のセルと、エラーで止まるセル
Empty との比較は寛容です。VBA は Empty を比較相手に合わせて変換します。数値と並べれば 0、String と並べれば "" です。そのため、空のセルはその両方と等しくなります。
' A5 は空
Debug.Print Range("A5").Value = 0 ' True
Debug.Print Range("A5").Value = "" ' True
一行目は実際のデータの不具合を生みます。If c.Value = 0 で売上ゼロの件数を数えるループは、空白のセルもすべてゼロとして数えてしまい、「残高ゼロの取引先」のレポートには、一度も入力されていない取引先がこっそり含まれます。0 と空白が別の意味を持つなら、先に IsEmpty で判定してください。
二つ目の落とし穴は逆方向です。セルに #N/A のようなエラーが入っていると、その .Value はエラー値になり、String と比較すると失敗します。
' A6 には #N/A を返した =VLOOKUP(...) が入っている
If Range("A6").Value = "" Then ' Run-time error 13: Type mismatch
実行時エラー 13 の Type mismatch は、日本語版 Excel では「型が一致しません。」と表示されます。最初の検索エラーで止まってしまう空白チェックは、VLOOKUP や XLOOKUP でデータを引いてくるシートでよく見かけます。どんな比較よりも先に IsError を確認してください。エラー 13 とその仲間については エラー処理のガイド で扱っています。
「空」の意味ごとに使うべき判定方法
「空かどうか」と言うとき、人が意味している問いは三つあります。それぞれに専用の判定方法があります。
1. 一度でも何か入力されたか? セルの値に IsEmpty を使います。「この入力セルはまだ手つかずか」や「次の空き行を探す」には、これが正しい判定です。
If IsEmpty(c.Value) Then c.Value = Date
2. セルに何も表示されていないか? ""、スペース、アポストロフィは空白として扱いつつ、エラーで止まることもなく、0 を空白として扱うこともないようにします。
Function LooksBlank(ByVal c As Range) As Boolean
If IsError(c.Value) Then Exit Function ' #N/A は空白ではない
LooksBlank = (Len(Trim$(CStr(c.Value))) = 0) ' ""、スペース、Empty
End Function
CStr(Empty) は "" なので本当に空のセルも通りますし、CStr(0) は "0" なのでゼロは通りません。
3. 範囲全体が空か? ループも IsEmpty も使いません。Excel に数えさせます。
Dim rng As Range
Set rng = Range("A2:A100")
If Application.WorksheetFunction.CountA(rng) = 0 Then
Debug.Print "Nothing at all in the range, not even formulas"
End If
If Application.WorksheetFunction.CountBlank(rng) = rng.Cells.Count Then
Debug.Print "Every cell is blank or shows an empty string"
End If
CountA は "" を返す数式を値として数え、CountBlank は空白として数えます。問いに合うほうを選んでください。非常に大きくなりうる範囲なら、CountA はセルを一つずつ回すループよりはるかに高速でもあります。
Empty、Null、Nothing、空文字列
この四つはデバッガーでは似たように見えますが、判定方法はそれぞれ違います。
| 値 | 意味 | Excel で出会う場面 | 判定 |
|---|---|---|---|
| Empty | 一度も値が代入されていない | 手つかずのセルの .Value、新しい Variant |
IsEmpty(v) |
"" |
文字を含まない String | "" を返す数式、クリアした TextBox |
Len(v) = 0 |
| Null | 不明、または混在 | 書式が混在した範囲の Font.Bold |
IsNull(v) |
| Nothing | どのオブジェクトも指していないオブジェクト変数 | 何も見つからなかった Find |
obj Is Nothing |
空のセルが Null になることも Nothing になることもありません。IsNull(Range("A5").Value) は False ですし、Range("A5") が Nothing になることもありません。Null が実際にどこから来るのかは IsNull のガイド で、オブジェクト参照については Nothing のガイド で扱っています。
判断の分かれ目:どの「空」なのかを名前で示す
空白セルにまつわる不具合のほとんどは、IsEmpty の不具合ではありません。どの種類の空なのかを言わずに「空」と書いたコードから生まれます。それを防ぐルールはこうです。判定の意味を、判定の名前に書き込む。 手つかずの入力セルには IsEmpty、数式や他人から来たデータには LooksBlank 関数、範囲全体には CountA または CountBlank、そして "" や 0 と比較する前には必ず IsError のガードを置きます。
データがエクスポートや同僚から来たものなら、LooksBlank を既定の選択だと考えてください。取り込んだシートはスペースや "" を返す数式だらけで、顧客の欄が空だと言うときに「一度も入力されていない」という意味で言う人はまずいません。
ExcelMaster の活用
空白セルの判定ロジックは書くのは簡単ですが、微妙に間違えるのも簡単です。空白をゼロとして数えるレポート、最初の数式で止まるループ、#N/A で止まるチェック、といった具合です。
ExcelMaster はまずシートを読み、「空白」のセルのうちどれが本当に空で、どれが "" の数式やスペースを持ち、どれがエラーを持っているかを見極めたうえで、データの実際の中身に合った判定を書きます。
よくある質問
VBA でセルが空かどうかを判定するには?
If IsEmpty(Range("A1").Value) Then を使います。これが True になるのは、一度も何も入力されていない場合だけです。セルに "" を返す数式や余分なスペースが入っている可能性があるなら、IsError で確認したあとに Len(Trim$(CStr(c.Value))) = 0 を使ってください。
空白のセルなのに IsEmpty が False を返すのはなぜですか?
そのセルは空ではないからです。空文字列を返す数式、スペース、またはアポストロフィだけが入っています。IsEmpty が読むのは値の型のタグであって、セルに表示されている内容ではありません。
VBA で範囲が空かどうかを判定するには?
Application.WorksheetFunction.CountA(rng) = 0 を使います。複数セルの範囲に対する IsEmpty は、範囲の値が配列なので常に False になります。
VBA の IsEmpty と空文字列の判定は何が違いますか?
IsEmpty が True になるのは、一度も代入されていない値だけです。= "" は空のセルと空文字列の両方で True になり、セルに #N/A のようなエラー値が入っていると Type mismatch エラー(「型が一致しません。」)が発生します。
空のセルがゼロとして数えられるのはなぜですか?
VBA は Empty を数値と比較するときに 0 に変換するので、空のセルでは If c.Value = 0 が True になります。空白とゼロが別の意味を持つなら、先に IsEmpty(c.Value) で判定してください。
検証環境
検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-10-04。
関連ガイド: VBA VarType and TypeName · VBA IsNull · VBA Nothing · VBA IsNumeric · VBA Data Types · VBA Last Row · VBA Error Handling · VBA SpecialCells
