月別アーカイブ: 2026年4月

指定した日時で複数ユーザーのOutlook予定表空き状態を一覧化する

  • 指定した日時において、指定したユーザーのOutlook予定表がどんな状態か調べます。(予定なし、取り込み中、外出中など)
  • 複数ユーザーの予定を一気に取得します。

アプリケーションの構成

  1. PowerAppsから複数ユーザーのUPN (メールアドレス) をカンマでつなげた文字列をPower Automateフローへ渡します。
  2. Power AutomateではGraph APIのcalendar: getScheduleを使って状態 (availabilityView) を取得します。
  3. 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) について同様の判定を行えばいいわけです。

グループアドレスをもとにチームのメンバーを一致させる

Microsoft Teamsのチームにユーザーを追加するときグループアドレスを使用すると、操作した時点のグループアドレスに含まれるユーザーが追加されます。しかし、グループアドレスに含まれるユーザーが変更されてもチームのユーザーは更新されません。

この記事ではPower Automateを使ってグループアドレスに含まれるメンバーを自動的にチームに追加する手順を紹介します。追加手順だけ示しますが、簡単な変更でチームから削除すべきメンバを抽出することもできます。

フローの全体像

実際にはスケジュールトリガで実行するのがいいでしょう。

アクションの設定


作成 グループアドレス

グループアドレス(メールアドレス)を指定します。

グループの一覧

Office365グループコネクタ

「行をフィルターする」に mail eq ‘outputs(‘作成 グループアドレス’)’

作成 グループアドレスのID

first(outputs(‘グループの一覧’)?[‘body’]?[‘value’])?[‘id’]

HTTP 要求 V2 を送信する

URIを以下のように設定。グループIDのところに「作成 グループアドレスのID」の出力を入れる。

Graph APIでtransitiveMembersを使用することが重要です。グループアドレスのメンバーは個人ユーザーとは限りません。入れ子でグループアドレスが入っている場合もあります。transitiveMembersを使うことで、最終的な個人ユーザーのみを抽出することができます。

$select=id,displayName,userPrincipalNameでidとdisplayNameとuserPrincipalNameを抽出する指示、$top=999で999件まで一度に取得する指示(指示なしの場合は一度に100件まで)をする。

https://graph.microsoft.com/v1.0/groups/{グループID}/transitiveMembers/microsoft.graph.user?$select=id,displayName,userPrincipalName&$top=999

JSON の解析

Contentに「HTTP 要求 V2 を送信する」の「本文」を設定する。

スキーマを以下のように設定する。

{
    "type": "object",
    "properties": {
        "value": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "displayName": {
                        "type": "string"
                    },
                    "userPrincipalName": {
                        "type": "string"
                    }
                },
                "required": [
                    "id"
                ]
            }
        }
    }
}

選択 グループアドレスメンバーのユーザーID

元に「JSON の解析」のbody value

マップのkey userID,
値を入力します 「JSON の解析」のBody id


作成 チームのID

メンバーを追加したいチームのIDを入力します

グループ メンバーの一覧表示

Office365グループコネクタ

グループIDに outputs(‘作成_グループアドレスのID’)

チームであればプルダウンメニューに候補として表示されるので、わざわざ「作成 チームID」で指定しなくてもOKです。

選択 チームのメンバーのIDのみ

元に「グループ メンバーの一覧表示」のbody/value

マップのkey userID
値を入力しますに 「グループ メンバーの一覧表示」の「ユーザーID」


アレイのフィルター処理

グループアドレスメンバーのユーザーID配列から、チームメンバーのユーザーID配列に含まれない要素を抽出する操作をする。

From: body(‘選択_グループアドレスメンバーのユーザーID’)

Filter Queryは以下の通り。

左辺: contains(body(‘選択_チームのメンバーのIDのみ’), item()?[‘userID’])

判定式: 「異なる」 (is not equal to)

右辺: true ※数式から記入する

チームにメンバーを追加

最後にMicrosoft Teamsコネクタの「チームにメンバーを追加する」アクションで、「アレイのフィルター処理」の結果で得られるユーザーのGUID配列をチームに追加して完了。


アレイのフィルター処理を書き換えれば、フロー実行の時点でチームに含まれるがグループアドレスに含まれないユーザーを抽出することもできます。

Office365グループコネクタの「グループからメンバーを削除」アクションを使えば、Power Automateでチームのメンバを削除するこもできます。

EVと火災

電気自動車は巨大なエネルギーを蓄積した走行用電池を内蔵しているため、火災時に危険性が高いといわれています。ただ、内燃機関はそもそもガソリンなどをエンジン内で燃焼させて動いていること、ガソリンが漏れて引火したら爆発が生じるこから、火災時に深刻な影響を及ぼすのは自動車一般のリスクです。

また、リチウムイオン電池の種類や個別の車種の構造にも由来することに注意が必要です。特に日産リーフは火災の報告が非常に少ないことで知られています。

リーフと火災

残念なことに3代目リーフはバッテリーとの因果関係を否定できない火災が発生しました(東洋経済, 2026/3/27)。日本のメーカーである日産、そのEV開発を支えたAESCには安全に対する深い信頼性を実現するように期待します。

以下は国交省のリコール不具合情報で調べた情報と報道によるもの。

  • 2021年04月01日 初代リーフ ZE0
    山中で車両から出火した。
    出火元や原因の特定には至らなかった。
  • 2021年08月28日 2代目リーフ ZE1
    大雨によって冠水した車両を駐車場にて保管していたところ出火した。
    原因の特定には至らなかった。
  • 2022年09月21日 2代目リーフ ZE1
    車両から出火した。車両を全焼した。
    外部からの熱源により火災に至ったものと推定
  • 2023年01月06日 2代目リーフ ZE1
    出火箇所と推定されたバッテリーモジュールを分解したが、焼損が激しく、原因の特定には至らなかった。
  • 2025年2月24日 2代目リーフ ZE1
    に鳥取県倉吉市のディーラーで急速充電中に出火。
    日産、鳥取のEV火災 出火原因は灯油こぼしたまま喫煙 車両や充電器以外と確認日刊自動車新聞, 2025/3/26