我的工作簿中有以下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")
等等。
然而,重新计算非常缓慢。我听说输入一系列单元可以提高性能。这是真的?我如何改变代码来做到这一点?谢谢!
[编辑]
这是其中一个工作表的样子。
答案 0 :(得分:1)
我不确定“输入一系列单元格”究竟是什么意思,但是函数中最慢的部分就在这里:
'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