ExcelでVLOOKUPやMATCHなどの関数を使っていると、検索に失敗したセルに「#N/A(エラー)」が表示されることがあります。
見た目では「空白」や「0」とは異なるため、集計や抽出を行う際に正確に処理するのが難しくなります。
特にVBAでオートフィルタを使う場合、「#N/A以外」を抽出したいのに、
単純に "<>#N/A"
と指定しても正しく動作しないことがあります。
この記事では、「#N/A以外のデータだけをフィルタで抽出する方法」を、
実務で使えるVBAコードとともに詳しく解説します。
目次
- ✅ 「#N/A」を含むデータで起こる問題とは
- ・#N/Aは通常の文字列ではなく“エラー値”
- ✅ 基本構文:「#N/A以外」を抽出する方法
- ✅ 応用①:オートフィルタ機能で「#N/A以外」を抽出
- ✅ 応用②:「#N/A」以外の値を別シートへ転記
- ✅ 応用③:「#N/A」以外かつ空白を除く条件で抽出
- ✅ なぜ「#N/A以外」は通常のCriteria指定では動かないのか
- ・原因:VBAのAutoFilterは「エラー値」を直接判定できない
- ✅ 実務での活用例:「#N/Aを除いて集計」「未マッチデータ除外」など
- ✅ 注意点と安定化のポイント
- ・1. On Error Resume Next は最小限に
- ・2. AutoFilter解除を忘れずに
- ・3. #N/A以外にも「#DIV/0!」「#VALUE!」などが混在する場合
- ✅ まとめ:VBAで「#N/A以外」を扱うならIsErrorを活用しよう
✅ 「#N/A」を含むデータで起こる問題とは
・#N/Aは通常の文字列ではなく“エラー値”
Excelの「#N/A」は見た目は文字列のように見えますが、
実際は 「セルの値がエラー型(Error)」 として扱われています。
そのため、次のような操作では正しく抽出されません。
Range("A1").AutoFilter Field:=1, Criteria1:="<>#N/A"
この指定では、VBAは「文字列『#N/A』」を探そうとするため、
実際のエラー値とは一致せず、フィルタ結果が想定通りにならないのです。
つまり、「#N/A以外」を正しく抽出するには、
エラー値そのものを判定して除外するロジックが必要です。
参考:【Excel】「#N/A」を判定する方法|エラー管理と資料の整え方を徹底解説
✅ 基本構文:「#N/A以外」を抽出する方法
まずは、最もシンプルに「#N/Aではないセルだけを残す」方法を紹介します。
Sub FilterExcludeNA()
Dim ws As Worksheet
Dim lastRow As Long
Dim rng As Range
Dim i As Long
Set ws = ThisWorkbook.Sheets("データ")
' 最終行を取得
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' データ範囲を設定
Set rng = ws.Range("A1:A" & lastRow)
' 既存フィルタ解除
If ws.AutoFilterMode Then ws.AutoFilterMode = False
' フィルタを一時的にかける(全データを対象)
rng.AutoFilter
' 「#N/A」以外を残す処理
For i = rng.Rows.Count To 2 Step -1
If IsError(ws.Cells(i, 1)) Then
ws.Rows(i).Hidden = True
End If
Next i
MsgBox "#N/Aを除外してフィルタしました。", vbInformation
End Sub
コードのポイント解説
IsError(ws.Cells(i, 1))
セルがエラー値かどうかを判定します。#N/A
もこの条件に含まれます。
参考:【VBA】数式の結果を取得する方法ws.Rows(i).Hidden = True
#N/Aが含まれる行を非表示にして、結果的に「#N/A以外」だけを表示しています。
参考:【Excel】「#N/Aならば空白」にする方法|エラーを自動で非表示にし資料をきれいに整える基本AutoFilter
を直接使わず、「ループ×非表示」というアプローチで確実に除外できます。
この方法なら、#N/A
以外のデータだけを残せるため、
見た目も正確で、後続の処理(コピー・集計など)もエラーなく実行できます。
✅ 応用①:オートフィルタ機能で「#N/A以外」を抽出
上記のように非表示制御で除外する以外に、
実際のオートフィルタ機能を使って可視セルだけを取得する方法もあります。
Sub FilterVisibleWithoutNA()
Dim ws As Worksheet
Dim rng As Range
Dim visibleRange As Range
Set ws = ThisWorkbook.Sheets("データ")
' フィルタ解除
If ws.AutoFilterMode Then ws.AutoFilterMode = False
' フィルタ範囲を設定
Set rng = ws.Range("A1").CurrentRegion
rng.AutoFilter Field:=1
' #N/Aセルを除外
On Error Resume Next
Set visibleRange = rng.Offset(1, 0).Resize(rng.Rows.Count - 1).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
Dim cell As Range
For Each cell In rng.Columns(1).Cells
If cell.Row > 1 Then
If IsError(cell.Value) Then cell.EntireRow.Hidden = True
End If
Next cell
MsgBox "#N/A以外を抽出しました。", vbInformation
End Sub
この構文では、
- オートフィルタでデータを整理
IsError
でエラーセルだけを非表示
という2段階で「#N/A以外」を抽出します。
見た目上は通常のフィルタのように動作し、
ユーザーが「N/Aを除外して結果を確認する」用途に最適です。
参考:【ChatGPT】Excel関数の聞き方をマスターしよう|効果的な質問方法と具体例を解説
✅ 応用②:「#N/A」以外の値を別シートへ転記
レポート作成やデータ整理では、「#N/Aを除いた値だけを別シートに出力したい」というケースも多いです。
次のコードでは、#N/Aをスキップして新しいシートに転記します。
Sub CopyWithoutNA()
Dim wsSrc As Worksheet
Dim wsDst As Worksheet
Dim lastRow As Long
Dim i As Long, j As Long
Set wsSrc = ThisWorkbook.Sheets("データ")
Set wsDst = ThisWorkbook.Sheets("結果")
wsDst.Cells.ClearContents
lastRow = wsSrc.Cells(wsSrc.Rows.Count, "A").End(xlUp).Row
j = 1
For i = 1 To lastRow
If Not IsError(wsSrc.Cells(i, 1)) Then
wsDst.Cells(j, 1).Value = wsSrc.Cells(i, 1).Value
j = j + 1
End If
Next i
MsgBox "#N/A以外のデータを転記しました。", vbInformation
End Sub
この方法は「フィルタを使わずにエラーを除外する」アプローチで、
VLOOKUPやMATCHを多用しているファイルでも安定して動作します。
✅ 応用③:「#N/A」以外かつ空白を除く条件で抽出
実務では「#N/Aと空白の両方を除外したい」ケースも多いでしょう。
その場合は、IsError
と Trim
の組み合わせで条件を絞ります。
Sub ExcludeNAandBlank()
Dim ws As Worksheet
Dim i As Long
Dim lastRow As Long
Set ws = ThisWorkbook.Sheets("データ")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
For i = 2 To lastRow
If IsError(ws.Cells(i, 1)) Or Trim(ws.Cells(i, 1).Value) = "" Then
ws.Rows(i).Hidden = True
End If
Next i
MsgBox "#N/Aと空白を除外して表示しました。", vbInformation
End Sub
このようにすれば、
実際に分析や報告資料に使える“きれいな抽出データ”を得られます。
参考:【VBA】シート全体のスペースを削除する方法:Trim 関数・Replace 関数
✅ なぜ「#N/A以外」は通常のCriteria指定では動かないのか
・原因:VBAのAutoFilterは「エラー値」を直接判定できない
Excel上では「#N/A」を手動でフィルタ除外できますが、
VBAのAutoFilter
メソッドは文字列基準で判定するため、
Criteria1:="<>#N/A"
や Criteria1:="=#N/A"
では一致しません。
これは、セルの内部的な値が Variant/Error型 だからです。
そのため、IsError()
関数を使うのが最も確実な方法になります。
✅ 実務での活用例:「#N/Aを除いて集計」「未マッチデータ除外」など
実務では次のようなケースでこのスクリプトが役立ちます。
- VLOOKUP結果で #N/A の取引先を除いて売上を集計したい
- マスタ未登録データ(#N/A)のみを抽出したい
- 正常データのみを別シートへ転記し、報告書を作成したい
- フィルタ済みデータを加工・印刷する前に #N/A を除外したい
これらは日常業務で非常に多く、
「#N/A以外」の抽出を自動化できれば手作業を大幅に削減できます。
✅ 注意点と安定化のポイント
・1. On Error Resume Next は最小限に
エラー回避目的で使うのは問題ありませんが、
スクリプト全体に適用すると本来の不具合を見逃す原因になります。
SpecialCells
や IsError
の部分だけに使いましょう。
・2. AutoFilter解除を忘れずに
フィルタ後の状態を残すと次の処理で意図しない動作になります。
終了時には ws.AutoFilterMode = False
を必ず入れておきましょう。
・3. #N/A以外にも「#DIV/0!」「#VALUE!」などが混在する場合
すべてのエラー値を除外したい場合は、
If IsError(ws.Cells(i, 1)) Then
のままでOKです。
これで全エラーを一括で除外できます。
✅ まとめ:VBAで「#N/A以外」を扱うならIsErrorを活用しよう
#N/A
は文字列ではなく「エラー型」なので"<>#N/A"
では抽出できないIsError()
でエラー値を判定し、除外またはスキップするのが確実- フィルタ後に
Hidden=True
を使うと見た目上も「#N/A以外」に整理できる - 別シート転記や集計処理にも応用可能
- フィルタ解除 (
AutoFilterMode=False
) とエラー制御を忘れずに
VBAで「#N/A以外」を扱う場面は、VLOOKUPを使った業務で非常に多く発生します。
本記事の方法を取り入れれば、エラー行を確実に除外して、
実務で止まらない・正確なデータ抽出 が実現できます。
ぜひあなたのマクロにもこのロジックを組み込み、
「#N/Aで止まらないVBA」を作成してみてください。