表のデータから条件に合う行だけ手作業でコピーしていませんか。VBA マクロを使えば、指定した条件に一致する行を自動で別シートに抽出できます。
この記事では、コピーしてすぐ使える完成コードと、VBE(Visual Basic Editor)での実行手順を解説します。条件を数値比較・部分一致・複数条件(AND / OR)に変えるカスタマイズ例と、動かないときの確認ポイントも紹介します。
練習用のサンプルファイルもダウンロードできます。
zip を展開すると、マクロ入りブック(filter-copy-sample.xlsm)が入っています。「元データ」シートにサンプルデータ、「抽出結果」シートは空の状態です。そのままマクロを実行して動作を確認できます。
条件に合う行を別シートにコピーするマクロ(完成コード)
以下のコードをコピーして、次のセクションの手順で実行すると、「元データ」シートの中から C 列(部署)が「営業部」の行だけを「抽出結果」シートにコピーします。
Sub CopyRowsByCondition()
Dim wsSource As Worksheet
Dim wsDest As Worksheet
Dim lastRow As Long
Dim destRow As Long
Dim i As Long
Set wsSource = ThisWorkbook.Sheets("元データ")
Set wsDest = ThisWorkbook.Sheets("抽出結果")
'--- 抽出先をクリアしてヘッダーをコピー ---
wsDest.Cells.Clear
wsSource.Rows(1).Copy Destination:=wsDest.Rows(1)
'--- 元データの最終行を取得 ---
lastRow = wsSource.Cells(wsSource.Rows.Count, 1).End(xlUp).Row
destRow = 2
'--- 1行ずつ条件を判定してコピー ---
For i = 2 To lastRow
If wsSource.Cells(i, 3).Value = "営業部" Then
wsSource.Rows(i).Copy Destination:=wsDest.Rows(destRow)
destRow = destRow + 1
End If
Next i
MsgBox destRow - 2 & " 行コピーしました"
End Subコードの中で書き換えが必要な箇所は 3 か所です。
"元データ"― コピー元のシート名"抽出結果"― コピー先のシート名wsSource.Cells(i, 3).Value = "営業部"― 抽出条件(列番号と比較する値)
条件の変え方は「条件の変え方(カスタマイズ例)」セクションで詳しく説明します。まずは使い方から見ていきましょう。
マクロの使い方(シート構成と実行手順)
シート構成を確認する
マクロを実行する前に、ブック内に次の 2 つのシートを用意します。
- 元データ ― 1 行目がヘッダー、2 行目以降がデータ。A 列(最終行の判定基準)はすべての行にデータを入れてください
- 抽出結果 ― 空のシート。マクロがヘッダーとデータを自動で書き込みます
この記事では、次のようなサンプルデータを使います。C 列の「部署」が「営業部」の行を抽出するのがゴールです。
| A(No) | B(名前) | C(部署) | D(売上) | E(評価) | |
|---|---|---|---|---|---|
| 1 | No | 名前 | 部署 | 売上 | 評価 |
| 2 | 1 | 田中太郎 | 営業部 | 850000 | A |
| 3 | 2 | 鈴木花子 | 総務部 | 420000 | B |
| 4 | 3 | 佐藤次郎 | 営業部 | 1200000 | A |
| 5 | 4 | 山田美咲 | 開発部 | 680000 | C |
| 6 | 5 | 高橋一郎 | 営業部 | 530000 | B |
| 7 | 6 | 伊藤恵子 | 総務部 | 310000 | C |
| 8 | 7 | 渡辺健太 | 開発部 | 920000 | A |
| 9 | 8 | 小林由美 | 営業部 | 760000 | B |
| 10 | 9 | 中村拓也 | 総務部 | 480000 | B |
| 11 | 10 | 松本さくら | 開発部 | 1050000 | A |

VBE を起動してコードを貼り付ける
- Alt+F11 を押して VBE(Visual Basic Editor)を開く
- メニューバーの「挿入」→「標準モジュール」をクリック
- 右側に開いたコードウィンドウに、完成コードを貼り付ける
"元データ"、"抽出結果"、条件の部分を自分のブックに合わせて書き換える

マクロを実行する
- コードウィンドウ内にカーソルを置いた状態で F5 を押す
- 処理が終わると「○行コピーしました」とメッセージが表示される
- Alt+F11 でシートに戻ると、「抽出結果」シートに条件に合う行だけがコピーされている
サンプルデータで実行すると、営業部の 4 名(田中・佐藤・高橋・小林)の行がヘッダー付きでコピーされます。

保存形式の注意: マクロ入りブックは .xlsm 形式で保存します。通常の .xlsx で保存するとマクロが消えるため、保存時に「マクロ有効ブック (*.xlsm)」を選んでください。
コードの解説
完成コードを貼り付けて動かすだけなら前のセクションまでで十分ですが、条件を変えるときにはしくみの理解が役立ちます。ここではポイントを 3 つに絞って説明します。
最終行の取得 ― End(xlUp)
lastRow = wsSource.Cells(wsSource.Rows.Count, 1).End(xlUp).Row
この 1 行は「A 列の一番下(100 万行目付近)から上に向かって、最初にデータがあるセルの行番号を取得する」という意味です。手作業で Ctrl+↑ を押す操作と同じです。
注意: この方法は A 列を基準に最終行を判定します。A 列の途中に空行があっても、その下にデータがあればループ範囲には含まれます。ただし、A 列の末尾側が空白だと、他の列にデータが残っていてもその行を見落とします。A 列はすべての行にデータが入っている状態にしてください。
For ループで 1 行ずつ判定する
For i = 2 To lastRow
If wsSource.Cells(i, 3).Value = "営業部" Then
'... コピー処理 ...
End If
Next iFor i = 2 でヘッダー行(1 行目)をスキップし、2 行目からデータの最終行まで 1 行ずつ処理します。
Cells(i, 3) は「i 行目の 3 列目」つまり C 列を指します。列番号は A = 1、B = 2、C = 3 のように数えます。自分のデータで条件にしたい列が何列目かを確認してください。
| 列 | A | B | C | D | E | F | G | H |
|---|---|---|---|---|---|---|---|---|
| 番号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
Rows(i).Copy で行全体をコピーする
wsSource.Rows(i).Copy Destination:=wsDest.Rows(destRow)
Rows(i).Copy は i 行目の全列をコピーします。Destination:= を指定すると、クリップボードを経由せず直接コピー先に書き込まれます。
destRow は抽出先シートの書き込み位置を管理する変数です。コピーするたびに destRow = destRow + 1 で 1 つ下にずらすことで、抽出結果が詰めて並びます。
補足: 完成コードの wsDest.Cells.Clear はセルの値と書式をクリアします。書式を残して値だけ消したい場合は、wsDest.Cells.ClearContents に置き換えてください。
条件の変え方(カスタマイズ例)
完成コードの If の行を書き換えるだけで、さまざまな条件に対応できます。ここでは実務でよく使う 4 パターンを紹介します。
数値の大小で抽出する
D 列(売上)が 80 万以上の行を抽出する場合は、次のように書き換えます。
If wsSource.Cells(i, 4).Value >= 800000 Then
使える比較演算子は次のとおりです。
| 演算子 | 意味 | 例 |
|---|---|---|
= | 等しい | = 500000 |
<> | 等しくない | <> 0 |
> | より大きい | > 1000000 |
>= | 以上 | >= 800000 |
< | より小さい | < 300000 |
<= | 以下 | <= 500000 |
文字列の部分一致で抽出する(Like)
B 列(名前)に「田」を含む行を抽出する場合は、= の代わりに Like を使います。
If wsSource.Cells(i, 2).Value Like "*田*" Then
* は「任意の 0 文字以上」を表すワイルドカードです。"*田*" は「田の前後に何があってもよい」=「田を含む」という意味になります。
| パターン | 意味 | マッチ例 |
|---|---|---|
"*田*" | 「田」を含む | 田中太郎、山田美咲 |
"田*" | 「田」で始まる | 田中太郎 |
"*部" | 「部」で終わる | 営業部、開発部 |
"??太郎" | 2 文字 +「太郎」 | 田中太郎 |
? は「任意の 1 文字」を表します。文字数が決まっている場合に使います。
2 つの条件を両方満たす行(AND)
C 列が「営業部」かつ D 列が 70 万以上の行だけを抽出する場合は、And でつなぎます。
If wsSource.Cells(i, 3).Value = "営業部" And wsSource.Cells(i, 4).Value >= 700000 Then
サンプルデータでは、営業部で売上 70 万以上の田中(85 万)・佐藤(120 万)・小林(76 万)の 3 名が抽出されます。
いずれかの条件を満たす行(OR)
C 列が「営業部」または E 列が「A」の行を抽出する場合は、Or でつなぎます。
If wsSource.Cells(i, 3).Value = "営業部" Or wsSource.Cells(i, 5).Value = "A" Then
サンプルデータでは、営業部の 4 名に加え、評価 A の渡辺・松本も対象となり、合計 6 名が抽出されます(田中・佐藤は両方に該当しますが、コピーは 1 回だけです)。
うまく動かないときの確認ポイント
マクロを実行してエラーが出たり結果が期待どおりにならないときは、次の表を確認してください。
| 症状 | よくある原因 | 対処 |
|---|---|---|
| 1 件もコピーされない | 列番号の指定が違う | 条件にしたい列がA列から何列目かを数え直す(A = 1、B = 2、C = 3…) |
| 1 件もコピーされない | 条件値の全角・半角が違う | セルの値とコード内の文字列が完全に一致しているか確認する。前後の空白にも注意 |
| 末尾の行が抜ける | A 列にデータがない行がある | A 列はすべての行に値を入れる。不要な空行があれば削除する |
| 「型が一致しません」エラー | 数値列に文字(”abc” など)やエラー値が混ざっている | セルのデータを数値に直すのが最善。コードで対処するなら IsNumeric() で判定してスキップする(後述) |
| 「インデックスが有効範囲にありません」 | シート名が違う | コード内の "元データ" "抽出結果" とシートタブの名前が完全に一致しているか確認する |
| ヘッダーが 2 行になる | For ループの開始が 1 になっている | For i = 2 To lastRow の 2 を確認する(1 にするとヘッダーも条件判定される) |
「型が一致しません」を防ぐ ― IsNumeric 関数
数値で比較したい列に “abc” のような文字やエラー値が混ざっていると、比較の時点で「型が一致しません」(エラー 13)が発生します。なお、セルに “850000” のように数字だけの文字列が入っている場合は、VBA が暗黙的に数値へ変換するためエラーにはなりません。
文字が混入する可能性がある場合は、IsNumeric() で数値かどうかを先に判定するのが確実です。
If IsNumeric(wsSource.Cells(i, 4).Value) Then
If wsSource.Cells(i, 4).Value >= 800000 Then
wsSource.Rows(i).Copy Destination:=wsDest.Rows(destRow)
destRow = destRow + 1
End If
End IfIsNumeric() は値が数値として扱えるかを返します。文字やエラー値の行はスキップされるため、マクロが途中で止まりません。
ただし最善策は、元データ側で数値列に文字が混入しないようにデータを整えることです。
まとめ
Forループで 1 行ずつ条件を判定し、Rows(i).Copyで別シートにコピーするのが基本の形Ifの条件を書き換えるだけで、文字列一致・数値比較・部分一致(Like)・AND / OR に対応できる- 列番号の数え方(A = 1)と、シート名の一致が最初の確認ポイント
- A 列はすべての行にデータを入れること。
End(xlUp)は A 列を基準に最終行を取得するため、A 列の末尾が空白だと行を見落とす
コメント