Excelの業務で「条件に一致する行を抽出して、特定の列だけをコピーしたい」というシーンは非常に多いものです。たとえば売上データの中から特定の担当者や商品だけを抽出し、その一部の列を報告書や他シートに貼り付けたい場合などです。
このような処理を手作業で行うと時間がかかりますが、VBAを使えば一瞬で自動化できます。この記事では、オートフィルタを使って条件に合うデータを抽出し、特定の列だけをコピーする方法を詳しく解説します。
実務での応用方法や注意点も交えながら紹介するので、この記事を読み終えるころには、データ抽出作業を効率化できるVBAスキルが身につくでしょう。
目次
✅ オートフィルタで特定の列をコピーする基本構造
・オートフィルタの仕組みを理解する
Excelの「オートフィルタ」は、特定の条件に一致する行だけを表示する機能です。VBAでも同様に使うことができ、条件を指定してデータを絞り込んだ後、表示されている行のみをコピーすることが可能です。
ポイントは、「オートフィルタで非表示になった行はコピーされない」という点です。つまり、VisibleCells(可視セル)を指定してコピーすれば、条件に合った行だけを自動で取得できます。
・基本的なVBA構文
次のコードは、オートフィルタを使って「特定の列」に基づいて抽出し、その結果から「別の列だけをコピー」する基本例です。
Sub CopyFilteredColumn()
Dim ws As Worksheet
Dim rng As Range
Dim copyRange As Range
Dim lastRow As Long
' 対象シートを設定
Set ws = ThisWorkbook.Sheets("データ")
' 最終行を取得
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' フィルタ範囲を設定(例:A列~D列)
Set rng = ws.Range("A1:D" & lastRow)
' オートフィルタを設定(例:B列="東京")
rng.AutoFilter Field:=2, Criteria1:="東京"
' 特定列(例:C列)をコピー
On Error Resume Next
Set copyRange = ws.Range("C2:C" & lastRow).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not copyRange Is Nothing Then
copyRange.Copy Destination:=ThisWorkbook.Sheets("出力").Range("A1")
Else
MsgBox "該当データがありません。"
End If
' フィルタ解除
ws.AutoFilterMode = False
End Sub
このコードでは、
- 「B列」でフィルタ条件を指定し、
- 「C列」だけをコピーして別シートに貼り付けています。
つまり、「特定の列で絞り込み、別の列を抽出する」という構造です。
参考:【VBA】特定の文字を含む列の処理:検索・削除・別シートにコピー
✅ コードの流れと各処理のポイント
・1. 最終行を取得する理由
VBAで「Range("A1:D1000")」のように固定範囲を指定すると、行数が変動するたびに修正が必要です。そのため、
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
という形で最終行を自動取得するのがベストです。これにより、データ量が増減してもコードの修正なしで動作します。
・2. AutoFilterで抽出条件を指定
rng.AutoFilter Field:=2, Criteria1:="東京"
「Field:=2」は範囲内の2列目(つまりB列)を意味します。ここで「東京」という条件を指定すると、B列が「東京」の行だけが表示されます。
複数条件を設定する場合は以下のように書けます。
rng.AutoFilter Field:=2, Criteria1:="東京", Operator:=xlOr, Criteria2:="大阪"
これにより、「東京」または「大阪」に一致するデータを抽出します。
参考:【VBA】オートフィルタの範囲を指定する方法|抽出漏れを防ぐ正しい設定手順
・3. 特定列の可視セルを取得
フィルタで非表示になっている行を除くには、SpecialCells(xlCellTypeVisible)を使います。
Set copyRange = ws.Range("C2:C" & lastRow).SpecialCells(xlCellTypeVisible)
これにより、表示されているC列のデータだけを抽出できます。オートフィルタ後のデータを安全に扱うための重要なテクニックです。
参考:【VBA】条件に一致するセルを複数取得する方法|Find・For Each・SpecialCells
・4. コピー&貼り付けの実行
コピー先には「Destination」を指定するのがポイントです。
copyRange.Copy Destination:=ThisWorkbook.Sheets("出力").Range("A1")
このように書くことで、貼り付け先を一行で指定できます。別ブックや別シートでも簡単に対応可能です。
参考:【VBA】コピーデータを貼り付ける場所を指定:Destinationパラメータ
・5. フィルタ解除を忘れずに
フィルタを解除せずに再実行すると、エラーや想定外の動作が起こる場合があります。
ws.AutoFilterMode = False
最後にこの一行を入れることで、常にシートを元の状態に戻せます。実務で複数マクロを連続実行する際にも重要です。
参考:【VBA】フィルターの一部だけを解除する方法|特定列だけ再表示したいときの解決策
✅ 実務で役立つ応用例
・複数列から特定列をコピーしたい場合
もし、抽出条件を複数列にまたがって指定したい場合は、次のように記述します。
rng.AutoFilter Field:=2, Criteria1:="東京"
rng.AutoFilter Field:=3, Criteria1:="販売"
上記のように、複数の列で条件を掛け合わせることも可能です。たとえば、「地域が東京」かつ「部門が販売」のデータだけを対象にする、といった形です。
その後に「C列」だけをコピーすれば、より絞り込まれたデータを得られます。
参考:【VBA】フィルター機能【複数条件・複数列フィルター】の操作設定
・別ブックへコピーする方法
コピー先を別ブックにしたい場合は、次のように指定します。
copyRange.Copy Destination:=Workbooks("集計結果.xlsx").Sheets("Sheet1").Range("A1")
同じワークブック内であれば問題ありませんが、別ブックの場合は事前に開いておく必要があります。
・データが存在しない場合のエラー対策
条件に一致するデータがない場合、「SpecialCells」でエラーが発生します。そのため、次のように例外処理を入れておくと安全です。
On Error Resume Next
Set copyRange = ws.Range("C2:C" & lastRow).SpecialCells(xlCellTypeVisible)
On Error GoTo 0
また、結果が空の場合にメッセージを出すと、実務での使い勝手が向上します。
✅ 注意点とトラブル対策
- フィルタ範囲に空白行を含めない
途中に空白があると最終行を正しく認識できないことがあります。あらかじめデータ範囲を明確にしておきましょう。 - ヘッダー行は含めないよう注意
コピー対象の範囲を「C2」から始めることで、ヘッダーが重複コピーされるのを防げます。 - オートフィルタを何度も設定する場合は解除を挟む
同一シートで再フィルタリングを行う際は、「AutoFilterMode = False」でリセットしてから再実行するようにしましょう。
✅ まとめ:VBAで特定列コピーを自動化して作業効率を大幅アップ
この記事では、ExcelVBAでオートフィルタを使って特定の列だけをコピーする方法を解説しました。
ポイントを整理すると次の通りです。
- オートフィルタで抽出 → SpecialCellsで可視セルだけを取得
- 必要な列だけを指定してコピー
- 最終行取得やエラー処理で柔軟に対応
- フィルタ解除を忘れない
日々の報告書作成やデータ抽出業務では、こうしたVBAの自動化が圧倒的に時間を短縮します。
慣れてくれば、複数条件の抽出や別ブック転記なども簡単に拡張できます。
VBAでのフィルタ+列コピー処理をマスターすれば、Excel作業のスピードと正確性が格段に向上するでしょう。