OUTLOOK VBA オブジェクトまとめ Store オブジェクト補足3 SearchFolderを別角度から

##前回からの流れ
[OUTLOOK VBA オブジェクトまとめ](http://qiita.com/Q11Q/items/ac14d96c00e707de5d13)
[OUTLOOK VBA オブジェクトまとめ Store オブジェクト補足 StoreオブジェクトはVBSで使用できる](http://qiita.com/Q11Q/items/c42099d1365a2f8a6298)
[OUTLOOK VBA オブジェクトまとめ Store オブジェクト補足2 未完のSearchFolder](http://qiita.com/Q11Q/items/476fd5c6c5d54d65e19e)
の続きでサーチフォルダを別の角度から責めてみます。
#準備
##ThisOutlookSession
ExcelのVBAには標準のモジュールのほかにThisworkbook,ワークシートごとのコードを書く場所が存在します。
Microsoft Outlook Objectというフォルダに
ThisOutlookSession
というのがあります。
これはAlt+F11でVBEを起動しF7でプロジェクトエクスプローラを起動させると見つけることができます。
そしてThisOutlookSessionをクリックして指定したらコードウィンドの上に(General)(Declare)
と書いてあるので(Declare)の右横の矢印をクリックしてApplicationniに変えます。
そして右側の窓がItemsendなどと表示されますのでさらに右横の矢印をクリックしてAdvancedSearchCompletedを探します。
するとコードウィンドに

```vbnet
Private Sub Application_AdvancedSearchComplete(ByVal SearchObject As Search)

End Sub
```
と表示されます
この間に
MsgBox "The AdvancedSearchComplete Event fired for " & _
SearchObject.Tag & " and the scope was " & SearchObject.Scope
blnSearchComp = True
をいれて下記のようにします

```vbnet
Private Sub Application_AdvancedSearchComplete(ByVal SearchObject As Search)
MsgBox "The AdvancedSearchComplete Event fired for " & _
SearchObject.Tag & " and the scope was " & SearchObject.Scope
blnSearchComp = True
End Sub
```
これが下記の文中では
AdvancedSearchCompleteイベント サブルーチン
などと呼ばれます。
次にプロジェクトエクスプローラで標準モジュールをクリックします

##モジュールレベルの変数の宣言
標準モジュールのDeclare部に次の1行をコピペします

```vbnet
Public blnSearchComp As Boolean
```

#本論
###Application.AdvancedSearchメソッド
- AdvancedSearch メソッド、および Outlook オブジェクト モデルに含まれるその関連機能では、Outlook のユーザー インターフェイスに表示される検索フォルダーは作成されません。
- ***ただし、返された Search オブジェクトの Save メソッドを使用すると、Outlook のユーザー インターフェイスの検索フォルダーの一覧に表示される検索フォルダーを作成することができます。***

 - Scope パラメーターを使用して、同じストアに 1 つ以上のフォルダーを指定することができます
 - 複数のストアに複数のフォルダーを指定することはできません。
 - **Scope パラメーターで同じストアに複数のフォルダーを指定するには、各フォルダーのパスの間にコンマ文字を使用し、各フォルダーのパスを単一引用符で囲みます。受信トレイや送信済みアイテムなどの既定のフォルダーでは、完全なフォルダー パスではなく、単純なフォルダー名を使用できます。たとえば、次の 2つのコードは、有効な Scope のパラメーターを表します。**
 - ここからがよくわからないのだが、Scopeの指定はInbox Sent Item の場合と"'受信トレイ', '送信済みアイテム'"の場合がある。エラーがでたら日本語の名前に変えてみる。

```vbnet
Scope = "'InBox', 'Sent Items'"    '<--レファレンスにある方法。これでうまくいかないときは日本語にする

Scope = "'受信トレイ', '送信済みアイテム'" '<--レファレンスにある方法。これでうまくいかないときは日本語にする

Scope = "'" & Application.Session.GetDefaultFolder(olFolderInbox).FolderPath _
& "','" & Application.Session.GetDefaultFolder(olFolderSentMail).FolderPath & "'"
```

- Filter パラメーターには、有効な DASL クエリを指定できます。DASL クエリの詳細については、[「アイテムをフィルターにかける」](https://msdn.microsoft.com/ja-jp/library/office/ff863965.aspx)、および[「名前空間でプロパティを参照する」]( https://msdn.microsoft.com/ja-jp/library/office/ff868915.aspx)を参照してください。
- 高度な検索の Filter パラメーターに JET クエリを使用することはできません。
- Scope パラメーターで指定されたフォルダーが含まれるストアでクイック検索が有効になっている場合は、クイック検索キーワードを使用して検索のパフォーマンスを向上させることができます。
- クイック検索が無効なときにクイック検索キーワードを使用すると、Outlook はエラーを返し、検索は失敗します。

指定された DAV Searching and Locating (DASL) 検索文字列に基づいて検索を実行します。
構文
式.AdvancedSearch(Scope, Filter, SearchSubFolders, Tag)

####[GetTable メソッド](https://msdn.microsoft.com/ja-jp/library/office/ff863660.aspx)
- Application.AdvancedSearch メソッド呼び出しの Filter パラメーターによってフィルターされたアイテムが含まれる Table オブジェクトを取得します。
- マッチング とは異なり、これらは、フィルターパラメーターを使用できません。テーブルのフィルターは、 Search.Filterによって決定されます。
- Search.Filterは読み取り専用プロパティなので、 Application.AdvancedSearchメソッドのフィルターパラメーターは、これらによって返されるTableオブジェクトのフィルターを確立します。

- Application.AdvancedSearchに指定されたフィルターパラメーターは、DASL クエリである必要があります。たとえばのフィルターは、JET クエリを受け付けません。プリフィックスを付けないでください DASL クエリでは、"@SQL ="からはじまります。追加する場合、"@SQL ="プレフィックス、クエリでエラーが発生します。詳細については、フィルタの項目を参照してください。

- これらは、親フォルダーのフォルダーの種類に設定する既定の列を持つテーブルを返します。既定の列セットを変更するには、 Columnsコレクションのオブジェクトの追加、削除、またはRemoveAllメソッドを使用します。既定の列セットの詳細については、 Table オブジェクトに表示される既定のプロパティを参照してください。

- マッチングとは異なりTable.Restrictを使用して、 *Searchオブジェクトに基づくテーブルにさらにフィルターを適用できません。*フィルターを再適用するのには、 Application.AdvancedSearchで新しいフィルターを指定します。
- **つまりサーチフォルダを作ってしまうと、さらに絞り込む(Restrict)ことができない**


####[Save メソッド](https://msdn.microsoft.com/ja-jp/library/office/ff868367.aspx)
- 検索フォルダーに検索結果を保存します。
- Saveメソッドでは、同じ名前の検索フォルダーが既に存在する場合、エラーが表示されます。
- 件名 'テスト' を持つアイテムの受信トレイを検索し、結果を検索フォルダーに保存します。
- AdvanceSearchCompleteイベント プロシージャは、検索が完了すると、true を指定するブール値のblnSearchCompを設定します。
- TestAdvancedSearchComplete()プロシージャはこのブール型の変数を使用して、検索が終了すると判断します。サンプル コードは、 ThisOutlookSessionなどのクラスモジュールに配置する必要があり、Outlook によってイベント プロシージャを呼び出す前に、 TestAdvancedSearchComplete()プロシージャを呼び出す必要があります。
- しかし上記の準備をしていれば、下記のコードを標準モジュールにコピペするだけで動きます。

```vbnet:TestAdvancedSearchComplete
Sub TestAdvancedSearchComplete()
Dim sch As Outlook.Search
Dim rsts As Outlook.Results
Dim i As Integer
blnSearchComp = False
Const strF As String = "urn:schemas:mailheader:subject = 'テスト'"
Const strS As String = "Inbox"
Set sch = Application.AdvancedSearch(strS, strF)
While blnSearchComp = False
DoEvents
Wend
sch.Save("Subject Test")
End Sub

```

####[Stop メソッド](https://msdn.microsoft.com/ja-jp/library/office/ff868896.aspx)
現在実行中の検索を直ちに終了します。


####[Application プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff868188.aspx)
####[Class プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff861620.aspx)
####["Filter/フィルター" プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff869970.aspx)
検索の範囲を指定したデータのサブセットに制限するために使用する DASL ステートメトを表す文字列値を返します。 読み取り専用
次の Microsoft Visual Basic for Applications (VBA) の例では、新しいSearchオブジェクトを作成します。イベント サブルーチンは、検索が終了して、検索結果と共にSearchオブジェクトのタグとフィルターのプロパティが表示されます。
検索オブジェクトに格納されたデータの整合性を確保するのには、

AdvancedSearchCompleteイベント サブルーチンを使用します。

```vbnet:
Sub TestAdvancedSearchComplete()
'MSの現サイトTestAdvancedSearch111Completeは誤り
'List all items in the Inbox that do NOT have a flag:
Dim objSch As Outlook.Search
Const strF As String = "urn:schemas:httpmail:messageflag IS NULL"
Const strS As String = "受信トレイ"
Dim rsts As Outlook.Results
Dim i As Integer
blnSearchComp = False
Const strF1 As String = "urn:schemas:mailheader:subject = 'テスト'"
Const strS1 As String = "Inbox"
Set objSch = _
Application.AdvancedSearch(Scope:=strS1, Filter:=strF1, _
Tag:="FlagSearch")
While blnSearchComp = False
DoEvents
Wend
Set rsts = objSch.Results
For i = 1 To rsts.Count
MsgBox rsts.Item(i).SenderName
Next
End Sub
```

####[IsSynchronous プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff869576.aspx)
検索が同期するかどうかを示す値を返します。読み取り専用です。Boolean

 - 同期または非同期の検索をすることができます。
 - 検索が同期の場合は、検索が完了するまでコードの実行が一時停止します。
 - 検索が非同期の場合は、コード実行が継続される場合でも、検索が完了します。
 -  非同期検索から意味のある結果を得るために、検索が完了したときに通知するのには、 AdvancedSearchCompleteイベントを使用します。

####[Parent プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff869782.aspx)

####[Results プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff863973.aspx)
検索の結果を指定する結果のコレクションを返します。読み取り専用です。

####[Scope プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff868452.aspx)
指定した検索のスコープを指定する文字列を返します。読み取り専用です。

- 検索が開始されると、検索のスコープが定義されています。詳細については、[AdvancedSearchメソッド]( https://msdn.microsoft.com/ja-jp/library/office/ff866933.aspx)を参照してください。
- 検索範囲の指定は、たとえば、フォルダー パスなどを指定します。フォルダー パスは単一引用符で囲むことをお勧めします。
- 単一引用符で囲まなかった場合、フォルダー パスに Unicode の文字が含まれていると、正しい結果を取得できないことがあります。
- 複数のフォルダー パスを指定するには、各フォルダーパスを単一引用符で囲み、コンマで区切ります。


####[SearchSubFolders プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff862523.aspx)
検索範囲に検索するフォルダーのサブフォルダーが含まれているかどうかを示す値を返します。読み取り専用です。 Boolean型
Trueの場合サブフォルダーまで検索します。

####[Session プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff867595.aspx)
####[Tag プロパティ](https://msdn.microsoft.com/ja-jp/library/office/ff869834.aspx)

- 現在の検索条件の名前を指定する文字列を返します。Tagプロパティを使用して、特定の検索を識別します。読み取り専用です。
- Search オブジェクトを作成すると、TagプロパティはAdvancedSearchメソッドを使用することによって設定されます。
- 以下のサンプルはユーザーの受信トレイのテストという単語が含まれるメールのうち、フラグがないすべてのアイテムを検索します。
- Tagプロパティによって指定された名前"FlagSearch"で、検索結果与えられます。
- AdvanceSearchCompleteイベント プロシージャは、検索が完了すると、 true を指定するブール値のblnSearchCompを設定します。
- AdvanceSearchCompleteイベント プロシージャでは、ユーザーが通常検索では、非同期 ( IsSynchronousプロパティを決定するかどうか、検索が同期または非同期)、使用するため、検索が完了したか識別することができ、同時に複数の検索を実行することができますので、ユーザーにタグが表示されます。
- 下記のコードは受信フォルダのメールで件名に「懇親会」という単語が含まれているものを検索し、その送信者をMsgBoxに一つ一つ表示します。
- つまりあまり役立たないコードですがワイルドカードに%を使用しているというのがポイントです。
- またこの場合は受信トレイではなくInBoxが正しいです。

```vbnet:
Sub TestAdvancedSearch111Complete()
'List all items in the Inbox that do NOT have a flag:
Dim objSch As Outlook.Search
Const strF As String = "urn:schemas:httpmail:messageflag IS NULL"
Const strS As String = "Inbox" '受信トレイにするとエラー
Dim rsts As Outlook.Results
Dim i As Integer
blnSearchComp = False
Const strF1 As String = "urn:schemas:mailheader:subject like '%懇親会%'"
Const strS1 As String = "Inbox" '受信トレイにするとエラー
Set objSch = _
Application.AdvancedSearch(Scope:=strS1, filter:=strF1, _
Tag:="FlagSearch")
While blnSearchComp = False
DoEvents
Wend
Set rsts = objSch.Results
For i = 1 To rsts.Count
MsgBox rsts.Item(i).SenderName
Next
End Sub
```