2016-08-29 79 views
0

我有一個應用程序,我目前正在使用一個字典對象(具體來說,它是字典字典的詞典,因此每個查找都有三個步驟,如果這是有意義的!)。我對這些字典進行了大量查詢,並將結果放在一起。excel字典對象錯誤

問題是,在以前版本的應用程序中,我使用VLookup函數來完成此功能,並且當我試圖查找不存在的鍵時會出錯。現在,它返回一個「Empty」,Excel很高興能夠乘以我已有的任何東西並返回一個零。這很難追蹤,我非常希望它像以前一樣返回一個錯誤。

有什麼我可以改變,讓它返回像VLookup一樣的錯誤,還是我需要創建一個新的類模塊來做到這一點?一個類模塊可能會要求我重新編寫大量的代碼,這是我想避免的(我需要在代碼中更新數百個查找)。

謝謝。

下面是我的一些代碼:

這是我使用的所有表中的字典加載模塊:

Sub LoadFactorsAndBaseRates() 
    Dim t As Double 
    t = Timer 
    Dim n As Name 
    Dim TempArray() 
    Dim dict1 As Dictionary 
    Dim dict2 As Dictionary 
    Dim i As Integer 
    Dim j As Integer 
    For Each n In ThisWorkbook.Names 
     If InStr(1, n.RefersTo, "#") <> 0 Or InStr(1, n.RefersTo, "\") Then GoTo skipname 
     If Not FactorLookup.Exists(n.Name) And n.RefersToRange.Parent.Name <> "Rate Matrix" And InStr(1, n.Name, "Print") = 0 And InStr(1, n.Name, "FilterDatabase") = 0 And n.Name <> "Policies" Then 
      Set dict1 = New Dictionary 
      On Error GoTo err1 
      TempArray = n.RefersToRange.Value 
      For j = 1 To n.RefersToRange.Columns.Count 
       On Error Resume Next 
       Set dict2 = New Dictionary 
       For i = 1 To UBound(TempArray, 1) 
        dict2.Add TempArray(i, 1), TempArray(i, j) 
       Next i 
       dict1.Add j, dict2 
      Next j 
      Erase TempArray 
      FactorLookup.Add n.Name, dict1 
     End If 
skipname: 
    Next n 
    Exit Sub 
err1: 
    If Err.number = 1004 Then Resume skipname 
End Sub 

這裏是查找代碼示例:

CoverageColumn = 2 
'Base Rate 
     Temp = FactorLookup("Base_Rates")(CoverageColumn)(State & "_" & Company & "_" & Terr) 

If Vehicle <> "Snowmobile" Then 
'Class 1 
    x = FactorLookup("Class1")(CoverageColumn)(State & "_" & Company & "_" & Class1) 
    Temp = xRound(Temp * x, 1) 
'Class 2 
    x = FactorLookup("Class2")(CoverageColumn)(State & "_" & Company & "_" & Class2) 
    Temp = xRound(Temp * x, 1) 
'Class 3 
    x = FactorLookup("Class3")(CoverageColumn)(State & "_" & Company & "_" & Class3) 
    Temp = xRound(Temp * x, 1) 
'Class 4 
    x = FactorLookup("Class4")(CoverageColumn)(State & "_" & Company & "_" & Class4) 
    Temp = xRound(Temp * x, 1) 

代碼基本上就是這樣一堆頁面:查找,乘,舍入到最接近的十分之一,重複。偶爾,我們添加一個步驟,而不是相乘。

xRound函數添加0.0000001,然後使用舍入函數四捨五入到指定的小數位數(以說明Excel VBA循環函數的奇怪性)。

+0

你可以檢查數據,看它是否爲空的乘法?例如。 '如果IsEmpty(MyVariable)= False那麼......' –

+0

在我們進一步討論之前,我很好奇爲什麼你有三層嵌套字典。我假設你使用它們來建立表間關係,然後查詢這些關係。在這種情況下,我肯定會建議轉移到爲這些查詢構建的系統(無論是遷移到數據庫還是直接像使用ADO的數據庫一樣查詢Excel)。 – Mikegrann

+0

是的,數據在乘法之前是空的,但在每個查找周圍添加「if」語句會非常耗時。我可以做到這一點,但這是我儘可能避免的事情。 – whitesox130

回答

0

您需要創建一個函數來「包裝」頂級字典,以便可以用三個「鍵」調用它,並在該組合不存在時返回錯誤值。

Function DoFactorLookup(k1, k2, k3) As Variant 
    Dim d, d2, rv 

    rv = CVErr(xlErrNA) ' #N/A error value 

    If FactorLookup.exists(k1) Then 
     Set d = FactorLookup(k1) 
     If d.exists(k2) Then 
      Set d2 = d(k2) 
      If d2.exists(k3) Then 
       rv = d2(k3) 
      End If 
     End If 
    End If 

    DoFactorLookup = rv 
End Function 
+0

我最終採取了這種方法。謝謝您的幫助。 – whitesox130