- 指定した日時において、指定したユーザーのOutlook予定表がどんな状態か調べます。(予定なし、取り込み中、外出中など)
- 複数ユーザーの予定を一気に取得します。
アプリケーションの構成
- PowerAppsから複数ユーザーのUPN (メールアドレス) をカンマでつなげた文字列をPower Automateフローへ渡します。
- Power AutomateではGraph APIのcalendar: getScheduleを使って状態 (availabilityView) を取得します。
- Power Automateフローから返されたJSONをコレクションに変換し、一覧表示します。
Power Appsからカンマ区切りメールアドレスと日時を渡す
UPNの入ったコレクションcolUPNsがあった場合、Concat関数を使い以下のようにして結合できます。
Concat(colUPNs, ThisRecord.Value, ",")
日時は”yyyy-mm-ddThh:nn:ss”形式で渡す必要があるので、Text関数で形式を指定します。現時刻を渡す場合の例は以下の通り。
Text( Now(), "yyyy-mm-ddThh:mm:ss" )
Power Automateフローで状態 (availabilityView) を取得

前準備として、トリガーで渡される日時を適切な形式にします。作成アクション (作成 input datetime) で以下のように書きます。
formatDateTime(triggerBody()?['text_1'], 'yyyy-MM-ddTHH:mm:00Z')
前準備として、入力されたUPNsをダブルクォーテーションで囲んだメールアドレスに変更します。
aaa@sample.com,bbb@sample.com を “aaa@sample.com”,”bbb@sample.com”
作成アクション (作成 – カンマ区切りUPNsを変換) に以下の式を入力します。ここでtriggerBody()?[‘text’]はトリガーのUPNsです。
concat('"', replace(triggerBody()?['text'], ',', '","'), '"')
このフローの主役はOffice365 Oulookコネクタの「HTTP要求を送信します」アクションを使用します。Graph APIのcalendar: getScheduleを参考にして記入します。
schedulesの[]の中には、直前に作った作成アクションの出力を入れています。
startTimeとendTimeのdateTimeはトリガーで指定した日時を指定のフォーマットにしています。startTimeは以下のように指定します。
outputs('作成_input_datetime')
また、endTimeはaddMinutes関数を使いstartTimeの60分後に設定します。
formatDateTime(addMinutes(outputs('作成_input_datetime'), 60), 'yyyy-MM-ddTHH:mm:00Z')

availabilityViewはavailabilityViewInterval (分) で区切られた時間幅で指定した時刻から先の予定を数値で返します。指定した時刻直後であれば、先頭の数値だけ見ればOKです。数値の意味はリンク先または以下の表を見てください。
「外出中」は日本語訳がおかしく「不在」がいいところです。
「他の場所で仕事中」の予定は、getScheduleで状態を取得すると4でなく0が出力されます。リンク先をよく読むと書いてあります。
| availabilityViewの数値 | Outlook予定表の状態 |
| 0 | 予定なし free |
| 1 | 仮の予定 tentative |
| 2 | 取り込み中 busy |
| 3 | 外出中 out of office |
| 4 | 他の場所で仕事中 Working elsewhere |
「HTTP要求を送信します」アクションの出力は「JSONの解析」アクションで配列に変換します。スキーマは以下のように書けます。
{
"type": "object",
"properties": {
"value": {
"type": "array",
"items": {
"type": "object",
"properties": {
"scheduleId": {
"type": [
"string",
"null"
]
},
"availabilityView": {
"type": [
"string",
"null"
]
},
"workingHours": {
"type": [
"object",
"null"
],
"properties": {
"startTime": {
"type": [
"string",
"null"
]
},
"endTime": {
"type": [
"string",
"null"
]
}
}
}
}
}
}
}
}
「JSONの解析」アクションから必要な項だけ抽出するには選択アクションを使います。うまく動的コンテンツが出ない場合は、数式でitem()?[‘scheduleId’]やitem()?[‘availabilityView’]と入力します。

最後のPower Appsに応答するアクションで終わりです。選択アクションの出力をそのまま指定すればOKです。

Power AppsでPower Automateフローから返されたJSONをコレクションに変換
JSONからコレクションに変換するにはparseJSONを使用します。
PowerAutomateから戻り値がlocResultに入っておりコレクションcolAvailabilityにするとしたら次のように書けます。
ClearCollect(colAvailability, parseJSON(locResult));
あとはThisRecord.availabilityViewの値を使ってFilterしたり色を付けたりといった処理をします。StartWith関数を使うと便利です。
権限に関する注意
この手法で予定の状態を取得するには、予定表に対して「空き時間情報を表示可能」以上のアクセス許可が必要です。「非公開」設定された予定表の情報を取得しようとするとGraph APIがエラーを吐きます。該当する予定表を管理するユーザーにアクセス許可を見直してもらう必要があります。
アクセス許可の変更は、対象の予定表(Outlook予定表の画面で左カラムにある)の上にマウスカーソルをホバーしたときに出現する三点ボタンからメニューを開き、「共有とアクセス許可」をクリックすることでアクセス許可変更画面が出ます。
余談ですが「空き時間情報を表示可能」レベルではgetScheduleは動くもののcalendarViewのshowasを読み取ることができません。showasが読めるとavailabilityViewが4の予定も見えるんですが。
その日が休暇予定か否かの判定
ある人の予定が終日休暇で「外出中」としているのか、一部の時間だけ不在なのを「外出中」としているのか、どのように判別すればいいでしょうか?
getScheduleでは指定した時刻からavailabilityViewIntervalの間の予定が調べられます。取り込み中よりも外出中のほうが優先されるため、availabilityViewIntervalで調べる時間の一部にでも外出中の予定があると外出中を示す3が戻ります。たとえばavailabilityViewIntervalを1440分 (設定できる最大値)にすると1日のどこかで外出中があるだけで3が戻ります。
終日不在予定なのかを判定するには、availabilityViewIntervalを短い時間に区切って得られるavailabilityView文字列を調べます。availabilityViewIntervalを60分として24時間の範囲で予定を調べると、終日「外出中」の予定が設定されていれば24個の3が並びます (例: 333333333333333333333333)。もし午前中だけ「外出中」であれば午後は3以外の値が並びます (例: 000000003333000222000000)。標準的な勤務時間帯がすべて3であった場合、終日不在とみなすことができます。
PowerAppsではMID関数で文字列の一部を抜き出せます。0時から24時のavailabilityViewに対して MID(availabilityView, 10, 8) と指定すれば9時から17時のavailabilityViewを抽出できます。条件式 MID(availabilityView, 10, 8) = “33333333” がTrueであれば終日不在とみなせます。
複数日にまたがるavailabilityViewを調べる場合、n日目はMID(availabilityView, 10 + 24*(n-1), 8) すなわち MID(availabilityView, 24*n – 14, 8) について同様の判定を行えばいいわけです。






