【问题标题】:Paste Excel range in Outlook在 Outlook 中粘贴 Excel 范围
【发布时间】:2013-09-10 20:52:36
【问题描述】:

我想在 Outlook 中粘贴一系列单元格。

这是我的代码:

Sub Mail_Selection_Range_Outlook_Body()

Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object

Set rng = Nothing
On Error Resume Next
' Only send the visible cells in the selection.
Set rng = Selection.SpecialCells(xlCellTypeVisible)
Set rng = Sheets("Sheet1").RangeToHtml("D4:D12").SpecialCells(xlCellTypeVisible, xlTextValues)
On Error GoTo 0

If rng Is Nothing Then
    MsgBox "The selection is not a range or the sheet is protected. " & _
           vbNewLine & "Please correct and try again.", vbOKOnly
    Exit Sub
End If

With Application
    .EnableEvents = False
    .ScreenUpdating = False
End With

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

On Error Resume Next
With OutMail
    .To = ThisWorkbook.Sheets("Sheet2").Range("C1").Value
    .CC = ""
    .BCC = ""
    .Subject = "This is the Subject line"
    .HTMLBody = RangeToHtml.rng
    ' In place of the following statement, you can use ".Display" to
    ' display the e-mail message.
    .Display
End With
On Error GoTo 0

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

Set OutMail = Nothing
Set OutApp = Nothing
End Sub

我没有收到任何错误,只是没有在 Outlook 中粘贴范围。

我删除了On Error Resume Next。它给了我一个错误

对象不支持此属性或方法。

【问题讨论】:

  • 这个Set rng = Sheets("Sheet1").RangeToHtml("D4:D12").SpecialCells(xlCellTypeVisible, xlTextValues) 看起来不对。 RangeToHtml(假设这是 MS 网站上的函数)返回一个字符串,因此您不能在该字符串上调用 SpecialCells。去掉那个On Error Resume Next,你会看到错误。
  • 就像@TimWilliams 所说的删除On Error Resume Next,除非你有非常具体的理由来包含它。
  • 感谢您的回复 Tim 和 Enderland,我已经删除了 On Error Resume Next,就像您说的那样,它给了我一个错误,即 Object 不支持此属性或方法。你有什么办法可以摆脱这个错误吗?
  • 那么错误会将你带到哪一行?

标签: excel vba outlook


【解决方案1】:

首先,RangeToHTML。脚本将其称为方法,但事实并非如此。这是 MVP Ron de Bruin 的流行函数。巧合的是,该链接指向您发布的脚本的确切来源,在这几行被 b̶u̶t̶c̶h̶e̶r̶e̶d̶ 修改之前。

使用Range.SpecialCells。此方法对范围进行操作并仅返回与给定条件匹配的那些单元格。在您的情况下,您似乎只对 可见文本 单元格感兴趣。重要的是,它在 Range 上运行,而不是在 HTML 文本上运行。

为了完整起见,我将在下面发布脚本的工作版本。我当然建议您忽略它并重温熊罗恩的出色原作。

Sub Mail_Selection_Range_Outlook_Body()

Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object

Set rng = Nothing
' Only send the visible cells in the selection.

Set rng = Sheets("Sheet1").Range("D4:D12").SpecialCells(xlCellTypeVisible)

If rng Is Nothing Then
    MsgBox "The selection is not a range or the sheet is protected. " & _
           vbNewLine & "Please correct and try again.", vbOKOnly
    Exit Sub
End If

With Application
    .EnableEvents = False
    .ScreenUpdating = False
End With

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


With OutMail
    .To = ThisWorkbook.Sheets("Sheet2").Range("C1").Value
    .CC = ""
    .BCC = ""
    .Subject = "This is the Subject line"
    .HTMLBody = RangetoHTML(rng)
    ' In place of the following statement, you can use ".Display" to
    ' display the e-mail message.
    .Display
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)
' By Ron de Bruin.
    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

    '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

【讨论】:

  • 我已经使用您的代码来满足我的要求并且它工作正常,想知道我是否也可以添加一些电子邮件正文......比如一些文本。我试过 .HTMLBody="Hi, ..." & .HTMLBody=RangetoHTML(rng) 但没用。
  • 在 Ron the Bruin 帖子中得到了答案,谢谢
  • @Vinod 除了宏粘贴的内容之外,您还能在电子邮件正文中添加一些额外的文本吗?
  • 另外,有没有办法让它也复制图像?
  • @synthaxe:您可以按照 Ron the Bruin 的帖子了解如何在电子邮件正文中添加其他文本...除了我现在使用 java 发送电子邮件之外,我不确定如何将图像添加到电子邮件中
【解决方案2】:

通常在 Ron de Bruin 的 RangeToHTML 函数的上下文中提出这个问题,该函数从 Excel.Range 创建一个 HTML PublishObject,通过 FSO 提取它,并将生成的 HTML 流插入到电子邮件的 @987654328 @。这样做会删除默认签名(RangeToHTML 函数有一个辅助函数 GetBoiler 会尝试插入默认签名)。

很遗憾,记录不充分的 Application.CommandBars 方法无法通过 Outlook 使用:

wdDoc.Application.CommandBars.ExecuteMso "PasteExcelTableSourceFormatting"

它将引发运行时 6158:

但是我们仍然可以利用Word.Document 可以通过MailItem.GetInspector 方法访问,我们可以执行类似的操作将选择从Excel 复制并粘贴到Outlook 电子邮件正文,保留您的默认签名(如果有一)。

Dim rng as Range
Set rng = Range("A1:F10") 'Modify as needed

With OutMail
    .To = "xxxxx@xxxxx.com"
    .BCC = ""
    .Subject = "Subject"
    .Display
    Dim wdDoc As Object     '## Word.Document
    Dim wdRange As Object   '## Word.Range
    Set wdDoc = OutMail.GetInspector.WordEditor
    Set wdRange = wdDoc.Range(0, 0)
    wdRange.InsertAfter vbCrLf & vbCrLf
    'Copy the range in-place
    rng.Copy
    wdRange.Paste
End With

请注意,在某些情况下,这可能无法完美保留列宽或在某些情况下保留行高,虽然它还会复制 Excel 范围内的形状和其他对象,但这也可能会导致一些奇怪的对齐问题,但对于简单的表格和Excel范围,很不错:

【讨论】:

  • 如何添加签名?我尝试标准.HTMLBody = myMailBody & .HTMLBody 但看不到签名,你知道为什么吗?也许用这种方法是不可能的?
猜你喜欢
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-26
  • 1970-01-01
相关资源
最近更新 更多