Why can't I get an item from the collection and store it in a variable?

I have a collection that I use to display a Map String -> MailItem . I fill in the map, and when I find a duplicate, I want to read the item in the collection.

It seems so easy, but I spent more than an hour trying to figure out why I cannot assign the Collection element to a local variable. (see PROBLEM in the code below)

oMailOther = cMails.Item(cMailKey) "An object variable or with a given block variable

Set oMailOther = cMails.Item(cMailKey) "Required Object"

Another form of cMails(cMailKey) gives the same error. Dim's movement around doesn't matter. cMails should be available as it was used earlier in the method. Pay attention to the line Debug.Print immediately before this statement , which works . What am I missing?

 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 

I also tried to replicate similar calls to Add and Item elsewhere, but it works .

 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 
+5
source share
3 answers

I copied your code and ran it. The cMails collection that you create is a collection of Strings , not mail objects; however, oMailOther declared as an Object type MailItem .

In his assignment without the Set keyword, VB complains that you want to assign something to the object (left side) and must use the Set keyword. Now, with the keyword Set , VB complains that the right side is not an object ...

To make cMails match mail elements, modify the Add statement as follows:

 cMails.Add oMail, cMailKey 

(i.e. you are not adding oMail.Subject , but the whole oMail object.)

Now use the Set keyword in Set oMailOther = cMails.Item(cMailKey) and everything works fine.

+6
source

oMailOther is a MailItem , so without question you should use Set what assigns it to a variable:

 Set oMailOther = cMails(cMailKey) 

However, your cMails collection cMails not contain a MailItem object. It contains only those objects (which are strings, not objects) that you previously added using cMails.Add oMail.Subject, cMailKey .

Apparently you meant cMails.Add oMail, cMailKey .

+2
source

The problem is not how you extract the elements, but how to add them:

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

Collection.Add The first parameter is what you store in the collection - in this case, Subject. When you try to get items from the collection here ...

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

... you are trying to get the object itself. Debug.Print works because you have a collection filled with strings.

If you need a MailItem collection, you need to populate it as follows:

 cMails.Add oMail, cMailKey 
+1
source

All Articles