在vba中使用自定义对象键访问词典中的项目 [英] Acces an item in a dictionary with a custom object key in vba

查看:84
本文介绍了在vba中使用自定义对象键访问词典中的项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在访问vba中的词典中的项目时遇到问题.

I've got a problem accessing items in a dictionary in vba.

我有以下字典:

Dim CResults as dictionary

我添加了项目:

CResults.add currentkey, result

Currentkey是我从名为DCRkey

Private loadcase as long
Private csystem as String
Private node as long

result是来自名为DCR的类的另一个对象:

and result is another object from a class called 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

That is where I've got the error: runtime error 424 object required

然后我认为搜索的键和项可能没有导入,因此我决定将整个字典显示在excel工作表上:

Then I thought maybe the key and the item that I search where not imported, so I decided to display my entire dictionary on an excel worksheet:

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

我看到的是:

  1. 我先前搜索的关键字存在于字典中:在工作表上进行视觉检查
  2. 我先前搜索的关键字确实存在于字典中:"This key is the same as the acceskey"显示一次
  3. for each循环访问字典中的项目是可行的,因为C1和Fs正确显示在工作表上
  1. The key that I was searching earlier exists in the dictionary : visual check on the sheet
  2. The key that I was searching earlier realy exists in the dictionary : "This key is the same as the acceskey" is displayed once
  3. Accessing an item in the dictionary from the for each loop works because C1 and Fs are displayed correctly on the worksheet

然后我想可能是由于testkey被定义为变体而不是DCRKey的事实,所以我尝试这样做:

Then I thought maybe it is due to the fact that testkey is defined as a variant and not a DCRKey, so I tried that:

dim a as variant
Set a = currentkey
.Cells(i,1) = CResults(a).C1

但是它不起作用,我仍然得到了runtime error 424.

But it doesn't works and I still got the runtime error 424.

我也尝试过:

CResults.exists(accesskey)

它返回false并在字典中创建一个新条目(我讨厌这样做),它具有与acceskey相同的键,并且为空.

It returns false and create a new entry in the dictionary (btw I hate when it does that), with the same key as acceskey and an empty item.

所以我的问题是:为什么使用自定义类型键访问项目在for each循环中起作用,而不是在独立调用中起作用.我错过了什么?该代码与我编写的代码非常相似,但不完全相同(以供您更好地理解).告诉我您是否认为真正的代码可以提供帮助. 感谢您的帮助.

So my question is: why accessing an item using a custom type key works in a for each loop and not in a standalone call. What have I missed? This code is very similar to the code that I wrote but not exactly the same (for you to understand better). Tell me if you think that the real code could help. Thanks for any help.

推荐答案

您需要记住,即使一个类的两个实例的所有属性都设置为相同的值,它们也不相同.

You need to remember that two instances of a class are not the same one, even if all their properties are set to the same values.

让我们考虑以下示例:

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后看到的对象不同.

In this example both objects of DCRKey class have all the properties set to the same values. However, they are not the same object as you can see after the code below run Debug.Prints at the end.

在那些Debug.Print中,使用了VBA内置功能ObjPtr.该函数的目的是返回指向给定对象的指针.每个对象实例都有其自己的唯一指针,因此,如果下面的代码打印了两个不同的指针,则意味着这些对象不相同.

In those Debug.Print VBA built-in function ObjPtr is used. The purpose of this function is to return pointer to the given object. Each instance of object has its own unique pointer, so if the code below printed two different pointers it means those objects are not the same.

现在,让我们考虑另一个示例:

Now, let's consider another example:

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

在这里,我们将类DCRKey的新实例分配给变量key1,然后将相同的对象分配给变量key2.现在ObjPtr应该为key1key2返回相同的值,因为这是同一对象,只是将其分配给两个不同的变量.

Here, we assigned a new instance of class DCRKey to the variable key1 and then we assigned the same object to the variable key2. Now ObjPtr should return the same value for both key1 and key2 since this is the same object, it is just assigned to two different variables.

现在,让我们回到字典.

Now, let's go back to dictionaries.

词典搜索Object类型键的方式是通过其指针.

The way how dictionary search for the key of Object type is by its pointer.

因此,如果要在字典中找到一个以对象作为键添加的条目,则需要使用完全相同的对象(而不是具有相同属性的对象).

So if you want to find an entry in a dictionary that is added with an object as a key, you need to use exactly the same object (not the object having the same properties).

示例:

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

这篇关于在vba中使用自定义对象键访问词典中的项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆