Office Space: Microsoft Outlook から定期的な予定の一覧を取得する

Office Space

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

Microsoft Outlook から定期的な予定の一覧を取得する

全体的に見て、Scripting Guy は期限に間に合わせたり期日に対応したりすることが苦手です。それは怠け者で無責任だからでしょうか。もちろん違います。むしろ、すべて Microsoft Outlook のせいです。私たちは事前に計画を立てようとしますが、収拾が付かなくなるのがおちの定期的な会議や予定はいつも忘れてしまいます。必要なのは、会議の日付、時刻、および場所を含む、すべての定期的な会議の一覧を取得するための迅速で簡単な方法です。しかし、私たちが知る限り、Outlook には定期的な予定に関する情報を取得するための迅速で簡単な方法は用意されていません。だから、会議を忘れたせいで期限に間に合わなかったときは、私たちを責めないで Outlook を非難してください。

注 : 当然、これは、Scripting Guy の座右の銘とうまく合っています。"責任は向こうにある。私でなく、向こうの、他の Scripting Guy のところに。"

はい、何でしょう。独力でやり遂げるべきで、すべての作業を Microsoft Outlook に頼ることはやめるべきだとおっしゃいましたか。このような情報を返す "スクリプト" を記述すべきだとおっしゃいましたか。うーん、突拍子もなさすぎて、かえってうまくいくかもしれません。

Const olFolderCalendar = 9

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

Set colItems = objFolder.Items

Set colFilteredItems = colItems.Restrict("[IsRecurring] = TRUE")

For Each objItem In colFilteredItems
    Set objPattern = objItem.GetRecurrencePattern
    If objPattern.PatternEndDate > Now Then
        Wscript.Echo "Meeting name: " & objItem.Subject
        Wscript.Echo "Duration: " & objItem.Duration & " minutes"
        Wscript.Echo "Location: " & objItem.Location
        Wscript.Echo
    End If
Next

このスクリプトでは、まず、olFolderCalendar という名前の定数を作成し、値を 9 に設定します。これは、情報の取得元となるフォルダ (予定表) を Outlook に指示するために後で使用します。次に、Outlook.Application オブジェクトのインスタンスを作成し、GetNamespace メソッドを使用して MAPI 名前空間にバインドします (そうですね、バインドできる名前空間が MAPI しかなくても、このコード行は必要です)。その後、次のように GetDefaultFolder メソッドを使用して Outlook 予定表にバインドします。

Set objFolder = objNamespace.GetDefaultFolder(olFolderCalendar)

(わかりましたか。定数 olFolderCalendar を後で使用すると言いましたよね。)

予定表にバインドしたら、次のコード行を使用して予定表フォルダにあるすべてのアイテムのコレクションを取得できます (参考までに、すべてのアイテムは AppointmentItem オブジェクトのインスタンスになります)。

Set colItems = objFolder.Items

ここはポイントです。これで、予定表にあるすべての予定と会議のコレクションを取得できました。しかし、本当に取得したかったのは "定期的" な予定と会議のコレクションです。でも、心配はいりません。Restrict メソッドを使用してこのコレクションをフィルタ処理し、定期的でない予定や会議を除外できます。次のコードでは、まさにこの処理が行われます。

Set colFilteredItems = colItems.Restrict("[IsRecurring] = TRUE")

ご覧のとおり、新しいコレクション (colFilteredItems という名前のコレクション) を作成しています。これは、Restrict メソッドを呼び出し、そのメソッドに次のパラメータを渡して行います。

"[IsRecurring] = TRUE"

皆さんの方がはるかに先を行ってますね。実を言うと、IsRecurring は AppointmentItem オブジェクトのプロパティで、指定された予定が複数回行われるようにスケジュールされているかどうかを判断します。IsRecurring が True の場合は、定期的な予定があります。IsRecurring が False の場合は、1 回で終わる予定です (これは好きな種類の会議ですが)。

注 : Restrict メソッドについてもっと詳しく知りたい場合は、前回の Office Space コラムを参照してください。

次は、For Each ループを設定して、このフィルタ処理されたアイテムのコレクションを調べます。その後、会議ごとに "件名"、"期間"、および "場所" を報告します。For Each ループからは、次のようなデータが返されます。

Meeting name: Updated: Scripting Guys Strategy Meeting
Duration: 60 minutes
Location: 43/3000

Meeting name: Updated: Script Center Refresh
Duration: 60 minutes
Location: Conf Room 5/1255 (10)

うまくいきましたね。

これはもう一つのポイントです。この特定のスクリプトは過小評価しなくても (結局このスクリプトをかなり使用して作業しましたが)、ほどほどにしか役立ちません。このスクリプトは、いくつかの定期的な予定があることを知らせてくれますが、それらの予定が "いつ" 行われるかについては日付や時刻など一切通知しません。計画を立て、期限を守ることが非常に困難でも無理はありません。ほら、Outlook のせいだと言ったでしょう。

そうでした。独力で、ということでしたよね。それでは、この問題をどう解決できるかを考えてみましょう。定期的な予定が行われる日時と頻度に関する情報は、RecurrencePattern オブジェクトという独立したオブジェクトに格納されます。GetRecurrencePattern メソッドを呼び出して、指定された予定に関連付けられている RecurrencePattern オブジェクトを取得する必要があります。この操作を行うと、予定が定期的に行われる頻度 (RecurrenceType)、各予定の開始時刻 (StartTime)、一連の予定の開始日 (PatternStartDate)、および一連の予定が終了するようにスケジュールされている日 (PatternEndDate) などの情報をエコー バックできます。このすべての処理を実行する変更後のスクリプトを次に示します。

Const olFolderCalendar = 9

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

Set colItems = objFolder.Items

strFilter = "[IsRecurring] = TRUE"

Set colFilteredItems = colItems.Restrict(strFilter)

For Each objItem In colFilteredItems
    Set objPattern = objItem.GetRecurrencePattern
    Wscript.Echo "Meeting name: " & objItem.Subject
    Wscript.Echo "Duration: " & objItem.Duration & " minutes"
    Wscript.Echo "Location: " & objItem.Location
    Wscript.Echo "Recurrence type: " & objPattern.RecurrenceType
    Wscript.Echo "Start time: " & objPattern.StartTime
    Wscript.Echo "Start date: " & objPattern.PatternStartDate
    Wscript.Echo "End date: " & objPattern.PatternEndDate
    Wscript.Echo
Next

上記のスクリプトを実行すると、次のような情報が返されます。

Meeting name: Updated: Scripting Guys Strategy Meeting
Duration: 60 minutes
Location: 43/3000
Recurrence type: 1
Start time: 1:00:00 PM
Start date: 5/27/2004
End date: 12/31/4500 11:59:00 PM

Meeting name: Updated: Script Center Refresh
Duration: 60 minutes
Location: Conf Room 5/1255 (10)
Recurrence type: 1
Start time: 11:00:00 AM
Start date: 6/25/2004
End date: 11/25/2005

ここでは、元のスクリプトに 2 つの新しい処理を追加しました。まず、各予定に関連付けられている RecurrencePattern オブジェクトを取得するために次のコード行を追加しました。

Set objPattern = objItem.GetRecurrencePattern

次に、その RecurrencePattern オブジェクトのプロパティをエコー バックするために、次の 3 行のコードを追加しました。この 3 行のコードでは、オブジェクト参照 objItem ではなく、オブジェクト参照 objPattern を使用していることに注意してください。これは、AppointmentItem オブジェクトではなく、RecurrencePattern オブジェクトを使用しているためです。確かにこれはややこしいですが、慣れるでしょう。

RecurrencePattern オブジェクトのプロパティをエコー バックする 3 行のコードを次に示します。

Wscript.Echo "Start time: " & objPattern.StartTime
Wscript.Echo "Start date: " & objPattern.PatternStartDate
Wscript.Echo "End date: " & objPattern.PatternEndDate

信じられないかもしれませんが、今は正しい方向に進んでいます。たとえば、これらの予定が定期的に行われる頻度を把握しています。問題なのは、RecurrenceType が次のいずれかの整数値で報告されるということだけです。

定数

olRecursDaily

0

olRecursMonthly

2

olRecursMonthNth

3

olRecursWeekly

1

olRecursYearly

5

olRecursYearNth

6

つまり、もう一度スクリプトを変更する必要があります。今回は、Select Case ブロックを使用して RecurrenceType を文字列値に変換します。Select Case ブロックは次のようになります。

Select Case objPattern.RecurrenceType
    Case 0 Wscript.Echo "Recurs daily."
    Case 1 Wscript.Echo "Recurs weekly."
    Case 2 Wscript.Echo "Recurs every N months."
    Case 3 Wscript.Echo "Recurs monthly."
    Case 5 Wscript.Echo "Recurs yearly."                
    Case 6 Wscript.Echo "Recurs every N years."
End Select

この変更後のスクリプトでは、RecurrenceType の値をエコー バックしません。この場合、RecurrenceType の値を "確認" して、より役立つ文字列値を代わりにエコー バックします。たとえば、RecurrenceType が 1 であると仮定します。この場合、"Recurs weekly" というメッセージをエコー バックします。次の特定のコード行で、この処理を行っています。

Case 1 Wscript.Echo "Recurs weekly."

変更後のスクリプトを実行すると、次のような出力が表示されます。

Meeting name: Updated: Scripting Guys Strategy Meeting
Duration: 60 minutes
Location: 43/3000
Recurs weekly.
Start time: 1:00:00 PM
Start date: 5/27/2004
End date: 12/31/4500 11:59:00 PM

Meeting name: Updated: Script Center Refresh
Duration: 60 minutes
Location: Conf Room 5/1255 (10)
Recurs weekly.
Start time: 11:00:00 AM
Start date: 6/25/2004
End date: 11/25/2005

ここで不足している情報が 1 つだけあります。それは、会議が行われる実際の曜日と日付です。実を言うと、少し複雑になってきているので、その部分は最後にとっておきました。各 RecurrenceType には、曜日と日付を正確に特定するのに役立つ一連のプロパティがあります。RecurrenceType と RecurrenceType に関連するプロパティの一覧については、「Microsoft Outlook VBA Language Reference」(英語) を参照してください。たとえば、毎週の予定には次の 2 つの関連付けられているプロパティがあります。

  • Interval: 会議が定期的に行われる頻度 (毎週、隔週、3 週間に 1 度など) を示します。

  • DayofWeekMask: 会議のある曜日 (月曜日、火曜日、水曜日など) を示します。

RecurrenceType と同様に、これらのプロパティの多くは整数値を返します。たとえば、DayOfWeekMask は次のいずれかを返します。

定数

olSunday

1

olMonday

2

olTuesday

4

olWednesday

8

olThursday

16

olFriday

32

olSaturday

64

つまり、本当に役立つ情報が返されるようにするには、これらのすべての整数値をもう少しわかりやすいものに変換する必要があります。このコラムでは、スペースの都合でそれぞれの変換について詳しく説明することができませんが、このような変換を実行するスクリプトをこのコラムの最後に付け加えておきます。

注 : 比較的簡単にしておくために、少しずるをして、すべての会議が特定の日 (たとえば、毎月第 2 木曜日) にだけ行われると想定します。たとえば、会議が毎月 2 日と毎週木曜日に行われるとしたらどうでしょうか。スクリプトを使用して情報を得ることはできますが、少し複雑になります。これについては、今後のコラムで取り上げる必要があります。つまり、このような一風変わった会議スケジュールがある場合は、今回のスクリプトは完全にではなく部分的に役立ちます。でも、後から修正する予定です。

ここでは、DayOfWeekMask の整数を会議が行われる曜日の名前に変換するコードを示しましょう。

Select Case objPattern.DayOfWeekMask
    Case 1
        strDay = "Sunday"
    Case 2
        strDay = "Monday"
    Case 4
        strDay = "Tuesday"
    Case 8
        strDay = "Wednesday"
    Case 16
        strDay = "Thursday"
    Case 32
        strDay = "Friday"
    Case 64
        strDay = "Saturday"
End Select

このスクリプトを実行すると、次のような出力が表示されます。

Meeting name: Updated: Scripting Guys Strategy Meeting
Duration: 60 minutes
Location: 43/3000
Occurs every Thursday.
Start time: 1:00:00 PM
Start date: 5/27/2004
End date: 12/31/4500 11:59:00 PM

Meeting name: Updated: Script Center Refresh
Duration: 60 minutes
Location: Conf Room 5/1255 (10)
Occurs every Friday.
Start time: 11:00:00 AM
Start date: 6/25/2004
End date: 11/25/2005

前よりもずっと良くなりました。

実際、定期的な予定を使用してできる処理はもっとたくさんありますが、今日はこれで十分でしょう (ご心配なく。いつかは頭の混乱も落ち着きますよ)。さて、お約束どおり、定期的な会議や予定を返す (また、わかりやすい形式に変換する) さらに完全なスクリプトを次に示します。ちなみに、次の新たな If-Then ブロックもスクリプトに追加しました。

If objPattern.PatternEndDate > Now Then

このブロックでは、単に、一連の定期的な予定の期限が既に切れているかどうかがチェックされます。切れている場合は、PatternEndDate の値が現在の日時よりも大きいことはなく、予定が出力に表示されません。そのため、今後の会議や予定に関する情報のみが返されます。

スクリプトは次のとおりです。

Const olFolderCalendar = 9

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

Set colItems = objFolder.Items

strFilter = "[IsRecurring] = TRUE"

Set colFilteredItems = colItems.Restrict(strFilter)

For Each objItem In colFilteredItems
    Set objPattern = objItem.GetRecurrencePattern
    If objPattern.PatternEndDate > Now Then
        Wscript.Echo "Meeting name: " & objItem.Subject
        Wscript.Echo "Duration: " & objItem.Duration & " minutes"
        Wscript.Echo "Location: " & objItem.Location
                Select Case objPattern.RecurrenceType
            Case 0 
                Wscript.Echo "Recurs daily."
            Case 1 
                If objPattern.Interval = 1 Then
                    Select Case objPattern.DayOfWeekMask
                        Case 1
                            Wscript.Echo "Occurs every Sunday."
                        Case 2
                            Wscript.Echo "Occurs every Monday."
                        Case 4
                            Wscript.Echo "Occurs every Tuesday."
                        Case 8
                            Wscript.Echo "Occurs every Wednesday."
                        Case 16
                            Wscript.Echo "Occurs every Thursday."
                        Case 32
                            Wscript.Echo "Occurs every Friday."
                        Case 64
                            Wscript.Echo "Occurs every Saturday."
                        End Select
                Else
                    Select Case objPattern.DayOfWeekMask
                        Case 1
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                " weeks on Sunday."
                        Case 2
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Monday."
                        Case 4
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Tuesday."
                        Case 8
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Wednesday."
                        Case 16
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Thursday."
                        Case 32
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Friday."
                        Case 64
                            Wscript.Echo "Occurs every " & objPattern.Interval & _
                                 " weeks on Saturday."
                        End Select
                    End If
            Case 2 Wscript.Echo 
               intInstance = objPattern.Instance
                Select Case intInstance
                    Case 1
                        strInstance = "first"
                    Case 2
                        strInstance = "second"
                    Case 3
                        strInstance = "third"
                    Case 4
                        strInstance = "fourth"
                    Case 5
                        strInstance = "fifth"
                    Case 6
                        strInstance = "sixth"
                End Select
                Select Case objPattern.DayOfWeekMask
                    Case 1
                        strDay = "Sunday"
                    Case 2
                        strDay = "Monday"
                    Case 4
                        strDay = "Tuesday"
                    Case 8
                        strDay = "Wednesday"
                    Case 16
                        strDay = "Thursday"
                    Case 32
                        strDay = "Friday"
                    Case 64
                        strDay = "Saturday"
                End Select
                intInterval = objPattern.Interval
                If intInterval = 1 Then
                    Wscript.Echo "Occurs on the " & strInstance & " " & strDay &  _
                        " of each month."
                Else
                    Wscript.Echo "Occurs on the " & strInstance & " " & strDay & _
                        " every " & intInterval & " months."
                End If         
            Case 3 
                If objPattern.Interval = 1 Then
                    Wscript.Echo "Recurs each month."
                Else
                    Wscript.Echo "Recurs every " & objPattern.Interval & " month."
                End If 
                intInstance = objPattern.Instance
                Select Case intInstance
                    Case 1
                        strInstance = "first"
                    Case 2
                        strInstance = "second"
                    Case 3
                        strInstance = "third"
                    Case 4
                        strInstance = "fourth"
                    Case 5
                        strInstance = "fifth"
                    Case 6
                        strInstance = "sixth"
                End Select
                Select Case objPattern.DayOfWeekMask
                    Case 1
                        strDay = "Sunday"
                    Case 2
                        strDay = "Monday"
                    Case 4
                        strDay = "Tuesday"
                    Case 8
                        strDay = "Wednesday"
                    Case 16
                        strDay = "Thursday"
                    Case 32
                        strDay = "Friday"
                    Case 64
                        strDay = "Saturday"
                End Select
                Wscript.Echo "Occurs on the " & strInstance & " " & strDay & " of the month."

            Case 5 
                strMonth = MonthName(objPattern.MonthOfYear)
                Wscript.Echo "Occurs each year on " & strMonth & " " & _
                    objPattern.DayofMonth & "."                 
            Case 6 
                intInstance = objPattern.Instance
                Select Case intInstance
                    Case 1
                        strInstance = "first"
                    Case 2
                        strInstance = "second"
                    Case 3
                        strInstance = "third"
                    Case 4
                        strInstance = "fourth"
                    Case 5
                        strInstance = "fifth"
                    Case 6
                        strInstance = "sixth"
                End Select
                Select Case objPattern.DayOfWeekMask
                    Case 1
                        strDay = "Sunday"
                    Case 2
                        strDay = "Monday"
                    Case 4
                        strDay = "Tuesday"
                    Case 8
                        strDay = "Wednesday"
                    Case 16
                        strDay = "Thursday"
                    Case 32
                        strDay = "Friday"
                    Case 64
                        strDay = "Saturday"
                End Select
                strMonth = MonthName(objPattern.MonthOfYear)
                Wscript.Echo "Occurs on the " & strInstance & " " & strDay & " of " & _
                    strMonth & " each year."
        End Select
        Wscript.Echo "Start time: " & objPattern.StartTime
        Wscript.Echo "Start date: " & objPattern.PatternStartDate
        Wscript.Echo "End date: " & objPattern.PatternEndDate
        Wscript.Echo
    End If
Next