简体   繁体   English

Excel UDF适用于整个范围而不是每个单元格

[英]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. 这是工作表之一。

http://imgur.com/a/XMoiS http://imgur.com/a/XMoiS

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM