Excel vba:.find函数返回运行时错误91

时间:2017-01-16 14:52:53

标签: vba excel-vba find runtime-error max

我已经阅读了几个小时的相关主题,但似乎无法找到解决方案。非常感谢您的帮助,谢谢。

我试图在一个范围内找到最大值然后找到它所在的行。 这段代码适用于我的前600多行数字,然后崩溃,并给我运行时错误91.它似乎总是在同一点崩溃独立于我做。

Dim rSearchRange As Range
Dim dMaxToFind As Double
Dim rSolutionrange As Range

Set rSearchRange = Sheets("MySheet").Range(Cells(672, 1), Cells(681, 1))

With Application.WorksheetFunction
       dMaxToFind = .Max(rSearchRange)
End With

'This bit here returns "nothing" even though i found the max value in this range
Set rSolutionrange = rSearchRange _
            .Find(What:=dMaxToFind, _
            LookIn:=xlFormulas, LookAt:=xlWhole, SearchOrder:=xlByRows, _
            SearchDirection:=xlNext, MatchCase:=False)

查看我的数据,看起来它会改变这些行的格式吗?

    Row 670 - 0.000458587
    Row 671 - 0.000458587
    Row 672 - 9.80465E-05
    Row 673 - 9.80465E-05

编辑:

dMaxToFind返回9.80465352566588E-05

单元格公式返回0.0000980465352566588

它是Range(细胞(672,1),细胞(681,1)之间的细胞中的相同值

似乎vba无法理解那两个是一样的吗?

谢谢,

标记

1 个答案:

答案 0 :(得分:0)

这是一个直接告诉你行号的功能。这与您在内置函数中使用获取最大值然后再次找到它的方法相反!

Function GetMaxRow(ByRef myRange As Range) As Long

    Dim aCell As Range

    Dim maxVal As Double
    Dim maxRow As Long

    maxVal = Application.WorksheetFunction.Min(myRange)
    maxRow = 0

    For Each aCell In myRange

        If aCell.Value > maxVal Then

            maxRow = aCell.row
            maxVal = aCell.Value

        End If

    Next aCell

    GetMaxRow = maxRow

End Function

您可能希望在此函数的结果中添加一些错误检查代码,例如,当函数返回0时,这意味着您没有将其传递给超过1个单元格的范围。

示例:

1 - 3.0
2 - 5.2
3 - 7.8
4 - 2.2
5 - 4.5
6 - 3.6

Dim rw as Long
rw = GetMaxRow(ActiveSheet.Range("A1:A6"))
' >> rw = 3

编辑:

您查询了循环的使用,可能是因为节省了时间。下面是一个时间表,当然这将在不同的计算机之间有所不同但你可以看到它是一个相当快速的例程,除非你的数据集很大......而且操作的顺序是线性的,正如预期的那样,意味着加倍范围大致加倍所花的时间。

2000  rows: 0.0050000s
4000  rows: 0.0099219s
8000  rows: 0.0196875s
16000 rows: 0.0392969s

测试的单元格值是0到1之间的随机双精度。

编辑2:

你对速度的兴趣达到了顶峰......所以我没有在一个范围内循环(慢),而是使用数组编写相同的函数。范围转换为数组,然后循环。这提供了大约10倍的速度提升!请参阅下文,了解相同数据的代码和时间。

Function GetMaxRow(ByRef myRange As Range) As Long

    Dim i As Long

    Dim maxVal As Variant
    Dim maxRow As Long

    maxVal = Application.WorksheetFunction.Min(myRange)
    maxRow = 0

    Dim myArray() As Variant
    myArray = myRange

    For i = 1 To myRange.Count

        If myArray(i, 1) > maxVal Then

            maxRow = i
            maxVal = myArray(i, 1)

        End If

    Next i

    GetMaxRow = myRange.Cells(maxRow).Row

End Function

时序:

2000  rows: 0.0006250s
4000  rows: 0.0018750s
8000  rows: 0.0034375s
16000 rows: 0.0068750s