こんにちは! Outlook VBAの世界へようこそ。
マクロの記録ボタンを押すだけのステージから一歩進み、自分の手で業務を劇的に効率化するコードを書こうとしているあなたを、私は心から歓迎します。ここをクリアすれば、Outlook VBAの基本はバッチリですよ。
今回は、ビジネスメールの品質をグッと上げる「社内用語の自動校正支援機能」を作ってみましょう。
「社内用語で書いたカジュアルな下書きを、送信ボタンを押す前にピシッと正式名称に直してくれたら……」
そんなビジネスパーソンの密かな願いを、VBAの力で鮮やかに叶えてみます。
—
なぜ「送信前の自動校正」が必要なのか?
私たちが日常的に使うビジネスメールには、つい「社内用語(スラングや略語)」が混ざってしまいがちです。
- 「来期の予実について……」 ➔ 「予算実績管理」
- 「例の案件の件ですが……」 ➔ 「プロジェクトA」
- 「ASPの改修が……」 ➔ 「クラウドサービス」
これをうっかり取引先に送ってしまったら大変ですよね。送信直前に人の目でチェックするのは限界があります。だからこそ、「メール送信(Send)の瞬間をフックにして、プログラムに強制スキャンさせる」という仕組みが最強の武器になります。
—
現場でそのまま使える!自動校正マクロの全コード
まずは、Outlookの「魔法の裏側」を覗いてみましょう。
以下のコードを、OutlookのVBAエディタ(`Alt` + `F11` キーで開きます)内の `ThisOutlookSession` にそのまま貼り付けてください。
‘ ==============================================================================
‘ 【モジュール名】 ThisOutlookSession
‘ 【概要】 メール送信イベントをフックし、本文中の社内用語を自動で正式名称に置換する
‘ ==============================================================================
‘ 1. メール送信のイベントを監視するための宣言
Public WithEvents SendersMail As Outlook.MailItem
‘ 2. Outlookが起動したときに監視をスタートする
Private Sub Application_Startup()
Set SendersMail = Nothing
End Sub
‘ 3. 新しいメール作成画面が開かれたとき、または選択されたときに監視対象を捉える
Private Sub Application_ItemSend(ByVal Item As Object, Cancel As Boolean)
Dim wsWord As Worksheet
Dim checkMail As Outlook.MailItem
‘ 処理対象がメールアイテムであるか確認
If TypeOf Item Is Outlook.MailItem Then
Set checkMail = Item
‘ ————————————————————————–
‘ 【核心】ここで本文の校正エンジンを呼び出す!
‘ ————————————————————————–
Call CorrectBusinessTerms(checkMail, Cancel)
End If
End Sub
‘ ==============================================================================
‘ 【関数名】 CorrectBusinessTerms
‘ 【概要】 辞書に基づき、本文中のワードを置換するメインロジック
‘ ==============================================================================
Private Sub CorrectBusinessTerms(ByVal mail As Outlook.MailItem, ByRef cancelSend As Boolean)
Dim bodyText As String
Dim confirmResult As VbMsgBoxResult
‘ 辞書データの定義(本来はExcelや外部ファイルから読み込むとスマートです)
Dim targetWords(2) As String
Dim replaceWords(2) As String
‘ 置き換え前(社内用語)
targetWords(0) = “予実”
targetWords(1) = “案件X”
targetWords(2) = “定例”
‘ 置き換え後(正式名称)
replaceWords(0) = “予算実績管理”
replaceWords(1) = “次世代基幹システム構築プロジェクト”
replaceWords(2) = “週次進捗報告会”
‘ 現在の本文を取得
bodyText = mail.Body
Dim i As Long
Dim isReplaced As Boolean
isReplaced = False
‘ 辞書ループを回して合致するワードを置換
For i = LBound(targetWords) To UBound(targetWords)
If InStr(bodyText, targetWords(i)) > 0 Then
‘ 該当ワードを置換
bodyText = Replace(bodyText, targetWords(i), replaceWords(i))
isReplaced = True
End If
Next i
‘ 置換が行われていた場合の処理
If isReplaced Then
‘ 本文を書き換える
mail.Body = bodyText
‘ ユーザーに確認を促す(優しさの設計)
confirmResult = MsgBox(“【校正システム】” & vbCrLf & _
“社内用語を正式名称に自動置換しました。” & vbCrLf & _
“このまま送信しますか?” & vbCrLf & _
“([いいえ]を選ぶと送信を一旦キャンセルします)”, _
vbYesNo + vbExclamation, “送信前チェック”)
If confirmResult = vbNo Then
cancelSend = True ‘ 送信をキャンセル
End If
End If
End Sub
—
コードの重要ポイントを分かりやすく解説!
ここが中級者へのステップアップの分かれ道です。コードの肝となる3つのポイントを解説します。
① `WithEvents` によるイベントの「待ち伏せ」
通常のVBAは「ボタンを押したら実行」ですが、Outlook VBAでは「メールを送信する(`ItemSend`)」といったユーザーの行動をトリガー(きっかけ)にできます。
`Public WithEvents SendersMail As Outlook.MailItem` と宣言することで、Outlookの裏側で常に目を光らせる番犬を飼うようなイメージで処理をフックできます。
② `ItemSend` の `Cancel` 引数の魔法
関数の引数にある `ByRef Cancel As Boolean`。ここが非常に重要です。
もし校正結果に納得がいかなかったり、誤変換があった場合に `Cancel = True` を代入すると、Outlookはメールの送信処理をピタッと中断してくれます。 これにより、「あ、送信しちゃった!」という事故を完全に防げます。
③ シンプルかつ強力な `Replace` 関数
VBA標準の `Replace(対象文字列, 検索文字列, 置換文字列)` 関数は非常に強力です。
今回は配列(`targetWords` と `replaceWords`)を使って複数のワードを一括置換する仕組みにしています。実務では、この部分をExcelファイルや外部データベースから読み込むように拡張すると、メンテナンス性が爆発的に向上します。
—
陥りやすい罠とエラー回避のコツ
初学者がこのコードを実装する際、よくハマるポイントをいくつかシェアしておきます。
- 罠1:マクロが無効化されている
- 対策: Outlookの「ファイル」>「オプション」>「セキュリティ センター」>「セキュリティ センターの設定」から「マクロの設定」を「すべてのマクロに警告を表示する」に変更してください。
- 罠2:HTMLメールとプレーンテキストの罠
- 対策: Outlookのメールには `Body`(テキスト)と `HTMLBody`(HTML形式)があります。今回のコードはシンプルな `Body` を対象にしているため、装飾の多いHTMLメールだとタグまで置換してしまうリスクがあります。本格的に運用する場合は `HTMLBody` に対する正規表現処理を検討するとさらにプロフェッショナルです。
—
まとめ:あなたの手でOutlookを「賢く」しよう
今回作成した自動校正機能は、ほんの一歩に過ぎません。しかし、この「送信イベントをフックしてデータを加工する」というアプローチをマスターすれば、宛先のドメインチェック、添付ファイルの付け忘れ防止、秘密情報の検出など、あらゆる自動化に応用できるようになります。
まずは自分のパソコンで動かし、その便利さを肌で感じてみてください。
あなたのOutlookライフが、よりスマートで快適なものになることを応援しています!
