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


Go to topic 38714

Return to index page 396
Return to index page 395
Return to index page 394
Return to index page 393
Return to index page 392
Return to index page 391
Return to index page 390
Return to index page 389
Return to index page 388
Return to index page 387