none
OUTLOOK2013(Office 15.0 Object Library)からのメール読み出しで、型「MailItem」へのキャストエラーになる。 RRS feed

  • 質問

  • お世話になります。

    へっぽこドラマー と申します。

    よろしくお願い致します。

    現在VB(VS2005)で開発したシステムから、MS OUTLOOK2013 内の受信フォルダのメールを読み出す機能に対応しようとしております。

    (受信フォルダから過去2か月以内のメールを順次読み込み、取捨選択後DBに落とし込む)

    以下にソース抜粋を記します。

            Dim myOlApp As Outlook.Application
            Dim myNameSpace As Outlook.NameSpace
            Dim myFolder As Outlook.Folder
            Dim myItem As Outlook.MailItem
            Dim i As Integer
            Dim ret As Boolean = False
            Dim dat最古受信日 As DateTime = Nothing
            Dim strQuery As String = String.Empty
            Dim duplCnt As Integer = 0

            Try
                Me.initProc()
                myOlApp = CreateObject("Outlook.Application")
                myNameSpace = myOlApp.GetNamespace("MAPI")
                myFolder = myNameSpace.GetDefaultFolder(6)

                dat最古受信日 = CDate(Format(Date.Now.AddMonths(-2), "yyyy/MM/dd"))
                For i = 1 To myFolder.Items.Count Step 1
                    Try
                        myItem = myFolder.Items(i)             ← (※)ここで例外が発生します
                        If myItem.ReceivedTime >= dat最古受信日 Then

                       :

    myFolder.Items.Count は3306で、i=1996で下記例外が発生します。

    "型 'System.__ComObject' の COM オブジェクトをインターフェイス型 'Microsoft.Office.Interop.Outlook.MailItem' にキャストできません。"

    デバッガで、カウンタiを1997に変更後に処理を継続させると、特に問題なくループを最終まで実行しました。

    この1996番目のメール(と思しき物?)は何なのか?例外を起こさずに認識する手段は?

    (認識さえできれば、読まなきゃいいだけなので)

    これらご存知の方いらっしゃいましたら、よろしくお願い致します。

    2016年9月30日 10:06

回答

  • Folder オブジェクト (Outlook)の解説によると、

    通常、同じ働きをするアイテムを同じフォルダーに配置するのは適切な方法ですが、フォルダーには種類の異なるアイテムが格納される場合があります。たとえば、既定では、予定表フォルダーに AppointmentItem オブジェクトと MeetingItem オブジェクトが格納される場合や、連絡先フォルダーに ContactItem オブジェクトと DistListItem オブジェクトが格納される場合があります。一般に、フォルダー内のアイテムを列挙するときは、アイテムの種類を推測しないでください。アイテムに適用できるプロパティにアクセスする前に、アイテムのメッセージ クラスを確認します。

    だそうなので、Items(i)から返ってきたオブジェクトは、myItemに代入する前にClassプロパティがolMailであるか確認する必要があるでしょう。

    // このClassプロパティを持っていてあらゆるItemを代入可能な型があるかどうかは知りませんが。無いのであれば、この部分はレイトバインディングするしかないかも。

    2016年9月30日 11:16

すべての返信

  • Folder オブジェクト (Outlook)の解説によると、

    通常、同じ働きをするアイテムを同じフォルダーに配置するのは適切な方法ですが、フォルダーには種類の異なるアイテムが格納される場合があります。たとえば、既定では、予定表フォルダーに AppointmentItem オブジェクトと MeetingItem オブジェクトが格納される場合や、連絡先フォルダーに ContactItem オブジェクトと DistListItem オブジェクトが格納される場合があります。一般に、フォルダー内のアイテムを列挙するときは、アイテムの種類を推測しないでください。アイテムに適用できるプロパティにアクセスする前に、アイテムのメッセージ クラスを確認します。

    だそうなので、Items(i)から返ってきたオブジェクトは、myItemに代入する前にClassプロパティがolMailであるか確認する必要があるでしょう。

    // このClassプロパティを持っていてあらゆるItemを代入可能な型があるかどうかは知りませんが。無いのであれば、この部分はレイトバインディングするしかないかも。

    2016年9月30日 11:16
  • Hongliang 様

    回答ありがとうございます。

    受信フォルダにこんな裏事情があったなんて知りませんでした。

    (とは言っても、きちんと解説を読まなかった自分が悪いので、裏事情ではないのでしょうが…)

    と言う事で例外発生の理由・原因がわかったので、代入での型不一致の例外は読み飛ばすように致しました。

    詳細は下記

                    Try
                        myItem = myFolder.Items(i)             ← (※)ここで例外が発生します                                Catch ex As InvalidCastException
                        myItem = Nothing
                    End Try
                    If myItem IsNot Nothing Then
                            :

                    End If

    原因がわかりホッとしました。

    大変助かりました。

    とりあえずは暫定対応ですが、Classプロパティを持っていて代入できるItemの型が見つけたら、

    Classプロパティを評価する手法に切り替えようと思います。

    ありがとうございました。

    2016年10月3日 7:25