【VBA】必要な行だけ抽出するマクロの作り方!フィルター操作完全不要

 

エクセルの一覧表から「特定の担当者の行だけ確認したい」「条件に合うデータだけ別シートに転記したい」という場面、毎日のように発生していませんか?

 

フィルター機能を使えばある程度絞り込めますが、条件が複数になったり、抽出結果を別シートに貼り付けたりする作業が加わると、途端に手間がかかります。

実は私も、会社員時代に何百件ものデータが入った一覧表から条件に合う行だけを毎日手作業で探し出し、別の書類に転記するという作業を繰り返していました。

 

この記事では、VBAを使って「条件に一致する行だけを自動で別シートに抽出する方法」を、プログラミング初心者でも理解できるように実際のコードと合わせて解説します。

ボタン1クリックで一瞬で処理が完了するので、毎日のルーティーン作業を大幅に短縮できます。

 

広告

大量データから手作業でデータを探すことの限界

エクセルで大量のデータを管理していると、必ず「この中から特定のデータだけ取り出したい」という場面が出てきます。

標準のフィルター機能を使えば画面上での絞り込みは可能ですが、「絞り込んだ結果を別のシートや書類に転記する」という作業が加わると、一気に手間が増えます。

私がマクロ開発依頼を受ける中でも「一覧表から条件に合う行を別シートに抽出したい」というニーズは非常に多く、毎月50件前後のご依頼の中でも特に頻度の高いテーマです。

 

手作業での抽出が引き起こす3つの問題

手作業でデータを抽出し続けることで、現場では必ず次の3つの問題が発生します。

 

まず1つ目は、作業時間の浪費です。

100件、200件を超えるデータになってくると、フィルターをかけて確認して、コピーして、別シートに貼り付けて、という一連の流れだけで10分以上かかることは珍しくありません。

これを毎日繰り返していると、週に1時間以上、月に4〜5時間もの時間をこの作業だけに費やしていることになります。

 

2つ目は、ミスの発生リスクです。

手作業でコピーペーストを繰り返すと「この行、転記し忘れた」「ひとつずれてしまった」というミスがどうしても発生します。

大切な情報が抜け落ちたまま書類を作成してしまうと、後から大きな問題になりかねません。

 

3つ目は、属人化の問題です。

「この作業はあの人しかできない」という状態が生まれると、その人が休んだり退職したりしたとき、業務が止まります。

VBAで自動化してしまえば、誰でもボタン1クリックで同じ作業を正確に行えるようになるため、属人化の解消にも直結します。

 

フィルター機能だけでは限界がある理由

エクセルのフィルター機能は、画面上でのデータ絞り込みには非常に便利です。

しかし「絞り込んだ結果を別シートに自動で転記する」「複数の条件を組み合わせて抽出する」「抽出結果を毎回クリアしてから上書きする」といった処理は、フィルター機能だけでは対応できません。

こういった「もう一歩踏み込んだ抽出作業」を自動化するために、VBAが非常に有効です。

 

VBAで行を抽出する仕組みを理解する

VBAで行を抽出するとき、基本となる考え方はとてもシンプルです。

「一覧シートの全データを1行ずつ確認して、条件に合う行だけを抽出結果シートにコピーする」という流れです。

この処理には For〜Next ループと If〜Then 条件分岐の2つの命令を組み合わせて使います。

どちらもVBAの基本中の基本となる命令なので、プログラミング初心者の方でも無理なく理解できます。

 

 

完全一致で行を抽出するVBAコード(基本形)

まずは「1つの条件に完全一致する行だけを抽出する」という最もシンプルなパターンから解説します。

 

以下のような一覧シートを想定しています。

A列:No B列:担当エリア C列:担当者名 D列:ステータス E列:案件名

一覧表の様式

 

抽出結果シートのC1セルに入力したエリア名に一致する行だけを、抽出結果シートに転記するVBAコードがこちらです。

Sub 条件一致行を別シートに抽出()
Dim ws一覧 As Worksheet
Dim ws抽出 As Worksheet
Dim 最終行 As Long
Dim i As Long
Dim 出力行 As Long
Dim 検索値 As String '処理対象のシートを設定',
Set ws一覧 = ThisWorkbook.Worksheets("一覧")
Set ws抽出 = ThisWorkbook.Worksheets("抽出結果") '抽出条件をセルから取得(例:C1セルに入力した値)
検索値 = ws一覧.Range("G2").Value '抽出結果シートの2行目以降をクリア
ws抽出.Rows("2:" & ws抽出.Rows.Count).ClearContents '最終行を取得
最終行 = ws一覧.Cells(ws一覧.Rows.Count, 1).End(xlUp).Row '出力開始行
出力行 = 2 'ヘッダーをコピー',
ws一覧.Rows(1).Copy ws抽出.Rows(1) '一覧シートを1行ずつ確認していく
For i = 2 To 最終行 'B列の値が検索値と一致する場合のみ転記
If ws一覧.Cells(i, 3).Value = 検索値 Then
ws一覧.Rows(i).Copy ws抽出.Rows(出力行)
出力行 = 出力行 + 1
End If
Next i
MsgBox "抽出が完了しました。", vbInformation
End Sub

 

コードの流れを解説します。

最初の Set ws一覧 = ThisWorkbook.Worksheets(“一覧") と Set ws抽出 = ThisWorkbook.Worksheets(“抽出結果") で、処理対象の2枚のシートをそれぞれ変数に格納します。

次に 検索値 = ws一覧.Range(“G2").Value で、抽出結果シートのC1セルに入力されている値(抽出したいエリア名)を取得。

 

ws抽出.Rows(“2:" & ws抽出.Rows.Count).ClearContents は抽出結果シートの2行目以降をクリアする処理です。

前回の抽出結果が残ったまま新しいデータが上書きされると、古いデータと混在してしまう危険があるため、毎回クリアしてから処理を開始するのが鉄則です。

 

Cells(ws一覧.Rows.Count, 1).End(xlUp).Row は一覧シートのA列の最終行を自動取得する命令です。

この書き方にしておくと、一覧表のデータが増えても範囲指定を変更する必要がありません。

 

For i = 2 To 最終行 のループで一覧シートのデータ行を1行ずつ確認し、If ws一覧.Cells(i, 2).Value = 検索値 の条件に一致する行だけを ws一覧.Rows(i).Copy ws抽出.Rows(出力行) で抽出結果シートにコピーします。

 

実行結果がこちら

マクロの実行結果

 

検索地に該当する行だけを「抽出結果」シートにコピペできました。

 

この基本形をしっかり理解しておくと、条件を変えたり抽出対象の列を変えたりするカスタマイズが簡単にできるようになります。

 

関連記事「別シートにテキストを転記」では、転記マクロをダウンロードすることができます。

 

 

実際にマクロを動かしてみて便利さを体感してみてください。

 

複数条件を組み合わせて行を抽出するVBAコード

実務では「担当者名が○○で、かつステータスが未完了の行だけ抽出したい」という複数条件での抽出が求められる場面が多くあります。

VBAでは And 演算子を使うことで、複数の条件を同時に指定することができます。

抽出結果シートのC1セルに担当者名、C2セルにステータスを入力し、2つの条件に両方一致する行だけを抽出するVBAコードがこちらです。

 

Sub 複数条件で行を抽出()

Dim ws一覧 As Worksheet
Dim ws抽出 As Worksheet
Dim 最終行 As Long
Dim i As Long
Dim 出力行 As Long
Dim 担当者名 As String
Dim ステータス As String
Set ws一覧 = ThisWorkbook.Worksheets("一覧")
Set ws抽出 = ThisWorkbook.Worksheets("抽出結果") '抽出条件を抽出結果シートのセルから取得
担当者名 = ws抽出.Range("C1").Value
ステータス = ws抽出.Range("C2").Value
ws抽出.Rows("2:" & ws抽出.Rows.Count).ClearContents
最終行 = ws一覧.Cells(ws一覧.Rows.Count, 1).End(xlUp).Row
出力行 = 2 ws一覧.Rows(1).Copy
ws抽出.Rows(1)
For i = 2 To 最終行 '担当者名とステータスが両方一致する場合のみ転記

If ws一覧.Cells(i, 3).Value = 担当者名 And _ ws一覧.Cells(i, 4).Value = ステータス Then
ws一覧.Rows(i).Copy
ws抽出.Rows(出力行)
出力行 = 出力行 + 1
End If
Next i

MsgBox "複数条件での抽出が完了しました。", vbInformation

End Sub

コードの流れを解説します。

 

基本形との違いはIf文の条件部分だけです。

If ws一覧.Cells(i, 3).Value = 担当者名 And ws一覧.Cells(i, 4).Value = ステータス Then という条件を設定することで、「C列の担当者名が一致する」かつ「D列のステータスが一致する」行だけが抽出対象になります。

 

And の部分を Or に変えると「どちらか一方でも一致する行を抽出する」という条件になります。

たとえば「担当者名が山田さん、または担当者名が鈴木さん」という条件にしたいときは Or を使います。

このように And と Or を使い分けるだけで、様々な抽出条件に柔軟に対応することができます。

 

部分一致(キーワード検索)で行を抽出するVBAコード

 

「セルの値が完全一致する行」だけでなく、「特定のキーワードを含む行を抽出したい」という場面もよくあります。

たとえば案件名に「改修」という文字が含まれている行だけを抽出したい、というケースです。

こういった部分一致検索には InStr 関数を使います。

InStr 関数は「ある文字列の中に指定した文字が含まれているかどうか」を調べる関数で、含まれていれば0より大きい数値が返ってきます。

 

Sub 部分一致で行を抽出()

Dim ws一覧 As Worksheet
Dim ws抽出 As Worksheet
Dim 最終行 As Long
Dim i As Long
Dim 出力行 As Long
Dim キーワード As String
Set ws一覧 = ThisWorkbook.Worksheets("一覧")
Set ws抽出 = ThisWorkbook.Worksheets("抽出結果") 'キーワードを取得',
キーワード = ws抽出.Range("C1").Value
ws抽出.Rows("2:" & ws抽出.Rows.Count).ClearContents
最終行 = ws一覧.Cells(ws一覧.Rows.Count, 1).End(xlUp).Row
出力行 = 2 ws一覧.Rows(1).Copy
ws抽出.Rows(1)

For i = 2 To 最終行 '案件名(C列)にキーワードが含まれている場合のみ転記 'InStr関数でキーワードが含まれているかチェックする

If InStr(ws一覧.Cells(i, 5).Value, キーワード) > 0 Then
ws一覧.Rows(i).Copy ws抽出.Rows(出力行)
出力行 = 出力行 + 1
End If
Next i

MsgBox "部分一致での抽出が完了しました。", vbInformation

End Sub

 

コードの流れを解説します。

 

If InStr(ws一覧.Cells(i, 5).Value, キーワード) > 0 Then という条件がポイントです。

InStr の第1引数に「検索対象のセルの値」、第2引数に「探したいキーワード」を指定します。

キーワードが含まれていれば1以上の数値が返ってくるので、「> 0」という条件で一致判定が可能。

 

キーワードが含まれていない場合は 0 が返るため、その行はスキップされます。

 

この方法を使えば、フィルターのテキストフィルター(特定の文字を含む)と同じような絞り込みを自動化することができます。

 

関連記事「別シートにテキストを自動転記」では、シートを指定するVBA、転記VBAが設定されたエクセルファイルをダウンロードすることができます。
▶ 別シートにテキストを自動転記(note記事)

 

抽出VBAをボタンに登録してさらに使いやすくする

VBAコードが完成したら、エクセルシート上にボタンを配置してワンクリックで実行できるようにしましょう。

ボタンを設置することで、VBAの知識がないスタッフでも同じ作業をミスなく実行できるようになります。

 

ボタンの作成手順

ボタンを設置する手順は非常に簡単です。

まず「開発」タブをクリックし、「挿入」→「ボタン(フォームコントロール)」を選択します。

ボタン作成方法

 

次に、シート上でボタンを配置したい場所をドラッグすると「マクロの登録」ダイアログが表示されます。

 

作成したマクロ名(例:条件一致行を別シートに抽出)を選んで「OK」をクリックすれば設定完了です。

ボタンの上で右クリックして「テキストの編集」を選ぶと、「▶ 抽出実行」のようなわかりやすいラベルをボタンに表示することもできます。

 

ボタンを設置した後は、抽出条件のセル(例:C1セルにエリア名を入力)を変えるだけで、毎回異なる条件での抽出が可能になります。

 

抽出VBAを使う際の注意点

抽出VBAを実装する際に、いくつか注意しておくべきポイントがあります。

 

1点目は、シート名の管理です。

VBAコードの中に書いてあるシート名(「一覧」や「抽出結果」など)と実際のシート名が一致していないとエラーになります。

シート名を変更する場合は必ずコード内のシート名も合わせて修正してください。

 

2点目は、データの最終行の取得方法です。

Cells(Rows.Count, 1).End(xlUp).Row を使うと、A列のデータがある最終行を自動で取得できます。

固定値(例:1000行目まで)で指定してしまうと、データが1000行を超えたときに取りこぼしが発生するため、必ず動的に最終行を取得する書き方にしましょう。

 

3点目は、抽出結果のクリア処理です。

ClearContents でデータをクリアしてから転記する処理を入れないと、前回の抽出結果が残ったまま新しいデータが積み上げられていくことになります。

毎回必ずクリアしてから抽出処理を実行するコードにしておきましょう。

 

実際の現場でどのように活用されているか

私が今まで受けてきたマクロ開発依頼の中でも、「一覧表から必要な行だけを抽出する処理」は非常に多いテーマです。

ここでは実際の依頼事例をもとに、どのような場面でこのVBAが活用されているかを紹介します。

 

事例① 工事管理の現場での活用

建設関係の会社で工事案件の管理をしているお客様から「担当者別に工事案件の一覧を抽出して、月次報告書を作りたい」というご依頼をいただきました。

案件が月に100件以上発生するため、毎月末になると担当者ごとにフィルターをかけてデータをコピーして、報告書に貼り付けるという作業だけで半日以上かかっていたそうです。

今回紹介したVBAを応用し、担当者名を入力してボタンを押すだけで、その担当者の案件一覧が自動で別シートに出力される仕組みを構築しました。

これにより、半日かかっていた作業が5分以内に完了するようになったとのことです。

 

事例② 在庫管理の現場での活用

製造業の会社で在庫管理を担当しているお客様から「在庫が一定数を下回った商品だけを一覧で確認したい」というご依頼をいただきました。

商品数が数百品目にのぼるため、手作業で在庫数を確認して発注対象品目を洗い出す作業が毎日発生していたそうです。

今回紹介した抽出VBAに「在庫数が基準値以下かどうかをチェックする条件分岐」を追加することで、発注が必要な商品だけを自動で別シートに抽出する仕組みを構築しました。

数値比較(<= で以下の判定)は文字列の一致判定と同じように If 文で対応できるため、今回紹介したコードの応用で実現できます。

 

事例③ 人事管理の現場での活用

人材派遣会社のお客様から「スタッフの勤務シフト一覧から、特定の期間に稼働しているスタッフだけを抽出したい」というご依頼をいただきました。

期間指定(日付の範囲検索)という条件が加わるため少し複雑になりますが、基本的な抽出VBAの考え方は同じです。

日付の比較には >= や <= の演算子を使い、「開始日以降かつ終了日以前」という条件で対象行を絞り込みます。

このように今回紹介したVBAをベースとして、条件の部分だけを変えることで、様々な業種・業務に応用できます。

 

まとめ ~ VBAで必要な行を瞬時に抽出して業務を劇的に効率化する ~

エクセルの一覧表から必要な行だけを手作業で探し出す作業は、データ量が増えるほど時間もミスも増え続けます。

VBAを使えば「完全一致での抽出」「複数条件での抽出」「部分一致(キーワード)での抽出」といったあらゆるパターンをボタン1クリックで処理することができます。

 

今回紹介した3種類のVBAコードは、どれもシンプルな構造をベースにしているため、業務の内容に合わせて条件の部分を書き換えるだけで様々な抽出作業に応用できます。

まずは基本形のコードを自分のエクセルファイルに取り入れて、ボタン1クリックで抽出できる環境を作ってみてください。

 

毎日フィルター操作に時間をとられていた方ほど、VBA導入後の変化を大きく実感できるはずです。

 

もし「自分の業務に合わせた複雑なチェック処理を実装したい」「既存のマクロを改良したい」といったご要望がありましたら、マメBlogのエクセルマクロ開発依頼にご相談ください。

 

 

業務内容に合わせたオーダーメイドマクロを設定させていただきます。

最後まで読んでいただきありがとうございました。エクセルVBAを使って面倒なルーティーン作業を自動化しちゃいましょう。