|
|
|
|
|
|
Excel
|
Match rows with multiple criteria
|
|
Ease of Use
|
Intermediate
|
Version tested with
|
2007
|
Submitted by:
|
drgs
|
Description:
|
MatchAll(vrnLookupValue, rngLookupArray) -- returns all cells (as a range object) which match criteria vrnLookupValue in contiguous or non-contiguous rngLookupArray.
MatchRows(
vrnLookupValue1, rngLookupArray1, _
vrnLookupValue2, rngLookupArray2, ... etc) -- returns all rows (entire rows as range object) which match multiple criteria in several columns rngLookupArrayx, which can be non-contiguous
|
Discussion:
|
MatchAll is based on worksheet function Match, and inherits its properties:
-- "123" will not match 123, unlike Find
-- works in filtered worksheets and hidden rows/columns, unlike similar functions FindAll based on Find
-- supports wildcards, question marks etc.
-- case-insensitive
-- vrnLookupValue "" will return nothing, unlike Find, which returns empty cells
|
Code:
|
instructions for use
|
Public Function Union(ByRef rng1 As Range, _
ByRef rng2 As Range) As Range
If rng1 Is Nothing Then
Set Union = rng2
Exit Function
End If
If rng2 Is Nothing Then
Set Union = rng1
Exit Function
End If
If Not rng1.Worksheet Is rng2.Worksheet Then
Exit Function
End If
Set Union = Application.Union(rng1, rng2)
End Function
Public Function MatchAll(ByRef vrnLookupValue As Variant, _
ByRef rngLookupArray As Range) As Range
Dim rngArea As Range
Dim rngTemp1 As Range
Dim rngTemp2 As Range
Dim vrnMatch As Variant
Dim lngCount As Long
Dim lngLast As Long
If rngLookupArray Is Nothing Then
Exit Function
End If
For Each rngArea In rngLookupArray.Areas
If rngArea.Columns.Count > rngArea.Rows.Count Then
Set rngTemp1 = rngArea.Rows
Else
Set rngTemp1 = rngArea.Columns
End If
For Each rngTemp2 In rngTemp1
With rngTemp2
lngCount = .Cells.Count
lngLast = 0
Do
vrnMatch = Application.Match(vrnLookupValue, .Parent.Range(.Cells(lngLast + 1), .Cells(lngCount)), 0)
If IsError(vrnMatch) Then
Exit Do
End If
lngLast = lngLast + vrnMatch
Set MatchAll = Union(MatchAll, .Cells(lngLast))
Loop Until lngLast = lngCount
End With
Next rngTemp2
Next rngArea
End Function
Public Function MatchRows(ParamArray vrnArgs() As Variant) As Range
Dim lngCriteriasCount As Long
Dim i As Long
Dim rngLookupArray As Range
Dim rngMatches As Range
Dim rngResult As Range
lngCriteriasCount = Int((UBound(vrnArgs) - 1) / 2)
For i = 0 To lngCriteriasCount
If IsObject(vrnArgs(i * 2 + 1)) Then
If vrnArgs(i * 2 + 1) Is Nothing Then
Exit Function
End If
If TypeOf vrnArgs(i * 2 + 1) Is Excel.Range Then
Set rngLookupArray = vrnArgs(i * 2 + 1)
If rngResult Is Nothing Then
Set rngResult = rngLookupArray.EntireRow
Else
Set rngLookupArray = Intersect(rngResult, rngLookupArray)
End If
Set rngMatches = MatchAll(vrnArgs(i * 2), rngLookupArray)
If rngMatches Is Nothing Then
Exit Function
End If
Set rngResult = Application.Intersect(rngResult, rngMatches.EntireRow)
End If
End If
Next i
Set MatchRows = rngResult
End Function
|
How to use:
|
- Example:
-
- Set wksSomedata = ThisWorkbook.Worksheets("Somedata")
- Set rngMatches = MatchRows("criteria1", Somedata.Columns(3), _
- "cri*a", Somedata.Columns(1).Resize(10, 1), _
- 1000, Somedata.Columns(2), _
- Somedata.Cells(10, 5), Somedata.Columns(4))
-
- If Not rngMatches Is Nothing Then
- Set rngMatches = Application.Intersect(Somedata.Columns(5), rngMatches)
- For Each rngCell In rngMatches
- '...
- Next rngCell
- End if
|
Test the code:
|
|
Sample File:
|
No Attachment
|
Approved by Jacob Hilderbrand
|
This entry has been viewed 41 times.
|
|