2016-08-05 94 views
0

我有我的工作簿下面的UDF:Excel的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

回答

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 
+0

我的意思是最好解析一個函數爲整個工作表,而不是每個單元格一次。那可能嗎? – posfan12

+0

@ posfan12 - 如果我正確理解你,你想只是一次更新一切?如果是這樣的話,你需要將它作爲宏運行而不是UDF。 – Comintern

+0

會更快嗎?此外,您發佈的代碼只會給我#VALUE!在每個細胞中。我不知道這個錯誤是什麼。 – posfan12