Sub copyRows()
Dim wsData As Worksheet
Dim wsReport As Worksheet
Dim srcRng As Range
Dim srcAfter As Range
Dim foundRng As Range
Dim copyRng As Range
Dim criteriaVal As String
Dim OutputRow As Long
Dim LR As Long
Dim firstFound As Long
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
.EnableEvents = False
End With
Set wsData = Sheets("Database")
Set wsReport = Sheets("Report")
'// Start row on report sheet to receive data
OutputRow = 3
'// Clear Report Sheet
LR = wsReport.Cells(Rows.Count, 1).End(xlUp).Row '// Last row
wsReport.Rows(OutputRow & ":" & LR).ClearContents
'// Value that is to be looked up
criteriaVal = wsReport.Range("A2").Value
'// Specify first row and column of database name field
Set srcRng = wsData.Range("A2")
'// Returns range from Start to last row in column
Set srcRng = wsData.Range(srcRng, _
wsData.Cells(Rows.Count, srcRng.Column).End(xlUp))
'// Change default error handling as find and findnext error when what
'// is not found.
On Error Resume Next
'// Set search after to first cell in search range
Set srcAfter = srcRng(1, 1)
Set foundRng = srcRng.Find(What:=criteriaVal, _
After:=srcAfter, _
LookIn:=xlValues, _
LookAt:=xlWhole, _
Searchorder:=xlByRows)
'// Criteria is not in data sheet
If foundRng Is Nothing Then Exit Sub
'// Set found range's entire row to copy range
Set copyRng = foundRng.EntireRow
'// First found in range of to prevent double finding.
firstFound = foundRng.Row
Do While True
'// Set Find after to one cell below found cell
Set srcAfter = foundRng.Offset(1, 0)
'// Set found to default for testing
Set foundRng = Nothing
'// Find next occurence of criteria in search range
'// • if not found will error and resume next and remain nothing.
'// • otherwise it will return the cell range it was found in
Set foundRng = srcRng.FindNext(After:=srcAfter)
'// Test if it was not found "Is Nothing"
'// • or it has looped around to beginning
If foundRng Is Nothing Or firstFound = foundRng.Row Then Exit Do
'// Join the last found with the previous found
Set copyRng = Union(copyRng, foundRng.EntireRow)
Loop
'// Return to defult error handling
On Error GoTo 0
'// Copy and paste found ranges into report worksheet
copyRng.Copy wsReport.Cells(OutputRow, 1)
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
.EnableEvents = True
End With
End Sub