Excelでオートフィルターを使って特定の条件に一致する行だけを表示しているとき、「表示されているデータだけをコピーしたい」と思っても、マクロで処理すると非表示の行まで含めてコピーされてしまうことがあります。
手作業であれば問題ないのに、VBAでうまくいかないと混乱しやすいです。
今回は、フィルター中の「表示されている行だけをコピーする方法」とその注意点を解説します。
なぜ非表示の行までコピーされてしまうのか?
まず、よくあるコード例を見てみましょう。
Range("A2:D100").Copy Destination:=Range("F2")
このようなコードでは、たとえ A2:D100 にフィルターがかかっていて一部の行だけが表示されていたとしても、範囲内のすべての行がコピーされてしまいます。
これは .Copy が「見た目」ではなく「範囲そのもの」に対して動作しているためです。
表示されている行だけをコピーする方法
フィルターで絞り込まれた「表示中のセルだけ」を対象にするには、SpecialCells(xlCellTypeVisible) を使うのがポイントです。
次のように記述することで、表示されているセルだけを選んでコピーできます。
Sub copy_visible_rows()
Dim src As Range
Dim dst As Range
Set src = Range("A2:D100").SpecialCells(xlCellTypeVisible)
Set dst = Range("F2")
src.Copy Destination:=dst
End Sub
このコードでは、Range("A2:D100") の中で、フィルターによって表示されている行のみがコピー対象になります。
実装するメリット
- 不要なデータ(非表示行)を除外できる
- 転記先に余計な行を含まず、整ったコピー処理ができる
- フィルターとマクロを組み合わせた実務処理が安定する
応用:行単位で値だけコピーしたいとき
.Copy を使うと、数式や書式まで含めてコピーされるため、値だけをコピーしたい場合には、ループで1行ずつ処理する方法もあります。
Sub copy_visible_values()
Dim r As Range
Dim cell As Range
Dim dstRow As Long
dstRow = 2
For Each r In Range("A2:A100").SpecialCells(xlCellTypeVisible).Cells
' 対象の1行全体を値としてコピー
Range("A" & r.Row & ":D" & r.Row).Copy
Range("F" & dstRow).PasteSpecial Paste:=xlPasteValues
dstRow = dstRow + 1
Next r
Application.CutCopyMode = False
End Sub
この方法では、1行ずつ値だけを抽出してコピーできるため、必要最小限の情報だけを取り出す用途に最適です。
まとめ
フィルターで表示されている行だけをコピーしたいのに、すべての行がコピーされてしまう問題は、.SpecialCells(xlCellTypeVisible) を使うことで解決できます。
押さえておきたいポイントは次のとおりです。
.Copyでは、範囲全体が対象になるため非表示行も含まれてしまう.SpecialCells(xlCellTypeVisible)を使えば、表示中のセルだけが対象になる- 必要に応じて、PasteSpecial を使った「値だけコピー」も可能
見た目に合わせた正確な処理を実現することで、マクロの信頼性と実用性が大きく向上します。
フィルターとマクロを併用した業務効率化に、ぜひ今回の方法を活用してみてください。


