【ExcelVBA】For…Nextステートメント3


For…Nextステートメント③

今回は、「For…Nextステートメント」を使用した少し実践的なプログラムを作成してみましょう。
IfステートメントとFor…Nextステートメントを学んだことで、様々なことができるようになりました。
今回作るプログラムは、Excelに列挙されているメールアドレスのリストに、順番に同じメールを送信するというものです。

少し長いプログラムで、まだ未学習の箇所も多いかと思いますが、実際にプログラムを作って動かしカスタマイズしてみる経験は、とてもスキルアップにつながりますので最後までチャレンジしてみてください。

プログラムを作る前に

Outlookを使用してメールを送信しますので、Outlookでメールの送受信ができるかどうかを事前に確認しておいてください。

メール一斉送信プログラム

本体のプログラムは次のようになります。

Sub VBA基礎第9回_1()
    Dim objOutlook As Object
    Dim objMail As Object
    
    Set objOutlook = CreateObject("Outlook.Application")
    
    Dim i As Integer
    For i = 2 To 4
        Set objMail = objOutlook.CreateItem(0)
    
        objMail.To = Cells(i, 2).Value
        objMail.Subject = "テストメール"
        objMail.Body = "メール本文"
        objMail.Send
        
        Set objMail = Nothing
    Next

    Set objOutlook = Nothing
    MsgBox "送信完了", vbInformation
End Sub

実行する前にExcelの方で少し準備が必要です。
次のようなExcelを準備しましょう。ここに記載しているメールアドレス宛に、メールを順次送信していきます。この画面キャプチャーはダミーですが、みなさんが作るものには実際に受信確認ができるメールアドレスを入れておきましょう。

[009-【ExcelVBA】For…Nextステートメント3-001.png]

では、実行してみてください。
設定した3つのメールアドレスに同じメールが届いていれば成功です。件名は「テストメール」、本文は「メール本文」とだけ書かれたスパムメールのようなものになっています。受信できないという方は、もしかしたら迷惑メールに入ってしまっているかもしれませんのでチェックをお願いします。

さて、このプログラムはどのように動いているのでしょうか。順番にみていきましょう。まずは、2~5行目のプログラムです。
[009-【ExcelVBA】For…Nextステートメント3-002.png]

これはOutlookでメール送信するための準備をしています。2行目と3行目は「Dim」から始まっていますので変数宣言ですね。
データ型は初めてみるかもしれません。「Object」です。
ここで宣言している変数「objOutlook」に5行目で値を代入しています。「Set」はObjectの値を代入するときに使用する予約語です。
VBAの得意としているものの1つは、このように他のOffice製品との連携です。

次に7~17行目のプログラムです。
[009-【ExcelVBA】For…Nextステートメント3-003.png]

これは、全体としてFor…Nextステートメントになっています。ループカウンタはiですね。
i=2から4までの計3回繰り返しています。このループカウンタiは11行目でも使用しています。
Cellsの第1引数に「i」があるので、セルの行番号を表していることがわかります。
セルB2からセルB4までのメールアドレスを順番に参照していることになりますね。

次にメールを送信している部分により注目してみてみましょう。9~16行目のプログラムです。
[009-【ExcelVBA】For…Nextステートメント3-004.png]

難しい(何をやっているかわからない)と感じるかもしれませんが、みなさんが普段メールを作って送るときの手順をVBAでプログラムが順番に行っているだけです。
・9行目→空メール(メールを新規作成)
・11行目→メールの送信先(To)を設定
・12行目→メールの件名(Subject)を設定
・13行目→メールの本文(Body)を設定

これでメールを送るための準備ができたので、14行目でメールを送信しています。
16行目はメール送信の後始末をしています。少しわかりにくいかもしれませんが、この処理をいれないとエラーになってしまいます。一度リセットしているイメージです。

これで1人分のメール送信がおわりました。
ループの先頭にもどって次のメール作成を行います。

個々の細かい部分に関して、完全に理解する必要はありませんし、現状では難しい部分もあるかと思います。
「Ifやループ等の構文がわかっても、それで一体何ができるのか?」ということに対する1つの答えになればと思います。

では、次はよりこのプログラムを使いやすくするために、カスタマイズをしてみましょう。

送信できるメールアドレス数を増やす

このプログラムは、メール送信を一度に3件までしかできません。
まぁこれでも十分に便利かもしれませんが、少し数を増やしてみましょう。

たとえば、10件までの一斉送信をするためには、この部分を修正すればOKですね。
[009-【ExcelVBA】For…Nextステートメント3-005.png]

メールアドレスが入力されていないとエラーになってしまう

たとえば、2つのメールアドレスに一斉送信したい場合、Excelには2つのメールアドレスを登録して3件目は空にすればよさそうです。
ですが、この状態でプログラムを実行するとエラーになってしまいます。
[009-【ExcelVBA】For…Nextステートメント3-006.png]

この画面で「デバッグ」をクリックすると次の画面になります。
[009-【ExcelVBA】For…Nextステートメント3-007.png]

これはエラーのためプログラムを実行しつづけられず、エラーが発生した箇所でプログラムの実行が一時停止している状況です。黄色の網掛けのところでエラーが発生しています。このようになってしまったら、VBE上部のショートカットボタンの「リセット」をクリックしてプログラムを強制停止してください。
[009-【ExcelVBA】For…Nextステートメント3-008.png]

エラーメッセージをよく見てみましょう。「送信先を指定する必要があります。」とあります。送信先というのは「To」のことですね。この「To」へのメールアドレス設定ができていないことが原因のようです。「i=2」のループ、「i=3」のループでは問題ありませんが、「i=4」のループでは11行目「Cells(i, 2).Value」が空白になってしまうので、「To」が設定されないまま処理が進み、メールを送るタイミングでエラーになってしまったのではないかという想像ができます。

このようにループ回数と入力しているメールアドレス数を一致させておかないとプログラムがエラーになってしまいます。
変更するたびにその都度プログラムを直してもいいのですが、少し面倒ですね。カスタマイズしてエラーにならないようにしてみましょう。

修正方法はいろいろあるかと思いますが、Ifステートメントを使ってみましょう。発生したエラーを分析した結果、エラーを回避するには次のように考えることができます。

<条件>
送信先が設定されているときのみ
<処理>
メールを送信する

もう少し実際のプログラムでどのように記述すればよいか、落としこんでみましょう。
<条件>
Cells(i, 2).Valueに何か値があったら
<処理>
objMail.Sendを実行する

では、実際に修正してみましょう。変更するのはこの箇所ですね。
[009-【ExcelVBA】For…Nextステートメント3-009.png]

件名に名前を入れたい

次は、件名をカスタマイズしてみましょう。件名は「テストメール」で固定になっています。名前をいれればメールを読んでもらいやすくなるはずです。
これもいくつか方法がありますがExcel側で件名を入力する欄を追加することにしましょう。

[009-【ExcelVBA】For…Nextステートメント3-010.png]

ポイントは送信先メールアドレスの右隣りに「件名」の欄を設けるという点です。ループしながら(行単位で)メールの送信処理を行っているので、ループの中からExcelの値を参照するには同じ行に値を設定した方がスムーズです。
プログラムを修正してみましょう。件名を設定している個所はこの部分でした。

[009-【ExcelVBA】For…Nextステートメント3-011.png]

今は固定値「テストメール」(固定値のことをリテラルとも言います)が設定されていますが、この部分を送信先と同じようにCellsを使ってExcelから読み込むように修正します。

本文をExcelから入力できるようにしたい

本文も同様にExcelから入力できるようにしてみましょう。本文の中に名前を入れられたりすると便利そうですよね。
今度はExcelの便利な機能も使いながらプログラムを修正してみます。

まずは、Excel側をこのように修正します。名前と本文の欄を新しく追加しました。それとは別に少し離れたところに「本文フォーマット」という欄を作ります。本文フォーマットの方に注目してみてください。1行目にあるべき名前がなく、「様」だけがありますね。
[009-【ExcelVBA】For…Nextステートメント3-012.png]

ここでポイントとなるのは、本文の欄は固定値を入力するのではなくExcelで式を設定することです。セルD2に次のような式を入力します。
セルD3とセルD4は、セルD2の式をコピーして設定しましょう。

=C2&$F$2

これは、セルC2の値とセルF2の値を「&」を使ってくっつけています。このことを文字列結合といいます。
D列に表示されている値を見てみましょう。フォーマットの方には入力されていなかった名前が1行目に表示されています。

ここまでくればあとは「件名に名前を入れるとき」と同様にプログラムの修正をしていけばOKです。

VBAを用いることのメリットの1つはこの例のように「Excelの機能を使える」という点があげられます。このメール一斉送信プログラムは例えばJavaやPHP等の他のプログラム言語で作ることも可能です。しかし、VBAの方がやはりお手軽に作れるかと思います。このメリットを生かすためには、全てVBAで作ろうとするのではなく、Excelで出来ることはExcelでやらせるということがポイントです。これでプログラムを書く絶対量を減らすことができます。
さらにもう1つのメリットは、「UIをExcelで作ることができる」という点も挙げられます。今回で言うとメールアドレスをリスト上にして入力しているわけですが、この機能を他の言語で作ろうとするとなかなか大変な作業になります。

メールのCCに自分のメールアドレスを設定したい

では最後に、メールが送信できたか心配なのでCCに自分のメールアドレスを設定して、送信確認できるようにしてみましょう。
注目するのはこの部分です。
[009-【ExcelVBA】For…Nextステートメント3-013.png]

「Object」も「Outlook.Application」もよくわかりませんが、「To」や「Subject」「Body」があるということは…?
そうです、実は「Cc」や「Bcc」もあります。
筆者がプログラムを作っているときには、普段からよくこのような予想や想像をしています。予想したことは外れることもよくあるので、いきなりプログラムを作るのではなく、インターネットで調べてみるとよいかと思います。今回は比較的わかりやすかったのではないでしょうか?

ちなみに、公式サイトはマイクロソフトの以下のサイトです。
正直、このサイトではよくわからないかと思います。このサイトで調べたいことを検索するのも一苦労です。筆者の場合は、「VBA Outlook.Application」といったキーワードで検索してヒットした、個人のブログや法人の情報サイトなどを参考にしています。

参考)MailItem.CC プロパティ (Outlook)

では、「Cc」に自分のメールアドレスを固定値(リテラル)で設定してみましょう。
プログラムを実行するとCCに設定したメールアドレスにもメールが届くかと思います。

宿題

今回は宿題はありません。
いくつかのカスタマイズ例を紹介しましたので、これを宿題の代わりに是非やってみて頂ければと思います。
業務の中でメールを使用することの多い方は、少し工夫(カスタマイズ)すれば実際に業務で使えるかもしれませんね。

次回は、カスタマイズの答え合わせです。

  • このエントリーをはてなブックマークに追加

PAGE TOP