こんにちは!業務自動化エンジニアの先輩です。
マクロの記録から一歩抜け出し、「自分で動的な仕組みを作ってみたい!」という段階に来たあなたへ。今回は、実務でめちゃくちゃ重宝する「Excelの送信予約日時を読み取って、Outlookで自動予約送信(DeferredDeliveryTime)を行う方法」を伝授します。
「深夜や休日にうっかり仕事のメールを送ってしまい、相手に気を遣わせてしまった……」
そんなビジネスマンの「あるある」を、Outlook VBAとExcelの連携でスマートに解決しましょう!
ここをクリアすれば、Outlook VBAの基本と、他アプリ(Excel)連携の作法はバッチリ身につきますよ。一緒にマスターしていきましょう!
—
1. そもそも「DeferredDeliveryTime」って何?
Outlookでメールを作成するとき、「今すぐ送信ボタンを押したくないけれど、明日の朝9時に自動で送りたい」と思ったことはありませんか?
Outlookの画面上では「配信遅延」という設定項目に当たります。これをVBAで操作するのが、`MailItem` オブジェクトが持つ `DeferredDeliveryTime` というプロパティです。
⚠️ 知る人ぞ知る、超重要な「罠」と仕様
プログラミング初学者がここで必ずハマる仕様があります。それは、「このプロパティを設定しても、Outlook自体が起動していて、かつオンライン状態でないと送信されない」という点です。
サーバルールで24時間配信されるわけではなく、「自分のOutlook(クライアント)が裏でタイマー待ちをしている」状態を作ります。だからこそ、送信トレイにメールが留まったままPCの電源を落とさないよう注意が必要です。この裏側の動きを知っているだけで、トラブルを未然に防げる一流のエンジニアに近づけますよ。
—
2. 全体像:どうやって動かすのか?
今回の仕組みは非常にシンプルです。
1. Excel側の準備: リスト(表)に「宛先」「件名」「本文」「送信予約日時」を入力しておく。
2. VBA側の処理:
- Excelのデータを上から順番に読み込む。
- Outlookのメールアイテムを新規作成する。
- 宛先や本文を設定する。
- `DeferredDeliveryTime` にExcelから読み取った日時を代入する。
- 「送信(Send)」メソッドを実行する!
「あれ? 送信ボタンを押していないのに送られるの?」と思うかもしれませんが、`DeferredDeliveryTime` さえセットされていれば、`Send` を実行してもすぐに飛び立たず、指定時間まで送信トレイでお行儀良く待機してくれます。
—
3. 実装コード(コピペで使える実用マクロ)
それでは、Excelの標準モジュールに貼り付けるだけでそのまま動く、洗練されたコードを公開します。今回は、現在アクティブなシートの2行目以降にデータが入っている想定で書いています。
Sub SendEmailsWithDeferredTime()
Dim olApp As Object
Dim olMail As Object
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
‘ 1. Excelのシート情報を取得(アクティブシートを対象)
Set ws = ActiveSheet
‘ 2. データの最終行を取得
lastRow = ws.Cells(ws.Rows.Count, “A”).End(xlUp).Row
‘ データがなければ終了
If lastRow < 2 Then
MsgBox "送信対象のデータが見つかりません。", vbExclamation, "確認"
Exit Sub
End If
' 3. Outlookのオブジェクトを生成(遅延バインディングを採用)
' ※Outlookが起動していなければ自動起動します
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If olApp Is Nothing Then
Set olApp = CreateObject("Outlook.Application")
End If
On Error GoTo 0
' 4. 行ごとにループ処理を回す
' 【Excel側の列定義の例】
' A列: 宛先 (To)
' B列: 件名 (Subject)
' C列: 本文 (Body)
' D列: 送信予約日時 (DeferredDeliveryTime)
For i = 2 To lastRow
' 空行スキップの安全装置
If ws.Cells(i, 1).Value <> “” Then
‘ メールの新規作成
Set olMail = olApp.CreateItem(0) ‘ 0 = olMailItem
With olMail
.To = ws.Cells(i, 1).Value
.Subject = ws.Cells(i, 2).Value
.Body = ws.Cells(i, 3).Value
‘ ★ここが今回の核心:送信予約日時の設定
‘ Excelセルに値が入っている場合のみ適用
If IsDate(ws.Cells(i, 4).Value) Then
.DeferredDeliveryTime = ws.Cells(i, 4).Value
End If
‘ 送信実行(DeferredDeliveryTimeが設定されていれば予約状態になる)
.Send
End With
‘ オブジェクトのメモリ解放(ループ内の鉄則)
Set olMail = Nothing
End If
Next i
‘ 後片付け
Set olApp = Nothing
MsgBox “すべての予約メールのセットが完了しました!”, vbInformation, “完了”
End Sub
—
4. コードの深掘り解説(ここがプロの技)
ただ動くだけのコードではなく、「なぜこのように書くべきか」というエンジニア視点のポイントを解説します。
① 「遅延バインディング(CreateObject)」を使う理由
VBAのコードを書く際、メニューの「参照設定」から `Microsoft Outlook XX.X Object Library` にチェックを入れる方法(早期バインディング)がよく紹介されます。
しかし、Excelファイルを他の人へ共有したり、Outlookのバージョンが変わったりすると、「コンパイルエラー:プロジェクトまたはライブラリが見つかりません」という恐怖のエラーに悩まされます。
今回のコードでは `CreateObject(“Outlook.Application”)` を使った遅延バインディングを採用しているため、参照設定のチェックが不要で、誰に配っても壊れにくい強固なコードになっています。
② ループ内でのメモリ解放 (`Set olMail = Nothing`)
大量のメールをループで作成・送信する際、Outlookのオブジェクト(メモリ)をそのまま放置すると、PCが重くなったり、最悪の場合はメモリリークを起こしてExcelやOutlookが強制終了します。
`For` ループの最後に `Set olMail = Nothing` を挟むことで、使い終わったメモリを綺麗に掃除しながら安全に処理を進めることができます。
③ `IsDate` 関数による型チェック
Excelのセルは自由度が高いため、ユーザーがうっかり「明日の朝」ではなく「あした」と文字で入力してしまうミスが起こり得ます。
`If IsDate(ws.Cells(i, 4).Value) Then` というガードを一枚挟むことで、日付として正しく認識できるデータだけを安全に `DeferredDeliveryTime` に渡すことができます。
—
5. 初学者が陥りやすい罠と対策
1. 「送信トレイに入ったまま、時間になっても送られない…」
- 原因: Outlookが「オフライン作業」になっていないか、あるいはOutlookアプリ自体がタスクトレイに最小化されず完全に終了している可能性があります。
- 対策: テスト時は、自分の別メールアドレス宛てにして、Outlookを起動したままPCを数分放置して動作確認を行ってください。
2. 「型が一致しません (Error 13)」が出る
- 原因: ExcelのD列(予約日時)のセルが、日付形式ではなく「文字列」として認識されている、あるいは空白セルにゴミデータが残っています。
- 対策: Excel側のセルの書式設定を「日付」または「ユーザー定義 (yyyy/m/d h:mm)」にしっかり合わせておきましょう。
—
まとめ
お疲れ様でした!今回はExcelのデータを読み取り、Outlookの `DeferredDeliveryTime` を使ってスマートに送信予約を行うテクニックを解説しました。
- Excelのセルから日付を取得し、Outlookの `DeferredDeliveryTime` に代入するだけ。
- 送信(`.Send`)しても、指定時間までOutlookがトレイで保持してくれる。
- 遅延バインディングとメモリ解放を意識すれば、実務で絶対に壊れない堅牢なマクロになる。
この技術をマスターすれば、例えば「金曜日の深夜に書いた業務連絡を、月曜日の朝8:50に一斉送信する」といった高度なタスクが、ボタン一つで自動化できるようになります。
現場でバリバリ使える自動化の武器を手に入れましたね。ぜひあなたの仕事に取り入れて、まわりのメンバーをあっと言わせちゃいましょう!それでは、次回の記事もお楽しみに!
