【入門編】Outlookのメール送信前に宛先をチェックする「誤送信防止」自動化マクロ – Outlook VBA解析バイブル

スポンサーリンク

こんにちは!いつも業務効率化や自動化の挑戦、お疲れ様です。

Excel VBAでマクロを書いたことがある方でも、「OutlookのVBAに入った途端、急に難しく感じて挫折してしまった……」という声をよく耳にします。それもそのはず。Excelは「セル(シート)に値を書き込む」という直感的な操作が中心ですが、Outlookは「イベント(メールを送る、受信するなど)を検知して動く」という、一歩進んだプログラミングの知識が必要になるからです。

でも、安心してください。ここをクリアすれば、Outlook VBAの基本はバッチリマスターできます。

今回は、実務での実用性が非常に高く、セキュリティ対策としても絶大な効果を発揮する「メール送信前の宛先チェック(誤送信防止)マクロ」をテーマに、Outlook VBAの心臓部である「オブジェクトモデル」をやさしく紐解きながら解説します。

「コピペで動いた!」のその先にある、「なぜこのコードで動くのか」という一生モノの知識を、一緒に身につけていきましょう!

1. Outlook VBAの心臓部「オブジェクトモデル」を覗いてみよう

プログラミングを始める前に、まずはOutlookというアプリケーションがどのような「構造」になっているかをイメージしてみましょう。
Outlook VBAを理解する最大のコツは、以下の「階層構造(オブジェクトモデル)」を頭に描くことです。

[Application] (Outlookアプリ全体)

├── [NameSpace / Session] (データへの入り口・ログイン状態)
│ │
│ └── [Folder] (受信トレイ、送信済みトレイなど)
│ │
│ └── [MailItem] (メール1通1通)
│ │
│ └── [Recipients] (宛先リスト)
│ │
│ └── [Recipient] (宛先1人ひとりの情報)

Excelでいう `Application > Workbook > Worksheet > Range` の関係とよく似ていますね。

主要な3つの登場人物

  • `Application` オブジェクト

すべての起点となる最上位のオブジェクトです。Outlookそのものを指します。

  • `NameSpace`(または `Session`)オブジェクト

Outlookの中にあるデータ(メールや予定表)にアクセスするための「鍵(ゲートウェイ)」です。歴史的な経緯から `MAPI` という名前空間を指定して取得します。

  • `MailItem` オブジェクト

私たちが普段作成している「メール1通」を表します。件名(`Subject`)、本文(`Body`)、宛先(`Recipients`)などの情報(プロパティ)を持っています。

今回は、この中の `Application` が持つ「メールを送信しようとした瞬間」というイベントをキャッチして、`MailItem` の中身を検査するプログラムを作ります。

2. 【コード公開】誤送信防止マクロの全貌

まずは、実際に動作するコードを見てみましょう。
このマクロは、「送信ボタンを押した時、宛先に特定のドメイン(例:自社のドメイン `example.com`)以外のメールアドレスが含まれていたら、警告を表示して送信をキャンセルできる」というものです。

貼り付け先:`ThisOutlookSession`

Outlook VBAでは、イベント(送信など)を検知するコードは必ず `ThisOutlookSession` という特別なモジュールに記述する必要があります。

‘ =================================================================
‘ Outlook 誤送信防止マクロ(送信前ドメインチェック)
‘ =================================================================
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim mail As Outlook.MailItem
Dim recips As Outlook.Recipients
Dim recip As Outlook.Recipient
Dim targetAddress As String
Dim domainName As String
Dim isExternalFound As Boolean
Dim warningMsg As String
Dim userResponse As VbMsgBoxResult

‘ 1. 安全対策:送信されるアイテムが「メール」であるかを確認
If TypeOf Item Is MailItem Then
Set mail = Item
Set recips = mail.Recipients
isExternalFound = False

‘ 2. 宛先(To, Cc, Bccすべて)を1人ずつループ処理でチェック
For Each recip In recips
‘ 宛先のアドレスを取得(Exchange環境や不完全なアドレスへの対策関数を呼び出す)
targetAddress = GetSMTPAddress(recip)

‘ メールアドレスからドメイン(@以降)を抽出
If InStr(targetAddress, “@”) > 0 Then
domainName = Mid(targetAddress, InStr(targetAddress, “@”) + 1)

‘ 3. 社内ドメイン(例: example.com)以外のドメインを見つけた場合
‘ ※ ご自身の組織のドメイン(例: yourcompany.co.jp)に書き換えてください
If LCase(domainName) <> “example.com” Then
isExternalFound = True
‘ 警告メッセージ用の文字列を作成(怪しいアドレスを蓄積)
warningMsg = warningMsg & “・” & recip.Name & ” (” & targetAddress & “)” & vbCrLf
End If
End If
Next recip

‘ 4. 社外の宛先が見つかった場合の警告処理
If isExternalFound Then
userResponse = MsgBox( _
“【警告】送信先に社外ドメインが含まれています!” & vbCrLf & vbCrLf & _
“以下の宛先に送信してもよろしいですか?” & vbCrLf & _
warningMsg, _
vbYesNo + vbExclamation + vbDefaultButton2, _
“誤送信防止チェック”)

‘ 「いいえ」が選ばれたら、送信をキャンセルする
If userResponse = vbNo Then
Cancel = True ‘ ★ここが魔法の1行です
MsgBox “送信をキャンセルしました。宛先を確認してください。”, vbInformation, “送信中止”
End If
End If
End If
End Sub

‘ =================================================================
‘ 【補助関数】Exchange環境などの特殊なアドレス表示から、
‘ 純粋なSMTPメールアドレス(xxx@yyy.com)を引き出すための堅牢な関数
‘ =================================================================
Private Function GetSMTPAddress(ByVal recip As Outlook.Recipient) As String
Dim addrEntry As Outlook.AddressEntry
Dim exUser As Outlook.ExchangeUser

On Error Resume Next
Set addrEntry = recip.AddressEntry

If Not addrEntry Is Nothing Then
‘ Exchange環境(社内LANなど)のアドレスの場合
If addrEntry.Type = “EX” Then
Set exUser = addrEntry.GetExchangeUser()
If Not exUser Is Nothing Then
GetSMTPAddress = exUser.PrimarySmtpAddress
Exit Function
End If
End If
End If

‘ 通常のインターネットアドレス(SMTP)の場合
GetSMTPAddress = recip.Address
End Function

3. ここがプロへの第一歩!コードの本質を徹底解説

このコードには、ただ「動く」だけではなく、実務の現場でバグを起こさないための「プロの知見」が詰まっています。ポイントを絞って解説しますね。

① 魔法の引数 `Cancel = True`

コードの最初にある `Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)` に注目してください。
このイベントハンドラが持つ `Cancel` という変数(引数)は、初期状態では `False`(送信する)になっています。
しかし、プログラムの中で `Cancel = True` と書き換えてプロシージャを終了すると、Outlookは「送信ボタンが押されなかったこと」にしてくれます。

これこそが、イベント駆動型プログラミングの醍醐味です。

② `MailItem.To` ではなく `Recipients` コレクションを使う理由

初心者がやりがちなミスに、`mail.To` という「宛先テキスト(例: “田中 太郎; Suzuki Ichiro”)」を文字列検索してしまう方法があります。しかし、これには大きな罠があります。

  • 罠1:`Cc` や `Bcc` に入っているアドレスを無視してしまう。
  • 罠2:表示名(ニックネーム)しか入っておらず、実際のメールアドレス(`@…`)が文字列に含まれていない場合、検知をすり抜けてしまう。

そのため、プロは必ず `mail.Recipients`(宛先オブジェクトの集まり) をループで回し、1人ずつの情報を正確に検査します。

③ Exchange環境の「EXアドレス問題」を突破する補助関数

企業でOutlookを使っている場合、メールアドレスが `xxx@example.com` のような形式ではなく、`/o=ExchangeLabs/ou=Exchange…` という特殊な社内専用形式(EX形式)で取得されてしまうことがあります。
これを知らずに「`@` が含まれているか」だけでチェックすると、社内宛てなのに「外部アドレス」と誤判定されたり、逆にすり抜けたりします。

補助関数 `GetSMTPAddress` は、そのアドレスがEX形式だった場合に、内部で「本来のSMTPアドレス(`@`形式)」に自動変換するという、実戦仕様の処理を行っています。

4. 陥りやすいエラーと回避策

マクロを作成する上で、誰もが一度は遭遇する「落とし穴」を先回りして解説しておきますね。

罠:`Set Nothing` によるメモリ解放の意識

VBA、特にOutlook VBAでは、使ったオブジェクトをそのままにしておくと、Outlookの動作が重くなったり、マクロが途中で動かなくなったり(メモリリーク)することがあります。
今回はイベント内のローカル変数なので自動解放されますが、より大きなプログラムを書くときは、処理の最後に `Set mail = Nothing` や `Set recips = Nothing` を書いて、明示的に「使い終わったよ」とパソコンに教えてあげる習慣をつけておくと、一流の仲間入りです。

5. このマクロをあなたのOutlookで動かす手順

さあ、実際に動かしてみましょう!手順はとても簡単です。

1. VBAエディタを開く
Outlookを開いた状態で、キーボードの `Alt` + `F11` を押します。
2. コードを貼り付ける
画面左側のツリーから `Microsoft Outlook Objects` > `ThisOutlookSession` をダブルクリックして開き、右側の白いエディタエリアに上記のコードを丸ごと貼り付けます。
(※ コード内の `”example.com”` は、ご自身の会社や学校のドメインに書き換えてくださいね)
3. 保存してエディタを閉じる
`Ctrl` + `S` で保存し、VBA画面を閉じます。
4. マクロのセキュリティ設定を確認する
Outlookの「ファイル」>「オプション」>「トラスト センター」>「トラスト センターの設定」>「マクロの設定」で、「すべてのマクロに対して警告を表示する」または「デジタル署名されたマクロに対してのみ警告を表示し、他のマクロはすべて無効にする」(自己署名が必要)に設定されていることを確認してください。

一度Outlookを再起動すると、マクロが有効になります。自分宛てやテストアドレスを使って、社外ドメイン宛てにテストメールを送信しようとしてみてください。警告画面が出現すれば大成功です!

まとめ:ここをクリアすれば、Outlook VBAの基本はバッチリ!

今回は、「イベントの検知(ItemSend)」「オブジェクトの階層(Application > MailItem > Recipients)」という、Outlook VBAの最も重要な基礎であり、かつ本質となる部分を学びました。

これが理解できれば、

  • 「特定の件名のメールが届いたら、自動で添付ファイルを保存する」
  • 「特定の時間に、Excelのリストからメールを自動作成して下書きに保存する」

といった、あらゆるOutlook自動化に応用できるようになります。

まずは今回の「誤送信防止」をあなたのOutlookに相棒として住まわせ、その便利さと、自分で書いたコードが動く感動をぜひ体感してください。

もし途中で分からないことが出てきても大丈夫。一歩一歩、オブジェクトモデルの階段を上っていきましょう。あなたの業務自動化ライフを心から応援しています!

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