こちらの記事は2015年08月29日にQiitaに投稿したものを移植したものとなります。

Qiitaからの移植に当たって内容の精査は行っていません。
従って、記事は当時の私の知識や当時の技術そのままです。

OutlookのAPIを使用して共有の予定表を取得する


取得結果の絞り込みの方法とか、他人のスケジュールの取得に言及しているサイトがなかったので書いてみました。前提として、Outlookがインストールされている必要があります。

まず、参照に「Microsoft.office.interop.outlook.dll」を追加します。以下が実際のソースコードです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
using Microsoft.Office.Interop.Outlook; 

//省略//

var outlookApp = new Microsoft.Office.Interop.Outlook.Application();
var rObject = outlookApp.Session.CreateRecipient("MailAddress or PersonName");
MAPIFolder mapiFolder = outlookApp.Session.GetSharedDefaultFolder(rObject, OlDefaultFolders.olFolderCalendar);

DateTime dt = DateTime.Today;
//In Japan
string startDate = dt.ToString("yy/MM/dd");
string endDate = dt.AddDays(10).ToString("yy/MM/dd");

//開始日、終了日の間の予定で絞り込むとき
string filter = "[Start] >= '" + startDate + "' AND [Start] <= '" + endDate + "'";
//予定の題名を「元旦」で絞り込む場合
//string filter = "[Subject] = '元日'";
//終日の予定で絞り込む場合
//string filter = "[AllDayEvent] = True";

//指定した条件で絞り込み
var list = mapiFolder.Items.Restrict(filter);

//結果のソート
list.Sort("[Start]");

//取得数
int i = list.Count;

foreach (AppointmentItem n in list)
Console.WriteLine(" Subject:" + n.Subject + "Start:" + n.Start + " End:" + n.End);

ユーザの指定


「CreateRecipient」メソッドで予定表を取得したいユーザを指定し、Recipientオブジェクトを生成します。

その後、「GetSharedDefaultFolder」メソッドを呼び出して、指定したユーザの共有の予定表フォルダの情報を取得します。この時点で、条件による絞り込みはできません。

1
2
var rObject = outlookApp.Session.CreateRecipient("メールアドレスとか名前とか"); 
MAPIFolder mapiFolder = outlookApp.Session.GetSharedDefaultFolder(rObject, OlDefaultFolders.olFolderCalendar);

「CreateRecipient」メソッドで指定するユーザは前方一致検索のようです。完全一致でなくても取得可能です。例えば「Tanaka taro」さんと「Tanaka takahiro」さんがいた場合、「Tanaka tar」まで指定すれば、「Tanaka taro」さんの共有の予定表情報が取得できます。

名前だと一意に識別できない可能性があるので、実際はメールアドレスで指定することになると思います。

取得結果の絞り込み


取得後に「Find」メソッドか「Restrict」メソッドで取得結果を絞り込むことができます。「Restrict」の場合、結果をコレクションで取得することができます。

例えば、下記の場合は開始日と終了日の範囲に該当するものに絞り込みます。

1
2
string filter = "[Start] >= '" + startDate + "' AND [Start] <= '" + endDate + "'";
var list = mapiFolder.Items.Restrict(filter);

このとき、文字列で条件を指定する必要があります。文字列以外で絞り込む方法(「Find」「Restrict」メソッドを使用しない方法)は調べた範囲ではわかりませんでした。おそらく無いような気がします。

日付で絞り込む際の注意点として、「yy/MM/dd」形式を指定しないといけないようです。これ以外の形式ではうまくいきませんでした。

また、上記では開始日・終了日に日付をまたぐ予定が含まれているときに、その予定情報(開始日終了日にまたぐ予定)は取得できません。これは絞り込みを複数回に分ければなんとかなると思います。(試してませんが・・・)

それ以外にも、上記の方法で日付範囲指定した際に範囲外の予定が表示されてしまう場合があり、これに関しては原因はわかりませんでした。

その他


Exchange環境の場合、サービス参照でExchangeサーバのURLを指定し、「Exchangeservicebinding」クラスのメソッドを使用してユーザのフォルダIDを取得することで、共有の予定表を確認することができるようです。

http://blog.liris.org/2011/01/ms-exchangeidapi.html

私の場合はExchangeサーバを参照しても「Exchangeservicebinding」クラスが見つからずにこの方法は試せませんでした。
英語で「Exchangeservicebinding not found」とかで検索すると情報がたくさん出てくるので、調べれば原因は特定できそうですが・・・

参考リンク


https://msdn.microsoft.com/ja-jp/library/office/Ff184606.aspx
https://support.microsoft.com/ja-jp/kb/310244
https://msdn.microsoft.com/ja-jp/library/office/microsoft.office.interop.outlook._items.find
http://anopara.matrix.jp/2014/05/13/coutlookから予定表データとかを取得する/