はじめに
Power Platform推進チームの小野です。
Power Automateの式では、計算の演算子である+
-
*
/
が使えず、四則演算の関数を使う必要がある、という投稿をしました。
四則演算は関数で実現できますが、Power Automateには累乗の計算をする関数がありません。
しかしネットワークエンジニアとしては、IPアドレス数の自動計算などの場面で、2の(32-n乗)とかが必要になることがあります。
どうしてもPower Automateで累乗の計算をしたい、というレアケースに対処する方法を紹介します。
POWER関数
Excel・Power Appsには、累乗を計算するためのPOWER関数が実装されています。
また、2 ^ 5
のように ^
演算子を使うことでも累乗の計算ができます。
ところが、Power AutomateにはPOWER関数がないのです。深刻なPOWER不足。
Power Automateで累乗計算
変数と四則演算を使って、Power Automateで累乗の計算を実現してみましょう。
変数の準備
ここでは、累乗する数値(基数)と累乗する回数(指数)は、フロー実行時に入力されるものとします。
まずは、ループ用カウンタは整数型、それ以外はFloat(小数)型の変数に格納します。
回答・バッファ・ループ用カウンタは、後ほど必要になってきます。
指数が0かどうか判定
続いて、指数の値が0かどうかを条件に分岐します。
true:指数が0の場合、基数に関わらず回答は必ず1になります。
回答の初期値を1に設定しているので、特に処理は不要です。
false:指数が0でない場合、累乗処理を行うループに入ります。
累乗処理のループ
ループ処理は、条件を満たすまで繰り返す「Do until」アクションを使います。
後述のとおり、掛け算のためにバッファを用いているため、中身は少しややこしくなっていますね。
以前の投稿のとおり、Power Automateでの掛け算にはMUL関数を使います。
累乗を実現するには、回答の変数に対して基数を繰り返し掛け算していくことになるので、
mul(variables('回答'), variables('基数'))
を variables('回答')
に格納
この計算を「変数の設定」アクションで繰り返せばよさそうに見えます。
ところが、Power Automateの「変数の設定」アクションでは、その変数自身を参照できない、という制約があるようで、下記の通りエラーになってしまいます。
The inputs of workflow run action '変数の設定' of type 'SetVariable' are not valid. Self reference is not supported when updating the value of variable '回答'.
変数自身を参照しなければよいので、回答を別の変数(バッファ)にコピーしておき、バッファに基数を掛けて、回答に格納する、という処理を行えばOKです。
variables('回答')
を variables('バッファ')
に格納
mul(variables('バッファ'), variables('基数'))
を variables('回答')
に格納
ループ用カウンタを増やす
上記の計算後、ループ用カウンタを1増やして、ループ用カウンタが指数の値を超えたら終了します。
ループ用カウンタを1増やす処理は、「変数の値を増やす」アクションで行っています。
前述のとおり、「変数の設定」アクションでは変数自身を参照できない制約がありますが、足し算・引き算においては「変数の値を増やす」アクション・「変数の値を減らす」アクションが用意されています。
これらのアクションを使うことで、変数自身を参照した足し算・引き算をすることができます。
i = i + 1
や i += 1
みたいな計算ですね。
一方、掛け算・割り算にはこういったアクションが用意されていないため、先ほどのようにバッファを使って変数自身の参照を避けながら計算する必要があります。
処理完了
以上で処理は完了です。
TIPS
TIPS:Do untilは最低でも1回実行される
ループ用カウンタ(初期値:1)が指数の値を超えたらループ終了なので、指数が0の時は、ループを開始した時点で終了条件を満たします。
そのため、「Do until」アクションの前の条件分岐は、一見すると不要に見えますよね。
しかし、条件分岐を使わずに実行すると、指数が0のときに基数(の1乗)がそのまま返されます。
これは、「Do until」アクションは、最低でも1回実行される仕様になっているため。
「Do until」アクションの終了条件を「常にtrue」になるようにしてみるとわかりやすいです。
実行結果↓
0乗という概念がそもそも特殊っぽい気がするので、フローでも特殊扱いとして条件分岐で処理することにしました。
とはいえこのあたりは、変数の初期値や計算式を調整することで、もっとシンプルなフローにできる余地がありそうですね。
TIPS:アクションのヘルプ
「変数の設定」と「変数の値を増やす・減らす」は、見た目がほぼ同じです(値が必須かどうかが違う)。
わりかりやすいアクション名をつけることが推奨されていますが、見た目がほぼ同じだと、かえって見分けがつきにくくなる恐れも…
「どっちだっけ?」となった場合は、アクション名の右の(?)マークをクリックして、アクションのヘルプを表示すると判別できます。
TIPS:ループ制限の変更
デフォルトでは、ループの回数は60回までに制限されています。
ネットワークエンジニアなら「2の64乗」まではやりたいところなので、制限を変更する必要があります。
ループアクションの「制限の変更」から、回数とタイムアウト時間を変更することができます。
もちろん、ループの制限には時間がかかりすぎるループや無限ループを中断させる意図があるので、必要以上に制限を緩くしないようにしましょう。
TIPS:「データ操作>作成」アクションで結果確認
最後の「データ操作>作成」のアクションは、最終的な回答の値を確認するためのデバッグ用として置いているものです。
ループの最後の値を確認するには、表示欄に数を入力するか、「次へ」ボタンを連打するかしないといけないので、地味に面倒。
TIPS:ループさせすぎ注意
ループ処理はそれなりに時間がかかります。
「2の32乗」で11秒、「2の64乗」で23秒かかりました。
ループ内の処理内容によっては、もっと時間がかかることになりますので注意が必要です。
また、変数に格納できる桁数にも限りがあります。
2の64乗(18,446,744,073,709,551,616)だと、百の位(18桁目)で四捨五入されているようです。
Bing曰く、変数は最大15桁とのこと(提示されたソースには記載が見当たらず…)。
日本の国家予算が15桁(約300兆円)なので、日常で扱う分にはほとんど問題にはならないとは思いますが、念のため。
おわりに
複雑な計算はPower Appsにやらせるのが賢明です(二度目)。
Power Automateは、なるべく計算されたあとの数字を受け取るだけにしてあげましょう。ツールも適材適所。