展望宏观经过250次迭代与错误而失败前运行(Outlook macro runs through 2

2019-07-03 17:35发布

描述:

我有一个Outlook宏,通过选择邮件文件夹中的循环,并写下一些信息为.csv文件。 它完美,直到250失败之前。 下面是一些代码:

Open strSaveAsFilename For Append As #1

CountVar = 0
For Each objItem In Application.ActiveExplorer.Selection
    DoEvents
    If objItem.VotingResponse <> "" Then
        CountVar = CountVar + 1
        Debug.Print "   " & CountVar & ". " & objItem.SenderName
        Print #1,  & objItem.SenderName & "," &  objItem.VotingResponse
    Else
        CountVar = CountVar + 1
        Debug.Print "   " & CountVar & ". " & "Moving email from: " & Chr(34) & objItem.SenderName & Chr(34) & " to: Special Cases sub-folder"
        objItem.Move CurrentFolderVar.Folders("Special Cases")
    End If
Next
Close #1

问题

此代码后通过电子邮件250运行,下面的截图弹出:

http://i.stack.imgur.com/yt9P8.jpg

我试着加入了“等待”功能让服务器休息,使我没有这么快的查询,但我得到同样的错误在同一点。

Answer 1:

感谢@ 76mel,他回答到我引用大量另一个问题。 我发现它是一个内置的限制在Outlook( 源 ),您不能打开超过250个项目,Outlook会他们都在内存中,直到宏结束不管。 解决方法,而不是通过在选择每个项目循环,:

For Each objItem In Application.ActiveExplorer.Selection

您可以通过父文件夹循环。 我想我可以做这样的事情:

For Each objItem In oFolder.Items

但是,事实证明,当你删除或移动电子邮件,它移到列表中的一个,所以它会跳过电子邮件。 通过我找到了一个文件夹进行迭代,最好的办法另一种答案是这样:

For i = oFolder.Items.Count To 1 Step -1 'Iterates from the end backwards
Set objItem = oFolder.Items(i)

这里是整个代码,它会提示一个文件夹选择来分析,该文件夹为“外出”在创建子目录回复以及它把打头的所有邮件“特殊情况”,“RE:”

Sub SaveItemsToExcel()
    Debug.Print "Begin SaveItemsToExcel"

    Dim oNameSpace As Outlook.NameSpace
    Set oNameSpace = Application.GetNamespace("MAPI")
    Dim oFolder As Outlook.MAPIFolder
    Set oFolder = oNameSpace.PickFolder
    Dim IsFolderSpecialCase As Boolean
    Dim IsFolderOutofOffice As Boolean
    IsFolderSpecialCase = False
    IsFolderOutofOffice = False

    'If they don't check a folder, exit.
    If oFolder Is Nothing Then
        GoTo ErrorHandlerExit
    ElseIf oFolder.DefaultItemType <> olMailItem Then 'Make sure folder is not empty
        MsgBox "Folder does not contain mail messages"
        GoTo ErrorHandlerExit
    End If

    'Checks to see if Special Cases Folder and Out of Office folders exists. If not, create them
    For i = 1 To oFolder.Folders.Count
        If oFolder.Folders.Item(i).name = "Special Cases" Then IsFolderSpecialCase = True
        If oFolder.Folders.Item(i).name = "Out of Office" Then IsFolderOutofOffice = True
    Next
    If Not IsFolderSpecialCase Then oFolder.Folders.Add ("Special Cases")
    If Not IsFolderOutofOffice Then oFolder.Folders.Add ("Out of Office")

    'Asks user for name and location to save the export
    objOutputFile = CreateObject("Excel.application").GetSaveAsFilename(InitialFileName:="TestExport" & Format(Now, "_yyyymmdd"), fileFilter:="Outlook Message (*.csv), *.csv", Title:="Export data to:")
    If objOutputFile = False Then Exit Sub
    Debug.Print "   Will save to: " & objOutputFile & Chr(10)

    'Overwrite outputfile, with new headers.
    Open objOutputFile For Output As #1
    Print #1, "User ID,Last Name,First Name,Company Name,Subject,Vote Response,Recived"

    ProcessFolderItems oFolder, objOutputFile

    Close #1

    Set oFolder = Nothing
    Set oNameSpace = Nothing
    Set objOutputFile = Nothing
    Set objFS = Nothing

    MsgBox "All complete! Emails requiring attention are in the " & Chr(34) & "Special Cases" & Chr(34) & " subdirectory."
    Debug.Print "End SaveItemsToExcel."
    Exit Sub
ErrorHandlerExit:
    Debug.Print "Error in code."
End Sub

Sub ProcessFolderItems(oParentFolder, ByRef objOutputFile)
    Dim oCount As Integer
    Dim oFolder As Outlook.MAPIFolder
    Dim MessageVar As String
    oCount = oParentFolder.Items.Count
    Dim CountVar As Integer
    Dim objItem As Outlook.MailItem

    CountVar = 0

    For i = oParentFolder.Items.Count To 1 Step -1 'Iterates from the end backwards
    Set objItem = oParentFolder.Items(i)
        DoEvents
        If objItem.Class = olMail Then
            If objItem.VotingResponse <> "" Then
                CountVar = CountVar + 1
                Debug.Print "   " & CountVar & ". " & GetUsername(objItem.SenderName, objItem.SenderEmailAddress) & "," & objItem.SenderName & "," & GetCompany(objItem.SenderName) & "," & Replace(objItem.Subject, ",", "") & "," & objItem.VotingResponse & "," & objItem.ReceivedTime
                Print #1, GetUsername(objItem.SenderName, objItem.SenderEmailAddress) & "," & objItem.SenderName & "," & GetCompany(objItem.SenderName) & "," & Replace(objItem.Subject, ",", "") & "," & objItem.VotingResponse & "," & objItem.ReceivedTime
            ElseIf objItem.Subject Like "*Out of Office*" Then
                CountVar = CountVar + 1
                Debug.Print "   " & CountVar & ". " & "Moving email from: " & Chr(34) & objItem.SenderName & Chr(34) & " to the, " & Chr(34) & "Out of Office" & Chr(34) & " sub-folder"
                objItem.Move oParentFolder.Folders("Out of Office")
            Else
                CountVar = CountVar + 1
                Debug.Print "   " & CountVar & ". " & "Moving email from: " & Chr(34) & objItem.SenderName & Chr(34) & " to the, " & Chr(34) & "Special Cases" & Chr(34) & " sub-folder"
                objItem.Move oParentFolder.Folders("Special Cases")
            End If
        End If
    Next i
    Set objItem = Nothing
End Sub

Function GetUsername(SenderNameVar As String, SenderEmailVar As String) As String
    On Error Resume Next
    GetUsername = ""
    GetUsername = CreateObject("Outlook.Application").CreateItem(olMailItem).Recipients.Add(SenderNameVar).AddressEntry.GetExchangeUser.Alias
    If GetUsername = "" Then GetUsername = Mid(SenderEmailVar, InStrRev(SenderEmailVar, "=", -1) + 1)
End Function

Function GetCompany(SenderNameVar)
    On Error Resume Next
    GetCompany = ""
    GetCompany = CreateObject("Outlook.Application").CreateItem(olMailItem).Recipients.Add(SenderNameVar).AddressEntry.GetExchangeUser.CompanyName
End Function


Answer 2:

为了解决这个问题,我使用了下列规则:

了“objOutlook.ActiveExplorer”具有有限的范围内(250级的对象)。

但是对象创建为每个电子邮件是无限的。

举个例子:

sub Over250()

  Total = objOutlook.ActiveExplorer.Selection.Count

  For X = 1 to Total

    Set objOutlook = CreateObject("Outlook.Application")
    Set ObjExplorer = objOutlook.ActiveExplorer     

   '**** DO YOU THINGS****

    Set objOutlook = Nothing
    Set ObjExplorer = Nothing

  Next X

end sub


文章来源: Outlook macro runs through 250 iterations before failing with error