我有一个集合,我用它来制作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
我还试图在其他地方复制类似的Add
和Item
来电,可行 。
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
答案 0 :(得分:6)
我复制了你的代码然后运行它。您正在创建的集合cMails
是Strings
的集合,而不是邮件对象的集合;但是,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)
oMailOther
是MailItem
,因此如果没有问题,您必须使用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