VBAでセルの数式がエラーか調べる|IsErrorの基本と実例
数式がエラーのセルのRange.Valueはエラーになる
セルに見えているエラー表示(例:#N/A、#DIV/0!、#VALUE!)は、VBAでRange.Valueを読み取ったときも「エラー型(Variant/Error)」として扱われます。つまり、値として数値や文字列ではなく、特殊なエラー値が入っています。これを前提に、IsError関数でTRUE/FALSEを判定できます。
最短で試すコードは次のとおりです。ワークシートのA1にエラー表示がある前提です。
- 単一セルの判定:Debug.Print IsError(Range(“A1”).Value)
- 範囲内でエラーを含むセルを数える:
Dim c As Range, cnt As Long
For Each c In Range(“A1:D10”)
If IsError(c.Value) Then cnt = cnt + 1
Next c
Debug.Print cnt
FAQ:Range.ValueがVariant以外だと何が起きる?
Variant以外の型の変数に代入すると、型の違いによっては「型が一致しません(エラー13)」が発生します。まずはVariantで受け、必要に応じて変換するのが無難です。
実務での使いどころ
IsErrorは、集計やレポート作成などで処理を止めずに進めたいときに役立ちます。たとえば、外部ブック参照切れ、0除算、VLOOKUPの未一致などでエラーが混ざる場面です。判定してスキップしたり、別シートにログを残したりできます。
用途の例:
- 貼り付け前にエラーセルを除外してクリーンな表だけを出力
- CSV書き出し時にエラーセルは空文字に置き換える
- 集計関数に渡す前にエラーセルを別配列へ移す
FAQ:手動でIFERRORを入れるのとVBA判定はどちらが良い?
数式の管理をシート側で行いたいならIFERRORが簡単です。多くのシートを横断して一括処理したい、またはログ化や条件分岐が必要ならVBAでIsError判定を使うほうが柔軟です。
エラー発生例
再現しやすい代表的な例を示します。これらのセルはVBAでもエラー型として取得されます。
- #DIV/0!:=1/0
- #N/A:=VLOOKUP(“x”, A1:B2, 2, FALSE)(一致なし)
- #VALUE!:”a”+1(型が合わない)
- #REF!:削除済み参照を含む数式
- #NAME?:未定義の名前や関数を参照
- #NUM!:不正な数値計算(例:負の平方根)
FAQ:再現しやすいテスト用の数式は?
空のワークシートで=1/0、=”a”+1、=NA()をそれぞれ入れると、#DIV/0!、#VALUE!、#N/Aが手早く再現できます。
IsError関数
構文は IsError(expression) As Boolean です。expressionに評価したい値(Variant推奨)を渡すと、エラー型ならTrue、そうでなければFalseを返します。セルの値を直接渡すほか、計算結果や関数の戻り値も判定できます。
関連の近縁関数:
- IsError:あらゆるエラー型をTrue
- IsNumeric / IsDate など:数値や日付の判定
- WorksheetFunction.IsErr / IsError:ワークシート関数との違いに注意
FAQ:IsErrorとWorksheetFunctionは何が違う?
VBAのIsErrorはVariantの型で判定します。WorksheetFunction.IsErrorはワークシート関数の文脈で評価するため、引数の扱いが異なり、配列やRangeをそのまま渡すとエラーになることがあります。基本はVBAのIsErrorを使うと安定します。
サンプルコード
最短→汎用→高速の順で3パターンを示します。
単一セルを判定
Sub Sample_IsError_OneCell()
Debug.Print IsError(Range(“A1”).Value)
End Sub
範囲をループして判定
Sub Sample_IsError_Loop()
Dim c As Range
For Each c In Range(“A1:D10”)
If IsError(c.Value) Then
Debug.Print c.Address
End If
Next c
End Sub
SpecialCellsでエラーだけを抽出
Sub Sample_IsError_SpecialCells()
On Error Resume Next ‘ エラー時(該当なし)でも中断しない
Dim tgt As Range
Set tgt = Range(“A1:D10”).SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If Not tgt Is Nothing Then
Debug.Print tgt.Address
End If
End Sub
FAQ:高速化のためにScreenUpdatingは必要?
画面の書き換えを伴う処理(選択や塗りつぶし)が多い場合のみ効果があります。値の走査だけなら効果は小さいため、まずはロジックの見直しと配列一括取得を優先します。
IsError関数を使った活用例
実務の処理フローに組み込むときの型です。
エラーセルをスキップして処理を続行
Sub SkipErrorCells()
Dim c As Range
For Each c In Range(“A1:D10”)
If IsError(c.Value) Then
‘ 何もしない(スキップ)
Else
‘ 通常の処理
End If
Next c
End Sub
エラーの種類を判定して処理を分岐
Sub BranchByErrorType()
Dim c As Range
For Each c In Range(“A1:D10”)
If IsError(c.Value) Then
Select Case CVErr(c.Value)
Case xlErrNA: Debug.Print c.Address & “: #N/A”
Case xlErrDiv0: Debug.Print c.Address & “: #DIV/0!”
Case xlErrValue: Debug.Print c.Address & “: #VALUE!”
Case xlErrRef: Debug.Print c.Address & “: #REF!”
Case xlErrName: Debug.Print c.Address & “: #NAME?”
Case xlErrNum: Debug.Print c.Address & “: #NUM!”
Case xlErrNull: Debug.Print c.Address & “: #NULL!”
End Select
End If
Next c
End Sub
FAQ:処理を止めずにログだけ残すには?
エラーセルのアドレスを配列やCollectionに溜めて、最後に1回だけ書き出すと速く、画面のちらつきも起きにくいです。
セルのエラーの種類
代表的なセルのエラー表示と、Excelの列挙子(XlCVError)およびCVErr数値の対応表です。
| 表示 | XlCVError定数 | CVErr数値 | よくある原因 |
|---|---|---|---|
| #N/A | xlErrNA | 2042 | 参照先に一致がない(LOOKUP系) |
| #DIV/0! | xlErrDiv0 | 2007 | 0で割り算 |
| #VALUE! | xlErrValue | 2015 | 型が合わない演算 |
| #REF! | xlErrRef | 2023 | 参照が削除された |
| #NAME? | xlErrName | 2029 | 名前定義や関数名の間違い |
| #NUM! | xlErrNum | 2036 | 不正な数値計算 |
| #NULL! | xlErrNull | 2000 | 交差演算子の誤用 |
FAQ:#N/Aだけを見分けたいときの最短コードは?
If IsError(v) Then If CVErr(v) = xlErrNA Then … のように、まずIsErrorで絞ってからCVErrで比較します。
Debug.Printで表示される「エラー XXXX」について
Immediateウィンドウでエラー型を出力すると、「エラー 2042」のように数値付きで表示されます。これはCVErrで取得される内部コードに一致します。上の表と見比べると、どのエラーに相当するかが分かります。
FAQ:「エラー 2042」はどのエラー?
#N/A(xlErrNA)です。VLOOKUPの未一致でよく出ます。
よくあるつまずき
WorksheetFunctionのIsErrorはRangeを直接渡すとエラーになりやすい
- Variant以外に代入して型不一致(エラー13)
- IFERRORで文字列化したセルはVBAではエラーではなくなる
FAQ:On ErrorとIsErrorはどちらを使う?
外部参照切れなど“式の結果がエラー”ならIsErrorで判定し、ファイルIOやオブジェクト参照など“実行時エラー”の可能性がある処理はOn Errorでハンドリングします。役割が異なります。
まとめ
- まずはIsErrorで“エラー型かどうか”を判定
- 必要に応じてCVErrとXlCVErrorで種類を分岐
- 範囲処理は配列一括取得やSpecialCellsで効率化
FAQ:最初に覚えるべきチェック手順は?
「IsErrorで絞る → CVErrで種類判定 → 必要ならログや色付け」の順がシンプルです。