例文を使って繰り返し業務を時短

【マクロ・VBA】特定シートと右隣のシート間でマッチングした行を新規シートに貼付け

エクセル、マクロ、VBAのfindでシート間のデータをマッチさせて新規シートに転記する VBA

ファインド_検索_新規シート貼り付け

このVBAコードは、検索データを含むシートから、対象データが含まれる別のシートを検索し、検索結果を新しいシートに貼り付けるプログラムです。以下、コードの各部分の説明をします。

*検索結果は空欄の行を削除してつめて表示

Sub 検索_行の抽出_ファインド_新規シート貼り付け()

With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With

Dim rM, rH, rMy, rFirst, rU As Range
     
'検索データがあるシート
Dim targetSheet As Worksheet
    Set targetSheet = Worksheets("検索データ")
    
   '検索範囲の指定
    Dim LstRow1 As Long '変数の宣言
    LstRow1 = targetSheet.Cells(Rows.Count, 1).End(xlUp).Row
    Set rH = targetSheet.Range("A1:A" & LstRow1)

 targetSheet.Next.Select
 
'対象データがあるシート
    Dim seathSheet As Worksheet
    Set seathSheet = Worksheets("検索データ").Next
    
    '対象範囲の指定
        Dim LstRow2 As Long
        LstRow2 = seathSheet.Cells(Rows.Count, 1).End(xlUp).Row
        Set rU = seathSheet.Range("A1:A" & LstRow2)
    
'③検索結果を出力するシート
Dim Num As Long
On Error Resume Next

Worksheets.Add(After:=ActiveSheet).Name = _
ActiveSheet.Name & "_" & VBA.Format(Now(), "h時mm分ss秒")

Dim outputSheet As Worksheet
    Set outputSheet = ActiveSheet
     
'処理
Dim i As Long
Dim cnt As Long: cnt = 2
      
For i = cnt To LstRow1
    DoEvents
    Dim searthCell As Range
    Set searthCell = targetSheet.Cells(i, 1)
        
    Dim FoundCell As Range
    If Not searthCell = "" Then
        Set FoundCell = rU.Find(searthCell, LookAt:=xlWhole, SearchOrder:=xlByColumns)
            
            Dim firstCell As Range
            If Not FoundCell Is Nothing Then
               Set firstCell = FoundCell
                
                Do
                DoEvents
                         
                    seathSheet.Rows(FoundCell.Row).Copy
                    outputSheet.Rows(cnt).PasteSpecial (xlPasteValues)
            
                    cnt = cnt + 1
                 
                    Set FoundCell = rU.FindNext(FoundCell)
                 
                    If FoundCell.Address = firstCell.Address Then
                    DoEvents
                         Exit Do
                    ElseIf FoundCell Is Nothing Then
                         Exit Do
                    End If
                Loop
                 
            End If
     End If
Next

Application.CutCopyMode = False
Application.Calculation = xlAutomatic
Application.ScreenUpdating = True
Application.DisplayAlerts = True

ActiveSheet.Range("A2").Select

MsgBox "完了"
End Sub

解説

まず、以下のコードでExcelアプリケーションの画面更新をオフにし、イベント処理を無効にし、計算モードを手動に変更します。これにより、処理速度が向上します。

次に、検索データが含まれるシートと対象データが含まれるシートを指定します。このコードでは、検索データがあるシートを “検索データ” 、対象データがあるシートを “検索データ” の隣にあるシートとしています。シートを指定した後は、それぞれのシートの検索範囲を指定します。ここでは、列Aから最終行までの範囲を指定しています。

次に、検索結果を出力するための新しいシートを作成します。シート名は、現在の日時を含めた名前になります。

その後、検索データがあるシートからデータを読み取り、それぞれの検索条件について検索を行い、一致するデータを新しいシートに出力します。

ForループでtargetSheetの各行を処理し、各行にある検索条件のセルをsearthCell変数に代入します。次に、’検索Findメソッドを使用して、searthCellを検索対象の範囲であるseathSheetの範囲rU内で検索します。もし一致するデータがあれば、そのセルをFoundCell変数に代入し、以降の処理を行います。

Doループで、’FoundFoundCellが見つかるたびに、その行を新しいシートにコピーしていきます。それぞれのデータが新しい行にコピーされると、cnt変数を増やし、次の行に移動します。そして、FindNextメソッドを使用して、次の一致するセルを検索し、同様の操作を続けます。最後に、最初に一致したセルに戻ってきたら、ループを抜けます。

最後に、Excelアプリケーションの設定を元に戻します。

  • シートの指定:’左から6番目のシート Worksheet(6)
  • 範囲指定:Set targetRng = Columns(“A”)
         Set rH = targetSheet.Range(“F2:F100001”)

<参考>

  • 項目をコピーする場合:Worksheets(“項目”).Rows(1).Copy ActiveSheet.Rows(1)
  • 書式を自動調整する場合:outputSheet.Columns(“A:AX”).AutoFit
  • 列削除:Columns(“A:E”).Delete /Columns(“A”).Delete

流れ

このコードは、①のシートからデータを取得して、そのデータを利用して②のシートから該当するデータを検索し、該当するデータを③のシートに出力するコードです。

①のシートから検索するデータの範囲を指定する。

②のシートから対象のデータの範囲を指定する。

③のシートを作成する。

①のシートの検索データを1つずつ取得し、②のシートで検索する。

該当するデータがあれば、それを③のシートに出力する。

ファインド_検索語句を指定

このVBAコードは、指定された範囲内でキーワードを検索し、検索結果をハイライト表示し、結果を別の列にコピーするマクロです。

Sub ファインド_キーワード()
 
    Dim Keyword As String
    Dim FoundCell As Range
    
    Dim firstFoundCell As Range
    
    Dim searchResult As Range
    
    Keyword = "横浜"
    
    'Set foundCell = Cells.Find(What:=Keyword)
    Set FoundCell = ActiveSheet.Range("A2:A1000").Find(What:=Keyword)
    Set firstFoundCell = FoundCell
    
    Set searchResult = FoundCell
    
    Do
        Set FoundCell = Cells.FindNext(FoundCell)
        
        If FoundCell.Address = firstFoundCell.Address Then
           
            Exit Do
        
        Else
            
            Set searchResult = Union(searchResult, FoundCell)
        End If
    Loop
    
    searchResult.Interior.ColorIndex = 27
    
    MsgBox Keyword & ":" & searchResult.Count & "件"
   
    Dim c As Range
    
    Dim cnt As Integer
    
    cnt = 2
    
    For Each c In searchResult
         
         Cells(cnt, "F") = c.Previous.Value
 
         Cells(cnt, "F").Borders.LineStyle = xlContinuous

         cnt = cnt + 1
        
    Next
 MsgBox "完了"
End Sub

解説

まず、’キーワードという変数に検索するキーワードを設定しています。次に、’ActiveSheet.Range(“A2:A1000”).検索(何:=キーワードActiveSheet.Range("A2:A1000").Find(What:=Keyword)という行で、検索範囲をActiveSheet上のA2からA1000までの範囲に設定し、’FindFindメソッドを使用してKeywordに一致する最初のセルを検索しています。

その後、Doループを使って、最初の検索結果セルから次の検索結果セルを探します。ループ内のIfステートメントは、検索範囲内で最初に検索されたセルに戻ってきた場合、ループを抜けます。そうでなければ、’ユニオンUnion関数を使って検索結果を1つの範囲にまとめ、それをsearchResult変数に代入します。

次に、’検索結果変数内のすべてのセルをハイライト表示し、その後、’For EachFor Eachループを使用して、’searchResultsearchResult変数内のセルを1つずつ処理し、その前の列にある値を別の列にコピーします。この場合、’Cells(cnt, “F”) = c.Previous.ValueCells(cnt, "F") = c.Previous.Valueを使用して、’cntcnt変数に対応する行のF列に値をコピーしています。

最後に、メッセージボックスで検索結果の件数を表示し、完了を示すメッセージボックスを表示します。

スピードアップのための改善策

  • ActiveSheet.Range("A2:A1000").Find(What:=Keyword)のように、明示的に範囲を指定するよりも、’Set FoundCell = Cells.Find(What:=KeywordSet FoundCell = Cells.Find(What:=Keyword)のように、範囲を省略する方が良い場合があります。これは、すべてのセルを検索するための時間が節約できるからです。
  • Withステートメントを使用して、Excelアプリケーションの設定を一時的に変更することで、マクロの処理速度を高速化できます。
  • できるだけ変数を使用して、セル範囲の取得や操作を最小限に抑えることもスピードアップにつながります。

コメント

タイトルとURLをコピーしました