使用 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”)粘贴到邮件正文中?