適材適所

パソコンができることはパソコンに。PowerShellやVBAを中心に徒然なるままに書きます

VBAでNotesの特定のフォルダのメールを参照する

VBAを使って、Notesを操作するシリーズです。

今回は、特定のフォルダに格納されているメールを参照するサンプルを紹介したいと思います。

VBAでNotesを操作するシリーズ

VBAでNoteメールの添付ファイルを保存する - 適材適所
VBAでNotesメールを作成・送信する_ファイル添付 - 適材適所
VBAでNotesメールを作成・送信する_CC/BCCの追加 - 適材適所
VBAでNotesメールを作成・送信する_最も簡単なサンプル - 適材適所
VBAでNotesカレンダーを取得する簡単なサンプル - 適材適所
VBAでNotesメールを取得する簡単なサンプル - 適材適所

コード全体

いつものようにアーリーバインディングでNotesの各オブジェクトを参照していますので、

Louts Domino Objectへの参照設定を行ってから実行する必要があります。

Sub serchViews()
    Const PASSWORD As String = "(任意のパスワード)"
    Const SERVER As String = "(任意のサーバー名)"
    Const NOTES_FILE As String = "(任意のファイル名).nsf"
    
    'セッションを確立
    Dim notesSession As notesSession: Set notesSession = New notesSession
    notesSession.Initialize PASSWORD
    'Notesのデータベースを取得
    Dim notesDB As NotesDatabase: Set notesDB = notesSession.GetDatabase(SERVER, NOTES_FILE)
    
    Dim view As notesView
    Dim entries As NotesViewEntryCollection
    Dim notesDoc As NotesDocument
    Dim viewName As String
    Dim i As Long, j As Long
        
    'DataBaseのViewの数だけ処理する
    For i = 1 To UBound(notesDB.Views)
        Set view = notesDB.Views(i)
        viewName = view.Name
        'フォルダを対象にする
        If view.IsFolder Then
            'ユーザーが作ったフォルダを対象にする
            '(カレンダー)等の余計なフォルダも対象になってしまうため丸カッコで囲まれているものを除外
            'もう少しスマートな方法があればよいのですが・・・
            If Not (viewName Like "(*)") Then
                'ここででフォルダ名をイミディエイトウィンドウに表示してみる
                Debug.Print viewName
                'View⇒Entriy⇒Documentと取得する
                Set entries = view.AllEntries
                For j = 1 To entries.Count
                    Set notesDoc = entries.GetNthEntry(j).Document
                    '--以下好きな処理を実行する(ここでは例として件名をイミディエイトウィンドウに出力している)
                    Debug.Print notesDoc.GetFirstItem("Subject").Text
                Next j
            End If
        End If
    Next i
End Sub

コードの解説

コードについて細かく見ていきましょう。

    Const PASSWORD As String = "(任意のパスワード)"
    Const SERVER As String = "(任意のサーバー名)"
    Const NOTES_FILE As String = "(任意のファイル名).nsf"
    
    'セッションを確立
    Dim notesSession As notesSession: Set notesSession = New notesSession
    notesSession.Initialize PASSWORD
    'Notesのデータベースを取得
    Dim notesDB As NotesDatabase: Set notesDB = notesSession.GetDatabase(SERVER, NOTES_FILE)

ここまではお決まりのコードが並んでいます。

NotesSessionオブジェクトを取得し、データベースを取得しています。

データベースの中にはフォルダやメールがあります。

    Dim view As notesView
    Dim entries As NotesViewEntryCollection
    Dim notesDoc As NotesDocument
    Dim viewName As String
    Dim i As Long, j As Long

NotesViewというオブジェクトが登場します。

Viewはフォルダやカレンダーを表します。

(ちょっと不思議な感じですが・・・)

Notesのメールフォルダにアクセスするためには、クラスの関係がどのようになっているかを知る必要があります。

Notesの基本的なクラスはこのような階層関係になっています。

NotesSession |-NotesDatabase |-NotesView |-NotesDocument

今回のサンプルの肝はフォルダを表すNotesViewを操作することになります。

    DataBaseのViewの数だけ処理する
    For i = 1 To UBound(notesDB.Views)
        Set view = notesDB.Views(i)
        viewName = view.Name
       ・・・
    Next i

For文の内部は次で解説します。

まずは、外観を見ていきましょう。

先ほどの階層関係から。NotesDatabaseクラスのViewsプロパティを参照します。

Viewsプロパティは配列のため、Uboundで最大インデックスを取得できます。

もちろん、Viewsの中身は、フォルダやカレンダーなどのViewになります。

        Set view = notesDB.Views(i)
        viewName = view.Name

view変数にViewを格納しています。

そしてviewName変数にviewの名前を格納します。

つまりviewNameにはフォルダ名が格納されることになります。

次にForの中を見てみます。

        'フォルダを対象にする
        If view.IsFolder Then
            'ユーザーが作ったフォルダを対象にする
            '(カレンダー)等の余計なフォルダも対象になってしまうため丸カッコで囲まれているものを除外
            'もう少しスマートな方法があればよいのですが・・・
            If Not (viewName Like "(*)") Then
               ・・・
            End If
        End If

IF文の中は長くなるので次で説明します。

ここでは、Viewに対してユーザーが作ったフォルダだけを対象にするための判定を行っています。

NotesViewにはisFolderメソッドがあります。

このメソッドを使えば、そのViewがフォルダかどうかを調べることができます。

しかし、ユーザーが作ったフォルダかどうか判定するためにはこれだけでは不十分でした。

受信ボックス以下、システム標準のフォルダもViewであり、フォルダであるためTrueと判断されてしまいます。

そこで、システム標準のフォルダとユーザーが作成したフォルダを区別するために

If Not (viewName Like "(*)") Then

この判定をいれています。

システム標準のフォルダのNameを調べてみると、受信ボックスは($Inbox)、ゴミ箱は($Trash)といった具合に()で囲まれていることがわかります。

これを利用し、Like演算子を使って判断します。

最後にIFの中を見ていきます。

                'ここででフォルダ名をイミディエイトウィンドウに表示してみる
                Debug.Print viewName
                'View⇒Entriy⇒Documentと取得する
                Set entries = view.AllEntries
                For j = 1 To entries.Count
                    Set notesDoc = entries.GetNthEntry(j).Document
                    '--以下好きな処理を実行する(ここでは例として件名をイミディエイトウィンドウに出力している)
                    Debug.Print notesDoc.GetFirstItem("Subject").Text
                Next j

ここまで来てやっとNotesViewというフォルダの中のメールにアクセスできるようになります。

長かった。

早速見ていきましょう。

コメントにもあるように、Viewの下には、Entryという概念があるようです。

そしてEntryの下にDocument(メール)があります。

階層が深いですね。

NotesViewのAllEntriesプロパティがEntryの集まり(配列)になります。

そしてそのEntryを通してDocumentを参照することができます。

Set notesDoc = entries.GetNthEntry(j).Document

それがこの部分です。

長かったですが、ここまで来ればDocumentに対する操作になり、やりやすくなります。

メールの添付ファイルを操作することもできますし、

From(送信者)やSubject(題名)、DeliveredDate(送受信日)などを参照してメールを特定してから処理をすることもできます。

それぞれのやり方は過去記事をご覧ください。

おわりに

ここまで書いておいて、やっぱりNotesのクラス構造は奥が深い(意味f・・ゲフン)なぁと思った次第です。

最近もっぱら下火のNotesですが、なくなったわけではないでしょうから、ひっそりと生き残っていくと思います。

少しずつですが、こういった地味なサンプルを引き続き紹介していければと思います。

ここまでお読みいただきありがとうございました。