Excel UDF的整个范围,而不是每个单元格

我的工作簿中有以下UDF:

Function GetRoundTime(Shp1 As String, Res1 As String, Shp2 As String, Res2 As String, Sht As String) As String Dim i As Long Dim TempSheet As Worksheet Set TempSheet = Workbooks("odds_datalog.xlsm").Worksheets(Sht) 'Need to find out what the last row is instead of hardcoding it at 2000 For i = 2 To 2000 If TempSheet.Cells(i, "D").Value = Shp1 And TempSheet.Cells(i, "I").Value = Shp2 And TempSheet.Cells(i, "E").Value = Res1 And TempSheet.Cells(i, "J").Value = Res2 Then GetRoundTime = CStr(TempSheet.Cells(i, "K").Value) Exit Function End If Next i GetRoundTime = "Failed" End Function Function GetOdds(Shp1 As String, Res1 As String, Sht1 As String, Shp2 As String, Res2 As String, Sht2 As String) As String Dim LeftTime As String Dim TopTime As String LeftTime = GetRoundTime(Shp1, Res1, Shp2, Res2, Sht1) TopTime = GetRoundTime(Shp2, Res2, Shp1, Res1, Sht2) If LeftTime = "NoAttack" Then GetOdds = "" ElseIf LeftTime = "TimedOut" Then GetOdds = "Time (left)" ElseIf LeftTime = "SameShip" Then GetOdds = "" ElseIf LeftTime = "Failed" Then GetOdds = "Failed" ElseIf TopTime = "NoAttack" Then GetOdds = "" ElseIf TopTime = "TimedOut" Then GetOdds = "Time (top)" ElseIf TopTime = "SameShip" Then GetOdds = "" ElseIf TopTime = "Failed" Then GetOdds = "Failed" Else GetOdds = Sqr(Val(TopTime) / Val(LeftTime)) End If End Function 

而且,每个单元格中都会调用GetOdds函数,如下所示:

 =GetOdds($A20,$B20,"log_hgn_hgn",D$1,D$2,"log_hgn_hgn") =GetOdds($A21,$B21,"log_hgn_hgn",D$1,D$2,"log_hgn_hgn") =GetOdds($A22,$B22,"log_hgn_hgn",D$1,D$2,"log_hgn_hgn") 

等等。

但是,重新计算非常缓慢。 我听说input一系列单元格可以提高性能。 这是真的? 我将如何改变代码来做到这一点? 谢谢!

[编辑]

这是一个工作表的样子。

View post on imgur.com

我不太清楚“input一系列单元格”的意思,但是函数的最慢部分在这里:

 'Need to find out what the last row is instead of hardcoding it at 2000 For i = 2 To 2000 If TempSheet.Cells(i, "D").Value = Shp1 And TempSheet.Cells(i, "I").Value = Shp2 And TempSheet.Cells(i, "E").Value = Res1 And TempSheet.Cells(i, "J").Value = Res2 Then GetRoundTime = CStr(TempSheet.Cells(i, "K").Value) Exit Function End If Next i 

您正在反复访问工作表,这很 。 你可能会得到最大的性能增益,将所有的值一次拉到一个数组中,而不是使用数组。 像这样的事情应该加速显着:

 Function GetRoundTime(Shp1 As String, Res1 As String, Shp2 As String, _ Res2 As String, Sht As String) As String With Workbooks("odds_datalog.xlsm").Worksheets(Sht) Dim lastRow As Long, values() As Variant lastRow = .Range("A" & .Rows.Count).End(xlUp).Row values = .Range(.Cells(2, 4), .Cells(lastRow, 11)).Value Dim i As Long For i = 1 To lastRow - 1 If values(i, 1) = Shp1 And values(i, 6) = Shp2 And _ values(i, 2) = Res1 And values(i, 7) = Res2 Then GetRoundTime = CStr(values(i, 8)) Exit Function End If Next End With GetRoundTime = "Failed" End Function