17

I have a computed range of values in a hidden column which I use for a dropdown box. To figure out which value the user has selected, I try to run a Find on that range, but for some reason Excel won't return the cell corresponding with their selection so long as the column is hidden.

How can I get Find working on cells in the hidden range. Remember - I'm searching cell calculated values, not formulas.

The following does not work:

Set inserted = Range("RDS_Event_IDs").Find(Range("SelectedEvent"), , xlValues, xlWhole)

so long as cells in Range("RDS_Event_IDs") is hidden.

Because the solution has to work in general situations, where some or all of the the range being searched might be hidden, and the entire sheet might be searched, it isn't feasible to programmatically un-hide all affected rows and columns and then re-hide the ones that were previously hidden.

Community
  • 1
  • 1
Alain
  • 26,663
  • 20
  • 114
  • 184

3 Answers3

27

According to Andy Pope (and he's never wrong) Find only works on hidden cells if you're using xlFormulas. Perhaps a Match instead?

Set inserted = Cells(Application.WorksheetFunction.Match("SelectedEvent", Range("RDS_Event_IDs"), 0), Range("RDS_Event_IDs").Column)
Doug Glancy
  • 27,214
  • 6
  • 67
  • 115
  • Slight adjustment, I'll want to go `Set inserted = Range("RDS_Event_IDs").Cells(...Match...)`, but yes, this is absolutely a good workaround. Thanks for the suggestion! – Alain Jun 10 '11 at 13:53
  • 1
    This does work on hidden cells, but not autofiltered hidden cells. – brettdj Mar 12 '15 at 14:09
  • 2
    It's better to use `Application.Match` than `WorksheetFunction.Match`, because it can handle errors properly. See this answer: https://stackoverflow.com/a/17751568/224067. `Application.Match` did not auto-complete for me in the VBA IDE, but it does work, and has the arguments as the regular Match function. – nhinkle Oct 10 '17 at 21:16
3

Functional Approach

Using Doug Glancy's answer, it would be nice to put that in a function for reusability.

''
' Find a range using `WorksheetFunction.Match()`. This alternative works well
' for finding range in hidden cells, and is not case sensitive.
'
' Created this solution based on answer on Stack Overflow @see https://stackoverflow.com/a/6298404/8309643
'
' @author Robert Todar <robert@roberttodar.com>
''
Function Find(ByRef searchRange As Range, ByVal what As Variant) As Range
    Set Find = Cells(Application.WorksheetFunction.Match(what, searchRange, 0), searchRange.Column)
End Function

Another alternative for searching for a range is to get an array from the range and loop that. Again, putting this in a function makes it easy to re-use!

''
' Finds a range based on it's value.
' This works faster than `Range.Find()` as it loops an array instead of cells.
' This also works for hidden cells where `Range.Find` does not.
'
' Note, this looks for first match, and is case sensitive by defaut, unless
' Option Match Case is used at the top of the module it is stored in.
'
' @author Robert Todar <robert@roberttodar.com>
''
Public Function FindFast(searchRange As Range, what As Variant) As Range
    ' Get data from range into an Array. Looping Arrays is much
    ' faster than looping cells.
    Dim data As Variant
    data = searchRange.Value
    
    ' Loop every row in the array.
    Dim rowIndex As Long
    For rowIndex = LBound(data, 1) To UBound(data, 1)
        
        ' Loop every column in the array.
        Dim columnIndex As Long
        For columnIndex = LBound(data, 2) To UBound(data, 2)
        
            ' If current row/column matches the correct value then return the range.
            If data(rowIndex, columnIndex) Like what Then
                Set FindFast = searchRange.Cells(rowIndex, columnIndex)
                Exit Function
            End If
        Next columnIndex
    Next rowIndex
    
    ' If the range is not found then `Nothing` is returned.
    Set FindFast = Nothing
End Function
Robert Todar
  • 2,085
  • 2
  • 11
  • 31
  • Not directly related, but where might I find more info on the way you've set out your "docstrings"? I'd love to adopt something similar to this and I'd enjoy working from a "spec" of sorts, if one exists. – Alex Peters Sep 12 '21 at 09:22
  • @AlexPeters, I am mimicking [JS Doc](https://jsdoc.app/) — which is the main documentation style for JavaScript. I do have a [Style Guide](https://github.com/todar/VBA-Style-Guide) on how I write my VBA; although it is probably not 100% complete or up to date. – Robert Todar Sep 13 '21 at 15:40
  • It's an unfortunate oversight that the Range.Find method provides no option to override its default in order to include hidden cells. But this is an excellent, useful workaround. Thanks! – pstraton Apr 02 '22 at 16:05
  • 1
    One suggestion is to make it more universal by declaring the 'what' parameter as a Variant. – pstraton Apr 02 '22 at 16:20
2

Is really necesary do it inside a macro, would be easier use match:

=MATCH(G9;H9:H16;0)

G9 : Cell of the DropDownBox

H9:H16 : Your range

0 : for exact match

It returns the index inside the array

Alen
  • 1,040
  • 1
  • 8
  • 13