使用vba中的自定义对象键访问字典中的项目
我有一个问题访问vba字典中的项目。
我有以下字典:
Dim CResults as dictionary
我添加项目:
CResults.add currentkey, result
Currentkey
是我从一个名为DCRkey
的类创build的一个对象
Private loadcase as long Private csystem as String Private node as long
result
是另一个类DCR
对象:
Private Fs as double Private C1 as double Private C2 as double ...
然后我尝试使用访问一个项目
Dim accesskey as DCRKey accesskey.loadcase=10 accesskey.node = 2000 accesskey.csystem="Global" Sheets("Results").cells(i,1).value= CResults(accesskey).C1
那是我得到的错误: runtime error 424 object required
然后,我想也许是关键和我search哪里没有导入的项目,所以我决定在Excel工作表上显示我的整个字典:
Dim testkey as variant dim i as integer i=1 with worksheet("Test") For each testkey in CResults.keys .cells(i,1)=test.node .cells(i,2)=test.loadcase .cells(i,3)=test.csystem .cells(i,4)=Cresults(testkey).C1 .cells(i,5)=Cresults(testkey).Fs if accesskey.loadcase=testkey.loadcase and accesskey.node=testkey.node and accesskey.csystem=testkey.csystem then Msgbox "This key is the same as the accesskey" End if i=i+1 Next End with
我所看到的是:
- 我之前search的关键字存在于字典中:在表格上进行可视化检查
- 我之前search的密钥实际上存在于字典中:
"This key is the same as the acceskey"
被显示一次 - 从
for each
循环访问词典中的项目,因为C1和Fs正确显示在工作表上
然后我想也许是因为testkey
被定义为一个变体而不是一个DCRKey
,所以我试着这样做:
dim a as variant Set a = currentkey .Cells(i,1) = CResults(a).C1
但它不起作用,我仍然有runtime error 424
。
我也做的是尝试:
CResults.exists(accesskey)
它返回false,并在字典中创build一个新的条目(顺便说一句,我讨厌什么时候这样做),与acceskey和空项目相同的密钥。
所以我的问题是:为什么使用自定义types键访问一个项目在for each
循环中工作,而不是在独立的调用。 我错过了什么? 这段代码和我写的代码非常相似,但不完全一样(为了让你更好理解)。 告诉我,如果你认为真正的代码可以帮助。 谢谢你的帮助。
你需要记住一个类的两个实例是不一样的,即使它们的所有属性都被设置为相同的值。
我们来看下面的例子:
Sub compareSimilarObjects() Dim key1 As DCRKey Dim key2 As DCRKey Set key1 = New DCRKey With key1 .loadcase = 10 .node = 2000 .csystem = "Global" End With Set key2 = New DCRKey With key1 .loadcase = 10 .node = 2000 .csystem = "Global" End With 'Debug.Print to check pointer assigne to those variables. Debug.Print "Key1: " & ObjPtr(key1) Debug.Print "Key2: " & ObjPtr(key2) End Sub
在此示例中, DCRKey
类的两个对象都将所有属性设置为相同的值。 但是,它们与下面的代码在最后运行Debug.Prints
之后看到的不同。
在那些Debug.Print
VBA内置函数ObjPtr
。 这个函数的目的是将指针返回给定的对象。 对象的每个实例都有自己的唯一指针,所以如果下面的代码打印两个不同的指针,则意味着这些对象是不一样的。
现在我们来看另一个例子:
Sub compareSimilarObjects() Dim key1 As DCRKey Dim key2 As DCRKey Set key1 = New DCRKey With key1 .loadcase = 10 .node = 2000 .csystem = "Global" End With Set key2 = key1 'Debug.Print to check pointer assigned to those variables. Debug.Print "Key1: " & ObjPtr(key1) Debug.Print "Key2: " & ObjPtr(key2) 'Now those pointers should be the same. End Sub
在这里,我们为variableskey1
分配了一个新的类DCRKey
实例,然后我们将同一个对象分配给variableskey2
。 现在ObjPtr
应该为key1
和key2
返回相同的值,因为这是同一个对象,它只被分配给两个不同的variables。
现在,让我们回到字典。
字典searchObject
types的关键字的方式是通过它的指针。
所以如果你想在一个字典中添加一个对象作为关键字,你需要使用完全相同的对象(而不是具有相同属性的对象)。
例:
Sub objectsToDictionaryTest() Dim CResults As Dictionary Dim accessKey As DCRKey Dim key As DCRKey Dim value As DCR '-------------------------------------------------------------------------------- Set CResults = New Scripting.Dictionary 'Let's create an object of [DCRKey] class (it will be used as a key when adding to 'the dictionary) and an object of [DCR] class (it will be used as a value). Set accessKey = New DCRKey With accessKey .loadcase = 10 .node = 2000 .csystem = "Global" End With Set value = New DCR With value .C1 = 10 .C2 = 20 .Fs = 3 End With 'Now, let's add a new entry to the dictionary [CResults] CResults.Add accessKey, value 'Let's create the other object of [DCRKey] that have exactly the same properties 'as object assigned to the variable [accessKey]. Set key = New DCRKey With key .loadcase = 10 .node = 2000 .csystem = "Global" End With 'Now, let's check how dictionary is acting when we try to find an entry by [accesKey] and [key]. Debug.Print "[accessKey] exists: " & CResults.Exists(accessKey) 'it should return True. Debug.Print "[key] exists: " & CResults.Exists(key) 'it should return False. Debug.Print "[Value for accessKey]: " & CResults.Item(accessKey).Fs 'it should print 3 'The line below should cause an run-time error 424: Object required. Debug.Print "[Value for key]: " & CResults.Item(key).Fs End Sub