Power Automate と Outlook の祝日カレンダーを利用して祝日には処理を中断するフローを作る

2021/02/03 追記
本記事では、イベントの取得(V4)を使用しておりますが、このアクションでは、定期的な予定を正確に取得することができませんでした。そのため、イベントのカレンダービューの取得(V3)の使用に変更してお使いください。



Power Automate にはスケジュール済みのクラウドフローという項目があり、月～金のみ実施したい作業の自動化などがしやくすくなっています。

しかし、以下の記事にも記載されている通り、Power Automate は祝日なんて知ったこっちゃないので、祝日も実行されてしまうことになります。

> Power Automate 非稼働日はフローを処理中断する方法
> https://qiita.com/yamad365/items/3213dcb49e93358c8df4

それを防ぐ方法として個別の祝日マスタを用意すれば、祝日はもちろん、祝日以外の実行させたくない日も処理を中断できるのですが、祝日だけ判定したい場合は、Outlook の日本の祝日カレンダーに祝日が登録されているかを確認することで、マスタいらずで対応ができそうだったので作ってみました。

# 作ってみたもの

全体としてはこのような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/885455e3-fb8b-f6d5-405b-12dfac8fa68b.png)

# 手順

1. スケジュール済みのクラウドフローを作成
2. タイムゾーンの変換アクションで、フローの中で使う日本の日付と、日付変更時間のUTCの日時を作成
3. Outlook の予定表で日本の祝日カレンダーを追加
4. イベントの取得アクションで、祝日カレンダーに当日と以降の祝日を1件取得
5. 作成アクションで、不要なApply to eachを回避
6. 条件アクションで、当日と一致している祝日かどうか判定
7. 一致していたらメール送信アクションで祝日のお知らせ
8. 一致していなかったらメールの送信アクションで、次回の祝日をお知らせ

## 1. スケジュール済みのクラウドフローを作成
まずは以下のようにスケジュール済みのクラウドフローを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/7760ac84-1a33-6090-090c-160c37b3bf0a.png)

## 2. タイムゾーンの変換アクションで、フローの中で使う日本の日付と、日付変更時間のUTCの日時を作成
次に後々利用する2つの日付時刻を作成します。

1つ目は、現在時間から、` yyyy-MM-ddT00:00:00`  の形で日本の日付を作成します。
日付だけが欲しいので、時間は全部0になっています。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/1774786e-3615-0e4f-3d20-57e34b484285.png)

2つ目は、先ほど作成した日本の日付から、日付変更時のUTCを求めます。
今度は時間も必要なので、` yyyy-MM-ddTHH:mm:ss`  の形で作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/e75e15ea-e439-b5aa-658b-e71deb6bdb5d.png)

例えば、2021年1月21日 10時15分に起動したとすると、
1つ目の結果は　2021-01-21T00:00:00、
2つ目の結果は　2021=01-20T15:00:00
になると思います。

## 3. Outlook の予定表で日本の祝日カレンダーを追加
それから、祝日カレンダーを追加します。

Outlook Webクライアントから、予定表を表示し、予定表の追加をクリックします。(画像はすでに追加されています)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/bc3f29c1-7a4a-8389-c65d-070e292c49c3.png)

祝日メニューから、日本の祝日を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/f20ac954-a06f-7410-590e-1158b91be68c.png)

これで追加完了です。

## 4. イベントの取得アクションで、祝日カレンダーに当日と以降の祝日を1件取得
それから、イベントの取得(V4)アクションを追加し、以下のような設定をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/be862d36-ec84-5efc-e84f-96280f17f648.png)

- 予定表ID は先ほどの日本の休日を選択します。
- フィルタークエリ では、実行当日以降の開始日付を持つ祝日のみを対象にするための設定をします。ここで選択する"変換後の時間"には、"日本の日付変更時のUTC時間日時を取得"で取得したものを設定してください。
- 並べ替え では、祝日の開始日時の昇順でデータを並び替えするため、祝日の開始日時を表す` start/datetime`を設定します。
- 上から順に取得 では、今回必要な件数である 1 を設定します。

## 5. 作成アクションで、不要なApply to eachを回避
イベントの取得(V4)アクションは、結果が配列で帰ってきます。
そのため何も考えないと、Apply to each が生まれてしまいます。

そこで以下のブログを参考に、Apply to each を削除します。
> first関数で不要なApply to eachを回避する
> https://mofumofupower.hatenablog.com/entry/2020/09/07/160111

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/c9901a06-cfbb-14c8-7ab2-29d028646af9.png)

入力には以下を設定し、1番最初の1件だけを取得するようにします。
` first(outputs('イベントの取得_(V4)')?['body/value'])` 

## 6. 条件アクションで、当日と一致している祝日かどうか判定
ここまできたらもう少しです。
条件アクションに以下のような設定をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/2d51059b-2c63-b7d1-0b06-fe33888d154e.png)

- 左辺には 先ほど取得した祝日の開始日時を入力するため、以下の式を設定します。` formatDateTime (outputs('最初の一行を取得')?['start'],'yyyy-MM-ddTHH:mm:ss')` 
- 右辺には、"変換後の時間"で、"現在の日本時間での日付を取得"にて取得したものを設定してください。
- この2つが等しいかどうか比較します。

## 7. 一致していたらメール送信アクションで祝日のお知らせ
ここからはおまけです。
以下のように、祝日だった場合のメールと、祝日出なかった場合のメールアクションを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/507b90b0-d0fe-8a4a-3aa4-be2cd3c566d7.png)

これで完了です！早速動かしてみます。
以下のようにUTCで2021年1月21日 18時(日本時間で1月22日 3時)のケースで動かしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/e25486f6-75eb-4c6d-684d-720699cd2386.png)

結果、祝日じゃない分岐で処理ができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/861394f3-5f2f-64e0-3d59-792b4706884b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/07f90612-e6cd-dce3-6d2e-62421c12f61a.png)

次にUTCで2021年2月23日 14時(日本時間で2月23日 23時)のケースで動かしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/c8908c28-879b-9eb7-38c9-8f9787fcbc51.png)

うまく祝日判定させることができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/7597fe9f-f981-6efb-4055-450550ade0a3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312282/05a0f263-f063-eb76-3efc-368fa2768bef.png)

# まとめ
上記の通り、Outlook の予定表を使えば、祝日で処理を分岐することができます。
(タイトルは中断するフローって言ってましたが、結果分岐してメール送るものになっていますが、許してください)
大丈夫だと思いますが、Outlookの祝日カレンダーが正確なのか、頼りになるかわからないって方は、次回の祝日判定の予定を通知するなどで次回の発火予測を立てるなど、補助的に活用するとよいかと思います。

# 以下参考にさせていただきました。
毎度参考にさせていただいています。ありがとうございます。

> Power Automate 非稼働日はフローを処理中断する方法　やまさんの記事
> https://qiita.com/yamad365/items/3213dcb49e93358c8df4

> first関数で不要なApply to eachを回避する　Hiroさんのブログ
> https://mofumofupower.hatenablog.com/entry/2020/09/07/160111

> Power Automate で扱う時刻を日本時間に変換したい　もくだいさんのブログ
> https://mokudai.jp/knowledge-base/power-automate/automate-convert-time-utc2japantime/

> クエリ パラメーターを使用して応答をカスタマイズする(filter の書き方)　MSドキュメント
> https://docs.microsoft.com/ja-jp/graph/query-parameters