Power Automateでエクセルのデータを日付でフィルターし、メールを送信する。「アレイのフィルター処理」アクション
Power Automateでエクセルのデータを日付でフィルターし、そのデータでメールを送信するやり方をステップバイステップでお見せします。その時に「アレイのフィルター処理」アクションの使い方がポイントです。
(動画時間:19:13)
Udemyオンラインコースを作りました!
マイクロソフトPowerApps 中級編【SharePointで、実務で使える業務アプリの作り方:勤怠管理アプリ編】
⇒ 半額になる「ディスカウントリンクページ」へ
事例の紹介。Power Automateで実現したい事
こんにちは、リーンシグマ、ブラックベルトのマイク根上です。
業務改善コンサルをしています。
今日はこの動画リクエストからです。
「日付をエクセルに入力してその日付に、メールを受け取るようにしたいのですが作成できません。ご存知でしたら教えて下さい。」
yuichiさん、ご質問ありがとうございました。
Power Automateの事例動画のコメント欄でこのご質問を頂きました。
⇒「【Power Automate】期限が来たら自動で通知メールを送信する。SharePoint「複数の項目の取得」アクション、フィルタークエリ」
その動画ではSharePointリストをデータベースとしましたが、
今日はそのエクセル版です。
今回実現したい事をもう少し明確化します。
予め決めた日付にメールを受け取るという事ですが、
これをPower Automateから見ると、
毎日今日が予め決めた日付なのかを確認しなければいけません。
つまり、トリガーは毎日の所定の時間となります。
そして今日がその予め決めた日付ならメールを送り、
そうでなければ何もしないという事です。
次にメールを送る為に何が必要かを考えます。メールを送るのに
「送信先のメルアド」、「件名」、「本文の文章」の内容が必要ですね。
これらがいつも同じであれば、
Power Automateの作成時にその情報を直接入れる事もできますが、
日によって内容を変えられる方が実用的です。
その為には予め決めた日付と一緒にそれらの情報も
一緒にエクセル内で管理すると良いでしょう。
最初に使うトリガーと必要なアクションが全てあるかを確認する。
それでは早速このフローを作成してみます。
Power Automateの作業画面の左のペイン内の「作成」から、
「一から開始」の「スケジュール済みクラウドフロー」をクリックします。
ここでスケジュールの設定ができますが、
他のやり方もお見せしましょう。ここはスキップします。
フロー名に適当な名前を入れて(ここでは「所定日にメール送信」)、
トリガーを「スケジュール」で検索すると、
「繰り返しスケジュール」トリガーがあります。
それを選び、間隔は毎日なので、「1日」としてします。(下図参照)
「詳細オプションを表示する」をクリックして、
トリガーが始まる「設定時刻」をここでは午前8時30分と指定します。
毎日その時間にこのフローが始まるのです。
念の為にご自分の「タイムゾーン」もちゃんと入れておきましょう。
これでトリガーの完成です。
次にやりたい処理は「予め決めた日付を確認する」です。
質問者さんはエクセルで管理をしたいという事でした。
まず、Power Automate内にそれができるアクションがあるかを確認します。
「新しいステップ」で、「Excel Online (Business)」を選んで、
有効なアクションの一覧を見ると「テーブルの取得」アクションがあります。
これでもできますが、
二つ上の「表内に存在する行を一覧表示」アクションを使います。
後で詳述ますが、こっちにはフィルタークエリと言う
テーブル取得時に条件で絞り込みができる便利な機能があるからです。
次にエクセル内の「日付」列に今日の日付のものがあるかどうかを
確認するアクションが必要です。
「新しいステップ」で、「データ操作」で検索すると、
「アレイのフィルター処理」アクションがあります。
アレイとは英語で、配列と言う意味で、テーブルを格納する変数で、
そのテーブルでフィルター処理ができるアクションです。
後で作業をしながら詳述しますが、
このアクションで「日付」列を今日の日付でフィルターを掛けて、
データがあるかどうかを見る事で目的を達成できます。
また「新しいステップ」で、「Outlook」で検索し、
「メールの送信」アクションでメールを送る事ができます。
これでやりたい事ができる目途が立ちました。
この様な手順で細かい設定作業をする前に
やりたい事を実現するためのトリガーと
全てのアクションを先に確認した方が良いです。
データベースとなるエクセルファイルの準備をする。
次に各アクションの設定作業をします。
しかし、実際に設定作業をしていくと色んな問題にぶつかります。
それらも一緒に見ていきましょう。
まず、上図がデータベースとなるエクセルで作った管理表です。
ここにメールを送信したい
「日付」、「送信先」、「件名」、「本文の文章」の列があり、
サンプルのデータを3つ入れておきました。
3つ目のデータはエラーです。
一番最初の列に「日付確認」列を作り、次の関数が入っています。
セルB3内
=IF(ISNUMBER(C3),”OK”,IF(C3=””,””,”日付がエラーです。”))
この数式は「日付」列にちゃんと日付が入って入れば「OK」と表示します。
Power Automateではその「OK」の行しか取得しない事で
処理の高速化とエラーの回避ができるのです。
ここで一つ必須事項があります。
PowerAppsでも同じですが、Power Automateで
エクセルをデータベースにするには
その表を「テーブル」にする必要がありますのでそうします。
- メニューバーで「ホーム」
- 「テーブルとして書式設定」
- お好きなテーブルの書式を選択
これで「テーブル1」と言うテーブルが作成されました。
Power Automateがこのエクセルファイルに接続できる様に、
このファイルを組織のOneDriveか
SharePointのドキュメントライブラリに保存します。
今回はチームで使うわけではないのでOneDriveに保存し、
ファイル名を「メール配信管理表」とします。
エクセルのデータを取得し、「アレイのフィルター処理」アクションで絞り込みをする。
それでは各アクションの設定にいきましょう。
トリガーはさっきのままで完成です。
次のアクションでさっきのエクセル関数に接続させます。
最初に完成図をお見せします。
「場所」で、「OneDrive for Business」を選んで、
次も「OneDrive」、そして次の「ファイル」でさっきのファイル名が一覧に出てきました。
そのファイルを選びます。
次の「テーブル」ですが、最初は選択肢の一覧が出てきませんでした。
これはエクセルをデータベースにする問題点ですが、
ライブでの運用時やテストをする時もエクセルに接続する時には
エクセルファイルを閉じておく必要があります。
さっきのエクセルファイルが開いていたので一覧が出ていなかったのです。
そのファイルを閉じて、改めてファイルを選ぶと、
今度は「テーブル1」が出てきました。それを選びます。
このアクションには後でまた戻ってきますが、次のアクションに行きます。
次は「アレイのフィルター処理」アクションですが、
これも先に完成図をお見せします。
最初の「差出人」で、変な日本語ですが、
ここでは対象となるテーブルを指定します。
右側の「動的なコンテンツの追加」をクリックすると前のアクションで取得したテーブルである
「Value アイテムの一覧」がありそれを選びます。
次の左側のボックスでどの列でフィルターを掛けるかを指定します。
「動的なコンテンツの追加」で「日付」の選択肢があるのでそれを選びます。
その右のボックスの演算子は「次の値に等しい」でそのままでいいです。
次の右のボックスで今日の日付の関数を入れたいです。
それにより「日付」列の値が今日の日付で絞り込みをするのです。
エクセルでは「TODAY」関数がありますが、
Power Automateでは違う関数です。
「動的なコンテンツ」で「式」タブを開いて、
スクロールダウンすると、
「日時」セクションに「utcNow()」関数があり、それを使います。
これで「OK」をクリックして選びます。
ここで一度テストをしたいですが、
画面右上の「フローチェッカー」を見ると、
次の「メールの送信」アクションでエラーが出ているので、
一先ずそれを削除します。
画面右上で一度「保存」し、その右の「テスト」をクリックして、
「手動」を選び、「テスト」、「フローの実行」、
「完了」とクリックしていき、実行結果を見る事ができます。
「正常に実行されました。」と出てきましたが、
「アレイのフィルター処理」アクションを展開すると、
ちゃんとエクセルのデータは入力されていますが(下図参照)、
今日の日付のデータが一つあるので、
それが出力欄で出てくるはずなのですが、出てきません。
それはさっきの条件式が不十分だからです。
Power Automateでの日付を扱う3つの注意事項と対処法
日付や時間は世界中に時差があるし、表示の仕方も沢山あるので
その対応でマイクロソフトも苦労しています。
そこで今回は3つの事に対処する必要があるのです。
一つは先ほど使った今日の関数の「utcNow」関数ですが、
これは日本時間でもアメリカ時間でもない、「協定世界時」と言うもので、
日本時間はそれよりも9時間足した時間になります。
その時間のズレを補正する必要があるのです。
もう一つはその時間とエクセル内の日付を比べる時に
その日付の書式を全く同じにする必要があります。
まずその二つの修正をやってみます。
またPower Automateに戻って、画面右上の「編集」をクリックして、
「アレイのフィルター処理」アクションの前で、
「アクションの追加」をします。
「日時」で検索をして、「タイムゾーンの変換」アクションを選びます。
上図がそのアクションの設定の完成図ですが、
「基準時間」で、「動的なコンテンツ」の、「式」タブで、
さっきのutcNow関数を入れます。
「変換元のタイムゾーン」で、「UTC 協定世界時」を、
「変換先のタイムゾーン」で、ご自分の住んでいるゾーンを選んで下さい。
ここでは「UTC + 9 大阪、札幌、東京」にし、日本時間にします。
「書式設定文字列」で「短い形式の日付パターン」にしておきます。
これで最初のUTC(協定世界時)と日本時間の時間のズレの問題は解決です。
残りの問題は「アレイのフィルター処理」アクション内を修正する事で解決します。
最初のそれらを解決した完成形をお見せします。
まず、右下のボックスの既存の「utcNow」を消して、
「動的なコンテンツ」の「式」タブで、
「formatDateTime(」とタイプして、括弧の間に「動的なコンテンツ」タブにして、
さっきの「タイムゾーンの変換」アクションで作成された「変換後の時間」を選び、
「,(カンマ)」を入れて次に「’yyyy/m/d’」で数式を完成させます。
formatDateTime(body(‘タイム_ゾーンの変換’), ‘yyyy/m/d’)
この数式で日付の書式を固定したのです。
この数式をコピーして、まずは「OK」で完成させ、
このアクションの右上の「…」をクリックして、
そのメニューから「メモを追加する」を選んで、
メモの入力ボックスが出るのでそこにペーストします。
これでさっきの数式の全体が見える様にしたのです。
もう一つの日時の問題は、わざわざマイクロソフトが作った感があるのですが、
Power Automateとエクセルは両方とも日付をシリアル番号に変換して、
日付同士を比べたり計算したりするのですが、
なんとその変換の仕方がその二つで違うのです。
それによるズレが出てしまうのです。
ですのでそのズレを補正する必要があります。
同じ「アレイのフィルター処理」アクション内で
左下のボックスの既存の「日付」を削除します。
そして「動的なコンテンツ」の「式」内で、
次の式を入力します。
addDays(‘1899-12-30’,int(item()[‘日付’]),’yyyy/m/d’)
このaddDays関数は第一引数の日から第二引数の日数だけ足して、
第三引数の書式で日付を表示します。
この数式でエクセルの日付のシリアル番号を
同じ日付のPower Automateのシリアル番号に変換するのです。
この数式内の「日付」をご自分のデータベースの日付のある列名に変えて使って下さい。
この数式もコピーし、「OK」をクリックして完成させて、
また右上の「…」をクリックして、「メモを編集する」を選んで、
さっきと同じメモ欄にこの式を追加して
詳細が分かる様にしておくと後で便利です。
ここの二つの数式の最後のシングルコーテーション内を同じにする事で、
日付の書式を全く同じにして、
同日であれば確実に同じと判断できる様にしたのです。
エクセルのデータを絞り込みをしながら取得ができる「フィルタークエリ」の使い方
ここでもう一度さっきと同じ手順でテストをしてみます。
そしたら、今度は「フロー実行に失敗しました。」とエラーが出てしまいました。
「アレイのフィルター処理」アクションを展開し、
エラーの詳細を見てもよく分かりません。(下図参照)
「入力」の右側の「未加工入力の表示」をクリックして、
入力されたデータが分かります。
日付データとして「ddf」と日付でないデータが入ってて、
addDays関数でそれを使って計算しようとしてエラーとなっていたのです。
ですので、エクセルのデータを持ってくる時に
「日付確認」列の値が「OK」であるレコードだけを持ってくれば良いのです。
その為に「表内に存在する行を一覧表示」アクションで、
詳細オプションを開き、「フィルタークエリ」を使い、
ここでは次の式を入れれば良いのです。
日付確認 eq ‘OK’
この式内の「eq」はイコールの意味です。
これについての詳細は次のリンクの記事をご覧下さい。
「【Power Automate】期限が来たら自動で通知メールを送信する。SharePoint「複数の項目の取得」アクション、フィルタークエリ」
これでまた同じ様にテストを実行します。
すると、今度は成功しました。
「アレイのフィルター処理」アクションを展開し、
「入力」データを見ると、「日付確認」が「OK」のものだけしかないので
さっきのフィルタークエリが上手くいったのが分かります。
「出力」データも見ると、
一つのレコードだけでこれは今日の日付のレコードなので、
フィルター処理も成功しました。
Power Automateはデバッグ作業が難しいので
全てのフローを完成してからデバッグ作業をするのではなくて、
今回の様に段階的にデバッグ作業をした方が良いです。
「アレイのフィルター処理」アクションで取得したデータの使い方
それでは最後の「メールの送信」アクションを完成させましょう。
さっき削除した「メールの送信」アクションをまた追加します。
しかし、ここで問題です。
さっきの「アレイのフィルター処理」アクションで取得したはずの
送信先などの選択肢が、「動的なコンテンツ」内にありません。
その理由はその取得したデータのデータ型がテーブル型であるのに対して、
ここでは文字列型を入れなければいけないので選択肢に出てこないのです。
それではどうすれば良いのでしょうか?
この「メールの送信」アクションをまた一先ず削除して、
違うアクションを追加します。
「コントロール」を選んで、
「Apply to eachコントロール」アクションを選びます。
これで指定したテーブルに対して
一行ずつ他のアクションを繰り返し実行できるのです。
その中に「メールの送信」アクションを追加するのです。
これも最初に完成形の図を見てみましょう。
これだと「アレイのフィルター処理」アクションから出てきた
「本文」と言うデータを選択できます。
日本語訳がまたおかしいですが、
これは取得した全体のデータの事です。
そしてその「Apply to each」アクション内でアクションを追加して、
また、「Outlook」の「メールの送信」アクションを追加します。
最初の「宛先」で「送信先」列を選択したいところですが、
これは「アレイのフィルター処理」アクションから出てきたものではないのでだめです。
ここで「式」タブにして、
この次の式を入れます
item()[‘送信先’]
Item関数の説明を見ると、
「この関数は、繰り返しアクション内で使用すると、
アクションのこの繰り返しに対するアレイ内の項目を返します。」
という事で、これにより、各繰り返しのレコードの
「送信先」列の値を持って来れるのです。
似たような数式を書くのでこの数式をコピーして、「OK」します。
次に「件名」で同じ様に「式」タブでさっきの式をペーストし、
列名を「件名」に変更し、「OK」します。
item()[‘件名’]
最後に「本文」で、列名は、「本文の文章」です。
「式」タブで、ペーストし、列名を「本文の文章」に変えて、「OK」します。
item()[‘本文の文章’]
これで最終完成ですのでテストをしてみましょう。
すると、フローが成功した模様です。宛先は僕のメルアドでして、
メールをチェックしたら、ちゃんとメールが届きました!
今日ご紹介した「アレイのフィルター処理」アクションと
「フィルタークエリ」機能は
Power Automateに必要なデータだけを持って来れるので、
エラーの確率も減らせて、
Power Automateの処理時間も劇的に減らす事ができるので
ぜひ使いこなして下さい。
Comment
マイク根上 様
お世話になります。松崎と申します。
PowerAutomate初心者ですが、本動画のような処理をしたく参考になるものがないかと
探していたところ、たまたまですが巡り合うことができ大変参考になりました。
ありがとうございます。
ただ一点問題があり、初心者には理解できないとこがありましたのでご質問させていただきます。
動画を参考にテスト版を作成して問題無しでしたので、実際の日付を指定してのテストを
実施したところ、指定日以外のものもすべて送信されてしまいました。
原因が不明です。気になるところは、「表内に存在する行を一覧表示」アクションの
「フィルタークエリ」は不要と思いましたので設定していないくらいで、あとは動画通りに
作成したつもりです。
申し訳ありませんが、ご教授のほどよろしくお願いいたします。
松崎様、
「フィルタークエリ」はここでは処理の高速化の為ですので、設定しなくても大丈夫です。
問題は「アレイのフィルター処理」アクションで、エクセルファイルの全ての日付データが「はいの場合(true)」となる事です。
このアクション内の条件式が全ての日付データで当てはまってしまう原因を見つけなくてはいけません。
条件が「false」になるなら、エクセル内の日付データの状態、タイムゾーンの状態、条件式の状態とを確認すれば解決が楽ですが、
今回は「true」ですので、そちらの環境を見てみないと何とも言えません。