ねらい:Excelの一覧から「宛先・件名・本文・添付」を自動でメール配信する“型”を作る
毎回同じようなメールを、宛先や本文の一部だけ変えて送る――これを手作業でやるのは時間のムダです。
VBA なら「一覧をなめる → Outlook メールを作る → 差し込み → 送信(または下書き保存)」を“ひな形化”できます。
ここでは、プログラミング初心者でも貼って動くように、
- シート設計(誰に、何を)
- Outlook 宛のメール作成テンプレ
- 一括配信(送信/下書き)
- よくあるパターン(請求書、レポート、リマインドなど)
を、かみ砕いて説明します。
準備:シート設計と Outlook 連携の考え方
シート設計(最低限これだけは用意する)
まずは、次のようなシートを 1 枚用意します(名前は「MailList」とします)。
A列:SendFlag(送信対象か Y/N)
B列:To(宛先メールアドレス)
C列:Cc(CC、空でも可)
D列:Subject(件名)
E列:BodyTemplate(本文テンプレート)
F列:AttachmentPath(添付ファイルのフルパス、空でも可)
G列:Name(差し込み用の名前)
H列:Extra1(差し込み用の追加項目)
本文テンプレート(E列)は、こんな風にプレースホルダを含めておきます。
{Name} 様
いつもお世話になっております。
{Extra1} の件につきまして、ご連絡申し上げます。
よろしくお願いいたします。
あとで VBA 側で {Name} や {Extra1} を置き換えるイメージです。
Outlook を使う前提(Excel からメールを飛ばす仕組み)
Excel VBA でメール自動送信する時は、ほぼ「Outlook の自動操作」です。
- Outlook がインストールされている
- (できれば)Outlook が起動している
ことが前提になります。
初心者向けには「早送りはせず、とりあえず下書きに保存して確認してから送る」運用が安全です。
あとで「自動送信モード」に切り替えるテンプレも用意します。
共通基盤:Outlook メール作成の基本テンプレ
Outlook メールを 1 通作る最小コード
まずは最も小さい“1通を作って送る”テンプレです。
' ModMail_Base.bas
Option Explicit
Public Function GetOutlookApp() As Object
On Error Resume Next
Set GetOutlookApp = GetObject(, "Outlook.Application")
If GetOutlookApp Is Nothing Then
Set GetOutlookApp = CreateObject("Outlook.Application")
End If
End Function
Public Sub SendTestMail()
Dim olApp As Object
Dim olMail As Object
Set olApp = GetOutlookApp()
Set olMail = olApp.CreateItem(0) ' 0 = olMailItem
With olMail
.To = "test@example.com"
.CC = ""
.Subject = "テストメール"
.Body = "これはテストメールです。" & vbCrLf & "Excel VBA から送信しています。"
' .Display ' 画面に表示するだけ(確認用)
.Send ' いきなり送信
End With
End Sub
VBここで重要なポイントは 2 つです。
1つ目:GetOutlookApp で、既に起動している Outlook があればそれを使い、なければ起動するという“お作法”にしていること。
2つ目:.Display と .Send を切り替えることで、「目で確認してから送る/自動で送る」を切り替えられること。
最初は必ず .Display で確認するのをおすすめします。
差し込み機能:本文テンプレートの {Name} や {Extra1} を置き換える
プレースホルダ置換の小さな関数
' ModMail_Template.bas
Option Explicit
Public Function ApplyTemplate(ByVal template As String, ByVal key As String, ByVal value As String) As String
ApplyTemplate = Replace(template, "{" & key & "}", value)
End Function
Public Function BuildBody(ByVal template As String, ByVal name As String, ByVal extra1 As String) As String
Dim body As String
body = template
body = ApplyTemplate(body, "Name", name)
body = ApplyTemplate(body, "Extra1", extra1)
BuildBody = body
End Function
VBこれで、
- テンプレ:
"{Name} 様 … {Extra1} の件 …" - Name:
"山田" - Extra1:
"売上レポート"
という入力から、きちんと差し込まれた本文が作れます。
本番では、差し込む項目が増えたら BuildBody の中を増やすだけで対応できます。
一括配信ロジック:一覧をループして Outlook メールを量産する
シートの 1 行 = 1 通のメールとして処理する
' ModMail_Bulk.bas
Option Explicit
Public Sub BulkMail_FromSheet(Optional ByVal sendNow As Boolean = False)
Dim ws As Worksheet
Set ws = Worksheets("MailList")
Dim a As Variant
a = ReadRegion(ws) ' A1 からの表全体
Dim olApp As Object
Dim olMail As Object
Set olApp = GetOutlookApp()
Dim r As Long
For r = 2 To UBound(a, 1) ' 2行目から最終行まで
Dim flag As String
flag = UCase$(Trim$(CStr(a(r, 1)))) ' SendFlag
If flag = "Y" Then
Dim mailTo As String
Dim mailCc As String
Dim subj As String
Dim tmpl As String
Dim attachPath As String
Dim name As String
Dim extra1 As String
mailTo = Trim$(CStr(a(r, 2)))
mailCc = Trim$(CStr(a(r, 3)))
subj = CStr(a(r, 4))
tmpl = CStr(a(r, 5))
attachPath = Trim$(CStr(a(r, 6)))
name = CStr(a(r, 7))
extra1 = CStr(a(r, 8))
Dim body As String
body = BuildBody(tmpl, name, extra1)
If Len(mailTo) = 0 Then
' 宛先がない行は飛ばす(ログを取りたい場合はここで別処理)
GoTo NextRow
End If
Set olMail = olApp.CreateItem(0)
With olMail
.To = mailTo
.CC = mailCc
.Subject = subj
.Body = body
If Len(attachPath) > 0 Then
If Dir(attachPath) <> "" Then
.Attachments.Add attachPath
Else
' 添付ファイルが見つからない場合も本当はログを残すと良い
.Body = body & vbCrLf & vbCrLf & "[※ 添付ファイルが見つかりませんでした: " & attachPath & "]"
End If
End If
If sendNow Then
.Send ' 自動送信モード
Else
.Display ' 下書きとして開くだけ
End If
End With
End If
NextRow:
Next r
MsgBox "メール自動配信処理が完了しました。", vbInformation
End Sub
VBここでの“肝”を整理します。
SendFlag 列が Y の行だけ処理します。
これにより、「この人だけ今回は送らない」という制御が簡単にできます。
sendNow 引数で「自動送信/表示のみ」を切り替えています。
最初は BulkMail_FromSheet False のように呼び出し、すべてのメールウィンドウが表示された状態で中身を確認してから、
OK になったら True にして“ガチ自動送信”に切り替えるのが安全です。
添付ファイルのパスが存在しない場合は、その旨を本文に追記しています。
実務では「ログシート」にも“添付ファイル未検出”を記録しておくと、後から原因の特定が楽になります。
例題:レポートを個別に添付して自動配信する
想定シナリオ
- 各顧客ごとに作成されたレポート(PDF)がフォルダにある
- ファイル名は
レポート_顧客ID.pdfのような規則でついている - MailList シートには、顧客ID とメールアドレスと名前が入っている
この場合、添付ファイルパス列(F列)を「自動で埋めてから送る」テンプレにできます。
添付パスを自動で作る例
' ModMail_AttachPrep.bas
Option Explicit
Public Sub PrepareAttachments()
Dim ws As Worksheet
Set ws = Worksheets("MailList")
Dim a As Variant
a = ReadRegion(ws)
Dim baseFolder As String
baseFolder = ThisWorkbook.Path & "\Reports" ' レポートが入っているフォルダ
Dim r As Long
For r = 2 To UBound(a, 1)
Dim custId As String
custId = Trim$(CStr(a(r, 9))) ' 例:I列に顧客IDがあると仮定
If Len(custId) > 0 Then
Dim path As String
path = baseFolder & "\Report_" & custId & ".pdf"
a(r, 6) = path ' 添付パス列に書き込み(F列=6)
End If
Next
WriteBlock ws, a, "A1"
FormatBlock ws, "A1"
MsgBox "添付パスの準備が完了しました。", vbInformation
End Sub
VBこの後に BulkMail_FromSheet False を実行すると、各行に対応する PDF を添付したメールが Outlook 上に開きます。
問題なければ BulkMail_FromSheet True に切り替えて本番運用にできます。
重要ポイントの深掘り:安全・確実に自動配信するための“クセづけ”
いきなり .Send しない(まずは Display で人間が最終確認)
メール自動化で一番やりがちな事故は、「宛先間違いの一斉送信」です。
これを避けるために、
- 開発・テスト段階は必ず
.Displayにして目で確認 - 宛先を全て自分のテストアドレスにして動作確認
- その後、本番アドレスに差し替える
というステップを「必ず踏む」ことをおすすめします。
BulkMail_FromSheet を呼ぶ Sub を 2 本用意して、
Sub Mail_Check()
BulkMail_FromSheet False ' 表示のみ
End Sub
Sub Mail_Send()
BulkMail_FromSheet True ' 自動送信
End Sub
VBのように分けておくと、間違いが起きにくくなります。
シートの設計を“仕様書化”しておく
MailList シートの列構成(列の意味)は、必ずコメントや別シートで仕様として書き残しておきましょう。
- A=SendFlag (Y/N)
- B=To
- C=Cc
- D=Subject
- E=BodyTemplate
- F=AttachmentPath
- G=Name
- H=Extra1
- I=CustomerID
など。
後から列を追加したり名前を変えたりする時に、VBA 側の「何列目を読んでいるか」との対応が分からなくなるのを防げます。
列番号でなく「列名」で取るように拡張することも可能ですが、
初心者向けにはまず「列は固定」という前提で運用を固めてしまう方が楽です。
ログを残すと“後で助かる”
本格運用になってくると、
- 何行目の誰に
- いつ送ったか/送らなかったか
- 添付ファイルは見つかったか
といったログが欲しくなります。
簡単な方法は、MailList シートの右側に「SentDate」「Error」といった列を追加して、
送信処理の中で、
ws.Cells(r, 10).Value = Now ' SentDate
ws.Cells(r, 11).Value = "OK" ' Error列に結果
VBなどと書き込むことです。
後から「送れた/送れていない」の確認が一瞬でできるようになります。
セルを逐次触らず、配列でまとめて処理するクセをつける
今回のコードも、基本的には
- ReadRegion → 配列処理 → WriteBlock
という流れにしています。
セルを一つずつ読み書きするコードに慣れてしまうと、行数が増えたときに一気に重くなり、“固まる Excel”ができあがります。
自動配信ツールは、数百件〜数千件のメールを対象にすることもあるので、
最初から「配列中心の設計」にしておくと後々ラクです。
まとめ:シートで“誰に何を送るか”を書き、VBA で「差し込み・添付・送信」を自動化する
自動配信ツール(メール)は、
「シートでシナリオを定義 → VBA で Outlook を操作 → Display/Send を切り替える」だけで、かなり実務的なレベルに到達します。
- SendFlag と To/Cc で“誰に送るか”
- Subject/BodyTemplate と差し込みで“何を送るか”
- AttachmentPath で“何を添付するか”
をシートに書かせて、VBA 側は“機械的に流すだけ”にするのが、壊れにくくて強い設計です。
。
