こんにちは!先輩エンジニアのボクです。
日々の業務で、取引先や社内から送られてくる巨大な添付ファイルに頭を悩ませたことはありませんか?「うっかり容量オーバーのメールを送ってしまい、メールサーバーがパンクした……」「セキュリティポリシーにひっかかって業務が止まった……」なんて事故は、エンジニアなら一度は耳にする悲劇です。
今回は、そんなインフラ事故を未然に防ぐための「受信メールの添付ファイルサイズを監視し、制限を超えていたら自動で送信者へ警告を飛ばすエージェント」をOutlook VBAで一緒に作っていきましょう。
「マクロの記録」から一歩抜け出して、Outlookのイベント駆動型プログラム(裏側で自動で動き続ける仕組み)を完全に手なずけるための極意を、優しく、そして骨太に解説していきますよ。ここをクリアすれば、あなたのOutlook VBAスキルは間違いなく中級者の領域に突入します!
—
1. 開発の全体像と「Outlookイベント」の正体
まず、私たちがこれから作る仕組みの全体像を把握しましょう。
多くの人が知っているExcelマクロは「ボタンを押したら動く」受動的なものですよね。しかし、Outlook VBAの真骨頂は「イベント(出来事)をトリガーにして自律稼働する」点にあります。
今回は、受信トレイに新しいメールが届いた瞬間に発火する `Application_NewMailEx` というイベントを使用します。
[メール受信]
↓ (自動検知)
[NewMailEx イベント発生]
↓
[添付ファイルのサイズを合計計算]
↓
├─ 規定値以内 ──→ 何もしない(スルー)
└─ 規定値超過 ──→ 【警告メールを自動返信】
この流れをコードで美しく、かつ安全に組み立てていきます。
—
2. 準備:どこにコードを書くのか?
ここがつまずきポイントの第1関門です。通常の標準モジュール(「標準モジュールを挿入」して書く場所)ではなく、Outlook特有の特別な場所にコードを書く必要があります。
1. Outlookを開き、`Alt + F11` キーを押してVBE(Visual Basic Editor)を開きます。
2. 左側のプロジェクトツリーにある `ThisOutlookSession` をダブルクリックしてください。
3. 以下のコードをそのまま貼り付けます。
※ `ThisOutlookSession` に書くことで、Outlookが起動している間、常に裏側でメールの到着を監視し続ける「エージェント」として機能するようになります。
—
3. 実装コード:制限超過チェッカー&警告返信エージェント
それでは、現場でそのまま使える実用的なコードを公開します。コード内のコメントをしっかりと読みながら進めてください。
Option Explicit
‘ ==============================================================================
‘ 【定数定義】 運用ルールに合わせて変更してください
‘ ==============================================================================
Private Const MAX_TOTAL_SIZE_MB As Double = 10# ‘ 添付ファイルの許容上限(MB)
Private Const WARNING_SUBJECT As Double = 0 ‘ (ダミー定義:拡張用)
‘ ==============================================================================
‘ イベントプロシージャ: 新着メールを受信した瞬間に自動実行される
‘ ==============================================================================
Private Sub Application_NewMailEx(ByVal EntryIDCollection As String)
On Error GoTo ErrorHandler
Dim vEntryIDs As Variant
Dim vID As Variant
Dim objItem As Object
Dim ns As Outlook.NameSpace
Set ns = Application.GetNamespace(“MAPI”)
‘ NewMailExは、複数のメールが同時に届いた場合、カンマ区切りの文字列でIDを返す仕様
vEntryIDs = Split(EntryIDCollection, “,”)
For Each vID In vEntryIDs
‘ EntryIDから実際のメールオブジェクトを取得
Set objItem = ns.GetItemFromID(vID)
‘ 取得したアイテムが「メール(MailItem)」であるかを厳密に判定
If TypeName(objItem) = “MailItem” Then
Call CheckAttachmentSize(objItem)
End If
Next vID
CleanUp:
Set objItem = Nothing
Set ns = Nothing
Exit Sub
ErrorHandler:
MsgBox “添付ファイル監視エージェントでエラーが発生しました: ” & Err.Description, vbCritical, “エラー”
Resume CleanUp
End Sub
‘ ==============================================================================
‘ コアロジック: 添付ファイルサイズの計算と警告メールの返信
‘ ==============================================================================
Private Sub CheckAttachmentSize(ByVal targetMail As Outlook.MailItem)
Dim objAttachment As Outlook.Attachment
Dim totalSizeByte As Double
Dim totalSizeMB As Double
Dim replyMail As Outlook.MailItem
Dim warningBody As String
totalSizeByte = 0
‘ 添付ファイルがない場合は処理を終了(無駄な走査を避けるパフォーマンス配慮)
If targetMail.Attachments.Count = 0 Then Exit Sub
‘ 添付ファイルの合計サイズ(バイト)を計算
For Each objAttachment In targetMail.Attachments
‘ ※注意: メールの本文にインライン埋め込みされた画像などもAttachmentに含まれます
‘ 必要に応じて除外ロジックを入れるとより堅牢になります
totalSizeByte = totalSizeByte + objAttachment.Size
Next objAttachment
‘ バイトをメガバイト(MB)に変換 (1MB = 1024 1024 バイト)
totalSizeMB = totalSizeByte / (1024 1024)
‘ 規定値を超過しているか判定
If totalSizeMB > MAX_TOTAL_SIZE_MB Then
‘ 返信メール(ReplyAll または Reply)の作成
Set replyMail = targetMail.Reply
‘ 警告メッセージの構築
warningBody = “【自動警告通知】” & vbCrLf & _
“送信されたメールの添付ファイル総容量が、社内規定の上限(” & MAX_TOTAL_SIZE_MB & “MB)を超過しています。” & vbCrLf & _
“現在の添付ファイル合計容量: ” & Format(totalSizeMB, “0.00”) & ” MB” & vbCrLf & vbCrLf & _
“大容量ファイルを送信する場合は、セキュアなファイル共有ストレージを利用するか、” & _
“ファイルを分割して再送してください。” & vbCrLf & _
“————————————————–” & vbCrLf & _
targetMail.Body
With replyMail
.Subject = “【警告】添付ファイル容量が上限を超えています (” & Format(totalSizeMB, “0.00”) & “MB)”
.Body = warningBody
‘ 現場の安全のため、最初はテストとして送信(.Send)ではなく画面表示(.Display)にすることを強く推奨します!
.Send ‘ 本番稼働時は自動送信
End With
‘ 監査ログやフラグ付け(必要に応じて)
targetMail.UnRead = False ‘ 既読にするなど
targetMail.Save
End If
CleanUp:
Set objAttachment = Nothing
Set replyMail = Nothing
End Sub
—
4. プロの視点:陥りやすい罠と「知見」の共有
ここで、実務でこのコードを動かす際に必ず直面する「罠」と、その回避策をいくつかシェアしておきます。
① インライン画像(署名のロゴなど)の罠
Outlookの仕様上、メールの署名に入っている会社ロゴの画像や、本文中に貼り付けられたスクリーンショットも「添付ファイル (`Attachments`)」としてカウントされます。
もし「本当はファイルを添付していないのに、署名の画像のせいで警告が飛んでしまった!」という事態を防ぎたい場合は、`objAttachment.FileName` の拡張子や、プロパティをチェックして除外するフィルター処理を組み込むのがプロの技です。
② 無限ループの恐怖(自爆メールに注意)
最も恐ろしいのは、「自分が自動送信した警告メール」に対して、再びこのマクロが反応してしまい、警告メールに警告メールを返す無限ループ(メールの爆撃)を引き起こすことです。
今回は `targetMail.Reply` を使っており、返信メールは通常の受信トレイに直接入るわけではないため比較的安全ですが、厳密な運用を行う場合は、送信者のメールアドレスが自分自身(ボット自身)でないか、あるいは件名に「【警告】」が含まれている場合は即座に処理を抜ける(Guard Clause)条件式を追加してください。
③ セキュリティ警告とマクロの有効化
Outlookのデフォルト設定では、外部からのマクロや、VBAからの自動メール送信(`.Send`実行時)の際に、「プログラムがあなたに代わってメールを送信しようとしています。許可しますか?」という鬱陶しいポップアップが出るか、あるいはブロックされます。
これに対処するため、社内利用であれば信頼できる場所(信頼済みドキュメント)に設定するか、グループポリシーでの調整が必要になる点を頭に入れておきましょう。最初は `.Send` ではなく `.Display`(画面に下書きとして表示する)にして動作確認をすることをおすすめします。
—
まとめ
今回は、Outlook VBAを使った「添付ファイル監視・警告返信エージェント」の構築方法を解説しました。
- `ThisOutlookSession` を使ってイベント駆動型のプログラムを作る。
- `Application_NewMailEx` で新着メールをリアルタイムにキャッチする。
- 添付ファイルのサイズをバイト単位で合計し、MBに換算して厳密に比較する。
ここをクリアできれば、単なるマクロの記録者から、業務プロセスをハックして自動化する「業務自動化エンジニア」への階段を確実に登り始めています。
ぜひ、自分の部署のルールに合わせて定数(`MAX_TOTAL_SIZE_MB`)を書き換え、安全なテスト環境で試してみてくださいね。あなたのエンジニアライフを応援しています!
