Outlook VBA用文本替换内联对象

时间:2014-05-23 08:24:49

标签: vba outlook email-attachments

我的收件箱中有一封电子邮件,其中包含内联对象(例如图片)。我想删除它,并在电子邮件的同一点插入文本。

我尝试了两种方法:

  1. 处理Dim objAttachment As Outlook.Attachment的对象。我尝试使用Position方法,但问题是它始终返回0,无论对象的位置如何(以及它是否为内联或"附件栏& #34;。)

  2. 处理Dim shp As Word.InlineShape的对象。我可以使用shp(和Set shpRange = objDoc.Range(shp.Range.Characters.First.Start, shp.Range.Characters.Last.End)确定Dim objDoc As Word.Document的位置;感谢an answer below)。我尝试以三种方式修改objDoc

    2.1。 shpRange.InsertAfter "Replacement Text 1"

    2.2。 shpRange.Text = "Replacement Text 2"

    2.3。 objDoc.Characters(1).InsertBefore "New Text"

    问题是他们都没有修改电子邮件。

  3. 到目前为止,我已将方法1与objMsg.HTMLBody = <mytext> + objMsg.HTMLBody一起使用,然后使用objMsg.Save。但这会在开头添加文字。

    PS:当一个人回复带有内嵌对象的电子邮件时,它有时会被对象位置的文本替换(我无法确定何时完成)。也许MS不提供完成相同功能。


    编辑(额外的详细信息,最初不包括在内以避免tl; dr)

    注意:

    1. 我目前使用的代码基于a post by Nicola Delfino。它使用objMsg.HTMLBody,见下文。 从好的方面来说,它找到了大多数内联附件/对象(有些是遗漏的),而且所有内容都在&#34;附件栏中#34; (我不知道它的正式名称)。 在不利方面,它无法区分内联和#34; bar-attached&#34;项目,它无法获取找到的内联对象的位置。所以我只在邮件正文的开头添加文本。

    2. 我看到我试过的任何电子邮件的问题。例如,我创建了一封电子邮件,并插入了Insert -> Picture的图片。发送电子邮件后,我使用了Sent Items文件夹中的电子邮件。

    3. 我附上了用于测试的示例电子邮件的图片。 enter image description here

    4. 可能是objMsg.HTMLBody永远无法工作的情况,并且在阅读this official page for Outlook 2007之后我应该使用WordEditor: &#34; 17.5使用WordEditor Outlook对象模型本身不提供确定项目主体中光标位置的直接方法。但是,由于每个项目主体的编辑器(“便笺”和分发列表除外)都是Microsoft Word的特殊版本,因此您可以使用Word技术不仅在插入点添加文本,还可以在任何地方添加格式化文本在项目中,甚至添加图片。&#34;

    5. 可能相关的链接:

    6. How do I get the selected text from a WordEditor Object and change it's color?

      Deletion of InlineShape does not work for RTF mails

      我的代码:

          Public Sub StripAttachments()
              'Put in the folder location you want to save attachments to
              Dim strFolder As String
              strFolder = "removed_attachments"
              Dim ilocation As String
              ilocation = GetSpecialFolder(&H5) & "\" & strFolder ' CSIDL_MY_DOCUMENTS As Long = &H5"
              On Error Resume Next
              ilocation = ilocation & "\"
      
              ' Instantiate an Outlook Application object.
              Dim objOL As Outlook.Application
              Set objOL = Application
              ' Get the collection of selected objects.
              Dim objSelection As Outlook.Selection
              Set objSelection = objOL.ActiveExplorer.Selection
      
              'Dim objMsg As Object
              Dim objMsg As Outlook.MailItem
              ' Check each selected item for attachments. If attachments exist, save them to the selected
              ' folder and strip them from the item.
              For Each objMsg In objSelection
                  ' This code only strips attachments from mail items.
                  If (objMsg.Class = olMail) Then
                      Dim objInsp As Outlook.Inspector
                      Set objInsp = objMsg.GetInspector
                  Dim objDoc As Word.Document
                  Set objDoc = objInsp.WordEditor
      
                      ' Get the Attachments collection of the item.
                      Dim objAttachments As Outlook.attachments
                      Set objAttachments = objMsg.attachments
                      Dim lngCount As Long
                      lngCount = objAttachments.Count
                      If lngCount > 0 Then
                          ' We need to use a count down loop for removing items from a collection. Otherwise,
                          ' the loop counter gets confused and only every other item is removed.
                          Dim strFile As String
                          strFile = ""
      
                          Dim I As Long
                          For I = lngCount To 1 Step -1
                              ' Save attachment before deleting from item.
                              ' Get the file name.
                              Dim objAttachment As Outlook.Attachment
                              Set objAttachment = objAttachments.item(I)
      
                              Dim strHTML As String
                              strHTML = "<li><a href=" & Chr(34) & "file:" & ilocation & objAttachment.FileName & Chr(34) _
                                & ">" & objAttachment.FileName & "</a><br>" & vbCrLf
                              strFile = strFile & strHTML
      
                              Dim attPos As Long
                              attPos = objAttachment.Position
                              ' Save the attachment as a file
                              objAttachment.SaveAsFile (ilocation & objAttachments.item(I))
                              ' Remove the attachment
                              objAttachment.Delete
                              ' Replace with text and hyperlink
                              'strFile = "Attachments removed from the message and backed up to [<a href='" & ilocation & "'>" & ilocation & "</a>]:<br><ul>" & strFile & "</ul><hr><br><br>" & vbCrLf & vbCrLf
                          Next I
      
                          strFile = "Attachments removed from the message and backed up to [<a href='" & ilocation & "'>" & ilocation & "</a>]:<br><ul>" & strFile & "</ul><hr><br><br>" & vbCrLf & vbCrLf
                          objDoc.Characters(1).InsertBefore strFile  ' Does nothing!
                          objMsg.HTMLBody = strFile + objMsg.HTMLBody
                          objMsg.Save
                      Else
                          msgbox ("No attachments were found in the selected email")
                      End If
                  Else
                      msgbox ("Selection is not of type olMail")
                  End If
              Next
      
          ExitSub:
              Set objAttachments = Nothing
              Set objMsg = Nothing
              Set objSelection = Nothing
              Set objOL = Nothing
          End Sub
      

1 个答案:

答案 0 :(得分:1)

如果我没记错的话,WordEditor基本上是一个单词Document,所以你应该可以做类似的事情(在Word中测试,可能需要调整Outlook),假设一个对象变量就像doc代表Document

修订版&amp;在Outlook 2010中测试

Dim shp as InlineShape
Dim doc as Object `Word.Document
Dim shpRange as Object `Word.Range
Const wdInlineShapePicture as Long = 3
Const wdInlineShapesEmbeddedOLEObject as Long = 1
Set doc = objMsg.GetInspector.WordEditor
For Each shp In doc.InlineShapes
    Select Case shp.Type 
        Case wdInlineShapePicture, wdInlineShapesEmbeddedOLEObject
            '## Assign a range object with the text position of the shape
            Set shpRange = doc.Range(shp.Range.Characters.First.Start, _
                                  shp.Range.Characters.Last.End)
            '## Replace the shape with text:
            shpRange.Text = "Replacement Text"
        Case Else
            '## Do something else for other shape types, etc.
      End Select

Next

这是一个处理传入邮件项目的示例宏,并用文本替换嵌入的图像。请注意UnProtect文档的需要:

Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
    Dim arr() As String
    Dim i As Integer
    Dim m As MailItem
    '## Word objects, using late-binding (or enable reference to MS Word)
    Dim shp As Object 'Word.InlineShape
    Dim doc As Object 'Word.Document
    Dim shpRange As Object 'Word.Range
    '## Establish some word constants for use with late-binding
    Const wdInlineShapePicture As Long = 3
    Const wdInlineShapeEmbeddedOLEObject As Long = 1
    Const wdInlineShapeLinkedPicture As Long = 4

    arr = Split(EntryIDCollection, ",")
    For i = 0 To UBound(arr)
        Set m = Application.Session.GetItemFromID(arr(i))
        Set doc = m.GetInspector.WordEditor
        doc.UnProtect
        For Each shp In doc.InlineShapes
            Select Case shp.Type
                Case wdInlineShapePicture, _
                     wdInlineShapeEmbeddedOLEObject, _
                     wdInlineShapeLinkedPicture

                    '## Assign a range object with the text position of the shape
                    Set shpRange = doc.Range(shp.Range.Characters.First.Start, _
                                              shp.Range.Characters.Last.End)
                    '## Replace the shape with text:
                    shpRange.Text = "Replacement Text"
                Case Else

            End Select
        Next
    Next
End Sub