I think CC's suggestion to read the data into memory is good if you're referencing a lot of data (as you apparently are).
Function Transitions(r As Range, _
dMin As Double, dMax As Double, _
Optional iOpt As Long = 0) As Variant
' UDF wrapper for nTransitions
If r.Columns.Count > 1 And r.Rows.Count > 1 Or _
dMin >= dMax Then
Transitions = CVErr(xlErrNum)
Else
Transitions = nTransitions(r.Value2, dMin, dMax, iOpt)
End If
End Function
Function nTransitions(av As Variant, _
dMin As Double, dMax As Double, _
Optional iOpt As Long = 0) As Long
' shg 2010
' VBA only
' Counts transitions in r between dMin and dMax
' iOpt < 0 => count negative transitions only (dMax to dMin)
' iOpt = 0 => count transitions in either direction
' iOpt > 0 => count positive transitions only (dMin to dMax)
Dim iPos As Long
Dim iNeg As Long
Dim v As Variant
Dim iOld As Long
If dMin >= dMax Then Exit Function
iPos = -(Sgn(iOpt) >= 0)
iNeg = -(Sgn(iOpt) <= 0)
For Each v In av
If VarType(v) = vbDouble Then
If v <= dMin Then
If iOld = 1 Then nTransitions = nTransitions + iNeg
iOld = -1
ElseIf v >= dMax Then
If iOld = -1 Then nTransitions = nTransitions + iPos
iOld = 1
End If
End If
Next v
End Function
Bookmarks