Power Automateのクラウドフローを会社休日スケジュールに合わせて実行させる

## スケジュール実行を曜日に合わせたいニーズ
自動化を実践していると平日だけ実行したいとか、決まった曜日にだけクラウドフローを動かしたいというニーズはあると思います。
曜日指定するだけならば、トリガーに設定すればよいですが……
土日だけ指定しても祝祭日や年末年始、お盆休みなどこれだけでは賄えないこともありますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/be1d5044-48a2-4d80-bd2f-4bd781a43402.png)

もう少し細かく、たとえば1年に1回休日カレンダーを設定しておくだけで、指定したクラウドフローを実行してくれるような仕組みを作ってみようと思います。

## この記事では
以下のようなことを実現したい人向けの記事です
・土日だけ、土日以外だけなどの条件でフローを動かしたい
・Excelで記載した特定の日付だけフローを動かしたい
・正月や祝祭日だけフローを動かしたい

それぞれの方法を紹介しています。ぜんぶ盛り込んでもよいですし、必要な方法だけを組み合わせても実用的かと思います。

## 基本な考え方
クラウドフローには、「スケジュール済みクラウドフロー」というトリガーがあります。いわゆる定期実行です。曜日は実行する時刻を設定できます。

今回は、このトリガーで毎日フローを実行させて、フローの中で今日が何曜日か、Excelで設定した日付条件にマッチするかなどを判定させたうえで動作させるような仕組みにします。

そこで、このように毎日実行させる設定にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/6d91d771-8710-4071-8ee6-367268e5376c.png)

### 日本の日付を変数に設定

まずは、今日が何日なのか日本の日付を取得して「日付」と名前を付けた文字列の変数に格納します。
utcNow()関数では世界標準時刻が取得できます。必要なのは日付だけなので、このまま使ってもよいのですが、午前9時より前に取得すると日本の時刻とは９時間ずれているために前日日付になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/b20a5804-8c3a-4b49-8a57-db438d1ccece.png)

そこで、以下の式をつかって日本の日付を取得してください。
```
convertFromUtc(utcNow(),'Tokyo Standard Time','yyyy-MM-dd')
````
余談ですが、日付のフォーマットや前日日付を取りたいというような場合については、こちらのブログで紹介しているので参考にしてください。

https://mocabrown.com/blog/archives/6273

### 日曜日にだけ実行
変数「日付」が何曜日なのかは、dayOfWeek関数の値で判断することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/75ef240e-2e7e-4d61-a34b-1c4613e829b1.png)

```
dayOfWeek(variables('日付'))
```
このように、文字列で日付を与えると以下のような整数が返ってきます。したがって、日曜日だけ動かしたければ0に等しい場合に実行させることで「はい」に設定した処理が動作します。

|曜日|INT|
|---|---|
|日|0|
|月|1|
|火|2|
|水|3|
|木|4|
|金|5|
|土|6|


実行してみると、日曜と判定されたので「はい」に設定した処理Aと処理Bが実行されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/8bc6d52f-f222-4cce-b4d1-b60987cc1afe.png)

ということは、土日に動作させたければ、こんな感じにすればよいですね。逆に、土日以外に動作させたければ、「はい」と「いいえ」の中身を入れ替えればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/3f587c70-6481-40a9-a342-26dc072f05e0.png)

### 特定の日付を指定して動作させる
たとえば、会社の創立記念日などカレンダーにはない日付を指定するにはどうしましょう？
適当なSharePointサイトのドキュメントライブラリに以下のようなExcelファイルで休日テーブルを用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/93c5f903-1130-490e-8176-835bb00b8945.png)

作製したテーブルを「用内に存在する行を一覧表示」アクションをつかって取ってきます。今日の日付は一覧とのマッチをテストするために、表内にあるのと同じ日付をいったん手入力しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/d769c49c-1220-4119-99bc-14d7133837cd.png)

テスト実行してみると、Excelで入力していた休日日付は数字として表示されています。今日の日付も数字にして比較してやればよさそうです。各行はvalueの中の配列に入っていることを確認しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/82858069-086d-44e9-be40-c07698fd39bd.png)

Excelのなかの休日日付はこのままでは扱いづらいので、「選択」アクションを使って配列にしてやります。「開始」にはvalueの値を設定します。
```
@{outputs('表内に存在する行を一覧表示')?['body/value']}
```

「マップ」にはその中から「休日日付」の値が取れるように以下のように式を設定します。この時「選択」をマップモードに切り替えておくのを忘れずに。
```
int(item()?['休日日付'])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/f7d4d3e5-740a-4bb4-9a89-0ff21ebdfcad.png)


日付の値だけを配列にして取得することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/4dca01fd-36ad-4ad9-8f62-eca591769b99.png)


### シリアル値で配列に含まれるか確認
次に、今日日付はもともと文字列の変数に入っていたので、「選択」で取得した配列に含まれるかを比較するために、こちらもシリアル化します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/f2b4eace-437c-43b3-b567-c5a38d22616d.png)

### 日付を比較できるようシリアル値する

まずはテストで「作成」をつかって下記の式を実行してみます。
```
add(div(sub(ticks('2025-03-10'),ticks('1900-1-1')),864000000000),2)
```
日付のシリアル化については、こちらのブログを参考にさせていただきました。

https://blog-tips.sekenkodqx.jp/2022/05/11/power-automate-function-ticks/

配列の中に指定した値がふくまれるかどうかは、contains関数をつかって調べることができます。「選択」配列を第１引数、「今日日付のシリアル値」を第２引数に入れます。
```
contains(body('選択'),outputs('今日日付のシリアル値'))
```
テストの実行結果はご覧の通り。シリアル値が配列に含まれているので、contains関数の結果がTrueになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/27712789-b6e3-4f91-901a-861a3c1b0f01.png)

あとは、日付の配列に含まれるかどうかを、先ほどの条件分岐にいれこめばOK、上出来です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/9c2b59f2-90cb-46c7-bd59-e11e66f310a3.png)

## 祝祭日を忘れてはいませんか？
さて、ここまででExcelに入力したオリジナルカレンダーに従ってクラウドフローを動作させることができました。もちろんカレンダーに祝日の情報を手入力してもよいのですが、「イベントのカレンダービューの取得(V3)」という便利なアクションがあります。
下図のように開始日付、終了日付にお正月日付をいれてテスト実行してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/a6970334-0fda-4ee5-854f-453d64ff5279.png)

結果はこのとおり。日本の休日カレンダーを参照して、開始時刻、終了時刻の間に存在する休日を配列としてかえしてくれます。
ということは、開始・終了に今日の日付をいれた結果の配列の要素数が１以上であれば、その日は休日であると判定することができそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/1f3042b2-23ea-4bcc-a5e7-cabc98435e86.png)

先ほどの「日本の休日」カレンダーで返された配列にいくつの要素があるかは、Length関数を使えばよいでしょう。条件式では1以上であれば「はい」に判定されるように設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/e1168953-eea8-4d2b-a558-7f6cf54591ff.png)

```
length(outputs('イベントのカレンダー_ビューの取得_(V3)')?['body/value'])
```

## まとめ
ここまでで、曜日判定、オリジナルカレンダー判定、日本の休日判定の３つの条件で動作させるかどうかを判定できるようになりました。

特に、カレンダーを使った方法はオールマイティーなので、これだけでも割と使えるのではないかと思います。

条件判定のあと、「はい」の中に実際に実行する部分を設定していますが、実行するユーザーがプレミアムライセンスを持っている場合には、クラウドフローをソリューションに入れて、実行部分を「子フロー」として別のフローに分割することもできます。

スケジュール起動と実動作を分けておくと、実行の成功、失敗をチャネルにまとめて通知するような仕組みも作りやすく、拡張性があるのでお勧めです。

## この記事を書いている人
職場でPower BIを使ったり困っている人のサポートをしたりしてます。[Qiitaの記事](https://qiita.com/DaddyDaddy/)　や　[個人的なブログ](https://mocabrown.com/blog/powerautomate/)　ではPower AutomateクラウドフローについてのTIPSのようなものを作ったりしているので、良かったら読んだり「いいね！」していただけると励みになります。