【问题标题】:Attaching Excel File in Email在电子邮件中附加 Excel 文件
【发布时间】:2020-02-22 09:23:35
【问题描述】:

我正在尝试解决 VBA 的问题,即在用户发送之前将文件从 Excel 直接附加到带有 .Display 的电子邮件中。该文件应保存,创建一个新的临时文件,将该临时文件复制并直接粘贴到电子邮件正文中,同时将实际的原始文档附加到电子邮件中以供参考。完成此操作后,它应该终止临时文件而不保存它。

我遇到的问题是它会创建新的临时工作簿,但不会将信息复制并粘贴到电子邮件中或将文档附加到电子邮件中。我的代码在下面带有股票电子邮件地址。任何帮助表示赞赏。错误信息似乎总是落在.Attachments.Add (ActiveDocument.FullName)

Sub SendEmailOutlook()
    ActiveWorkbook.Save

    'Send an email. basically just to standardize and error-proof the process
    'RangetoHTML function (below this macro) allows a range of cells to be pasted into the email body    
    Dim strbody As String    
    Dim rng As Range    
    Dim OutApp As Object    
    Dim OutMail As Object    
    Dim Message As String    
    Dim subject As String    
    Dim UpdateTime As String        

    'this line is extra for HTML formatting but it makes the text easier to read    
    strbody = "<P STYLE='font-family:Calibri;font-size:12pt'>"

    subject = "2018 Safety Walk Form for " & Sheets("2018 Safety Walk").Range("H5") & " " & Sheets("2018 Safety Walk").Range("K5")

    Message = "Team <br><br>Please see the attached form for, " & Sheets("2018 Safety Walk").Range("K5")

    'Set last row based on input data
    '    Dim lastRow As String    
    '    lastRow = Sheets("Email").UsedRange.Rows.Count
    'Set range for email body    
    'The column is on the right, the row on the left. Change to .Range("A1:H30") if you want it to be static

    Set rng = Sheets("2018 Safety Walk").Range("B5:K43")

    'Create email
    With Application    
        .EnableEvents = False    
        .ScreenUpdating = False    
    End With

    Set OutApp = CreateObject("Outlook.Application")    
    Set OutMail = OutApp.CreateItem(0)

    With OutMail    
        .To = "123@123.com"    
        .BCC = ""    
        .subject = subject    
        .HTMLBody = strbody & Message & RangetoHTML(rng) & "<br>"    
        .Attachments.Add (ActiveDocument.FullName)        
        .Display    'you can use .Send to have the macro send the email without needing to confirm it    
    End With

    On Error GoTo 0

    With Application    
        .EnableEvents = True    
        .ScreenUpdating = True    
    End With

    Set OutMail = Nothing    
    Set OutApp = Nothing    
End Sub




Function RangetoHTML(rng As Range)    
    Dim fso As Object    
    Dim ts As Object    
    Dim TempFile As String    
    Dim TempWB As Workbook

    TempFile = Environ$("temp") & "/" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"

    'Copy the range and create a new workbook to past the data in    
    rng.Copy    
    Set TempWB = Workbooks.Add(1)

    With TempWB.Sheets(1)    
        .Cells(1).PasteSpecial Paste:=8    
        .Cells(1).PasteSpecial xlPasteValues, , False, False    
        .Cells(1).PasteSpecial xlPasteFormats, , False, False    
        .Cells(1).Select    
        Application.CutCopyMode = False

        On Error Resume Next    
        .DrawingObjects.Visible = True    
        .DrawingObjects.Delete   
        On Error GoTo 0
    End With         

    'Copy the range and create a new workbook to past the data in
    rng.Copy
    Set TempWB = Workbooks.Add(1)
    With TempWB.Sheets(1)
        .Cells(1).PasteSpecial Paste:=8
        .Cells(1).PasteSpecial xlPasteValues, , False, False
        .Cells(1).PasteSpecial xlPasteFormats, , False, False
        .Cells(1).Select
        Application.CutCopyMode = False
        On Error Resume Next
        .DrawingObjects.Visible = True
        .DrawingObjects.Delete
        On Error GoTo 0
    End With

    'Publish the sheet to a htm file
    With TempWB.PublishObjects.Add( _
         SourceType:=xlSourceRange, _
         Filename:=TempFile, _
         Sheet:=TempWB.Sheets(1).Name, _
         Source:=TempWB.Sheets(1).UsedRange.Address, _
         HtmlType:=xlHtmlStatic)
        .Publish (True)
    End With

    'Read all data from the htm file into RangetoHTML
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
    RangetoHTML = ts.readall
    ts.Close
    RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
                          "align=left x:publishsource=")

    'Close TempWB
    TempWB.Close SaveChanges:=False

    'Delete the htm file we used in this function
    Kill TempFile
    Set ts = Nothing
    Set fso = Nothing
    Set TempWB = Nothing
End Function

【问题讨论】:

  • 这将有助于了解您收到的确切错误消息是什么。也就是说...ActiveDocument 来自哪里?那是一个 Word 对象,而不是 Excel 对象。尝试改用ActiveWorkbook
  • 嘿帕特里克,我也尝试使用 ActiveWorkbook - 结果相同。运行宏“运行时错误'424':需要对象”时收到错误消息。一旦我进入宏,.Attachment.Add (ActiveWorkbook.FullName) 就是突出显示的黄色(将其更改回工作簿而不是文档。运行宏时,收到的错误消息是“运行时错误'-2147024894 (80070002)':找不到此文件。验证路径和文件名是否正确。”它应该从临时文件中提取信息以将单元格复制/粘贴到电子邮件正文中,但附加原始文档。

标签: excel vba excel-formula


【解决方案1】:

来自 OP 的评论:

运行宏时,收到的错误消息是“运行时错误 '-2147024894 (80070002)': 找不到这个文件。验证路径和 文件名是正确的。”

这是因为在您的 RangeToHTML 函数中,您正在创建 两个 临时工作簿,但只关闭一个。因此,一旦RangeToHTML 返回,您的ActiveWorkbook 指的是剩余的临时工作簿,而不是您的原始工作簿。由于尚未保存,其.FullName 属性还没有值,因此出现“找不到此文件”错误。

RangeToHTML 中,删除您复制/粘贴的这些部分之一,您的问题将得到解决:

'Copy the range and create a new workbook to past the data in    
rng.Copy    
Set TempWB = Workbooks.Add(1)

With TempWB.Sheets(1)    
    .Cells(1).PasteSpecial Paste:=8    
    .Cells(1).PasteSpecial xlPasteValues, , False, False    
    .Cells(1).PasteSpecial xlPasteFormats, , False, False    
    .Cells(1).Select    
    Application.CutCopyMode = False

    On Error Resume Next    
    .DrawingObjects.Visible = True    
    .DrawingObjects.Delete   
    On Error GoTo 0
End With         

'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
    .Cells(1).PasteSpecial Paste:=8
    .Cells(1).PasteSpecial xlPasteValues, , False, False
    .Cells(1).PasteSpecial xlPasteFormats, , False, False
    .Cells(1).Select
    Application.CutCopyMode = False
    On Error Resume Next
    .DrawingObjects.Visible = True
    .DrawingObjects.Delete
    On Error GoTo 0
End With

您还应该在您的SendEmailOutlook 过程中,根本不要使用ActiveWorkbook,因为您可以看到,如果您不小心,这会绊倒您。直接设置和使用对工作簿的引用总是更好。

所以,类似:

Dim wb as Workbook
Set wb = Workbooks("Your Workbook Name")

或:

Dim wb as Workbook
Set wb = ActiveWorkbook

SendEmailOutlook 的开头,然后在过程中其他地方当前使用ActiveWorkbook 的任何位置使用wb

【讨论】:

    猜你喜欢
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 2023-03-07
    • 2014-10-10
    • 2019-03-18
    • 2018-03-24
    相关资源
    最近更新 更多