简体   繁体   English

使用Excel VBA从Outlook发送富文本电子邮件

[英]Sending rich text email from Outlook using Excel VBA

I am using the following (piece of) code in a macro to send outlook emails using Excel VBA. 我在宏中使用以下(部分)代码来使用Excel VBA发送Outlook电子邮件。

Function send_mail_rich_text(ByVal send_to As String, ByVal mail_subject As String, ByVal mail_content As Range, ByVal cc_list As String, ByVal bcc_list As String, ByVal rr As String) As String

Set psht = ActiveSheet

Err.Number = 0

If LCase(rr) = "yes" Then
    rr_boo = True
Else
    rr_boo = False
End If

Set oOlApp = CreateObject("Outlook.Application")

olMailItem = 0
Set oOlMItem = oOlApp.CreateItem(olMailItem)

'get Excel cell range which shall be in the mail
Set oWB = ActiveWorkbook
Set oWS = Range("mail.content").Worksheet
oWS.Activate
Set oRange = mail_content

oRange.Copy ' Range is now in Clipboard

On Error Resume Next

Dim oWdDoc As Object

With oOlMItem
    '.Display
    .To = send_to
    .CC = cc_list
    .BCC = bcc_list
    .Subject = mail_subject
    .ReadReceiptRequested = rr_boo

    Set oOlInsp = .GetInspector
    Set oWdDoc = oOlInsp.WordEditor ' get Word Document from the MailBody
    olFormatRichText = 3
    .bodyformat = olFormatRichText ' change to RichTextFormat

    Set oWdRng = oWdDoc.Paragraphs(oWdDoc.Paragraphs.Count).Range        
    oWdRng.Paste ' paste Excel range from Clipboard

    Set oWdRng = oWdDoc.Paragraphs(oWdDoc.Paragraphs.Count).Range

    .send

End With

Application.CutCopyMode = False

If Err.Number <> 0 Then
    save_mail_rich_text = "error"
Else
    save_mail_rich_text = "sent"
End If

psht.Activate

End Function

However, I get can a compile error on the line " Set oWdDoc = oOlInsp.WordEditor ". 但是,在“ Set oWdDoc = oOlInsp.WordEditor ”行上出现编译错误。 Error says " Function call on the left-hand side of assignment must return Variant or Object ". 错误显示“ Function call on the left-hand side of assignment must return Variant or Object ”。 Further, the strange part is that I have two macros with the exact same code except that one sends and the other saves draft. 此外,奇怪的是我有两个具有完全相同代码的宏,除了一个宏发送而另一个保存草稿。 The compilation error occurs only in case of send macro. 仅在发送宏的情况下才会发生编译错误。 What I am missing here? 我在这里想念的是什么?

Please try this: 请尝试以下方法:

Function send_mail_rich_text(ByVal send_to As String, ByVal mail_subject As String, _
    ByVal mail_content As Range, ByVal cc_list As String, ByVal bcc_list As String, _
    ByVal rr As Boolean) As String

    Dim oOlApp As Object    ' Outlook.Application
    Dim oOlMItem As Object  ' Outlook.MailItem
    Dim oWdDoc As Object    ' Word.Document

    Err.Clear

    Set oOlApp = CreateObject("Outlook.Application")
    Set oOlMItem = oOlApp.CreateItem(olMailItem)

    ' Range can be copied directly as given as Range via function call
    mail_content.Copy

    ' On Error Resume Next   ' activate it after debugging
    With oOlMItem
        .To = send_to
        .CC = cc_list
        .BCC = bcc_list
        .Subject = mail_subject
        .ReadReceiptRequested = rr ' can be used directly if given as boolean
        .BodyFormat = 3 ' 3=RichTextFormat

        Set oWdDoc = .GetInspector.WordEditor

        ' by this you paste below your signature
        ' oWdDoc.Paragraphs(oWdDoc.Paragraphs.Count).Range.Paste

        ' by these alternatives you paste before your signature
        oWdDoc.Range(oWdDoc.Content.Start, oWdDoc.Content.Start).Paste
        oWdDoc.Bookmarks("\StartOfDoc").Range.Paste

        .Display ' change to .Send after debugging
    End With

    Application.CutCopyMode = False

    If Err.Number <> 0 Then
        send_mail_rich_text = "error"
    ElseIf oOlMItem.Sent = True Then
        send_mail_rich_text = "sent"
    Else
        send_mail_rich_text = "no error, but not sent"
    End If
End Function

As ReadReceiptRequested is expected as boolean, I changed it within the function call. 由于ReadReceiptRequested应该为布尔值,因此我在函数调用中对其进行了更改。 Be aware to change your calls to this function accordingly. 请注意相应地更改对此函数的调用。 I tested it with this: 我对此进行了测试:

Private Sub TestSendmailFunction()
    Debug.Print send_mail_rich_text("to@test.com", "Test", ActiveSheet.Range("B2:C3"), _
        "cc@test.com", "bcc@test.com", False)
End Sub

It is not necessary to switch to another sheet and later back to the previous one as you give "mail_content" as range. 当您将“ mail_content”设置为范围时,不必切换到另一张纸,也不必稍后再回到上一张纸。 A range can be copied directly also from non-active sheets. 范围也可以直接从非活动工作表中复制。

You should use Option Explicit at the beginning of every VBA module to prevent errors like "send_mail_rich_text" vs. "save_mail_rich_text" or unknown objects like oWdRng. 您应该在每个VBA模块的开头使用Option Explicit ,以防止类似“ send_mail_rich_text”和“ save_mail_rich_text”之类的错误或诸如oWdRng之类的未知对象。

You can combine commands if you don't need the object again: Instead of Set oWdRng = ... and oWdRng.Paste you can use the whole part: ....Paste . 如果您不再需要该对象,则可以组合命令:代替Set oWdRng = ...oWdRng.Paste ,可以使用整个部分: ....Paste

If you can add a reference to "Microsoft Excel xx Object Library" and "Microsoft Word xx Object Library" then you can exchange Object by eg Outlook.Mailitem to provide more debugging features by "early binding". 如果可以添加对“ Microsoft Excel xx对象库”和“ Microsoft Word xx对象库”的引用,则可以通过例如Outlook.Mailitem交换Object ,以通过“早期绑定”提供更多调试功能。 Then also the predefinded constants as olFormatRichText (from internal ENUM OlBodyFormat) are known and can be used directly. 然后,预定义的常量olFormatRichText (来自内部ENUM OlBodyFormat)也是已知的,可以直接使用。

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

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