I have a Collection which I use to have a String -> MailItem
map. I fill the map, and when I find a duplicate key I want to read the item in the Collection.
This seems so easy, but I spent more than an hour trying to figure out why I can't assign a Collection item to a local variable. (see PROBLEM
in code below)
oMailOther = cMails.Item(cMailKey)
"Object variable or With block variable not set"
Set oMailOther = cMails.Item(cMailKey)
"Object required"
The other cMails(cMailKey)
form gives the same error. Moving the Dim around doesn't make any difference. cMails
must be available because it's used earlier in the method. Note the Debug.Print
line just before this statement, that 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 Add
and Item
calls elsewhere and 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
Now, an Excel VBA Collection is a group of similar items. You can use built-in collections such as the Workbooks collection, which is a collection of all the open workbooks, in your VBA code. The Worksheets Collection, on the other hand contains all the worksheets in your workbook.
A collection variable is a composite variable whose internal components, called elements, have the same data type. The value of a collection variable and the values of its elements can change. You reference an entire collection by its name.
Collections in VBA are objects that can store groups of related items, much like an array. Unlike arrays, a single collection can store items of different types because each item in a collection is stored as a Variant.
I copied your code and ran it. The collection cMails
you are creating is a collection of Strings
, not of mail objects; however, oMailOther
is declared as an Object
of type MailItem
.
In your assignment without the Set
keyword, VB complains that your want to assign something to an object (left-hand side) and should use the Set
keyword. Now, with the Set
keyword, VB complains that the right-hand side is not an object...
To make cMails
into a colection of mail items, change the Add
statement as follows:
cMails.Add oMail, cMailKey
(i.e. you don't add oMail.Subject
but the whole oMail
object.)
Now use the Set
keyword in Set oMailOther = cMails.Item(cMailKey)
and everything works fine.
oMailOther
is a MailItem
, so without a question you must use Set
what assigning it to a variable:
Set oMailOther = cMails(cMailKey)
However your cMails
collection does not contain a MailItem
object. It contains only subjects (that are strings as opposed to objects) that you previously added with cMails.Add oMail.Subject, cMailKey
.
Apparently you meant cMails.Add oMail, cMailKey
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With