【问题标题】:Out Of Memory generating emails via excel vba内存不足通过 excel vba 生成电子邮件
【发布时间】:2017-09-26 12:17:52
【问题描述】:

我有一些在 excel 中运行的 VBA 代码,它根据主题名称生成电子邮件并将 excel 文件附加到电子邮件中。宏似乎对 101 封电子邮件运行良好,然后几乎 100% 的时间都失败了。每个附件为 15kb,创建的电子邮件总量会有所不同,但为了测试,我总共有 128 个。

实际的电子邮件组成是电子邮件的正文,附有默认签名,主题是静态的,收件人是可变的。

我无法识别代码所需的任何修改,每次迭代我都会放弃 OAMail 项目,所以我有点不知所措(这是看似出错的标准问题)。

代码如下:

Sub Generate_Emails()

    Dim OApp As Object
    Dim OMail As Object
    Dim signature As String
    Dim emailbody As String
    Dim ET As Worksheet
    Dim Sum_WS As Worksheet
    Dim EL As Worksheet
    Dim CS As Worksheet

    Set ET = ActiveWorkbook.Worksheets("EmailTemplate")
    Set Sum_WS = ActiveWorkbook.Worksheets("Summary")
    Set EL = ActiveWorkbook.Worksheets("EmailList")
    Set CS = ActiveWorkbook.Worksheets("ControlSheet")
    Set OApp = CreateObject("Outlook.Application")

    'Check if emails can be generated
    If CS.Range("F2") = "No" Then
        MsgBox "Cannot generate files until Files have been generated", vbExclamation
        Exit Sub
    Else
        i = Application.WorksheetFunction.CountA(EL.Range("A:A"))
        body = ET.Range("A1")

        'Go through each email in email list
        For j = 2 To i
            'Create email object
            Set OMail = OApp.CreateItem(0)
            'Get default signature
            With OMail
                .GetInspector
            End With
            'Allocate signature and body
            signature = OMail.HTMLBody
            'Create the whole email and add attachment
            With OMail
                .To = EL.Cells(j, 2)
                .Subject = "SOx RemTP Audit " & Sum_WS.Range("C2")
                .HTMLBody = body & vbNewLine & signature
                .Attachments.Add Sum_WS.Range("B2") & "\SOx RemTP Audit " & Sum_WS.Range("C2") & " - " & EL.Cells(j, 1) & ".xlsx"
                .Save
            End With

            Application.StatusBar = "Generating Email " & j & " of " & i
            DoEvents

            Set OMail = Nothing
        Next j
        Application.StatusBar = False
    End If
    Set OApp = Nothing
    MsgBox "All emails placed into Outlook draft folder", vbInformation
End Sub

任何帮助将不胜感激。

干杯

【问题讨论】:

  • 只是在黑暗中拍摄 - 保存后尝试关闭对象
  • 假设您的意思是:使用 OMail .To = EL.Cells(j, 2) .Subject = EmailSubject .HTMLBody = body & vbNewLine & signature .Attachments.Add AttachmentsFolder & EL.Cells(j, 1 ) & ".xlsx" .Save Set OMail = Nothing End With Then yes, 但它的差别为零
  • 不,我在想 OMail.Close 0
  • 在保存后添加 OMail.Close 会弹出“Argument Not Optional”
  • 啊,我明白了,这完成了工作。代码现在将成功运行,而且似乎工作得更多。按道理说,同时“打开” 100 多封电子邮件会导致内存故障

标签: vba excel email


【解决方案1】:

一些注意事项:您的代码看起来不错,但使用 Option Explicit

'##开头的代码中查看我的cmets……

Option Explicit '## force proper variable declare to avoid typos and issues

Public Sub Generate_Emails()
    Dim OApp As Object
    Dim OMail As Object
    Dim signature As String
    Dim emailbody As String
    Dim ET As Worksheet
    Dim Sum_WS As Worksheet
    Dim EL As Worksheet
    Dim CS As Worksheet

    Set ET = ActiveWorkbook.Worksheets("EmailTemplate")
    Set Sum_WS = ActiveWorkbook.Worksheets("Summary")
    Set EL = ActiveWorkbook.Worksheets("EmailList")
    Set CS = ActiveWorkbook.Worksheets("ControlSheet")
    Set OApp = CreateObject("Outlook.Application")

    'Check if emails can be generated
    If CS.Range("F2") = "No" Then
        MsgBox "Cannot generate files until Files have been generated", vbExclamation
        Exit Sub
    Else
        Dim i As Long '## dim i
        i = Application.WorksheetFunction.CountA(EL.Range("A:A"))
        emailbody = ET.Range("A1")

        'Go through each email in email list
        Dim j As Long '## dim j
        For j = 2 To i
            'Create email object
            Set OMail = OApp.CreateItem(0)
            'Get default signature
            With OMail '## tidied up your with block (one is enough)
                .GetInspector

                'Allocate signature and body
                signature = .HTMLBody

                'Create the whole email and add attachment
                .To = EL.Cells(j, 2)
                .Subject = "SOx RemTP Audit " & Sum_WS.Range("C2")
                .HTMLBody = emailbody & vbNewLine & signature
                .Attachments.Add Sum_WS.Range("B2") & "\SOx RemTP Audit " & Sum_WS.Range("C2") & " - " & EL.Cells(j, 1) & ".xlsx"
                .Save
                .Close 0 '## close the mail to not leave it open (this might be the issue)
                         '0=olSave; 1=olDiscard; 2=olPromptForSave
            End With

            Application.StatusBar = "Generating Email " & j & " of " & i
            DoEvents

            'Set OMail = Nothing '## not needed
        Next j
        Application.StatusBar = False
    End If
    'Set OApp = Nothing '## not needed

    MsgBox "All emails placed into Outlook draft folder", vbInformation
End Sub

Set Something = Nothing 几乎不需要,因为 VBA 会在 End Sub 上自动执行此操作。

【讨论】:

  • 选项显式被添加到整个工作簿中,我的印象是它级联下来。至于添加.close,我将其添加并收到错误“Argument not optional”。与它隔离的是“.close”
  • 我已经通过添加“.close 0”而不是“.close”解决了这个问题。代码现在完美而高效地运行。感谢您的帮助。
【解决方案2】:

通过在 With 语句中添加“.close 0”解决了问题。

原始循环:

'Go through each email in email list
        For j = 2 To i
            'Create email object
            Set OMail = OApp.CreateItem(0)
            'Get default signature
            With OMail
                .GetInspector
            End With
            'Allocate signature and body
            signature = OMail.HTMLBody
            'Create the whole email and add attachment
            With OMail
                .To = EL.Cells(j, 2)
                .Subject = "SOx RemTP Audit " & Sum_WS.Range("C2")
                .HTMLBody = body & vbNewLine & signature
                .Attachments.Add Sum_WS.Range("B2") & "\SOx RemTP Audit " & Sum_WS.Range("C2") & " - " & EL.Cells(j, 1) & ".xlsx"
                .Save
            End With

            Application.StatusBar = "Generating Email " & j & " of " & i
            DoEvents

            Set OMail = Nothing
        Next j

修改循环,添加 .close 0 并合并 with:

    'Go through each email in email list
    For j = 2 To i
        'Create email object
        Set OMail = OApp.CreateItem(0)
        'Get default signature
        With OMail
            .GetInspector
            'Allocate signature
            signature = OMail.HTMLBody
            'Create the whole email and add attachment
            .To = EL.Cells(j, 2)
            .Subject = emailsubject
            .HTMLBody = emailbody & vbNewLine & signature
            .Attachments.Add attachmentsfolder & EL.Cells(j, 1) & ".xlsx"
            .Save
            .Close 0
        End With


        Application.StatusBar = "Generating Email " & j & " of " & i
        DoEvents

        Set OMail = Nothing
    Next j

感谢 Peh 和 Sam 提供解决方案

【讨论】:

    猜你喜欢
    • 2019-09-03
    • 2016-04-25
    • 2017-09-14
    • 1970-01-01
    • 2022-11-09
    • 2017-01-21
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多