事務の現場では、特定の要素に基づいて、個別にメールを作成し送る機会が意外と多いです。直近だけでも4件、同様の需要がありました。これらの要望にはこれまでは「Wordの差込印刷機能を利用して、指定のメーラーで送信する」といった、ノンプログラミングな手法が用いられてきていました。

しかし、この手法、社内にメールサーバを持っていたような昔だったら有効だったのですが、現代のように「クラウド」にしてしまっていた場合、送信制限に抵触してアカウントが凍結される恐れもあります。

例えば、Office365の場合、

  • 1分間に30通以上送信するとアウト
  • 1日あたり10,000通以上のメール送信
  • 1度に送れる送信先は500名まで
  • 受診者のプロキシアドレス制限は400名まで
  • 1メールあたり25MBまで(初期値) – 最大150MBまで管理者であれば拡張可能
  • 添付ファイルのサイズは34MBまで。大容量ファイルBoxやOneDriveなどのリンクを公開し、パスワードを付与して送ると良い

特に1つ目の30通以上/1分間の制限が厳しく、差込印刷でメール送信をすると、軽くアカウント凍結されてしまいます。今回はこの課題をクリアしつつ、指定のメンバーへ個別のメールを送信してみたいと思います。(今回は1分間に20通送るようにしています)

今回使用するファイルやライブラリ

※今回のAccessアプリは64bit版として作成していますので、32bit版で動かすと不具合が出ると思います。

また、今回のアプリでは、以下のライブラリを利用しています。

アプリの仕様

今回のアプリケーションは、ユーザへ現在の定期券の登録データを個別に通知する為のプログラムです。以下のような仕様が含まれています。

  1. 社員マスタには社員のデータ、定期券のデータを用意しておく
  2. 通信文マスタは、送信するメールのヘッダや本文、署名、返信先アドレスなどを格納しておく。
  3. Reply-Toに対応しており、返信先アドレスで送信元とは違う、グループアドレスを指定可能
  4. 通信文の新規追加・既存データの編集用ダイアログを用意
  5. 回答期限は「西暦 + 曜日」で表記する
  6. メールはHTML形式とし、改行コードはすべて<br>タグに変換して挿入する
  7. 既存の登録データは起動時に自動的に5世代バックアップを行う
  8. 任意のタイミングで既存データをZIP形式でバックアップ・復元出来る機能を付けておく(7zip64.dll対応)
  9. メールの連続送信は、Outlookを直接操作し、1通送る毎に3秒間のウェイトを掛けるようにしています。

また、今回のプログラムは以下の参照設定(事前バインディング)を入れています。

  • Microsoft Office 16.0 Object Library – Accessのリボンコントロール、FileDialogの呼び出しで必要
  • Microsoft Outlook 16.0 Object Library – Outlook 2019を遠隔操作するために必要
  • Microsoft Scripting Runtime – ファイルの存在確認などでFilesystem Objectを使うために必要
  • Microsoft VBScript Regular Expressions 5.5 – メールアドレス形式確認で正規表現を使うために必要

ソースコード

社員マスタデータのインポート

  • FileDialogにて用意しておいたxlsxのリストにリンクテーブルを張っています。
  • xlsxファイルのパスは、renewimportの処理へ送られ、ここで実際のメインの処理が実行される仕組みです。
  • 対象者一覧シートm_employeeとしてリンクテーブルを設定しています。
  • 社員マスタテーブルを全削除⇒社員マスタへデータを追加という形で、洗い替えでデータを取り込んでいます。
  • マスタ編集画面が開かれていた場合、社員マスタのサブフォームを再読込するコードを最後に実行しています。

メールの一括送信

  • 一括送信ダイアログの送信ボタンを実行した時に発動するコードです。
  • ダイアログのコンボボックスの選択されているIDを元に、通信文マスタのデータを取り出します。
  • 回答期限についてはFormat関数にて西暦+曜日表記に、定期代についてはFormat関数にてカンマ区切りにして変換を掛けています。
  • chkMailAddress関数にて簡易的に「メールアドレス形式のチェック」を行っています。
  • 返信先アドレスが空の場合には送信できないようにしてあります。
  • .ReplyRecipients.Addオプションにて、Reply-To(返信先アドレス)を設定可能です。
  • BodyFormatをolFormatHTMLにした場合には、HTMLメールなのでBodyではなくHTMLBodyで指定しなければなりません。
  • 今回は送信時に指定秒数間のスリープを入れて、office365の制限を回避させている為、Declare FunctionにSleepが必要です。

使い方の手順

本プログラムは社員マスタおよび事前に用意しておいた通信文のフォーマットに従って、メールで通知するプログラムですので、決められた手順でデータの準備と送信を行わなければなりません。

社員マスタデータの取り込み

添付の社員マスタテンプレートにデータを準備しておきます。会社メールアドレスの列については間違えのないように。このアドレスをToとして利用します。

準備が整ったら、

  1. リボンの「メール送信」タブを開く
  2. データのインポートにある「社員マスタ取り込み」をクリック。
  3. 用意しておいたxlsxファイルを指定すると取り込み開始
  4. 取り込みが完了したら、社員マスタテーブルにデータがInsertされます。

通信文マスタのデータ作成

通信文とは、メールに差し込む元になるテンプレートなデータです。用途に応じて用意しておくと良いでしょう。各項目は以下のような使われ方をします。

  • 通信文名 – 一括送信時にコンボボックスに出てくるリストの名前
  • 件名 – メール送信時のSubject項目として利用される。
  • 本文 – メールの冒頭本文にあたります。改行はすべてBRタグに変換されますので、見た目のままメールに差し込まれます。
  • 返信内容 – 本文と同様
  • 回答期限 – 西暦カレンダーで選択が可能。実際に差し込まれる時は、西暦 + 曜日での表現に変換されます。
  • あとがき – ここは無理に入れなくても良いですが、「よろしくお願い申し上げます」的なメッセージを入れておくと無難でしょう。
  • 担当署名 – 通常は送信者の署名を入れておきますが、返信先アドレスがグループアドレスならば、グループに従った署名を入れておくと良いでしょう。
  • ウェイト – デフォルトは300msで決め撃ちです。
  • 返信先アドレス – FROMと同じアドレスを入れてもOKです。空だと登録はできません。相手が返信をクリックするとToに表示されるアドレスを登録しておきます。

図:通信文編集用ダイアログの表示例

メールの一括送信

社員マスタのメンバーに対して、メールを送信します。通信文マスタで設定しておいた内容をここでロードし送信しますが、返信先アドレスが設定されていない時には、送信ができませんのでご注意ください。

図:メール一括送信ダイアログ

データのバックアップ

本体プログラムであるpostman.accdbを起動すると、データ保存場所であるdatabase.accdbのバックアップを5世代に渡って自動で作成します。古いものは自動で其の際に削除されます。このバックアップとは別に、任意のタイミングでZIP形式で取れるのが、データのバックアップ。暗号化ZIPとなっているので、バックアップファイルはパスワードを入力しないと解凍できません。

デフォルトパスワードはpleasemrpostmanとなっていて、VBAのコード内にあります。

社員マスタおよび通信文マスタのデータをバックアップします。

関連リンク

共有してみる: