使用 VBA 方法Attachment.SaveAsFile()调用将文件附件保存在 Outlook 邮件项中会产生预期的结果(文件以相同文件名保存在文件系统上),即使文件名带有non-ASCII字符也是如此。

但是,VBA 显然以16-bit 复合格式 String的格式存储文件名,其中带重音字母的存储为(字母,重音)对。我找不到一种在消息正文中输出带有重音字母的字符串的方法,该重音字母显示为一个字形(“é”)而不是两个字形(“ e´”)。

具体来说,使用以下代码时,附件将以正确的文件名正确保存在磁盘上:

' Save the Outlook attachment
oAttachment.SaveAsFile (sTempFileLocation)

这导致文件被写入sTempFileLocation中指定的文件夹,并且文件名与 Outlook 消息中的显示方式(重音,non-ASCII 字符等)相符。

但是,在检索和操作文件名时,似乎使用了特殊字符的 16-bit 复合内部表示形式。这意味着文件名**“àprésent.txt”显示为“ a` pre_sent.txt”**(带重音的字符用 2 个连续字节中的重音字符表示)。

例如:

sAttachmentName = fso.getfilename(sTempFileLocation)
Debug.Print ("Attachment name = [" & sAttachmentName & "]")

将导致:

Attachment name = [a` pre´sent.txt]

关于此问题的信息很少,到目前为止,我发现的只是此 MSDN 链接描述了MultiByteToWideChar()函数。从那里看来,16-bit 内部 VBA 渲染是隐式发生的,甚至与计算机有关(取决于所使用的代码页和语言环境)。

以下是一个 self-contained 简约示例,该示例尝试将第一条选定消息的电子邮件附件保存到您的“我的文档”文件夹中,除非该附件已经存在:

Sub SaveMessageAttachments()
    Dim objApp As Outlook.Application
    Dim oSelection As Outlook.Selection
    Dim aMail As Outlook.MailItem
    Dim fso As Object

    On Error Resume Next
    ' Instantiate an Outlook Application object.
    Set objApp = CreateObject("Outlook.Application")
    ' Get the collection of selected objects.
    Set oSelection = objApp.ActiveExplorer.Selection

    If oSelection Is Nothing Then
        Exit Sub
    End If

    ' Select the 1st mail item in the current selection
    Set aMail = oSelection.item(1)

    Dim sAttachmentFolder  As String
    ' Get the path to your "My Documents" folder
    sAttachmentFolder = CreateObject("WScript.Shell").SpecialFolders(16)

    Set fso = CreateObject("Scripting.FileSystemObject")

    Dim oAttachments As Outlook.Attachments
    Dim lItemAttachmentCount As Long

    Set oAttachments = aMail.Attachments
    lItemAttachmentCount = oAttachments.Count

    If (lItemAttachmentCount > 0) Then
        Dim lAttachmentIndex As Long
        For lAttachmentIndex = 1 To lItemAttachmentCount
            Dim oAttachment As Outlook.attachment
            Set oAttachment = oAttachments.item(lAttachmentIndex)
            Dim sFileName As String
            sFileName = oAttachment.FileName
            If LenB(sFileName) > 0 Then
                Dim sFilePath As String
                sFilePath = sAttachmentFolder & "\" & sFileName
                If fso.fileexists(sFilePath) Then
                    MsgBox "Cannot save attachment " & lAttachmentIndex & vbCr _
                        & "File already exists: " & vbCr _
                        & sFilePath, vbExclamation + vbOKOnly
                Else
                    If MsgBox("Saving atachment " & lAttachmentIndex & "?" & vbCr _
                        & "Save location: " & vbCr & sFilePath, _
                        vbQuestion + vbOKCancel) = vbOK Then
                        ' Save the attachment to the temporary folder
                        oAttachment.SaveAsFile (sFilePath)
                        Dim sAttachmentName As String
                        sAttachmentName = fso.getfilename(sFilePath)

                        Dim lAttachmentLength As Long
                        lAttachmentLength = fso.getfile(sFilePath).size

                        Dim sURL As String
                        sURL = "file://" & Replace(sFilePath, "\", "/")

                        MsgBox "Attachment " & lAttachmentIndex _
                            & " saved as: " & sAttachmentName & vbCr _
                            & "Size: " & lAttachmentLength & vbCr _
                            & "URL = " & sURL, _
                            vbInformation + vbOKOnly
                    End If
                End If
            End If
        Next lAttachmentIndex
    End If
End Sub

如您所见,SaveMessageAttachments()子例程使用正确的文件名将文件正确保存到文件系统中。但是,Outlook 对话框(以及尝试将附件文件名或 URL 写入 VBA 中的邮件正文时)将始终使具有重音符号的文件名呈现。请尝试使用带有名为 e.g 的附件的 Outlook 消息进行尝试。 “àprésent.txt”)。

但是,奇怪的是,如果我尝试将sURL粘贴到邮件正文中,尽管 URL 的书写不正确(重音字母的 2 个字符分解),Outlook 似乎可以找到并打开文件。

如何使用 VBA 转换此带重音符号的字符串(sAttachmentName)以便正确地将其(“àprésent.txt”而不是“ a` pre_sent.txt”)粘贴到邮件正文中?