Office Space: Outlook の仕事を操作する

Office Space

Office Space へようこそ。Office Space は、Microsoft® Office アプリケーションのスクリプト作成に関するヒントとテクニックを紹介するコラムです。毎週火曜日と木曜日に新しいヒントを掲載します。過去のヒントについては、Office Space アーカイブを参照してください。Microsoft Office でのスクリプト作成について質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。

Outlook の仕事を操作する

Microsoft では、Exchange サーバーが停止するたびに、業務が急停止します。この理由は、...少しお待ちください...

上司が最初の文を次のように変更してはどうかと言っています。"万が一" Microsoft で Exchange サーバーが停止した場合は、業務が急停止するでしょう。ここでは、...少しお待ちください...

いいでしょう。もし、どう考えてもあり得ないことですが万が一にも Exchange サーバーが...まあ、皆さん言いたいことはおわかりですね。

要点は、Microsoft では Exchange が日々の業務において重要な役割を担っているということです。一例を挙げると、かなりの従業員が同僚のことを名前ではなく電子メール アドレスを使って呼んでいます。Bill Gates ですって? だれですか。あ、billg のことですね。なぜそのように言ってくださらなかったのですか。

ほかに、多くの従業員が Microsoft Outlook のみで会議や予定を管理しているいることが挙げられます。森の中で木が 1 本倒れても、その周りにだれもいなければ、木が倒れたときに音がしたかどうかはわかりません。しかし、これだけはわかっています。Outlook に予定が記録されていなければ、その予定は存在しないのです。だれもその予定にあなたを参加させることなどできません。

言い換えれば、Outlook の予定表機能を使用するユーザーは非常に多く、Outlook の予定表なしには生活できなくなっているのです。しかし、おかしなことに、こういったユーザーは必ず作業が必要な仕事のリストを作成するにもかかわらず、これを電子形式では保存しないのです。代わりに、やるべき仕事を封筒の裏に書き留めたり、モニターに付箋で貼り付けたり、レポート用紙の余白に書き込んだりするのです。Outlook にやらなければならない仕事のすべてを記録するメカニズムが組み込まれていればいいのに。

まあ、言うまでもないことですが、Outlook にはやるべき仕事のすべてを記録するメカニズムが組み込まれています。しかし、どうしたわけか Outlook の仕事機能は Outlook の予定表ほどは利用されていません (たとえば、多くのユーザーが、特定の期限を設定した仕事を作成するのではなく、予定表を使って自分だけの予定を作成しています)。どうして Outlook の仕事機能を利用しないのでしょう。その質問に対して考えられる答えは 1 つだけあります。どれほど簡単に Outlook の仕事をスクリプトから利用できるのかを知らないのです。

しかし、それはもう過去の話です。新しい仕事を作成する必要がありますか。では、まさしくそのことをやってくれるスクリプトがここにあります。

Const olTaskItem = 3

Set objOutlook = CreateObject("Outlook.Application")
Set objTask = objOutlook.CreateItem(olTaskItem)

objTask.Subject = "Script Center Master Plan"
objTask.Body = "Final report for Script Center master plan."
objTask.ReminderSet = True
objTask.ReminderTime = #10/10/2005 12:00 PM#
objTask.DueDate = #10/11/2005 12:00 PM# 
objTask.ReminderPlaySound = True
objTask.ReminderSoundFile = "C:\Windows\Media\Ding.wav"

objTask.Save

簡単だと言いましたよね。このスクリプトでは、まず olTaskItem という定数を定義し、その値に 3 を設定しています。これは、後で実際に仕事を作成するときに使用します。次に Outlook.Application オブジェクトのインスタンスを作成してから、以下のコードを使って TaskItem オブジェクトのインスタンスを作成しています。

Set objTask = objOutlook.CreateItem(olTaskItem)

特に凝った操作はありません。単純に CreateItem メソッドを呼び出して定数 olTaskItem を渡し、Outlook で新しい仕事が作成されるようにしています。

その後、次のようなコードを使って、新しい仕事のプロパティに値を構成しています。

objTask.Subject = "Script Center Master Plan"
objTask.Body = "Final report for Script Center master plan."
objTask.DueDate = #10/11/2005 12:00 PM# 
objTask.ReminderSet = True
objTask.ReminderTime = #10/10/2005 12:00 PM#
objTask.ReminderPlaySound = True
objTask.ReminderSoundFile = "C:\Windows\Media\Ding.wav"

上記のプロパティが何に使われるかはそれほど苦労せずにおわかりになるでしょう。基本的に、ここでは 2005 年の 10 月 11 日の正午までに完了する必要がある Script Center Master Plan という名前の仕事を作成しています。また、この仕事のアラームも合わせて設定しています。正確に 24 時間前 (2005 年 10 月 10 日の正午) に、注意を引くための効果音 Ding.wav と共にアラームが表示されます。全体的に、とても単純な構成です。

注 : 上記のプロパティ以外にも仕事に構成できるプロパティがあることを付け加えておきます (完全な一覧については、MSDN の「Microsoft Outlook VBA Language Reference」(英語) を参照してください)。

上記のコードでは、新しい仕事がメモリ内に作成されます。実際にこの仕事を保存し、Outlook の仕事に追加するには、Save メソッドを呼び出す必要があります。

objTask.Save

とても簡単です。

けれども、皆さんの中には少し疑い深い方もいるようですね。結局、この仕事が実際に Outlook の仕事に追加されたことはどうやって確認するのでしょうか。そのような場合は常に、次のようなスクリプトを実行できます。これは、Outlook のすべての仕事の一覧を返すスクリプトです。

Const olFolderTasks = 13

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderTasks)

Set colTasks = objFolder.Items

For Each objTask In colTasks
    Wscript.Echo "Subject: " & objTask.Subject
    Wscript.Echo "Date due: " & objTask.DueDate 
    Wscript.Echo "Percent complete: " & objTask.PercentComplete 

    Select Case objTask.Status
        Case 0
            Wscript.Echo "Status: Not started."
        Case 1
            Wscript.Echo "Status: In progress."
        Case 2
            Wscript.Echo "Status: Complete."
        Case 3
            Wscript.Echo "Status: Waiting."
        Case 4
            Wscript.Echo "Status: Deferred."
    End Select

    Select Case objTask.Importance
        Case 0
            Wscript.Echo "Importance: Low"
        Case 1
            Wscript.Echo "Importance: Normal"
        Case 2
            Wscript.Echo "Importance: High"
        End Select

    Wscript.Echo "Last modified: " & objTask.LastModificationTime 
Next

これも単純なスクリプトなので、説明はほとんど要りませんね。このスクリプトでは、まず、定数 olFolderContacts を定義し、値を 13 に設定しています。この定数を使用して、どの Outlook フォルダの情報を取得するかを Outlook に指示します。続いて、Outlook.Application オブジェクトのインスタンスを作成し、GetNamespace メソッドを使用して MAPI 名前空間にバインドします (以前のコラムで説明したとおり、これは接続できる唯一の名前空間です。ただし、このコードはやはりスクリプトに含める必要があります)。仕事フォルダにアクセスするために、次に GetDefaultFolder メソッドを呼び出して、Outlook にアクセス先のフォルダを指示する定数を渡しています。

Set objFolder = objNamespace.GetDefaultFolder(olFolderTasks)

接続したら、次の 1 行のコードだけで仕事フォルダにあるすべてのアイテムのコレクションを取得できます。

Set colTasks = objFolder.Items

その後、For Each ループを設定して、単純に取得したコレクションのアイテム 1 つ 1 つについて、Subject、DateDue、PercentComplete などのプロパティの値をエコー バックしています。Body プロパティについては値を取得していないことに気が付かれたかもしれません。これは、Body プロパティを取得すると Outlook のセキュリティ警告がトリガされ、メッセージ ボックスに応答してスクリプトが取得対象の仕事にアクセスできるようにしなければならなくなるためです。Body プロパティの値を取得しないようにすることで、セキュリティ警告を回避し、スクリプトがユーザーの介入を必要とせずに実行できるようにしています。

また、Status および Importance の処理には Select Case ステートメントを使っていることにも気付かれたかもしれません。これは、これらのプロパティが値を整数として保持しているためです。たとえば、Status の場合値が 0 であれば仕事が開始されていないことを、1 であれば仕事が進行中であることを示します。これらの一見意味のない整数値を返すのではなく、Select Case を使用して値を解析し、適切なメッセージを返すようにしています。たとえば、Status の値が 2 の場合は、仕事が完了しているという事実をエコー バックしています。

Case 2
    Wscript.Echo "Status: Complete."

うまくいきましたね。

また、フィルタを使用して取得する仕事の種類を制限することもできます。たとえば、アクティブな仕事 (つまり、完了していない仕事) のみを取得したいとします。この操作を実行するサンプル スクリプトを次に示します。

Const olFolderTasks = 13

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderTasks)

Set colItems = objFolder.Items
strFilter = "[Complete] = FALSE"
Set colTasks = colItems.Restrict(strFilter)

For Each objTask In colTasks
    Wscript.Echo "Subject: " & objTask.Subject
    Wscript.Echo "Date due: " & objTask.DueDate 
    Wscript.Echo "Percent complete: " & objTask.PercentComplete 

    Select Case objTask.Status
        Case 0
            Wscript.Echo "Status: Not started."
        Case 1
            Wscript.Echo "Status: In progress."
        Case 2
            Wscript.Echo "Status: Complete."
        Case 3
            Wscript.Echo "Status: Waiting."
        Case 4
            Wscript.Echo "Status: Deferred."
    End Select

    Select Case objTask.Importance
        Case 0
            Wscript.Echo "Importance: Low"
        Case 1
            Wscript.Echo "Importance: Normal"
        Case 2
            Wscript.Echo "Importance: High"
        End Select

    Wscript.Echo "Last modified: " & objTask.LastModificationTime 
Next

今日のコラムでは、フィルタについての詳細な説明は省きます。詳細については、Microsoft Outlook 関連の以前のコラムを参照してください。ただし、フィルタを設定するには、2 行のコードで済むことを記しておきます。1 行はフィルタを指定する (この場合は、Complete プロパティが False である仕事のみを選択する) コードで、もう 1 行は指定した条件を基にアイテムの新しいコレクションを取得するコードです。

strFilter = "[Complete] = FALSE"
Set colTasks = colItems.Restrict(strFilter)

次に、For Each ループでは、元になったすべての仕事が含まれるコレクションではなく、この新しいフィルタされたコレクションのアイテム 1 つ 1 つに対して処理を行います。

もちろん、一番いいものは最後のお楽しみにとってあります。本当は気が進まない仕事が、仕事のリストにありませんか。その場合は、その仕事を削除してしまいましょう。

Const olFolderTasks = 13

Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objFolder = objNamespace.GetDefaultFolder(olFolderTasks)

Set colItems = objFolder.Items

strFilter = "[Subject] = 'Script Center Master Plan'"
Set colTasks = colItems.Restrict(strFilter)

For Each objTask In colTasks
    objTask.Delete 
Next

おわかりのように、このスクリプトは、完了していない仕事のみを返すこの前のスクリプトと似ています。この場合は、件名が Script Center Master Plan である仕事のみを返すフィルタを設定しています。

strFilter = "[Subject] = 'Script Center Master Plan'"
Set colTasks = colItems.Restrict(strFilter)

返されたコレクション内の仕事 1 つ 1 つに対して、Delete メソッドを呼び出して仕事のリストからこれを削除しています (ここでは、フィルタに指定した仕事の件名は一意であると仮定していますが、そうでない可能性もあります)。

objTask.Delete

これで、Script Center Master Plan については心配する必要はなくなりました。よく言われるように、Outlook にないものは、実在しないのです。