Power AutomateApply to each 回避

Power AutomateApply to each 回避

こんにちは。アーティサン株式会社の小刀稱(ことね)です。

「Power AutomateでExcelをSharePointリストにインポートしたい時に考えること」シリーズの第6回です。

本シリーズでは、私が実際にPower Automateを用いて、「ExcelをSharePointリストにインポートする」フローを作成していきます。

また、作成の際に学んだ点や躓いた点を中心に紹介いたします。

Power Automateでどんな事ができるのか知りたい、実際の作成方法を知りたい、という方に向けた記事です。

前回は、Microsoft Graph APIベースの「SharePoint REST V2.0」を使用して、 SharePointのドライブ一覧を動的に取得し、一覧から今回使用するドライブ情報をドライブ名で検索する手法についてお伝えしました。

第5回目の内容はこちらを参照ください。

Power AutomateでExcelデータをSharePointにインポートするために考えること(第5回)

今回は、「動的にExcelデータを取得する」方法の続きで、ExcelデータのファイルIDを動的に取得する方法についてお伝えしていきます!

Excelデータの動的な取得(ファイルID編) その2

ファイルIDを取得するには、以下の手順を実施していきます。

  • Excelデータが保存されたSharePointドキュメントライブラリのドライブIDを取得

    • ドライブ一覧を取得

    • ドライブ一覧から今回使用するドライブ情報をドライブ名で検索

    • 対象のドライブIDを取得 ← 今回の対象

  • ExcelデータのファイルIDを取得

前回のブログでは、「ドライブ一覧から今回使用するドライブ情報をドライブ名で検索」までが完了しました。

今回は「対象のドライブIDを取得」についてお伝えします。

前回アレイのフィルター処理アクションで取得した”Excelファイルの保存場所”に関する情報は、以下のとおりです。

この中から「id」値(ハイライト部分)を抽出します。

Power AutomateApply to each 回避

「JSONの解析」アクションを使ってid値の取得を試したが・・・

私はまず以下の手順でid値を取得してみました。

  • JSONの解析アクションにてアレイのフィルター処理アクションのbody要素を解析

    ※「JSONの解析」アクションの設定方法については、前回のブログを御覧ください。

  • 作成アクションを作成し、入力項目にアレイのフィルター処理アクションのid値を指定

    Power AutomateApply to each 回避

すると自動的にApply to eachアクションで囲われました。
※「Apply to each」は配列の要素数だけループ処理を行うアクションです。

id値は1つしかないのに、なぜApply to eachアクションで囲われるのでしょうか。

それは、アレイのフィルター処理アクションで得た結果のbody要素が配列([])になっているためです。

Power Automateでは、配列内の項目を取得する場合、自動的に「Apply to each」アクションで囲まれるようになっています。 しかし今回取得されるid値は1つであることが明確です。 このような場合、わざわざApply to eachアクションを行う必要はありません。

よって、不要なApply to eachアクションを回避するように設定しましょう。 回避が必要な理由については、本記事の最後で整理しますね。

「Apply to each」アクションを回避してid値を取得しよう

さて、先程とは方法を変えてid値の取得を試みたいと思います。
仕切り直しのため、さっき使ったJSONの解析アクションは削除してしまいます。

目標は”Apply to eachを回避しつつ、id値を取得”することです。 これを実現するための考え方としては、「アレイのフィルター処理」アクションで得た結果のbody要素のうち、先頭項目のid値を抽出するというものです。

上記で説明した考え方が少し分かりづらいので、順を追って説明していきます。

Power AutomateApply to each 回避

まず、アレイのフィルター処理アクションのbody要素は、以下の式によって取得できます。(上図(1)破線部分)

body(‘アレイのフィルター処理’)

さらに取得したbody要素(=配列)のうち、先頭項目だけ取得するには、first()関数を用います。
( )内に上記のbody要素を挿入します。具体的には以下です。(上図(2)実線範囲)

first(body(‘アレイのフィルター処理’))

最後に、上記で取得した結果から、id値を抽出します。 具体的には以下です。(上図の(3))

first(body(‘アレイのフィルター処理’))[‘id’]

上記式を設定することで、作成アクションがApply to eachアクションで囲まれることを回避できました。

Power AutomateApply to each 回避

ドライブIDを取得する部分のフローは以下のとおりです。

Power AutomateApply to each 回避

ちなみに今回は、取得した要素のうち、先頭項目だけ取得するためにfirst()関数を用いました。
要素の0番目を取得する要素の末尾項目を取得するでも同様の結果を得ることができます。

要素の0番目を取得する:body(‘アレイのフィルター処理’)[0][‘id’]

要素の末尾項目を取得する:last(body(‘アレイのフィルター処理’))[‘id’]

Apply to eachを回避すべき理由

最後に、なぜ不要なApply to eachを回避する必要があるのか考えてみましょう。

それは、以下2つの理由があります。

  • 保守性の向上

    フローの作成者以外がこのフローを見た際、「Apply to each」アクションがあると「ドライブIDは1つしか取得してないはずなのに、なんでループ処理をしているのかな?」と思われてしまいます。

    他の人がメンテナンスすることを考えた場合、ミスリードしない設計にすることは重要です。

  • 可読性の向上

    執筆時時点(2021年8月)では、Power Automateの多重ループ数は最大8となっています。

    また、「Apply to each」アクションは、配下のアクションを確認するために都度クリックする必要があります。 「Apply to each」アクションが多くなるとフロー全体の可読性が低下します。

    流石に8重ループまで使用することはないと思いますが、不要なループは少しでも回避することで、 多重ループを防ぐことができるため、結果的にフロー全体の可読性向上に繋がります。

さて、今回の連載でドライブIDを取得するまでのフローが完成しました。

今回はここまで!

不要なApply to eachを回避する手法は、汎用的に活用できる内容ですので、是非覚えていただければと思います。

次回は、ExcelデータのファイルID・テーブルIDを動的に取得する方法についてお伝えします。

ここまで読んでいただき、ありがとうございました。

弊社ではPower Platform(Power AppsやPower Automateなど)を用いてお客様の業務を自動化するご支援を数多く承っております。

業務の中で、「普段手動でやっている業務を自動化できないか」というような疑問がある場合には、お気軽にアーティサン株式会社までお問い合わせください。

Power AutomateApply to each 回避

小刀稱知哉

大分県出身(温泉大好き♥♥)、現在は東京都在住

1990年4月9日生まれ

30才にしてメーカーの技術営業からIT業界にジョブチェンジ!!!

趣味は読書

Power Platform(SharePoint・Power Apps・Power Automate)に関する営業活動や設計、開発などを担当しております!

Power AutomateApply to each 回避

こんにちは、Microsoft MVP(Azure / Business Applications)の松本典子です。

本連載の前々回(第10回)、前回(第11回)では、ユーザーが送信した写真から文字を読み取るLINEボットをノーコードで作成する方法を紹介しました。このうち、前回のワークフロー作成編では「Apply to each」というアクションを利用しています。

前回はあまり詳しく説明しませんでしたが、実はPower Automateでワークフローを作成する際には、このApply to eachアクション※注を利用する場面が多くあります。また、ワークフローを作っているうちに自動的に挿入されることもあり、よく理解しないまま使っている方も多いかもしれません。

そこで今回は、前回作成したワークフローを振り返り、また動作検証用のワークフローも作成しながら、Apply to eachがどのような働きをするのか、どんな場面で使うのかについて説明していきます。

※注:なお、Azure Logic Appsで同様の動作をするのは「For each」アクションです。名前が違うので注意してください。

1. 「Apply to each」アクションとは

Apply to eachは、ワークフローの中でループ処理(繰り返し処理)を行うためのアクションです。組み込みコネクタの1つであるコントロールコネクタに含まれています。

Power AutomateApply to each 回避

コントロールコネクタは組み込みコネクタに分類されている

Power AutomateApply to each 回避

コントロールコネクタに含まれるApply to eachアクション

ところで、Apply to eachを直訳すると「それぞれに適用する」となります。この「それぞれ」とはどういう意味でしょうか。

それを理解するためにはまず「アレイ(配列)」について知る必要があります。アレイは変数の一種で、「一度に複数の値を保存できる変数」です。

本連載第8回で作成したワークフローでは変数を使いました。変数は、ワークフローの中で何らかの値を一時的に保存しておく“名前付きの箱”のようなものです。たとえば第8回では「日付」という変数に、ワークフローを実行した日の日付(たとえば「2022-03-15」)を保存しています。このように、実行するたびに変化する値を扱うワークフローでは、変数の利用が欠かせません。

ただし、ふつうの変数※注は一度に1つの値しか持てないため、用途によっては不便なこともあります。そこで活躍するのが、一度に複数の値を持てるアレイです。

※注:変数を初期化する際には、保存できる値の「型(タイプ)」も指定します。数値、文字列、ブーリアン(true/false)といった一般的な型の変数は、一度に1つの値しか保存できません。アレイ(配列型)を指定すると、複数の値が格納できます。

ここでやっとApply to eachアクションの説明に戻ります。Apply to eachは、前のコネクタからアレイが渡されたときに、値を1つずつ順番に取り出して同じ処理を繰り返し実行します。つまり「それぞれの値に処理を適用する」のでApply to eachというわけです。アレイに格納された値をすべて処理し終えたら、繰り返し(ループ)を終了します。

前回作成したLINEボットでは、トリガーとなる「HTTP要求の受信時」コネクタでLINEから取得する「events」が、複数の値を格納するアレイとなっています。このトリガーはLINEでメッセージ(写真)を受信したときに起動しますが、一度に複数のメッセージを受信しても処理できるようにアレイになっているのです。したがって、ワークフローの後続の処理をApply to eachアクションで繰り返すようにして、受信したすべてのメッセージに対して読み取り処理を実行しているわけです。

Power AutomateApply to each 回避

前回作成したワークフロー(Apply to eachの部分)

2. 今回作成するワークフロー

Apply to eachアクションについての理解を深めるために、今回は同じワークフローをApply to eachを使う方法/使わない方法で作成して比較してみたいと思います。作成するのは、受信したメールの添付ファイルをOneDriveの指定フォルダに自動保存するワークフローです。

2-1. Apply to eachアクションを使わない場合のワークフロー

まずはApply to eachアクションを使わずにワークフローを作成してみます。

Power AutomateApply to each 回避

Apply to eachアクションを使わない場合のワークフロー

Apply to eachアクションを使わない場合、ワークフロー全体図はこのような形になります。「ファイルの作成」アクションの「ファイル名」「コンテンツ」には、「新しいメールが届いたとき」のトリガーから得られる添付ファイルの情報を使うために、それぞれ以下の式(関数)を入力します。

・ファイル名:triggerBody()?['attachments']?[0]?['name']
・ファイル コンテンツ:triggerBody()?['attachments']?[0]?['contentBytes']

Power AutomateApply to each 回避

メールの添付ファイルを自動でOneDriveの指定フォルダに保存するワークフロー(添付ファイルが1つ、複数の場合)

ただし、上で作成したワークフローには大きな問題があります。「受信したメール1通に1つの添付ファイル」であれば正常に動作するのですが、添付ファイルが2つ以上ある場合でも添付ファイルは1つしか処理されません。実行結果は「エラー」にはならないものの、期待する結果(すべての添付ファイルをOneDriveに保存する)のとおりには動きません。

※お詫びと訂正:掲載当初、複数の添付ファイルがある場合に「エラーが表示される」と説明していましたが、正しくは上述のとおりでした。お詫びのうえ訂正いたします。(2022/03/24 11:10 編集部)

Power AutomateApply to each 回避

ファイルの作成アクションを増やす(?)

この問題は、ファイルの作成アクションをあらかじめ添付ファイルの数だけ用意すれば解決できるように思えます。しかし、添付ファイルの個数は事前にはわからないので、この解決策は現実的ではありません※注。つまり「受信したメールの添付ファイルの数に応じて」、添付ファイルの個数ぶんだけ処理を繰り返す仕組みが必要なのです。

※注:さらにファイルの作成アクションを複数個用意すると、今度は「添付ファイルが1個だけ」だった場合に処理がエラーとなる問題もあります。

2-2. Apply to eachアクションを使う場合のワークフロー

次に、Apply to eachアクションを使ってワークフローを作成してみます。

Power AutomateApply to each 回避

Apply to eachアクションを使う場合のワークフロー

Apply to eachアクションを使う場合のワークフロー全体図はこのような形になります。

Apply to eachアクションの「以前の手順から出力を選択」という欄に「添付ファイル」と表示されています。これにより、アレイに格納されている要素(添付ファイル)の数だけ、Apply to eachの枠内に作成したワークフローが繰り返し実行されるので、添付ファイルが1つでも、2つ以上でもエラーとなりません。

Power AutomateApply to each 回避

「ファイル名」「ファイルコンテンツ」は動的なコンテンツから選ぶ

先ほどの「2-1. 『Apply to each』コネクタを使わない場合のワークフロー」では、ファイル名とファイルコンテンツを式として(なかば強引に)入れる必要がありましたが、こちらでは「動的なコンテンツ」から簡単に入力できます。

またファイルの作成アクションで、ファイル名に動的なコンテンツから「添付ファイル 名前」を入力すると、Apply to eachアクションが自動的に作成されて、その枠内にファイルの作成アクションが移動します。このように、前のステップからアレイが渡されるのでApply to eachを使って処理することが推奨される場合、Power Automateではユーザーが選択しなくても自動的にApply to eachが挿入されます。

3. Apply to eachアクションの並列処理

Power AutomateのApply to eachアクションは、通常はアレイの値を1つずつ取り出して、順番に処理していく仕組みとなっています。ただし、これを並列処理に変更することもできます。1つずつ順に処理する必要がないワークフローでは、複数の値を同時に処理する並列処理のほうが早く済みます。

Power AutomateApply to each 回避

Apply to eachアクションのメニュー

「Apply to each」アクションの右側にある「…」をクリックするとメニューが開くので、「設定」をクリックします。

Power AutomateApply to each 回避

並列処理(コンカレンシー制御)を有効にする

「コンカレンシー制御」をオンにすると、「並列処理の次数」(一度に何個の処理を並列処理するか)を指定できます。オンにしたあとは、ワークフローがうまく動くかどうか、処理結果に不具合がないかどうかを確認しておきましょう。

4. 最後に

今回はApply to eachアクションの仕組みを紹介してきました。どのように動作するのか、少しはイメージできたでしょうか? Apply to eachが用意されていることで、Power Automate/Azure Logic Appsは複雑な処理のワークフローを簡単に作成できるようになっています。

前述したとおり、Power Automateではワークフロー内でアレイ(アレイとして定義されている動的なコンテンツを含む)を指定すると、Apply to eachアクションが自動的に挿入されます。したがって、多くの人はあまり意識せずにこれを使っているかもしれません。ただし、処理によってはApply to eachが不要な場面もあります※注。その場合はApply to eachで行われている処理を理解したうえで、関数を利用するなとワークフローの見直しや修正をすることをオススメします。

※注:たとえばアレイに含まれる値が1つだけの場合でも、処理に使う変数がアレイ型であれば、Power Automateは自動的にApply to eachを挿入してしまいます。今回の検証方法をアドバイスしてくださったMicrosoft MVPのHiroさんが、ご自身のブログでこれを回避する方法を紹介されていますので参考にしてください。
●参考ブログ「MoreBeerMorePower」:first関数で不要なApply to eachを回避する

Apply to each の上限は?

そして このアクションのあとに Apply to each を使用しますが、 Office 365 およびフリーのライセンスでは5,000までしか対応していません。

Power Automateのアクション実行回数は?

Power Automate のフローには「アクション数は 500 まで」という制限があります。 一般的なフローではまず問題になりませんが、込み入った業務プロセスをフロー化するなど、開発規模が大きくなると、どうしてもこの上限を意識する必要があります。

Powerautomate Do Untilの制限は?

回数:Do untilの上限のループ回数を指定します。 デフォルトは60になっています。 タイムアウト:Do until内部の処理を開始してから、どれほど経過したら強制的に処理を終了させるかを指定します。 デフォルトは1時間となっています。