[英]Excel UDF for entire range instead of each cell
I have the following UDFs in my workbook: 我的工作簿中包含以下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
And, the GetOdds function is called in every cell like this: 并且,在每个像这样的单元格中都调用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")
And so on. 等等。
However, the recalculation is very slow. 但是,重新计算非常缓慢。 I heard that inputting a range of cells speeds up performance.
我听说输入一定范围的单元格可以提高性能。 Is this true?
这是真的? How would I alter the code to do this?
我将如何更改代码来做到这一点? Thanks!
谢谢!
[edit] [编辑]
Here's what one of the worksheets looks like. 这是工作表之一。
I'm not sure exactly what you mean by "inputting a range of cells", but the slowest part of your function is here: 我不确定“输入一系列单元格”到底是什么意思,但是功能最慢的部分在这里:
'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
You are repeatedly accessing the Worksheet, and that is slow . 您反复访问工作表,这很慢 。 You'll likely get your biggest performance gain by pulling all of the values into an array at once and using the array instead.
通过将所有值一次拉入数组并改为使用数组,可能会获得最大的性能提升。 Something like this should speed it up significantly:
这样的事情应该可以大大加快速度:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.