【入門編】【上級者向け】Outlookの「送信トレイ」を監視し、送信失敗したメールを自動再送するエラーリカバリシステム – Outlook VBA解析バイブル

スポンサーリンク

こんにちは!バックオフィスや業務システムの自動化、本当にお疲れ様です。
日々の業務で「Outlookからメールを送ったはずなのに、ネットワークの瞬断で送信トレイに引っかかったままエラーになっていた……」なんて冷や汗をかいた経験はありませんか?

今回は、そんな現場の絶望をスマートに救い出す、「送信トレイを監視し、送信失敗したメールを自動で再送するエラーリカバリシステム」を一緒に作っていきましょう。

「マクロの記録」から一歩進んで、Outlookの裏側の仕組み(オブジェクトのライフサイクル)まで踏み込む、少しリッチで知的な内容です。でも、安心してください。一つひとつ噛み砕いて、優しくエスコートしますね。ここをクリアすれば、あなたのOutlook VBAスキルは間違いなく一段上のステージに到達しますよ!

なぜ「送信トレイの監視」が必要なのか?

私たちがOutlookで「送信」ボタンを押したとき、メールは即座に外の世界へ飛び立つわけではありません。一度「送信トレイ(Outbox)」という一時置き場に格納され、Outlookの送受信エンジンによって順次サーバーへと送り出されます。

しかし、以下のような理由でメールが送信トレイに取り残されることがあります。

  • 送信直後の突発的なWi-Fiの瞬断
  • 添付ファイルの容量オーバーによるタイムアウト
  • サーバー側の一時的な混雑

人間であれば「あ、エラーが出てるな」と気づいて送り直せますが、完全自動化システムや大量送信を行うシーンでは、この「取り残し」を見逃して業務がストップしてしまうのが一番の恐怖です。

ならば、「VBAに送信トレイを監視させ、エラー品を見つけたら優しく背中を押して(再送して)あげればいい」という発想です。

現場でそのまま使える!自動再送システムの全体像

今回のコードは、標準モジュールに記述する「定期実行型」のロジックです。Outlookにはファイル保存時のイベントなどは豊富ですが、送信トレイの監視には「タイマー処理(`Application.OnTime`のような仕組み)」、あるいは手動・ボタン実行、またはアドイン的なアプローチが必要です。

今回は、最も堅牢で実務に組み込みやすい「送信トレイ内の未送信アイテムをスキャンし、一網打尽に再送を試みるプロシージャ」を構築します。

以下のコードを、あなたのOutlookのVBAエディタ(`Alt + F11` で起動)の「標準モジュール」に貼り付けてください。

Option Explicit

‘ ==============================================================================
‘ 【メイン処理】送信トレイをスキャンし、スタック(滞留)しているメールを再送する
‘ ==============================================================================
Public Sub RetryFailedEmails()
Dim ns As Outlook.NameSpace
Dim outboxFolder As Outlook.MAPIFolder
Dim mailItems As Outlook.Items
Dim targetItem As Object
Dim mailItem As Outlook.MailItem
Dim retryCount As Long

‘ セッションの取得
Set ns = Application.GetNamespace(“MAPI”)

‘ 「送信トレイ」フォルダを取得
‘ ※言語環境(日本語)に依存するため olFolderOutbox を使用するのが安全です
Set outboxFolder = ns.GetDefaultFolder(olFolderOutbox)
Set mailItems = outboxFolder.Items

‘ 送信トレイが空なら終了
If mailItems.Count = 0 Then
Debug.Print “送信トレイは空です。異常なし。”
Exit Sub
End If

retryCount = 0

‘ 逆順ループ(コレクションの削除や状態変更を伴う処理の鉄則!)
Dim i As Long
For i = mailItems.Count To 1 Step -1
Set targetItem = mailItems(i)

‘ アイテムがMailItem(メール)であるか厳密に型チェック
If TypeOf targetItem Is Outlook.MailItem Then
Set mailItem = targetItem

‘ 【重要】ここで「送信エラーになっているか」を判定します
‘ 送信トレイにあるメールのうち、一度送信試行されてフラグが変わったものや、
‘ 特定の条件に合致するものを捕捉します。
‘ 今回はシンプルに「送信トレイに留まり続けている未送信メール」を対象とします。

On Error GoTo ErrorHandler

‘ 再送のアプローチ:
‘ 一度「未送信(オフライン作業中など)」の状態をリフレッシュし、送信アクションを再トリガーします。
‘ Outlookのオブジェクトモデルでは、送信トレイ内のアイテムの .Send メソッドを
‘ もう一度叩くことで、送信キューの最先尾に再登録させることができます。

mailItem.Send
retryCount = retryCount + 1
Debug.Print “再送実行: ” & mailItem.Subject

End If
NextItem:
Next i

If retryCount > 0 Then
MsgBox retryCount & ” 件のスタックメールに対して再送処理を実行しました。”, vbInformation, “リカバリシステム”
Else
Debug.Print “再送対象のメールはありませんでした。”
End If

Exit Sub

ErrorHandler:
‘ 個別のメールでエラーが発生した場合でも、ループを止めずに次へ進む
Debug.Print “エラー発生(スキップします): ” & Err.Description
Resume Next
End Sub

コードの深掘り:ここがエンジニアのこだわりポイント

初心者から一歩抜け出すために、上記のコードに隠された「プロの知見」を3つ解説します。ここさえ押さえれば、他のVBAコードも見違えるほど安定しますよ。

1. コレクション操作の鉄則「逆順ループ」

For i = mailItems.Count To 1 Step -1

通常、`For Each` や `1 To Count` で上から順にアイテムを操作すると、アイテムを送信(移動)した瞬間にインデックスの番号がズレてしまい、「処理漏れ」や「実行時エラー」を引き起こします。
末尾から先頭に向かって数える「逆順ループ(Step -1)」を使うことで、配列のズレに影響されない強靭なループ構造が完成します。これは実務の鉄則です。

2. 安全な型チェック (`TypeOf … Is`)

送信トレイには、通常のメール(MailItem)だけでなく、会議の返信やレポートなど、様々なオブジェクトが紛れ込む可能性があります。
`TypeOf targetItem Is Outlook.MailItem` で厳密にフィルタリングすることで、「予期せぬオブジェクトでプロパティエラーが起きた…」という現場の悲劇を未然に防ぎます。

3. エラーハンドリングの局所化 (`Resume Next`)

大量のメールを処理する際、1通の壊れたメールのせいでマクロ全体が止まってしまうのは最悪です。
`On Error GoTo ErrorHandler` をループ内に配置し、問題のあるメールはログ(`Debug.Print`)に残しつつ、次のメールの救出劇へ華麗にシフトする構造にしています。

陥りやすい罠とアドバイス

実際にこのシステムを運用する際、以下の罠に気をつけてください。

  • ネットワークの回復を待つ:

完全にオフラインの状態でこのマクロを走らせても、当然メールは飛びません。もし完全自動化を目指すなら、VBAからWindowsのAPIを叩いてインターネット接続を確認するロジックを前段に挟むと、さらに「神システム」に近づきます。

  • セキュリティ警告の壁:

Outlook VBAからプログラムで `.Send` を実行する際、セキュリティソフトやOutlookの仕様によっては「プログラムがメールを送信しようとしています」というポップアップが出る場合があります。これは組織のセキュリティポリシー(グループポリシー)に依存するため、事前に管理部門と相談するか、信頼できるアドインとして署名を行う必要があります。

おわりに

お疲れ様でした!今回はOutlookの「送信トレイ」という、普段あまり触れない深部をVBAでコントロールする方法を解説しました。

「エラーを検知して、自動でリカバリする」。
この発想が実装できるようになると、あなたの作るツールは単なる「お助けマクロ」から、現場を24時間守り抜く「堅牢な業務システム」へと生まれ変わります。

もし実装でつまづいたり、「もっとこういう自動化がしたい!」というリクエストがあれば、いつでも先輩エンジニアに聞いてくださいね。あなたのVBAライフを、これからも応援しています!

タイトルとURLをコピーしました