为什么我不能从Collection中获取项目并将其存储在变量中?

时间:2015-06-20 13:05:53

标签: vba

我有一个集合,我用它来制作String -> MailItem地图。我填写地图,当我找到一个重复的密钥时,我想阅读集合中的项目。

这看起来很容易,但我花了一个多小时试图找出为什么我不能将Collection项目分配给局部变量。 (请参阅下面的代码中的PROBLEM

  

oMailOther = cMails.Item(cMailKey)“对象变量或未设置块变量”

     

Set oMailOther = cMails.Item(cMailKey)“需要对象”

另一个cMails(cMailKey)表单给出了相同的错误。移动Dim并没有任何区别。 cMails必须可用,因为它在方法的前面使用过。 请注意本声明之前的Debug.Print行,有效 。我错过了什么?

Option Explicit
Option Compare Text

Public cMails As Collection

Public Sub GetOutlookAttachments()
    Set cMails = New Collection

    Dim oStore As Store
    For Each oStore In Session.Stores
        If oStore.DisplayName = "Outlook Data File" Then
            ProcessFolder oStore.GetRootFolder()
        End If
    Next
End Sub

Private Sub ProcessFolder(oFolder As Folder)
    Debug.Print oFolder.FolderPath
    ProcessItems oFolder.Items

    Dim oSubFolder As Folder
    For Each oSubFolder In oFolder.Folders
        ProcessFolder oSubFolder ' recurse
    Next
End Sub

Private Sub ProcessItems(oItems As Items)
    Dim oItem As Object
    For Each oItem In oItems
        DoEvents
        If TypeOf oItem Is MailItem Then
            Dim oMail As MailItem
            Set oMail = oItem
            Dim cMailKey As String
            cMailKey = oMail.ConversationID & "-" & oMail.ConversationIndex
            If Not Contains(cMails, cMailKey) Then
                cMails.Add oMail.Subject, cMailKey
            Else
                Debug.Print cMails.Item(cMailKey)
                Dim oMailOther As MailItem
 PROBLEM        oMailOther = cMails.Item(cMailKey)
                Debug.Print cMailKey & ": " & oMailOther.Subject
            End If
        ElseIf TypeOf oItem Is MeetingItem Then
            ' ignore
        Else
            Debug.Print "oItem Is a " & TypeName(oItem)
        End If
    Next oItem
End Sub

Public Function Contains(col As Collection, key As Variant) As Boolean
    Dim obj As Variant
    On Error GoTo err
    Contains = True
    obj = col(key)
    Exit Function
err:
    Contains = False
End Function

我还试图在其他地方复制类似的AddItem来电,可行

Public Sub Test()
    Set cMails = New Collection

    Dim cMailKey As String
    cMailKey = "hello"
    cMails.Add Session.Stores.Item(1), cMailKey

    Debug.Print cMails(cMailKey)
    Dim oStore As Store
    Set oStore = cMails(cMailKey)
    Debug.Print oStore.DisplayName
End Sub

3 个答案:

答案 0 :(得分:6)

我复制了你的代码然后运行它。您正在创建的集合cMailsStrings的集合,而不是邮件对象的集合;但是,oMailOther被声明为Object类型的MailItem

在没有Set关键字的作业中,VB抱怨您想要将某些内容分配给对象(左侧),并且应该使用Set关键字。现在,使用Set关键字,VB抱怨右侧不是对象......

要使cMails成为邮件项目的集合,请更改Add语句,如下所示:

cMails.Add oMail, cMailKey

(即你不要添加oMail.Subject但是整个oMail对象。)

现在使用Set中的Set oMailOther = cMails.Item(cMailKey)关键字,一切正常。

答案 1 :(得分:2)

oMailOtherMailItem,因此如果没有问题,您必须使用Set将其分配给变量的内容:

Set oMailOther = cMails(cMailKey)

但是,您的cMails集合不包含MailItem对象。它仅包含您之前使用cMails.Add oMail.Subject, cMailKey添加的主题(即字符串而不是对象)。

显然你的意思是cMails.Add oMail, cMailKey

答案 2 :(得分:1)

问题不在于您检索项目的方式,而是

If Not Contains(cMails, cMailKey) Then
    cMails.Add oMail.Subject, cMailKey
Else

Collection.Add的第一个参数是您在集合中存储的内容 - 在本例中是主题。当您尝试从此处的集合中检索项目时...

Debug.Print cMails.Item(cMailKey)
Dim oMailOther As MailItem
MailOther = cMails.Item(cMailKey)
Debug.Print cMailKey & ": " & oMailOther.Subject

...您正在尝试检索对象本身。 Debug.Print有效,因为您的集合中填充了字符串。

如果您需要MailItem的集合,则需要像这样填写:

cMails.Add oMail, cMailKey