簡體   English   中英

Excel UDF適用於整個范圍而不是每個單元格

[英]Excel UDF for entire range instead of each cell

我的工作簿中包含以下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")

等等。

但是,重新計算非常緩慢。 我聽說輸入一定范圍的單元格可以提高性能。 這是真的? 我將如何更改代碼來做到這一點? 謝謝!

[編輯]

這是工作表之一。

http://imgur.com/a/XMoiS

我不確定“輸入一系列單元格”到底是什么意思,但是功能最慢的部分在這里:

'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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM