【发布时间】:2018-06-17 10:04:30
【问题描述】:
我目前正在研究一个简单的 VBA 宏,它收集 Outlook 邮箱中邮件的一些元数据(例如EntryId、ReceivedTime、Recipients 等...)。
为此,它递归地遍历所有文件夹并从每个文件夹中的MailItems 收集数据。
但我遇到了错误,这些错误不限于同一个对象(有时错误会更早弹出,但不会更晚),说明该对象不支持自动化(运行时错误430)。
奇怪的是,大约有 14000 个 MailItems 被处理而没有失败,通常在 14232 处它会崩溃。
关于此错误,我有两个问题:
- 我正在处理一个非本地邮箱,因此只有部分数据应该缓存在本地
.ost文件中。
缓存中缺少数据会是导致错误的原因吗? - 如果缓存不是问题,那我的代码有什么问题?
代码的简化版本:
(请注意,所有非 MailItem 对象都通过显式类型检查排除)
Sub cache()
Dim objOl As Outlook.Application
Dim objNs As Outlook.NameSpace
Dim folder As Outlook.MAPIFolder
Dim vFolders As Outlook.Folders
Set objOl = New Outlook.Application
Set objNs = objOl.GetNamespace("MAPI")
Set vFolders = objNs.Folders
'This is where we're looking for the mailbox to work with
For i = 1 to vFolders.count
If StrComp(vFolders(i), "The Mailbox") = 0 Then
walk vFolders(i)
End If
Next
End Sub
Sub walk(folder As Outlook.MAPIFolder)
Dim item As Object
Dim vItems As Outlook.Items
Set vItems = folder.Items
If vItems.count > 0 Then
For i = 1 to vItems.Count
Set item = vItems(i)
If item.class = 43 Then
'This is where the debugger shows the runtime error 430
Debug.Print item.EntryID & vbCrLf & item.ReceivedTime
End If
Next
End If
Dim vFolders as Outlook.Folders
Set vFolders = folder.Folders
If (vFolders.count > 0) Then
For i = 1 To vFolders.Count
walk vFolders(i)
Next
End If
End Sub
更新:
我根据建议更新了代码。没有多点表示法和For Each 循环,性能提高了,但问题一直出现在完全相同的项目上,只要我尝试访问(主题、entryID 或其他)之类的数据。
【问题讨论】:
-
似乎您在 VBA 中的内存不足。如果你发布完整的代码,我们可以看到你对这些项目做了什么,并提出了改进内存使用的方法。还是上面的代码也会产生问题?
-
我唯一要做的就是将数据打印到这样的文件中:
print #1, item.EntryID。没有别的... -
..或递归中的堆栈空间不足。尝试
Sub walk(folder As Outlook.MAPIFolder, ByVal depth As Integer)并调用walk tmpFolder, depth + 1来跟踪您的递归深度。 -
我按照你的要求做了,最深的递归级别直到崩溃是 5,它甚至没有崩溃,它在 3 崩溃。因此我认为可以排除这种情况。跨度>