【Outlook VBA】メール保存で「操作は失敗しました」のエラーが出る原因と対策
メールアイテムの「SaveAsメソッド」を使うと「操作は失敗しました」というエラーが起こることがあります。
このエラーが起こる原因は主に次の2つです。
- 保存フォルダのパスが間違っている
- ファイル名に使用できない文字が含まれている
それぞれについて解説しますので、エラーに悩んでいる方は確認してみてください。
1.保存フォルダのパスが間違っている
これは単純に「SaveAsメソッド」で指定するパス名が間違っている場合です。
mllItem.SaveAs "C:filename.msg"
例えば、このようなパス名を指定するとエラーとなります。.
mllItem.SaveAs "C:\filename.msg"
正しくはこのようにフォルダ名の後に「\」マークを付ける必要があります。
フォルダパスを変数などにしていると「\」マークを忘れがちなので、一度パスを表示して正しいパスになっているか確認してみてください。
2.ファイル名に使用できない文字が含まれている
他にエラーが発生しやすいのはファイル名に使用できない文字が含まれているケースです。
/, :, *, ?, <, >, |
このような半角文字列はファイル名に使用することができません。
そのため、このようなファイル名で「SaveAsメソッド」を使おうとするとエラーが発生します。
例えば↓のようなプログラムを使用していると、メールの件名によってエラーが発生します。
Sub SaveMailError()
'選択中のメールをドキュメントフォルダに保存
'ドキュメントフォルダのパスを取得
Dim wsh As Object, strDocPath As String
Set wsh = CreateObject("WScript.Shell")
strDocPath = wsh.SpecialFolders("MyDocuments")
'選択中のメールアイテムオブジェクトを取得
Dim mllItem As Outlook.MailItem
Set mllItem = GetCurrentItem
If mllItem Is Nothing Then Exit Sub
'メールタイトルを取得
Dim strFileName As String
strFileName = mllItem.Subject
'メールを保存(ここでエラーが起こる)
mllItem.SaveAs strDocPath & "\" & strFileName & ".msg"
End Sub
Private Function GetCurrentItem() As Object
'選択中のメールアイテムオブジェクトを返す
On Error Resume Next
Select Case TypeName(Application.ActiveWindow)
Case "Explorer" 'Outlookのメインウィンドウがアクティブ
Set GetCurrentItem = Application.ActiveExplorer.Selection.Item(1)
Case "Inspector" 'Outlookのメールウィンドウがアクティブ
Set GetCurrentItem = Application.ActiveInspector.CurrentItem
End Select
End Function
このプログラムでは選択中のメールをドキュメントフォルダに保存しています。
そして、注意するべきポイントはメールタイトルをファイル名に使用している点です。
'メールタイトルを取得
Dim strFileName As String
strFileName = mllItem.Subject
'メールを保存(ここでエラーが起こる)
mllItem.SaveAs strDocPath & "\" & strFileName & ".msg"
この部分ですが、保存するときのファイル名にメールタイトル(strFileName)を使用しています。
つまり、メールタイトルに使用できない文字が含まれているとエラーが発生します。
《ドキュメントフォルダのパス取得については下記記事参照》
対策:ファイル名に使用できない文字を変換
Sub SaveMailNoError()
'アクティブなメールをドキュメントフォルダに保存
'ドキュメントフォルダのパスを取得
Dim wsh As Object, strDocPath As String
Set wsh = CreateObject("WScript.Shell")
strDocPath = wsh.SpecialFolders("MyDocuments")
'アクティブなメールオブジェクトを取得
Dim mllItem As Outlook.MailItem
Set mllItem = GetCurrentItem
If mllItem Is Nothing Then Exit Sub
'メールタイトルを取得
Dim strFileName As String
strFileName = mllItem.Subject
'ファイル名に使用できない文字列を置換
Dim arrNG As Variant: arrNG = Array("/", ":", "*", "?", Chr(34), "<", ">", "|")
Dim arrOK As Variant: arrOK = Array("/", ":", "*", "?", """, "<", ">", "|")
Dim i As Long
For i = LBound(arrNG) To UBound(arrNG)
strFileName = Replace(strFileName, arrNG(i), arrOK(i))
Next
'メールを保存
mllItem.SaveAs strDocPath & "\" & strFileName & ".msg"
End Sub
Private Function GetCurrentItem() As Object
'選択中のメールアイテムオブジェクトを返す
On Error Resume Next
Select Case TypeName(Application.ActiveWindow)
Case "Explorer" 'Outlookのメインウィンドウがアクティブ
Set GetCurrentItem = Application.ActiveExplorer.Selection.Item(1)
Case "Inspector" 'Outlookのメールウィンドウがアクティブ
Set GetCurrentItem = Application.ActiveInspector.CurrentItem
End Select
End Function
このようなプログラムを使用すれば、メールタイトルによるエラーが発生しません。
'ファイル名に使用できない文字列を置換
Dim arrNG As Variant: arrNG = Array("/", ":", "*", "?", Chr(34), "<", ">", "|")
Dim arrOK As Variant: arrOK = Array("/", ":", "*", "?", """, "<", ">", "|")
Dim i As Long
For i = LBound(arrNG) To UBound(arrNG)
strFileName = Replace(strFileName, arrNG(i), arrOK(i))
Next
対策しているのはこの箇所で使用できない文字を全角文字へ変換しています。
このような変換を間に挟むことによりエラーを回避することができます。