
Office Space へようこそ。Office Space は、Microsoft® Office アプリケーションのスクリプト作成に関するヒントとテクニックを紹介するコラムです。毎週火曜日と木曜日に新しいヒントを掲載します。過去のヒントについては、Office Space アーカイブを参照してください。Microsoft Office でのスクリプト作成について質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
私たちは Microsoft Scripting Guys であるという事実にもかかわらず、人生で直面するあらゆる問題に対する処方箋となるようなスクリプトをご紹介できたことはないと感じています (ほとんどのスクリプトはお役にたったでしょうが、すべてではないでしょう)。実際、システム管理となると、短時間で簡単に作成できるソリューションが常にベスト ソリューションであるという考え方があります。コマンド ライン ツールやグラフィカル ユーザー インターフェイスを使用するよりも、スクリプトを記述したほうが手早く簡単であると思っています。ただし、これは常にそうだとは限りません。スクリプトよりも GUI を使用したほうが簡単で仕事が早いなら、GUI の使用をお勧めするでしょう (そうなれば、私たちが書かなければならないスクリプト コラムも 1 つ減るでしょうから)。
その好例は Microsoft Outook です。Office Space では、次の 2 つの理由で Outook を詳しく取り上げませんでした。まず、「Outlook のユーザー インターフェイスはよくできている」こと。もう 1 つは、「Outlook に追加された新しいセキュリティ機能のお陰で、これ以上、Outlook スクリプトを作成しても、今以上に手早く簡単にスクリプト作成できるとは保証できなくなり、常に無人で実行できるとは限らない」からです。Microsoft Outlook でのスクリプトに関するコラムを書こうと思っても、スクリプトのほうがユーザー インターフェイスよりも優れていなければ意味がありません。
これが当てはまるのが、電子メール メッセージのフィルタ処理です。大部分のユーザーは、特定の条件に合致したメール メッセージをすべて取得して何らかの処理を行いたいと考えています。 たとえば、Ken Myer から送信されたすべてのメッセージを受信トレイから別のフォルダに配置することが考えられます。事業計画という件名のすべてのメッセージを印刷するにはどうすればよいのでしょう。再検討すべきすべてのメッセージに印を付け、1 つの Word ドキュメントにテキストを落とすこともあります。このような作業はユーザー インターフェイスから行うことができますし、さほど複雑でない次のようなスクリプトを使用して行うこともできます。
Const olFolderInbox = 6
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderInbox)
Set colItems = objFolder.Items
Set colFilteredItems = colItems.Restrict("[Subject] = 'Project Proposal'")
For Each objMessage In colFilteredItems
objMessage.PrintOut
Next
事業計画という件名のすべての電子メールを自動印刷するこのスクリプトは、olFolderInbox という定数を定義し、その値を 6 に設定することから始まります。この定数は、バインドする Outlook フォルダを指定します。次に、Outlook.Application オブジェクトのインスタンスを作成し、GetNamespace メソッドを使用して MAPI 名前空間 (偶然にも、バインドが可能な唯一の名前空間) にバインドします。次に GetDefaultFolder メソッドを呼び出し (olFolderInbox 定数を唯一のパラメータとして渡し)、これにより受信トレイとの接続を作成します。
さて、これからがプログラムの佳境です。まずは、次のコード行を使用して、受信トレイにあるすべてのアイテムのコレクションを取得します。
Set colItems = objFolder.Items
このコレクションを取得したら、Restrict メソッドを呼び出して指定された条件に合わないメールを除外します。この場合、受信トレイから電子メールが削除されるわけではありません。件名が「事業計画」というすべてのメールを取得し、これらを colFilteredItems という新しいコレクションに配置するだけです。これは、角かっこで電子メール メッセージ プロパティ (件名) を囲み、等号を追加し、単一引用符で対象件名行を囲むことによって行います。 つまり、次のようになります。
Set colFilteredItems = colItems.Restrict("[Subject] = 'Project Proposal'")
Ken Myer からのメールだけを取得したい場合はどうすればよいのでしょうか。これも、上の例と同じです。
Set colFilteredItems = colItems.Restrict("[From] = 'Ken Myer'")
同じように、電子メール メッセージ プロパティ (送信者) を角かっこを囲み、等号を追加し、単一引用符で対象件名を囲みます。
再検討する電子メール アイテムに印を付けるにはどうすればよいのでしょうか。MailItem の説明を Microsoft Outlook VBA Language Reference (英語) で調べると、FlagStatus プロパティが整数値であることが確認できます。さらに詳しく調査すると、メッセージが再検討のために印が付けられていることを指示するには、プロパティ値 2 を使用することがわかります (ヒント : 定数 olFlagStatus の列挙値を確認してください)。コードは次のようになります。
Set colFilteredItems = colItems.Restrict("[FlagStatus] = 2")
値 2 は単一引用符で囲みません。文字列値は単一引用符で囲みます。数値やブール値を処理する場合は不要です。 たとえば、次のコードは未読メッセージのコレクションを取得します。
Set colFilteredItems = colItems.Restrict("[Unread] = True")
簡単でしょう。一般的に、MailItem オブジェクトのプロパティであれば、これを使用してフィルタ処理できます。フィルタ処理要件を組み合わせることもできます。たとえば、Ken Myer からの未読メッセージだけを取得するとしましょう。次のようにします。
Set colFilteredItems = colItems.Restrict("[Unread] = True AND [From] = 'Ken Myer'")
このケースでは別個の 2 つのフィルタ、すなわち、[Unread] = True および [From] = 'Ken Myer' を使用します。ここでは、AND 演算子を使用して 2 つのフィルタを組み合わせています。
あるいは、Ken Myer または Pilar Ackerman いずれかの電子メールのみを取得することもできます。
Set colFilteredItems = colItems.Restrict("[From] = 'Ken Myer' OR [From] = 'Pilar Ackerman'")
いかがでしょうか。
素晴らしいのは、電子メールを絞り込んで取得できるだけではなく、メール コレクション全体を操作できることです。 サンプル スクリプトでは、PrintOut メソッドを使用してコレクション内の各電子メールを印刷します。
For Each objMessage In colFilteredItems
objMessage.PrintOut
Next
Word ドキュメントやデータベースに各メッセージを落とすことも簡単にできます。あるいは、コマンド ウィンドウに各メッセージを表示することもできます。この操作は、Body プロパティの値をエコーバックすることによって行えます。
For Each objMessage In colFilteredItems
Wscript.Echo objMessage.Body
Next
同様に、電子メールも、コマンド ラインからすばやく簡単に読むことができます。
注 : メッセージ本文をエコーバックする場合は、表示されるダイアログ ボックスに対してセキュリティ対策を施す必要があります。 |
Outlook のユーザー インターフェイスよりもスクリプトのほうが適しているのは、この電子メールのフィルタ処理だけであるとしたのは前にも述べたとおりです (そして幸いにも、スクリプティングが本領を発揮できる場所がまだまだあることがわかりました。失業したくないので、私たちも必死です)。本日ご紹介したスクリプトがすべての問題を解決できるかどうは保証できません。しかし、まったく役立たずであることも断言はできません。とりあえず試していただいてご判断ください。