Excel(エクセル)でのデータ集計から、その結果を取引先や社内のメンバーにメールで報告するまでの業務は、多くのビジネスパーソンが毎日行っている定型作業です。もし、Excel VBA(マクロ)を使って「ボタンを一つ押すだけで、顧客リストから宛先を読み取り、個別の名前や金額を挿入したメールを一瞬で作成・送信する」ことができれば、数時間かかっていた作業が数秒で終わるようになり、宛先間違いなどのヒューマンエラーも完全にゼロにすることができます。 VBAからOutlookを操作してメールを自動化する技術は、実務において非常に強力かつ人気のあるテクニックです。しかし、いざ自動送信マクロを作って実行してみると、「プログラムが、ユーザーの代わりに電子メール メッセージを送信しようとしています」というセキュリティ警告画面が突然表示され、マクロが止まってしまうという壁に多くの人がぶつかります。 この記事では、Excel VBAを使ってOutlookメールを自動作成・送信するための基本的なコードの書き方から、複数人への一斉送信(差し込み送信)の実践的なマクロ、そして最大の障壁となる「セキュリティ警告」が発生する本当の原因と、それを回避・対処するための具体的な方法を網羅的に詳細に解説します。
目次
- 1. VBAからOutlookを操作するための基本(事前準備)
- 2. 【基本編】VBAでOutlookメールを作成・送信する標準コード
- 3. 【応用編】Excelのリストから一斉送信(差し込み送信)するマクロ
- 4. 実務で必須のテクニック:Outlookの「署名」を残したまま本文を作成する方法
- 5. Outlookのセキュリティ警告でマクロが止まる原因とは?
- 6. セキュリティ警告を出さずに自動送信するための回避策と対処法
- 7. まとめ
1. VBAからOutlookを操作するための基本(事前準備)
Excel VBAからOutlookという「別のアプリケーション」を動かす場合、VBAに対して「Outlookの機能を呼び出す」という宣言を行う必要があります。これには「事前バインディング(参照設定)」と「実行時バインディング」という2つのアプローチがあります。 この記事では、他のパソコンにExcelファイルを渡してもエラーになりにくく、事前の設定作業(VBEでのチェックボックスのオンオフ)が一切不要な「実行時バインディング(CreateObject関数を使用する方法)」を採用して解説します。この方法であれば、コードをコピーして貼り付けるだけで、どの環境でもすぐにOutlook連携マクロを動かすことができます。
2. 【基本編】VBAでOutlookメールを作成・送信する標準コード
まずは、宛先、件名、本文、添付ファイルといったメールの基本要素を設定し、Outlookのメッセージウィンドウを作成する最もシンプルなコードを紹介します。 以下のコードを、VBE(Visual Basic Editor)の標準モジュールにコピーして実行してみてください。(※実行する前にOutlookアプリがパソコンで起動している必要があります)。
Sub CreateOutlookMail()
' Outlookアプリケーションとメールアイテムのオブジェクト変数を宣言
Dim olApp As Object
Dim olMail As Object
Dim mailBody As String
' Outlookのアプリケーションオブジェクトを生成(実行時バインディング)
Set olApp = CreateObject("Outlook.Application")
' 新規メールアイテムを作成(0はメールアイテムを意味する)
Set olMail = olApp.CreateItem(0)
' 本文を変数に組み立てる(vbCrLfは改行コード)
mailBody = "株式会社〇〇" & vbCrLf & _
"営業部 山田様" & vbCrLf & vbCrLf & _
"いつもお世話になっております。" & vbCrLf & _
"今月のお見積書を添付にて送付いたします。" & vbCrLf & vbCrLf & _
"ご確認のほどよろしくお願いいたします。"
' メールの各項目を設定
With olMail
.To = "[email protected]" ' 宛先(To)
.CC = "[email protected]" ' CC
.BCC = "[email protected]" ' BCC
.Subject = "【送付】今月のお見積書" ' 件名
.Body = mailBody ' 本文
' 添付ファイルがある場合はフルパスを指定
' .Attachments.Add "C:\Work\見積書.pdf"
' メールの表示(いきなり送信せず画面で確認する)
.Display
' 自動的に送信してしまう場合は以下のコメントアウトを外す
' .Send
End With
' オブジェクトの解放
Set olMail = Nothing
Set olApp = Nothing
End Sub
コードの解説と各プロパティの意味
- CreateObject(“Outlook.Application”): これがExcelからOutlookを起動(または連携)させるための魔法の言葉です。
- .To / .CC / .BCC: 宛先のメールアドレスを指定します。複数のアドレスを指定したい場合は
"[email protected]; [email protected]"のようにセミコロン(;)で区切って入力します。 - vbCrLf: VBAにおける「改行」を表す定数です。本文の文字列を組み立てる際に、段落を分けるために使用します。
- .Attachments.Add: パソコン上に存在するファイルを添付します。必ず「C:\…」から始まるフルパスで指定します。
「.Display」と「.Send」の違い
メールオブジェクトに対する最後のアクションです。 .Display は、作成したメールを画面上にポップアップ表示させます。ユーザーは内容を目視で確認し、自分で「送信」ボタンを押すことができます。 一方、.Send は、画面に何も表示させることなく、バックグラウンドで強制的にメールを送信(送信トレイへ送る)します。完全な自動化を実現する場合は .Send を使用しますが、後述するセキュリティ警告のトリガーになるのはこのコマンドです。
3. 【応用編】Excelのリストから一斉送信(差し込み送信)するマクロ
実務で最も要望が多いのが、Excelシートにまとめられた「顧客リスト」を上から順番に読み込み、それぞれの会社名や担当者名を本文に差し込んで、連続してメールを作成するマクロです。 例えば、以下のようなリストがSheet1にあるとします。 ・A列:会社名 ・B列:担当者名 ・C列:メールアドレス ・D列:請求金額 このリストの2行目から最終行までをループ処理(For〜Next)で回し、連続してメールを作成するコードは以下のようになります。
Sub SendMailFromList()
Dim olApp As Object
Dim olMail As Object
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim mailBody As String
Set olApp = CreateObject("Outlook.Application")
Set ws = ThisWorkbook.Worksheets("Sheet1")
' A列の最終行を取得
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
' 2行目から最終行までループ
For i = 2 To lastRow
' セルにアドレスが入力されている場合のみ処理
If ws.Cells(i, 3).Value <> "" Then
Set olMail = olApp.CreateItem(0)
' 本文の差し込み作成
mailBody = ws.Cells(i, 1).Value & vbCrLf & _
ws.Cells(i, 2).Value & " 様" & vbCrLf & vbCrLf & _
"今月の請求金額は " & Format(ws.Cells(i, 4).Value, "#,##0") & " 円です。"
With olMail
.To = ws.Cells(i, 3).Value
.Subject = "【ご請求額のお知らせ】" & ws.Cells(i, 1).Value & "御中"
.Body = mailBody
' 一斉送信時の誤爆を防ぐため、ここではDisplay(下書き表示)としています
.Display
End With
Set olMail = Nothing
End If
Next i
Set olApp = Nothing
MsgBox "メールの作成が完了しました。", vbInformation
End Sub
このマクロを実行すると、リストにある人数の分だけOutlookのメール作成画面が次々と立ち上がります。各メールの宛先と本文には、エクセルから抽出された個別の名前や金額が正確に埋め込まれています。
4. 実務で必須のテクニック:Outlookの「署名」を残したまま本文を作成する方法
ここまで紹介した標準コード(.Body = mailBody)を実行して気づくのが、「普段Outlookの新規メール作成時に自動で挿入されるはずの『署名(自分の名前や電話番号)』が消えてしまう」という問題です。 VBAで .Body プロパティに文字列を代入すると、最初から入力されていた署名ごと、本文全体が「上書き」されてしまうためです。 署名を残したまま、その上の部分に本文を挿入するには、以下の2つのテクニックを組み合わせて使用します。
- 本文を書き換える前に、先に
.Displayを実行してメール画面を立ち上げ、署名を展開させる。 .Bodyではなく、HTML形式の本文プロパティである.HTMLBodyを使用し、自分の本文と既存の署名データを結合させる。
【署名を保持するコード例】
Sub CreateMailWithSignature()
Dim olApp As Object
Dim olMail As Object
Dim myBody As String
Set olApp = CreateObject("Outlook.Application")
Set olMail = olApp.CreateItem(0)
' HTML形式で改行する場合は <br> タグを使用する
myBody = "山田様<br><br>お世話になっております。<br>資料を送付します。<br><br>"
With olMail
.To = "[email protected]"
.Subject = "資料送付の件"
' ★重要:先にDisplayを実行して署名を自動挿入させる
.Display
' ★重要:自分の作成した本文(myBody)の直後に、既存のHTMLBody(署名部分)をくっつける
.HTMLBody = myBody & .HTMLBody
End With
Set olMail = Nothing
Set olApp = Nothing
End Sub
この書き方をマスターすれば、ビジネスメールとして違和感のない完璧な自動送信マクロを作成することができます。
5. Outlookのセキュリティ警告でマクロが止まる原因とは?
自動化が軌道に乗り、先ほどのコードを .Send(自動送信)に書き換えて実行した際、多くのユーザーが以下のような警告画面に直面します。
表示される警告メッセージの内容
「プログラムが、ユーザーの代わりに電子メール メッセージを送信しようとしています。これが予期しない動作である場合は、[拒否] をクリックして、ウイルス対策ソフトウェアが最新のものであることを確認してください。」 この画面が出ると、プログレスバーが溜まるまでの数秒間は「許可」ボタンを押すことができず、マクロの処理は完全に一時停止(フリーズ)します。数十件のメールを一斉送信するループ処理の中でこの警告が出ると、1件送信するたびに数秒待たされて許可ボタンを手動で押し続けなければならず、自動化の意味が全くなくなってしまいます。
なぜ警告が出るのか(マルウェア対策の仕組み)
この警告は、Outlookに備わっている「セキュリティとトラストセンター」の機能によるものです。 過去、悪意のあるプログラム(マクロウイルスなど)が、ユーザーの知らない裏側で勝手にOutlookを操作し、アドレス帳にあるすべての連絡先にウイルス付きメールを大量送信するというサイバー攻撃が流行しました。 これを防ぐため、Outlookは「外部プログラム(Excel VBAなど)が、確認画面を出さずに直接 .Send を実行しようとした場合」に、この警告ポップアップを出して処理をブロックする仕様になっています。 ただし、この警告は常に出るわけではありません。Windowsにインストールされているウイルス対策ソフトウェア(Windows Defenderなど)が「有効」かつ「最新の状態」であるとWindowsのセキュリティセンターが認識している環境下では、Outlookは「安全な環境である」と判断し、この警告を出しません。つまり、警告が出るということは、PCのセキュリティソフトの状態が正しく認識されていないか、無効になっていることが根本的な原因です。
6. セキュリティ警告を出さずに自動送信するための回避策と対処法
この忌まわしいセキュリティ警告を回避し、マクロをスムーズに実行するための対策はいくつか存在します。環境や社内ルールに合わせて最適なものを選択してください。
対策1:Outlookの「プログラムによるアクセス」設定を変更する
最も正攻法であり、システム的に警告をオフにする方法です。(※会社のPCの場合、管理者権限がないと変更できないことがあります)。
- Outlookを起動し、「ファイル」タブをクリックします。
- 左下の「オプション」をクリックします。
- 「Outlookのオプション」ウィンドウの左側から「トラスト センター(またはセキュリティ センター)」を選択し、「トラスト センターの設定」ボタンをクリックします。
- 左側のメニューから「プログラムによるアクセス」を選択します。
- 「プログラムによるアクセスに対するセキュリティ」の選択肢を、一番下の「不審な動作に関する警告を表示しない(推奨しません)」に変更します。
- 「OK」を押してOutlookを再起動します。
これで、VBAから .Send を実行しても警告が出なくなります。
対策2:SendKeysを利用してキーボード操作で送信させる
Outlookの設定がロックされていて変更できない場合の裏ワザとして、VBAの .Send メソッドを使わず、メールを .Display で表示させた直後に、VBAから「Ctrl + Enter」キー(Outlookの送信ショートカット)を押したことにして強制送信させる方法があります。
With olMail
.Display
' 表示されるまで少し待機(環境に応じて調整)
Application.Wait [Now() + "0:00:01"]
' Ctrl + Enter を擬似的に送信
Application.SendKeys "^{ENTER}"
End With
ただし、SendKeysは「その瞬間に一番手前に開いているウィンドウ」に対してキー操作を行うため、実行中にユーザーが別のアプリを触ったりすると誤作動を起こすリスクがあり、不安定な手法です。
対策3:CDO(Collaboration Data Objects)を利用してOutlookを経由せずに送信する
Outlookというアプリケーションそのものを介さず、VBAからSMTPサーバー(メールの送信サーバー)に直接通信してメールを送る手法です。 CDOを利用すればOutlookのセキュリティ警告は一切関係なくなりますが、SMTPサーバーのアドレスやポート番号、認証IDとパスワードをVBAコード内に直接記述しなければならず、セキュリティ上のリスクやネットワーク知識が求められるため、初心者向けではありません。
対策4:VBAでは「表示(Display)」まで行い、送信は手動にする(実務推奨)
自動化の観点からは少し後退するように思えますが、現場の実務運用において最も安全で推奨されるのがこの方法です。 コード内では .Send を使わず、必ず .Display で止めておきます。数十件のメールであっても、画面上にすべてのメール作成ウィンドウが立ち上がります。あとは、ユーザーが宛先や添付ファイルに間違いがないかを目視でサッと確認しながら、手動で「送信ボタン(またはCtrl+Enter)」を連打して送信していきます。 完全自動送信は、万が一VBAの記述ミスやExcelリストの行ズレがあった場合、本来送るべきではない相手に見積書などの機密情報が瞬時に一斉送信されてしまうという「致命的な情報漏洩事故」を引き起こす危険性を孕んでいます。 「作成の手間はVBAでゼロにするが、最終的な送信のトリガーは人間が責任を持って引く」という運用にするだけで、セキュリティ警告の問題も回避でき、誤送信リスクも防ぐことができるため、強く推奨されるアプローチです。
7. まとめ
VBAによるOutlookメールの自動作成・送信は、Excelに蓄積されたデータを即座に外部へアウトプットするための究極の効率化ツールです。 基本的なコードは CreateObject("Outlook.Application") でオブジェクトを生成し、宛先(To)や件名(Subject)、本文(Body)を設定するだけというシンプルな構成で実現できます。さらに、本文を作成する際は .Display を先に実行してから .HTMLBody を結合することで、大切な「署名」を消さずに保持できるという実務特有のテクニックも習得しました。 そして、VBAメール自動化における最大の関門である「セキュリティ警告」は、ウイルス対策ソフトの状態に起因するOutlookの防衛機能です。警告を消すためにはトラストセンターの設定を変更する必要がありますが、組織のセキュリティポリシーによっては変更が不可能な場合も多々あります。 そのような場合は、無理に .Send による完全自動化を追求するのではなく、.Display によって作成までを自動化し、最後の送信作業だけは人間の目による最終チェックを通すという運用に切り替えるのが、最も安全かつ確実な方法です。 自身の環境と業務の性質に合わせて最適なアプローチを選択し、日々のメール送信業務から解放される快適な自動化環境を構築してください。