空白セルかどうか判定するには

VBAの処理でよくあるのが「セルが空白かどうか」を判定する場面です。主に以下の2つの方法があります。

  1. 空文字列との比較する方法
    If Range("A1").Value = "" Then
  2. IsEmpty関数を使う方法
    If IsEmpty(Range("A1")) Then

ほとんどの場合は空文字列””かどうかの書き方でOKです。レアケースですが、IsEmpty関数を使って判定が必要なケースもあります。

Rangeオブジェクトの書き方がいくつかあるのでそれを以下で紹介します。

なお、この書き方で判定できないのはセルの数式がエラーになっている場合です。それについては後述します。

空文字列(“”)との比較とIsEmpty関数の違い

空文字列(“”)での判定

セルの値が空文字列かどうかを判定します。以下のケースでTrueになります:

  • セルに何も入力されていない(真の空白セル)
  • セルに=””のような数式で空文字列が設定されている
  • セルに””を直接代入した場合

注意点: スペースのみのセル(” “)は空文字列ではないため、Falseになります。

IsEmpty関数での判定

セルが本当に空(何も代入されていない状態)かどうかを判定します。Trueになるのは:

  • セルに何も入力されていない場合のみ

数式で=””を設定したセルや、VBAで一度値を代入してから削除したセルはFalseになります。

空文字列の判定とIsEmpty関数のどちらを使うべきか

実務では””を使うケースが圧倒的に多いです。理由は、ユーザーが入力するセルには数式が含まれることがあり、その結果が空白の場合も「空白」として扱いたいためです。

  • ユーザー入力の有無を判定: = “” (数式の結果が空白の場合も検出できる)
  • VBAで値を代入したか判定: IsEmpty (初期状態と区別できる)
  • 一般的な空白判定: = “” (より広範囲に空白を検出できる)

空白判定の書き方

Rangeオブジェクトの書き方には複数あります。「Range(“セル座標”)」、「Cells(行位置, 列位置)」の主に2つの書き方と、それに加えてRangeオブジェクト変数を扱う書き方などです。

以下に4種類のコードがありますが、いずれの書き方もA1セルの値が空文字列かどうか判定しています。

Range(“セル座標”) での書き方

Cells(y, x) での書き方

Rangeオブジェクト変数に代入する書き方

Rangeオブジェクト変数とValue値の文字列変数に代入する書き方

注意が必要なケース

スペースのみのセルの場合

ユーザーがスペースだけを入力したセルは空白と判定されません。これを検出したい場合はTrim関数を使います。

Null値の扱い

データベースから取得したデータなどでNull値が入る場合があります。Null値は””とは異なるため、別途判定が必要です。

セルの数式がエラーになっている場合

上記はセルの値がエラーになっていない場合の書き方ですが、セルに「#N/A!」(参照先が無いエラー)や「#DIV/0!」(0割りエラー)のようなエラー表示がされている場合は、「Range.Value」のValueプロパティで値が取得できないため、エラーとしてVBAの処理が止まってしまいます。

もしエラー値かどうかを判定したいのであれば以下のようにRangeオブジェクトのValue値に対してIsError関数を利用します。

IsError関数の詳細は「VBAでセルの数式がエラーか判定する(IsError)」をご参照ください。

ここで問題になるのが、エラー判定のコードを書いた方がいいかどうか、という点です。

このようなエラー値の対応を入れるかどうかは、状況によって変わります。具体的には、セルにエラーが無いことを前提とするか、エラーがあることを前提とするか、です。

VBAを実行するとかしないとかの前に、ブックのデータがエラーになっていておかしいのでセルの値が正しく表示されるように修正するのが先、という場合の方がおそらく多いでしょう。

ここではセルがエラー値かどうかという話だけですが、他にもブックのデータが想定していない内容であることが多岐にある場合、それら全部の不正チェックをVBAでやるのか、という話です。

おそらくそこで想定されるエラー処理を入れても日の目を見ないことの方が圧倒的に多いはずです。多くの場合はブックを直せばエラーは解消するので。

なので、セルの値がエラーかどうかの判定はよほどの場合にのみ入れるようにしておき、通常は上記の「If Range(セル座標).Value = “” Then」での空白チェックでよいと思われます。

ちなみに私はほとんどの場合においてIsError関数での判定処理は入れません。面倒なので。