2016-08-29 7 views
0

私は現在、辞書オブジェクトを使用しているアプリケーションを持っています(具体的には辞書の辞書ですので、意味があればそれぞれの検索に3つのステップがあります)。私はこれらの辞書に多数の検索を行い、その結果を一緒に掛けます。excel辞書オブジェクトエラー

問題は、以前のバージョンのアプリケーションでは、この機能を実現するためにVLookup関数を使用していましたが、存在しなかったキーをルックアップしようとするとエラーになります。今、それは "空"を返します.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) 

コードは、基本的に単なる一束のページです。ルックアップ、乗算、最も近い10分の1に丸めます。時折、乗算の代わりに追加するステップがあります。

xRound関数は0.0000001を加算し、丸め関数を使用して小数点以下の桁数に丸めます(Excel VBAラウンド関数の奇妙さを考慮します)。

+0

データをチェックして、乗算前に空であるかどうか確認できますか?例えば。 'If​​ IsEmpty(MyVariable)= False then ... ' –

+0

これ以上のことをする前に、ネストされた辞書の3つのレベルがなぜあるのか不思議です。私はあなたがテーブル間の関係を構築するためにそれらを使用していると仮定し、それらの関係をクエリします。その場合、私は間違いなく、これらの種類のクエリ(データベースに移行するか、ADOを使用してデータベースのように直接クエリを実行する)のために構築されたシステムに移行することをお勧めします。 – Mikegrann

+0

はい、乗算に先立ってデータは空ですが、1回のルックアップごとにif文を追加すると非常に時間がかかります。私はそれをすることができますが、可能ならば私が避けようとしていることです。 – whitesox130

答えて

0

トップレベル辞書を3つの「キー」で呼び出すことができるように関数を作成し、その組み合わせが存在しない場合はエラー値を返す必要があります。

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