【VBA】Outlookオブジェクトを用いたメール送信の基本事項

# はじめに
メールの自動送信をしたい場合もあると思います。
ここでは、**VBA**で**Outlookオブジェクト**を操作してメール送信をする方法について、その骨組みだけ紹介しておきます。

基本さえ分かれば、応用的なこともどんどん理解できるようになると思います。
なお、プログラムを実行するとメールが送信されてしまうので、最初は自分のアドレス宛てに送るなど事故のないようにしてください。

**＜目次＞**
[1. メール送信の基本の形](#1-メール送信の基本の形)
[2. 参照設定をする場合](#2-参照設定をする場合)
[3. ファイルを添付する場合](#3-ファイルを添付する場合)
[4. HTML形式でメールを送信する場合](#4-html形式でメールを送信する場合)
[5. 外部ライブラリについての補足](#5-外部ライブラリについての補足)

# 1. メール送信の基本の形

### 1-1. 参照設定をしない場合のソースコード

まずは、参照設定をしない場合です。

```vb
'参照設定なしでメール送信
Sub SendMailNonReferences()
    Dim objOutlook As Object
    Set objOutlook = CreateObject("Outlook.Application") '外部ライブラリからOutlookを操作するオブジェクト作成
    Dim objMailItem As Object
    Set objMailItem = objOutlook.CreateItem(0) 'MailItemオブジェクト作成（末尾の(0)でMailItemオブジェクトを指定）
    
    objMailItem.To = "t-yama-3@example.com" 'メールの宛先を指定
    objMailItem.Subject = "おはようございます" 'メールのタイトルを指定
    objMailItem.Body = "VBAからメール送信をしてみました" 'メールの本文を指定
    objMailItem.Send 'Sendメソッドで送信
End Sub
```

前半の４行は、外部ライブラリからOutlookのメールを操作するための**[MailItemオブジェクト](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem)**を呼び出しているだけです（ここはコピペでもOKです）。
呼び出したオブジェクトは変数`objMailItem`に格納しています（変数名は任意なので`mi`とか短くしても構いません）。
この**MailItemオブジェクト**に、メールの宛先や本文を格納して送信することになります。

後半の４行は、**MailItemオブジェクト**に、メールの宛先、タイトル、本文を設定して送信するという操作をしています。
要するに、この後半の４行で必要な指定をすればVBAからメール送信ができるということです。

コードを見れば、おおよそ意味が見えてくると思いますが、使用しているプロパティとメソッドなどをまとめると次のとおりです。

### 1-2. MailItemオブジェクトのプロパティ・メソッド（抜粋）

|名称|内容|データ型|
|---|---|---|
|[Toプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.to)|宛先の取得又は設定を行う|String|
|[CCプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.cc)|CCの取得又は設定を行う|String|
|[BCCプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.bcc)|BCCの取得又は設定を行う|String|
|[Subjectプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.subject)|メールタイトルの取得又は設定を行う|String|
|[Bodyプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.body)|メール本文の取得又は設定を行う|String|
|[Sendメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.send(method))|メールの送信を行う|-|
|[Displayメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.display)|Outlookメールを表示する|-|

このほかにも、[様々なプロパティとメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem)がありますので、必要に応じて調べてみてください。

# 2. 参照設定をする場合

次は事前に参照設定を行う場合の例です。
参照設定すると、プログラムの実行前に外部ライブラリを読み込みます。
これによりオブジェクトの呼び出しが簡単になるとともに、コードを書いているときに、関連するメソッドやプロパティの候補が自動表示されたりします。

### 2-1. 参照設定の方法

VBAメニューの「ツール」から「参照設定」を開き、`Microsoft Outlook X.X Object Library`にチェックを入れてOKボタンを押します。
![2020-12-13 112538.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551412/62e1c7ce-7c0a-9a24-29fb-0201fb72e958.png)

### 2-2. 参照設定をした場合のソースコード

参照設定をした場合は、次のようにコードを書くことができます。これで本記事の標題どおり７行になります。
これが、一番オーソドックスな形だと思います。

```vb
'参照設定ありでメール送信
Sub SendMail()
    Dim objOutlook As New Outlook.Application 'Outlookを操作するオブジェクト作成
    Dim objMailItem As Outlook.MailItem
    Set objMailItem = objOutlook.CreateItem(olMailItem) 'MailItemオブジェクト作成
    
    objMailItem.To = "t-yama-3@example.com" 'メールの宛先を指定
    objMailItem.Subject = "こんにちは" 'メールのタイトルを指定
    objMailItem.Body = "参照設定をしてメール送信をしてみました" 'メールの本文を指定
    objMailItem.Send 'Sendメソッドで送信
End Sub
```

基本的には、参照設定しない場合とほとんど同じです。なお、**後半４行は全く同じ**です。
前半３行はコピペすれば済みますので、基本的な説明は以上となります。

前半３行部分について、もう少し理解を進めたい場合は、「[5. 外部ライブラリについての補足](#5-外部ライブラリについての補足)」をご覧ください。

# 3. ファイルを添付する場合

続いて、ファイルを添付してメールを送信する場合です。

### 3-1. ファイル添付してメール送信するソースコード

```vb
'ファイルを添付してメール送信
Sub CreateMailWithAttachment()
    Dim objOutlook As New Outlook.Application 'Outlookを操作するオブジェクト作成
    Dim objMailItem As Outlook.MailItem
    Set objMailItem = objOutlook.CreateItem(olMailItem) 'MailItemオブジェクト作成
    
    objMailItem.To = "t-yama-3@example.com" 'メールの宛先を指定
    objMailItem.Subject = "こんにちは" 'メールのタイトルを指定
    objMailItem.Body = "ファイルを添付をしてメールを送信します" 'メールの本文を指定
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-20.png") 'ファイルを添付
    objMailItem.Send 'Sendメソッドで送信
End Sub
```

**＜説明＞**
加えた行は、次の１行のみです。
見てのとおり、末尾に引数としてファイル名を渡すだけです。

```vb
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-20.png") 'ファイルを添付
```

[Attachmentsオブジェクト](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.attachments)の[Addメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.attachments.add)を使用してファイルを添付しています。

### 3-2. ファイルを複数添付してメール送信するソースコード

ファイルを複数添付する場合のソースコードです。

```vb
'ファイルを複数添付してメール送信
Sub CreateMailWithAttachment()
    Dim objOutlook As New Outlook.Application 'Outlookを操作するオブジェクト作成
    Dim objMailItem As Outlook.MailItem
    Set objMailItem = objOutlook.CreateItem(olMailItem) 'MailItemオブジェクト作成
    
    objMailItem.To = "t-yama-3@example.com" 'メールの宛先を指定
    objMailItem.Subject = "こんにちは" 'メールのタイトルを指定
    objMailItem.Body = "ファイルを添付をしてメールを送信します" 'メールの本文を指定
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-19.png") 'ファイルを添付
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-20.png") 'ファイルを添付
    objMailItem.Display 'メールを表示
    Dim ans As Long
    ans = MsgBox("このメールを送信しますか？" & vbCrLf & "（いいえを選択すると下書き保存します）", vbYesNo + vbQuestion + vbSystemModal)
    If ans = vbNo Then
        objMailItem.Close olSave '保存して閉じる
        Exit Sub
    End If
    objMailItem.Send 'Sendメソッドで送信
End Sub
```

**＜説明＞**
余計なコードを増やしてますが、ファイルを複数送信するには、次のように、ファイルの数だけAddメソッドを繰り返し実行するだけです。

```vb
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-19.png") 'ファイルを添付
    Call objMailItem.Attachments.Add("C:\Users\user\Pictures\2020-12-20.png") 'ファイルを添付
```

なお、余計に加えた部分では、ファイルを送信するかどうかのメッセージを表示するようにしています。

```vb
    objMailItem.Display 'メールを表示
    Dim ans As Long
    ans = MsgBox("このメールを送信しますか？" & vbCrLf & "（いいえを選択すると下書き保存します）", vbYesNo + vbQuestion + vbSystemModal)
    If ans = vbNo Then
        objMailItem.Close olSave '保存して閉じる
        Exit Sub
    End If
```

「はい」を選択すればそのままメール送信をします。
「いいえ」を選択すればファイルを下書き保存して閉じます（[Closeメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.close(method))）。

[Closeメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.close(method))には、セーブモードを指定する[引数](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.olinspectorclose)を渡す必要があります。
引数の種類は次のとおりです。

|名前|値|説明|
|---|---|---|
|olDiscard|1|保存せず閉じる|
|olPromptForSave|2|保存するかどうかをユーザーに確認する|
|olSave|0|保存して閉じる|

# 4. HTML形式でメールを送信する場合

HTML形式でメール文を作成すると、フォントの種類や色の設定ができます。

```vb
'HTML文でメール送信
Sub SendMailByHTML()
    Dim objOutlook As New Outlook.Application 'Outlookを操作するオブジェクト作成
    Dim objMailItem As Outlook.MailItem
    Set objMailItem = objOutlook.CreateItem(olMailItem) 'MailItemオブジェクト作成
    
    objMailItem.To = "t-yama-3@example.com" 'メールの宛先を指定
    objMailItem.Subject = "こんにちは" 'メールのタイトルを指定
    objMailItem.HTMLBody = "<b>HTML</b>で<font color=""red"" face=""ＭＳ Ｐ明朝,ＭＳ 明朝"" size=""5"">メール送信</font>をしてみます" 'メールの本文を指定
    objMailItem.Display 'メールを表示
    'objMailItem.Send 'Sendメソッドで送信
End Sub

```

![2020-12-20 231127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551412/b8644c59-df89-63f8-d1a1-9a4d84ab1a57.png)

**＜説明＞**
変更するのは、メール本文の指定をするところのみです。
テキスト形式で本文を設定する場合は、[MailItem.Bodyプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.body)を使用していましたが、HTMLで設定する場合は[MailItem.HTMLBodyプロパティ](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem.htmlbody)を使用することになります。

```vb
objMailItem.HTMLBody = "<b>HTML</b>で<font color=""red"" face=""ＭＳ Ｐ明朝,ＭＳ 明朝"" size=""5"">メール送信</font>をしてみます"
```

HTMLのことは、この記事のテーマではないですが、よく使用する属性は次のようなものです。

|名前|書式|説明|
|---|---|---|
|color属性|\<font color="red">\</font>|文字色を指定|
|size属性|\<font size="5">\</font>|文字サイズを指定（1～7の範囲、標準は3）|
|face属性|\<font face="ＭＳ 明朝">\</font>|フォントの指定|
|bタグ|\<b>\</b>|太字の指定|
|brタグ|\<br>|改行の指定|

# 5. 外部ライブラリについての補足

ここから先は、**分からなくとも何とかなる**ところなので、興味のある方のみお読みください。

上記の「**[2-2. 参照設定をした場合のソースコード](#2-2-参照設定をした場合のソースコード)**」のうち、前半の３行を見ていきます。

まず、最初の１行です。

```vb
    Dim objOutlook As New Outlook.Application 'Outlookを操作するオブジェクト作成
```

ここでは、[外部ライブラリ](https://excel-ubara.com/excelvba1/EXCELVBA438.html)から**[Outlookオブジェクト](https://docs.microsoft.com/ja-jp/office/vba/api/overview/outlook/object-model)**というものを呼び出しています（難しく言うなら、インスタンスを生成しているということになります）。
このOutlookオブジェクトは、Outlookの持つ様々な機能（メール、連絡帳、予定表）を操作することができるものです。

続いて、２行目と３行目です。

```vb
    Dim objMailItem As Outlook.MailItem
    Set objMailItem = objOutlook.CreateItem(olMailItem) 'MailItemオブジェクト作成
```

ここでは、Outlookオブジェクトの**[CreateItemメソッド](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.application.createitem)**を使用して、メールを操作する**[MailItemオブジェクト](https://docs.microsoft.com/ja-jp/office/vba/api/outlook.mailitem)**を呼び出しています（ここでも、インスタンスを作成してます。）。

CreateItemメソッドの引数に`olMailItem`という定数を渡していますが、この定数の正体は数字の`0`です。
なので、`Set objMailItem = objOutlook.CreateItem(0)`と書いても同じ結果となります。

定数の意味は次の表のとおりです。

|名前|値|説明|
|---|---|---|
|olMailItem|0|メール|
|olAppointmentItem|1|予定表|
|olContactItem|2|連絡先|
|olTaskItem|3|タスク|
|olJournalItem|4|履歴フォルダー内の履歴項目|
|olNoteItem|5|メモフォルダー内のメモ|
|olPostItem|6|パブリックフォルダーの投稿アイテム|
|olDistributionListItem|7|連絡先フォルダー内の配布リスト|

つまり、今回は、Outlookの機能のうち**メール機能**のみを操作するので、最初の`olMailItem`を指定して**MailItemオブジェクト**を呼び出しているということになります。

# さいごに

VBAでメールやIEを操作するのは、一見難しそうに見えます。
しかし、実際の難しい設定についてソースコードに書く必要はなく、必要なライブラリさえ呼び出せば、結構簡単に扱えるようになっています。

なお、ここで書いた方法の他に、CDO(Microsoft Collaboration Data Objects)を使用して、SMTPサーバ経由でメールを送信する方法もありますが、CDOを使用する方法は現在推奨されていないようです（「[コラボレーションデータオブジェクト (CDO) 1.2.1 は、Outlook 2010 以降のバージョンではサポートされていません](https://support.microsoft.com/ja-jp/help/2028411/collaboration-data-objects-cdo-1-2-1-is-not-supported-with-outlook-201)」を参照）。
このあたりは、また後日まとめようと思っています。