Reputation: 545
I've got an issue where a CellIsInVisibleRange
function selects a cell which it shouldn't.
The code that's looping is as follows:
wCount = 0
loopCount = 0
For Each wCell In wRange
loopCount = loopCount + 1
If CellIsInVisibleRange(wCell) Then
MsgBox ("HERE IT BE")
wCount = wCount + 1
"codey-code"
End If
Next
The function which fails for me is:
Function CellIsInVisibleRange(cell As Range)
CellIsInVisibleRange = Not Intersect(ActiveWindow.VisibleRange, cell) Is Nothing
End Function
What's happening is, I've got a visible range of rows being 1, 64, 65, 66. This loop accepts a supposedly visible wCell in Row 45.
I'm looking at this sheet, and that row is most definitely not visible.
Do you see what's wrong with this function?
Thanks.
EDIT:
@KekuSemau
Thanks for the reply. That code works well but I wonder if there is a more efficient way to go about doing this. The line wCell.SpecialCells(xlCellTypeVisible)
returns a "Type mismatch" error but I feel like something like this would be quicker. I suppose I should have shown that I declare the range I'm seeking over as well.
Set wRange = Range("$" & nameColumnLetter & "$1:$" & nameColumnLetter & "$" & lastRow)
wCount = 0
loopCount = 0
For Each wCell In wRange
loopCount = loopCount + 1
'If CellIsInVisibleRange(wCell) Then
If wCell.SpecialCells(xlCellTypeVisible) Then
code
code
code
End If
Next
Am I close to a quicker method here?
Thanks again.
Upvotes: 1
Views: 875
Reputation:
My work-in-progress answer until we get to discuss a little, here's how I would revise your code:
Set wRange = Range("$" & nameColumnLetter & "$1:$" & nameColumnLetter & "$" & lastRow)
wCount = 0
'counts blanks and non-blanks, changed from original based on my guess of what you want
loopCount = wRange.Count
Set wRange2 = wRange.SpecialCells(xlCellTypeVisible)
For Each wCell In wRange2
code
code
code
Next wCell
Upvotes: 2
Reputation: 11801
The Range.EntireRow and Range.EntireColumn range objects have a property named "Hidden" that can be checked prior to performing a computationally expensive Intersect evaluation. In this case, you would check if cell.EntireRow.Hidden is hidden. If it is hidden, there is no point checking if it is within the visible range.
Public Function CellIsInVisibleRange2(cell As Range) As Boolean
If (cell.Worksheet Is ActiveWindow.VisibleRange.Worksheet) Then
If Not cell.EntireRow.Hidden Then
CellIsInVisibleRange2 = Not (Application.Intersect(cell, ActiveWindow.VisibleRange) Is Nothing)
End If
End If
End Function
Upvotes: 0
Reputation: 6856
ActiveWindow.VisibleRange
does not seem to be very 'intelligent', it bluntly returns the Range form the topleft cell to the bottomright cell.
Try it out: Go to a new sheet, hide Rows 5-10, then hide column E, for example.
Then type this in the immediate window in the VB Editor:
?ActiveWindow.VisibleRange.Address
It will output something like $A$1:$M$47
, ignoring missing ranges.
You can intersect the VisibleRange
with the non-hidden-cells like this:
Public Function CellIsInVisibleRange(cell As Range) As Boolean
CellIsInVisibleRange = False
' wrong sheet active?
If Not cell.Worksheet Is ActiveWindow.VisibleRange.Worksheet Then Exit Function
' <Really> visible range
Dim rng As Range
Set rng = Intersect( _
ActiveWindow.VisibleRange, _
ActiveWindow.VisibleRange.Worksheet.Cells.SpecialCells(xlCellTypeVisible))
CellIsInVisibleRange = Not Intersect(rng, cell) Is Nothing
End Function
Upvotes: 2