参考サイトのサンプルをマネしながら少しだけ改造して、OutLookのメールをAccessのテーブル"tbl_mail"に取り込むVBAを書いてみました。
一度取り込んだメールは二度と取り込まない仕組みなのですが、実行してみると必ず1通だけ重複したメールを取り込んでしまいます。
対象フォルダは「個人用フォルダ」の中の「受信トレイ」の中の「集荷」です。
サンプルとして3通のメールを入れていますが、何度実行しても、
"新しいメールはありませんでした。"とはならずに、
"読込み1件・重複2件"となります。
最近ADOを勉強し始めたばかりで原因がさっぱりわかりません。
このサンプルに対する質問は検索してもほとんど見つけられませんでした。
よろしくお願いいたします。
Access2010(Win7)で作り、DBはUSBに保存して、Access2007(vista)でも使っています。
フォームのボタンで標準モジュールのFunction MailGetoを呼び出して実行しています。
Function MailGeto()
On Error GoTo エラー
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim myNaSp As NameSpace
Dim myFolder As MAPIFolder
Dim mySecFolder As MAPIFolder
Dim myThrFolder As MAPIFolder
Dim myItem As MailItem
Dim myindex As Long, x As Long, y As Long, i As Long, r As Long
Dim MyCri As String
Set cn = Application.CurrentProject.Connection
Set rs = New ADODB.Recordset
rs.Open "tbl_mail", cn, adOpenKeyset, adLockOptimistic
Set myNaSp = GetNamespace("MAPI")
Set myFolder = myNaSp.GetDefaultFolder(olFolderInbox)
i = 0: r = 0
For x = 1 To myFolder.Folders.Count
Set mySecFolder = myFolder.Folders(x)
For myindex = 1 To mySecFolder.Items.Count
Set myItem = mySecFolder.Items(myindex)
'受信日時と件名をつなげた文字列を一意とする
MyCri = myItem.ReceivedTime & myItem.Subject
'条件…"tbl_mail"テーブルの"KEY"フールドの値と一致するもの
rs.Find "KEY='" & MyCri & "'"
If rs.EOF Then '検索条件と合致する物がない場合
rs.AddNew
rs!Key.Value = MyCri
rs.Fields("フォルダー").Value = mySecFolder
rs.Fields("受信日").Value = myItem.ReceivedTime
rs.Fields("送信者").Value = myItem.SenderName
rs.Fields("件名").Value = myItem.Subject
rs.Fields("メール").Value = myItem.SenderEmailAddress
rs.Fields("内容").Value = myItem.Body
rs.Update
i = i + 1 'メール件数を求めます。
Else
r = r + 1
End If
Next
Next
If i = 0 Then
MsgBox "新しいメールはありませんでした。"
Else
MsgBox "メールの更新が完了しました。" & Chr(13) & Chr(13) & _
"・読込み " & i & "件" & Chr(13) & _
"・重複 " & r & "件"
End If
rs.Close
cn.Close
Exit Function
エラー:
If Err.Number = 287 Then
MsgBox "書き出しを中止しました"
Else
MsgBox Err.Number & Err.Description
MsgBox "予期せぬエラーが発生しました"
End If
End Function
No.2ベストアンサー
- 回答日時:
大変申し訳ありません。
私の勘違いだったようです。
検証結果、条件に合致しない場合には、EOF BOF ともに True になりました。
迷宮に入っていたのはヘルプを~@;}%した私でした。 orz
こちらでは何故か、主キー設定無し・全てのフィールドでインデックス無し
にしても機能しました?
>1つ目のメールアイテムに対して・・・
こちらです。
わざわざ調べていただいてありがとうございます。
おかげさまで自分なりにEOF BOFについて調べて、より深く理解することができました。
主キーについては謎のままですが、ADOで更に違うテーブルへレコードを書き移す際にも主キーがないとうまくいきませんでしたので、設定したままにしておきます。
>1つ目のメールアイテムに対して・・・
>こちらです。
なるほど、そうなんですね。
意味が分かってくると捗りますし楽しいです。
お忙しい中ありがとうございました。
次の機会があればまた宜しくお願いいたします。
No.1
- 回答日時:
ここが迷宮の入り口かも?
>If rs.EOF Then '検索条件と合致する物がない場合
合致しない場合に、EOFにはならなくて最後のレコードに移動します。
ヘルプより
『カレント行の位置は、検出されたレコードに設定され、
条件を満たす行がない場合は、Recordset の最後 (または最初) に設定されます』
EOF は最後のレコードの【次】です。
『EOF カレント レコードの位置が Recordset オブジェクトの最後のレコードより後にあることを示します。』
なので、rs.EOF は常に不成立です。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DAOのレコードセットなら、NoMatch プロパティで簡単に調べられますので
DAOのレコードセットを使われるのが分かりやすいかと思います。
(Find でも Seek でも有効です)
ADO で、Rs.Recordcount = Rs.AbusolutePosition で最後のレコードか否かを判断できますが
最後のレコードに行った理由が
該当するレコードが無いため、か
たまたま最終レコードが該当したため、かは判別不能のような気がします。
(自信なさげ・・・)
この回答への補足
ありがとうございます。
実は回答を待つ間にテーブルのKEYフィールドに主キーを設定したところ、正常に作動しました。(理由はよくわからないままですが…)
>合致しない場合に、EOFにはならなくて最後のレコードに移動します。
読むほどにわからなくなってきたので少しご解説頂きたいのですが、上記rs.Find…の動作は、カレントレコードのフィールドの値1つに対してメールアイテムの最初から最後までを捜索するのか、1つ目のメールアイテムに対してフィールドの値の最初から最後までを捜索するのかどちらなんでしょうか。
自分では前者だと思っているのですが…。(トンデモ質問でしたらスミマセン)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) vbaを早くしたい 5 2022/09/09 10:58
- Visual Basic(VBA) VBAでoutlook365が起動しません。 4 2022/08/25 13:31
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) VBAが止まります。 3 2022/08/31 14:09
- Visual Basic(VBA) excel vbaでvlooupの変数がわかりません。 7 2022/05/30 09:35
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
- Visual Basic(VBA) 稀に1円合いません? Sheet1から金額と個数を貼り付ける下記コードで、金額を切り上げるコードを何 3 2022/09/05 15:11
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
データの二重表示の原因
-
Accessでの排他制御
-
Access 削除クエリが重い
-
3つ以上のテーブルをUNIONする...
-
Accessにインポートしたら並び...
-
accessで検索&入力 データの...
-
数百万件レコードのdelete
-
Access カレントレコードがあり...
-
非連結サブフォームのレコード...
-
C# Windows Forms で、Accessみ...
-
Access 1レコードずつcsvで出力...
-
Access VBA Me.Requery レコー...
-
一部重複しているレコードの削除
-
Accessでのレコードの削除時の...
-
ManagementStudioからのデータ削除
-
レコードロックする方法
-
テーブルのレコード削除ができ...
-
AccessのSQLについて教えてくだ...
-
ACCESSのBookmarkプロパティの...
-
(ACCESS)並び替えをしないで...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Accessにインポートしたら並び...
-
データの二重表示の原因
-
2つの項目が重複するレコード...
-
3つ以上のテーブルをUNIONする...
-
数百万件レコードのdelete
-
Access VBA Me.Requery レコー...
-
非連結サブフォームのレコード...
-
Access 削除クエリが重い
-
ACCESSのBookmarkプロパティの...
-
Access 1レコードずつcsvで出力...
-
ManagementStudioからのデータ削除
-
Accessの重複クエリで最小以外...
-
Accessでの排他制御
-
Accessで重複したデータを一件...
-
(ACCESS)並び替えをしないで...
-
フォームからのレコード削除に...
-
SQLServerで同一条件レコードの...
-
Accessでの禁止文字チェック
-
Accessでレコードが更新された...
-
テーブルのレコード削除ができ...
おすすめ情報