ACCESSだけでメール送受信(CDOで送信,Winsockで受信)するサンプルを紹介します。
    Winsockで強かに受信、CDOでスマートにデコードは Winsock,CDO,ADOの連携(CDOデコード)

CDO(Microsoft Collaboration Data Objects)を利用してメールを送信できるそうです。
へ〜、知らなかった! 勉強不足.....
それなら、BSMTP(BASP21)を使わずに、ACCESSだけでメールクライアントができるのでは?
.....という浅はかな思いつきの結果、泥沼にはまってしまいました。

送信は、CDOで割と簡単にできたのですが、受信がでした。
一般的なインターネットプロバイダのサーバから、CDOでメールを受信することは困難なようです。
ホームページをあちこち迷い歩いた末、WSOCK32.DLLを使うことにしました。
WSOCK32.DLL(Winsock)を利用すると、POP3サーバと通信できるそうです。
※ テストした環境は、Windows2000XP-Proです。
特に難しかったのは、(まだ、途上かも知れませんが)デコードです。
送信時は、CDOがエンコードしてくれますが、受信時にWSOCK32.DLLデコードしてくれません。
コーディングでデコードする破目に陥ってしまいました。

以下のエンコードに対処しました(したツモリです)。間違っているかも知れません
    ISO-2022-JP(base64とquoted-printable)
    UTF-8(quoted-printableと8bit)
    ISO-8859-1(base64とquoted-printable) (RFC1345の特殊文字には対応していません)
    &#xxxxx;形式のエンコード
    base64形式でエンコードされた添付ファイル
トライ&エラーを繰り返し、日本語英語のメールは、ほぼ読めるようになりました。

かなりエエカゲンですが、サンプルのMDBを掲載しています。
内容は、以下の動作のみに絞って、できるだけシンプルにしてあります。
 @ AccessからJPEGなどの添付ファイル付きEメールを送信する。
 A Accessで添付ファイル付きEメールを受信し、内容をテーブルに保存する。
ご希望なら、ダウンロードしてご覧下さい。
ダウンロード(Access2000版)
ホームページを探しても、このテーマの有効な情報は、少ないと感じました。
あくまでもサンプル無保証ですが、自分で作ろうと思っている方には、参考になるでしょう。
ソースコードは、完全公開です。(完璧さに自信はありませんが.....)
Windowsの機能のみを使っているので、何かあっても自力で対応ができます。

CDOデコードする方法もあります。                    サンプルの一覧.....
Winsock,CDO,ADOの連携(CDOでデコード)は、教科書通りのCDOの使い方をかい潜り、ちゃっかりデコードだけしてもらいます。
多少裏技的ですが、VBAソースはシンプル&デコードは高完成度なので、現実的な方法(お勧め)です。

この仕組みを使ったメーラーもどきもあります。
http://www.ynsk.co.jp/nsk/knowhow/nskdcm/nskdcm4.htm
ハードディスク上のファイルをメールに添付したり、受信した添付ファイルをハードディスクに保存するするステップを含みます。
多少複雑ですが、添付ファイルの扱い方を知りたい方には参考になると思います。
このサンプルで動作確認ができ、更に連携した使い方を模索される方にお勧め致します。

●操作方法
 ・ ファイルはLZH形式で圧縮されています。
 ・ 解凍後にMDBファイルが1つ作成されます。
 ・ このファイルをダブルクリックして起動して下さい。(単独で動作します)
●MDBファイルの内容
 ・ メールユーザ(テーブル)……利用するメールアカウントの情報を保存します。
 ※ 以下のように設定して下さい。
     メールアドレス
     POP3サーバ
     ユーザ
     パスワード ← POP3サーバのパスワード
     SMTPサーバ
     リターン ← 受信時にサーバなどから通知されるメッセージが設定されます。
     受信要求 ← 0(受信しない)または-1(受信する)を設定して下さい。
     仮受信 ← -1(メールをサーバから消さない)または0(消す)を設定して下さい。
 ※ 複数レコードを格納できます。
     複数レコードを格納すると複数ユーザのメールを受信できます。
 ・ 受信メール(テーブル)……受信したメールはこのテーブルに保存されます。
 ・ 受信メール添付(テーブル)……受信したメールに添付ファイルがあった場合、
     このテーブルに保存されます。
 ・ 送信メールW(テーブル)……送信するメールの内容をこのテーブルに設定します。
 ※ 以下のように設定して下さい。
     メール番号 ← 送信するメールに任意の番号を指定して下さい。
     宛先アドレス ← 宛先のメールアドレス
     CCアドレス ← CCのメールアドレス
     BCCアドレス ← BCCのメールアドレス
     差出人アドレス ← 差出人のメールアドレス
     件名 ← メールの件名
     宛先名 ← メールの宛先名(本文の先頭の位置に表示されます。)
     本文 ← メールの本文
     署名 ← メールの署名(本文の末尾の位置に表示されます。)
     リターン ← メール送信時にサーバなどから通知されるメッセージが設定されます。
 ※ 複数レコードを格納できます。
     複数レコードを格納すると複数件のメールを一度に送信できます。
 ・ 送信メール添付W(テーブル)……送信するメールに添付ファイルがある場合、
     このテーブルに保存して下さい。
 ※ 以下のように設定して下さい。
     メール番号 ← 送信メールW(テーブル)のメール番号と同じ値を指定して下さい。
     添付ファイル番号 ← 添付ファイルの連番
     添付ファイル名 ← 添付ファイルの名前(例:XXXX.JPG)
     添付ファイル ← 添付ファイルをロングバイナリーデータの形式で保存して下さい。
     添付ファイル長さ ← 添付ファイルの長さをバイト単位で設定して下さい。
 ※ 添付ファイルの保存方法は、 http://www.ynsk.co.jp/nsk/knowhow/binfld/binfld.htm
     の説明と同様にして下さい。
 ※ 添付ファイルを送信する場合のみ、送信メール添付W(テーブル)にレコードを作成して下さい。
 ・ Q_メール受信(更新クエリ)……このクエリを実行するとメールが受信されます。
 ※ メールユーザ(テーブル)の受信要求(フィールド)に
     -1を設定したメールユーザが対象となります。
 ※ メールは、受信メール(テーブル)に保存されます。
     添付ファイルがあった場合、受信メール添付(テーブル)に保存されます。
 ・ Q_メール送信(更新クエリ)……このクエリを実行するとメールが送信されます。
 ※ Autoexec(マクロ)などは作っていません。
    各テーブルとモジュールの内容を設定して、直接クエリを実行して下さい。
 ・ B_POP3(モジュール)……メールの受信とデコードを行います。
 ※ このモジュールを実行するためには、作業用のフォルダが必要です。
    B_POP3(モジュール)の中のコーディング
    「Private Const BWorkDir As String = "c:\maildata"」と
    「Private Const BWorkTempDir As String = "c:\maildata\temp"」で
    作業用のフォルダを指定しています。
    ダウンロードしたままの設定で操作する場合、
    Cドライブ直下にmaildataというフォルダとmaildataフォルダのなかに
    tempというフォルダを作成して下さい。
    別のフォルダを利用する場合、フォルダの指定を変更して下さい。
    「Private Const c_WorkDir非消去 As Integer = -1」というコーディングがあります。
    -1のままだと、1メールごとに上記作業用のフォルダの中身を削除しません。
    1ユーザのメールが複数あって、それを受信した場合、作業用のフォルダには全件分のファイルを残しています。
    デバック時に1ユーザごとに受信すれば、中間結果を追えるので、有効なことがあります。
    ファイルには、「mail1.txt」,「mail2.txt」.....などの番号を付けています。
    ファイルと受信したメールを照合させるため、テーブルに保存したメールの「件名」にも番号を付けています。
    0にすると、作業用のフォルダには最後の1件分のファイルしか残りません。
    安定した運用段階に入れば、0にした方がディスク負荷は小さくなります。
 ・ B_SMTP(モジュール)……メールの送信を行います。
 ※ このモジュールを実行するためには、作業用のフォルダが必要です。
    B_SMTP(モジュール)の中のコーディング
    「Private Const BWorkTempDir As String = "c:\maildata\temp"」で
    作業用のフォルダを指定しています。
    ダウンロードしたままの設定で操作する場合、
    Cドライブ直下にmaildataというフォルダとmaildataフォルダのなかに
    tempというフォルダを作成して下さい。
    別のフォルダを利用する場合、フォルダの指定を変更して下さい。
 ・ B_Winsock(モジュール)……WSOCK32.DLLに関連するプロシージャ群です。

変なメールへの対応

POP3サーバから受信したデータを眺めていると、変なメールがあることに気付きます。
例えば「To:」(宛先)を示す行自体が無いメールもありました。
From:」(差出人)の表示が(文字化けせず)ちゃんと読めるのに崩れているメールもあります。
どちらも、内容はスパムでした。
To:」や「From:」が取り出せない変なメール件名の先頭に[Bad]という文字を付けるようにしました。
※ 該当のコーディング(モジュール)の位置には注釈(コメント)を入れてあります。

Subject:」(件名)の行に?マークが並んでいて読めないスパムメールをしばしば見掛けます。
この読めない件名をエンコードする試みは、あっけなく断念しました。
POP3サーバから受信した直後のデータを16進で見ても3F(?)が並んでいました。
POP3サーバに到達した時点で、崩れていたのではないでしょうか?
元は日本語の「Subject:」(件名)が、SMTPサーバを通る時に崩れたと推測されます。

メールの日付(Date)ですが、「Date:」から取得するのがでしょう。
しかし、「Date:」は、確証はありませんが、メーラーが設定しているようです。
パソコンの時刻を取っているとすると、精度も低い可能性があります。
中には、「Date:」に年を含まないメールもありました。
そこで、「Received:」から日付(日時)を取得するようにしました。
「Received:」は、SMTPサーバが書き込むと思われるので、内容も安定しているようです。
タイムラグも大きいとは考え難いので、実用的に、問題が少ないと思います。
SMTPをリレーした場合、下側に記述された「Received:」の方が、送信元に近いと推測しました。
いちばん下側の「Received:」から取得するようにしています。
国外のSMTPを通ってくるメールもあるので、時差の表示も見て、日本の時刻に読み替えるようにしました。

ホームページに載せてからも、テストや改善をしています。
文字だけのメールでは、BASP21を使ったサンプルより軽快に動作します。
「そりゃ〜、デコードヌケがあるけ〜ヨ!」と言われそうですが.....
ところが、500KB以上の結構大きな添付ファイル付のメールは、BASP21を使ったサンプルと比べ、
受信に倍以上の時間を要することに気付きました。
「やっぱし、半端者のやることか?」.....トホホ.....使えね〜!

少しでも速くなるように、処理のロジックを見直しました。
環境にもよると思いますが、1〜3MB程度の添付ファイル付で、BASP21を使ったサンプルと比べ、
ほぼ同等の時間で受信するようになりました。
※その際、[Bit6(RFC2045の逆)変換]のコーディングも1行にし、上位プロシージャに吸収しました。
添付ファイルのファイル名(filename)がメールのソース上で2行にまたがる場合、不具合があり、修正しました。
base64でエンコードされた4バイトごとのデータを、いかに速く3バイトごとにデコードするか?
割と短いステップですが、的な部分だと思います。
サブクラス化」によって、「POP3サーバとの交信」と「デコード」を並列して実行させるのが理想です。
余談ですが、
XPのパソコンでテストしているとき、VBAのステップを中断してみました。
POP3サーバからの通信は止まらず、メール1件分が流れ続けました。
ちなみに、2000ではステップを中断した時点で、受信も止まりました。ややこしいな〜!
Winsockには、そんな話があるのかも知れません。「私が知らなかっただけ?」
サブクラス化」は行っていません。(現在、断念.....中です。)

VB系の言語は、ビット演算が得意でないと思っていました。(日頃は、事務系なので、気にも止めません。)
「AND」などの論理演算子や「掛け算」「割り算」でビットの操作が行えることが解かりました。
文字型の変数に「0」と「1」を並べるようなもっちゃりした方法を使っていたのをビット演算に変えました。
RFC2045をデコードするための変換テーブルも文字型にして、Mid関数で参照していました。
無理やりバイト型の構造体に入れて、添え字で参照するようにしました。
CPUへの負荷が減り、処理時間も短縮する効果があったようです。
以上のように、base64でエンコードされた添付ファイルデコードには、力を入れました。

IEから[ページの送信]でメールを送ると、UTF-8でエンコードされることがありました。
UTF-8(quoted-printable)のデコードを追加しました。

本文がbase64でエンコードされていてcharsetの指定がないメールが見つかりました。
試しにiso-2022-jpを仮定してデコードしたら、読めました。
他のメーラーでも読めたので、本文がbase64でエンコードされていてcharsetの指定がない場合、
iso-2022-jp仮定してデコードするようにしました。

XPでテストしていると、「無効なオブジェクトを参照.....」というようなエラーのポップアップが出たことがあります。
詳しいことは解っていませんが、ADOのバージョンを上げることが対策になると思います。

ADOのバージョンを上げるには、モジュールのデザインビューで
[ツール]-[参照設定]のコマンドメニューを選択して、参照設定のウィンドウを開いて下さい。
現在は、「Microsoft ActiveX Data Objects 2.5 Library」にしています。
不安定な現象は、「Microsoft ActiveX Data Objects 2.1 Library」で起こりました。
変更する際は、先に中止する参照のチェックをオフにし、下にスクロールして、追加する参照をチェックして下さい。

UTF-8ですが、今度は8bitでエンコードされたメールを受信しました。
POP3サーバからは、いったんバイト型の構造体に受信します。
これまでは、それを文字型の変数に変換してデコードしていました。
base64quoted-printableでエンコードされていれば、問題なかったのですが、
8bitでエンコードされていると、文字型に変換した時点で崩れる(正常に変換されない)文字がありました。
base64quoted-printableなら、SHIFT-JISの1バイト系(英数字)の範囲に収まります。
ところが、日本語がUTF-88bitでエンコードされるとSHIFT-JIS範囲外のコードになることがあるようです。
文字型に変換できないので、このケースは、16進の文字列に迂回させることで対応しました。

ご意見、お問い合わせは → 

ACCESSの使い方トップページ



〒745-0801 山口県周南市大字久米327-145
中川システム開発 ホームページ
Tel(0834)28-0205 Fax(0834)28-1272