|
Subject:
|
Searching a range in a worksheet
|
|
Posted By:
|
tiyyob
|
Post Date:
|
1/4/2006 11:24:31 PM
|
Hi all.
I want to seach data in a complete range e.g A1:A8 in worksheet.
so that if exactly macthing data exists in any other range at this sheet. i should get back the the address of range.
using find function in VBA.... i m able to find a single cell in any given range but not a complete range consisting of more then one cells.
any help will be highly appreciated.
Tiyyob
|
|
Reply By:
|
maccas
|
Reply Date:
|
1/6/2006 9:32:09 AM
|
Try the following bit of code which will create a UDF to do your job for you. Please note the possibility of creating a circular reference if you include your FindRange formula cell in the SearchRange.
Option Explicit
Public Function RangeFind(ToMatch As Range, SearchIn As Range, Optional Instance As Integer = 0) As String
Dim rngToMatch As Range
Dim rngSearchIn As Range
Dim intInstance As Integer
Dim arrvResults As Variant
Dim booSuccess As Boolean
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = True
' Set up the ToMatch range
Set rngToMatch = ToMatch
' Set up the SearchIn range
Set rngSearchIn = SearchIn
' Set up the instance counter and take 0 (the first range found) by default
intInstance = Instance
' Call the custom routine below built to give the array of all matches
booSuccess = arrRangeFind(rngToMatch, rngSearchIn, arrvResults)
' If no success then quit out
If Not booSuccess Then
RangeFind = "No Matches"
Exit Function
End If
' If instance count too high give message else give address of match
If intInstance > UBound(arrvResults) Then
RangeFind = "Not enough range matches"
Else
RangeFind = arrvResults(intInstance).Address
End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = False
End Function
Private Function arrRangeFind(ByVal rngToMatch As Range, ByVal rngSearchIn As Range, ByRef vAllRanges As Variant) As Boolean
Dim Cell As Range
Dim SearchCells As Range
Dim MatchRange As Range
Dim arrFound() As Range
Dim intFoundCounter As Integer
Dim i As Integer
' Search every cell in the search range
For Each Cell In rngSearchIn
' Create a subset of cells in the search range that match the TLH cell value
If Cell.Value = rngToMatch.Cells(1, 1).Value Then
If SearchCells Is Nothing Then
Set SearchCells = Cell
Else
Set SearchCells = Union(SearchCells, Cell)
End If
End If
Next
intFoundCounter = 0
' Now search through our list of initially matching cells
For Each Cell In SearchCells
Set MatchRange = Range(Cell, Cell.Offset(rngToMatch.Rows.Count - 1, rngToMatch.Columns.Count - 1))
' use our custom RangesMtach function to determine if the pair of ranges do match
If RangesMatch(rngToMatch, MatchRange) Then
' Resize the array of found ranges
ReDim Preserve arrFound(intFoundCounter)
' Add our newly found range
Set arrFound(intFoundCounter) = MatchRange
' Move the found counter on one
intFoundCounter = intFoundCounter + 1
End If
Next Cell
' Set up the output
If intFoundCounter = 0 Then
Set vAllRanges = Nothing
arrRangeFind = False
Else
vAllRanges = arrFound
arrRangeFind = True
End If
End Function
Private Function RangesMatch(ByRef rng1 As Range, ByRef rng2 As Range) As Boolean
Dim i As Integer
Dim j As Integer
' Check they are not the same range
If rng1.Parent.Name = rng2.Parent.Name And rng1.Address = rng2.Address Then
RangesMatch = False
Exit Function
End If
' Check the two ranges have the same number of columns
If rng1.Columns.Count <> rng2.Columns.Count Then
RangesMatch = False
Exit Function
End If
' Check the two ranges have the same number of rows
If rng1.Rows.Count <> rng2.Rows.Count Then
RangesMatch = False
Exit Function
End If
' Match the values in ecah corresponding cell and quit out if different
For i = 1 To rng1.Rows.Count
For j = 1 To rng1.Columns.Count
If rng1.Cells(i, j).Value <> rng2.Cells(i, j).Value Then
RangesMatch = False
Exit Function
End If
Next j
Next i
' If we've got here then we must have a match
RangesMatch = True
End Function
|
|
Reply By:
|
kencjohnson
|
Reply Date:
|
1/13/2006 10:26:40 PM
|
This is just a macro that scans the UsedRange of the worksheet for other ranges with a set of values that are identical to those in the selected range. When such a range is found a MsgBox shows its address. The search for other such ranges continues after OK is clicked. If no duplicate ranges are found a MsgBox states "No other range on this sheet has that set of values.
Public Sub find_range() Dim vaLookFor As Variant Dim vaLookAt As Variant Dim stLookForAddress As String Dim iRowCounter1 As Long Dim iRowCounter2 As Long Dim iColumnCounter1 As Integer Dim iColumnCounter2 As Integer Dim stResult As String Dim FoundCount As Long stResult = "Looking" stLookForAddress = Application.InputBox(prompt:="Select the range of cells to look for", Default:=Selection.Address, Type:=8).Address vaLookFor = Range(stLookForAddress) vaLookAt = ActiveSheet.UsedRange 'Move across one column For iColumnCounter1 = 1 To UBound(vaLookAt, 2) - UBound(vaLookFor, 2) + 1 'Move down one row For iRowCounter1 = 1 To UBound(vaLookAt, 1) - UBound(vaLookFor, 1) + 1 If iRowCounter1 = 1 Then Let stResult = "Looking" 'Check values in columns For iColumnCounter2 = 1 To UBound(vaLookFor, 2) 'Check values in rows For iRowCounter2 = 1 To UBound(vaLookFor, 1) 'Exit For Next loop checking rows as soon as row values not equal If vaLookAt(iRowCounter1 + iRowCounter2 - 1, iColumnCounter1 + iColumnCounter2 - 1) _ <> vaLookFor(iRowCounter2, iColumnCounter2) Then Let stResult = "Not Equal" Exit For End If Next iRowCounter2 'Exit For Next loop checking columns because an unequal cell has been found 'Change stResult to "Looking" so that next part of Used Area is checked If stResult = "Not Equal" Then Let stResult = "Looking" Exit For ElseIf iColumnCounter2 = UBound(vaLookFor, 2) Then 'All cells equal, now tell user the address If Range(Cells(iRowCounter1, iColumnCounter1), _ Cells(iRowCounter1 + UBound(vaLookFor, 1) - 1, iColumnCounter1 + UBound(vaLookFor, 2) - 1)).Address <> Selection.Address Then FoundCount = FoundCount + 1 MsgBox Range(Cells(iRowCounter1, iColumnCounter1), _ Cells(iRowCounter1 + UBound(vaLookFor, 1) - 1, iColumnCounter1 + UBound(vaLookFor, 2) - 1)).Address End If End If Next iColumnCounter2 Next iRowCounter1 Next iColumnCounter1 If FoundCount = 0 Then MsgBox "No other range on this sheet has that set of values" End Sub
Ken Johnson
|