简体   繁体   English

Outlook 使用 Excel VBA 发送邮件时有时会崩溃

[英]Outlook sometimes crashes when sending mail using Excel VBA

I have VBA code in Excel to perform the following actions:我在 Excel 中有 VBA 代码来执行以下操作:

  1. retrieve order request检索订单请求
  2. pull SAP reports提取 SAP 报告
  3. validate order request验证订单请求
  4. connect to SAP to do transaction连接到 SAP 进行交易
  5. send email发送 email
  6. loop (from #4) until all orders are done循环(从#4开始)直到所有订单都完成

The sending email part crashes probably 15% of the time on replying to the second email.发送 email 部分在回复第二个 email 时可能有 15% 的时间崩溃。 I can continue the automation flow by acknowledging the below error, restart Outlook, and the script continues like nothing happened.我可以通过确认以下错误来继续自动化流程,重新启动 Outlook,脚本继续运行,就像什么都没发生一样。

在此处输入图像描述

I'm thinking that it might be a memory issue with this particular bot as it's only this one that fails.我认为这可能是这个特定机器人的 memory 问题,因为只有这个机器人失败了。 I do comprehend that after the the code hits End Sub , then all the variables should be cleared from memory.我确实理解在代码命中End Sub之后,应该从 memory 中清除所有变量。

The code is only for replying.该代码仅用于回复。 It gets called after the SAP transaction is done.在 SAP 事务完成后调用它。

Sub EmailReply()
    
    Application.ScreenUpdating = False
    
    Call OpeningDuties
    
    Dim olApp As Outlook.Application
    Dim oLNameSpace As Outlook.Namespace
    Dim objOwner As Outlook.Recipient
    Dim topOlFolder As Outlook.MAPIFolder
    Dim oLMail As Outlook.MailItem
    Dim i As Long
    Dim wdDoc As Word.Document
    
    Dim EmailAddress As Object
    
    Dim fdr_Unprocessed As Outlook.MAPIFolder
    Dim fdr_Pending As Outlook.MAPIFolder
    Dim fdr_Processed As Outlook.MAPIFolder
    
    Set myNameSpace = Outlook.Application.GetNamespace("mapi")
    Set objOwner = myNameSpace.CreateRecipient("retailrma@company.com")
    objOwner.Resolve
    
    If objOwner.Resolved Then
        Set topOlFolder = myNameSpace.GetSharedDefaultFolder(objOwner, olFolderInbox)
    End If
    
    Set fdr_Unprocessed = topOlFolder.Folders("RMA - Unprocessed")
    Set fdr_Pending = topOlFolder.Folders("RMA - Pending")
    Set fdr_Processed = topOlFolder.Folders("RMA - Processed")
    
    For Each oLMail In fdr_Unprocessed.Items
    
        If (oLMail.Subject = Range("Email_Subject").Text And Format(oLMail.ReceivedTime, "Medium Time") = Format(Range("Email_Date").Text, "Medium Time") And oLMail.SenderEmailAddress = Range("Email_Address").Text) _
          Or (oLMail.Subject = Range("Email_Subject").Text And Format(oLMail.ReceivedTime, "Medium Time") = Format(Range("Email_Date").Text, "Medium Time")) Then
     
            'if email can be found then reply email  or send email
        
            'Define copy range on Email Template sheet as a word document
            Dim CopyRange As Range
        
            'Set wdDoc = oLMail.GetInspector.WordEditor
        
            'Determining if the email should be responded in English or French
            If Range("email_language") = "En" Then
            
                FirstRow = 3
                FirstColumn = 3
                LastRow = 246
                LastColumn = 9
    
            ElseIf Range("email_language") = "Fr" Then
    
                FirstRow = 3
                FirstColumn = 11
                LastRow = 246
                LastColumn = 16
    
            End If
        
            Sheets("Email Template").Select
            Sheets("Email Template").Range(Cells(FirstRow, FirstColumn), Cells(LastRow, LastColumn)).AutoFilter Field:=1, Criteria1:="Show"
        
            Set ReplyAll = oLMail.ReplyAll
            Set EmailAddress = Range("Email_Address")
            Set CopyRange = Range(Cells(FirstRow, FirstColumn), Cells(LastRow, LastColumn)).SpecialCells(xlCellTypeVisible)
            
            'Error handling if no email address
            If EmailAddress = 0 Then
                RMAStatus = "Non valid email address"
                Application.ScreenUpdating = True
                Exit Sub
            End If
        
            With ReplyAll
                .To = EmailAddress
                .CC = "retailrma@company.com"
                .Display
                .BodyFormat = olFormatHTML
                Set wdDoc = oLMail.GetInspector.WordEditor
                CopyRange.Copy
                wdDoc.Application.Selection.PasteAndFormat Type:=wdFormatOriginalFormatting  'pastes the approved / non approved IMEIs into outlook reply email
                .Send
            End With
        
            'move email to processed folder
            oLMail.Move fdr_Processed
        
            'Resets Email Template
            Sheets("Email Template").Range(Cells(FirstRow, FirstColumn), Cells(LastRow, LastColumn)).AutoFilter Field:=1
        
            GoTo ExitSendEmail
        
        End If
        
    Next oLMail
    
ExitSendEmail:
    
    Application.ScreenUpdating = True
    
End Sub

First of all, make sure that all objects are defined correctly in the code:首先,确保在代码中正确定义了所有对象:

Dim oLNameSpace As Outlook.Namespace

But later in the code another object is used:但稍后在代码中使用了另一个 object:

 Set myNameSpace = Outlook.Application.GetNamespace("mapi")

Another possible weak area is a Word object model used for editing emails.另一个可能的薄弱环节是用于编辑电子邮件的 Word object model。

Set wdDoc = oLMail.GetInspector.WordEditor

Try to use the HTMLBody property of the MailItem class instead.尝试改用MailItem class 的HTMLBody属性。

Also you may add a delay between each iteration.您也可以在每次迭代之间添加延迟。 See the Timer function for more information.有关详细信息,请参阅定时器function。 The following example uses the Timer function to pause the application.以下示例使用Timer function 暂停应用程序。 The example also uses DoEvents to yield to other processes during the pause.该示例还使用DoEvents在暂停期间让步给其他进程。

Dim PauseTime, Start, Finish, TotalTime
If (MsgBox("Press Yes to pause for 5 seconds", 4)) = vbYes Then
    PauseTime = 5    ' Set duration.
    Start = Timer    ' Set start time.
    Do While Timer < Start + PauseTime
        DoEvents    ' Yield to other processes.
    Loop
    Finish = Timer    ' Set end time.
    TotalTime = Finish - Start    ' Calculate total time.
    MsgBox "Paused for " & TotalTime & " seconds"
Else
    End
End If

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM