Excel 手动调用(';=';)或通过宏调用之间的函数性能差异
我写了一个查找函数。它的性能差别很大,这取决于我是在工作表上手动调用它(通过“=”)还是通过宏调用它 我的宏执行以下操作:Excel 手动调用(';=';)或通过宏调用之间的函数性能差异,excel,vba,performance,excel-formula,Excel,Vba,Performance,Excel Formula,我写了一个查找函数。它的性能差别很大,这取决于我是在工作表上手动调用它(通过“=”)还是通过宏调用它 我的宏执行以下操作: Function betterSearch(searchCell As Range, aCol As Range, bCol As Range) For Each cell In aCol If LCase(cell.Value) = LCase(searchCell.Value) Then betterSearch = bC
Function betterSearch(searchCell As Range, aCol As Range, bCol As Range)
For Each cell In aCol
If LCase(cell.Value) = LCase(searchCell.Value) Then
betterSearch = bCol.Cells(cell.row, 1)
Exit For
End If
betterSearch = "Not found"
Next
End Function
宏打开resultsWorkbook和dataWorkbook,然后从dataWorkbook中的resultsWorkbook搜索a列中的四个值,并从dataWorkbook的其他列返回相应的数据
'...opening resultWorkbook and dataWorkbook
For aRow = 6 To 9
resultWorkbook.Worksheets("B3").Cells(aRow, 125).Value = _
betterSearch(resultWorkbook.Worksheets("B3").Cells(aRow, 1) _
, dataWorkbook.Worksheets("page 1").Range("A:A") _
, dataWorkbook.Worksheets("page 1").Range("Z:Z"))
resultWorkbook.Worksheets("B3").Cells(aRow, 126).Value = _
betterSearch(resultWorkbook.Worksheets("B3").Cells(aRow, 1) _
, dataWorkbook.Worksheets("page 1").Range("A:A") _
, dataWorkbook.Worksheets("page 1").Range("I:I"))
Next aRow
它真的很慢-一个文件需要分钟。但是,当我手动打开该文件并键入公式并按Enter键时,它会立即计算(因此,在这方面,我的函数不需要优化-它已经计算快速,但只是在工作表中,而不是在宏中)
我不想优化功能。我想了解性能差异产生的原因。我有
Application.Calculation=xlCalculationManual
用于运行的主应用程序和执行所有工作的不可见应用程序:ExcelApp.Calculation=xlCalculationManual
,它似乎正在将工作簿的状态更改为手动,但性能很慢,就好像工作簿仍然存在一样自动。您可以使用Find
功能,并使用MatchCase:=False
使其不区分大小写
它将比在你的专栏中循环快得多
代码
Function betterSearch(searchCell As Range, aCol As Range, bCol As Range) As String
Dim FndRng As Range
Set FndRng = aCol.Find(what:=LCase(searchCell.Value), LookIn:=xlValues, lookat:=xlWhole, _
searchorder:=xlRows, searchdirection:=xlNext, MatchCase:=False)
If Not FndRng Is Nothing Then ' Find was successful
betterSearch = bCol.Cells(FndRng.Row, 1)
Else
betterSearch = "Not found"
End If
End Function
可能与使用整个列范围有关
我认为,从宏调用函数时,强制Excel为每个整列引用将一百万个值传输到VBA(将数据从Excel传输到VBA非常慢)
从工作表调用函数时,您只传输一个范围对象,然后逐单元格循环,因此传输到VBA的数据量可能会减少数十万倍(取决于查找匹配项所需的距离)
尝试在宏中为整列引用设置范围变量,然后将范围变量而不是范围(I:I)传递给BetterSearch原因是,在宏中循环遍历范围的单元格。与阵列相比,这是非常缓慢的。 每个cell.value调用都在减速。在Excel本身中,这种减速并不严重,因为范围对象是应用程序本身的对象 一次将所有需要的数据从应用程序传递到VBA比多次只传递少量数据要慢 如果你重写你的代码,它将是快速独立的从哪里你调用它 首先将searchValue存储在变量中。因此,您不需要为每个调用计算公式。在代码中,每次比较都会计算搜索值,但这没有意义,因为它不会更改 其次,将aCol范围的值存储在变量数组中。这是一次非常快的整个列。之后,您可以非常快速地比较列中的每个值(比查找或匹配函数快) 这是您更改的代码
Function betterSearch(searchCell As Range, aCol As Range, bCol As Range)
Dim searchVal as String
Dim colVals() as Variant
Dim r as Long
searchVal = LCase(searchCell.Value)
colVals = aCol.Value ' Read data of whole column only once
For r = 1 to Ubound(colVals,1)
If LCase(colVals(r,1)) = searchVal Then
betterSearch = bCol.Cells(r, 1)
Exit For
End If
betterSearch = "Not found"
Next
End Function
使用
worksheetfunction.match
除了问题之外-是否有理由需要在VBA中使用此(嗯)BetterSearch
函数?您基本上编写了一个性能较差的基本Vlookup或Index/Match版本。@Rik Sportel,我需要它,因为Vlookup接收和查找的符号数量最多,而我的函数没有这个缺陷。我在问题中说,当我自己称之为betterSearch时,它执行得很快!真正的问题是为什么它在宏中变慢。只检查打开工作簿所需的时间。@UGP,它相对较小。我有一个GUI,它告诉我当每个操作开始时,查找值会占用大部分时间。谢谢您的回复。但我仍然想知道为什么同一个函数的结果不同,问题是关于这一点,而不是优化函数。我决定按照您的建议优化我的函数,但不幸的是,您的代码在Set FndRng…
行上出现了类型不匹配错误…谢谢。旅游回答真的很有帮助。我创建了Range
变量,并将Range(“I:I”)
替换为Range(“I2:I1200”)
。性能大大提高。然而,它仍然比手动重新计算每个值要慢得多。。。我想知道还有什么可以做的吗?它看起来相当可疑-当我只查找5-10个值时,速度会非常快,而增加查找值的数量似乎会成倍地增加所需的时间。