はじめに
この記事ではPower Apps の Slider.Onchange の動作に関する検証結果を纏めています。
これらの検証の纏めは、特定の処理の開始、完了を監視したい。
という要望に役立つかと思います。
発生した事象
事象としては以下のようなことが発生しました。
これらの検証結果です。
— コルネ (@koruneko32767) May 3, 2021
何か私の認識間違ったりしていたらご指摘くださいーhttps://t.co/r2TdYqKmGm#PowerApps https://t.co/cRtkpHfeLc pic.twitter.com/ldp2bPZkLG
前提条件
Screen.OnVisible
UpdateContext({val:0});
UpdateContext({isChange:false});
UpdateContext({txt:""})
DropDown.OnChange
UpdateContext({isChange:true});
UpdateContext({val:val+1});
UpdateContext({isChange:false});
Slider.default
val
Slider.OnChange
If(!isChange, UpdateContext({txt:"execute slider.OnChange"}))
Label.Text
txt
上記設定を行い、ドロップダウンの値を変更しました。
その結果、 DroDown.OnChange 内の式が動作することになります。
これらの式は、こちらの公式docs にも記載の、
通常、複数の数式は ; 演算子と一緒にチェーンすることにより評価され、各々を順次に順番に評価します。 ともある通り、順に式が評価されるはずです。
よって以下のような動作になると想像されます。
- 変数
isChangeの値がtrueに設定される - 変数
valの値に1が加算される - 2の動作によってSlider にも設定されている
valの値が変更されたので、Slider.OnChangeが動作する Slider.OnChangeが動作した結果、If関数 内のisChangeの値が評価される。
isChangeの値は1でtrueに設定されており、!により否定がとられているので、 "False の場合" の式が実行される。
ただし、今回は "False の場合" の式が設定されていないため、なにも実行されない。- 変数
isChangeの値がfalseに設定される
しかし実際の動作としては、 Slider.OnChange の動作によって、 !isChange が true と判断されて、変数 txt に"execute slider.OnChange"が設定されてしまった。
また、この問題に関してふらり さんも検証していただけました。
ありがとうございます!!
フシギな動作ですねぇ。
— ふらり (@flali_world) May 3, 2021
Slider.OnChange のトリガーになる変数の変更回数通りにSlider.OnChange がトリガーされて、Slider.OnChange の中の足し算は変数PointUPの最終変更値が反映されました... pic.twitter.com/N67amvSCda
これらの結果から、ふらりさんも述べている通り、他コントロールでのSlider の値の変更回数分しっかりトリガーされていることがわかります。
ただ、ここで1つきづいたことがあります。
例えば、 "Button1" を押したときの動作ですが、変数 val の変更に対して、すぐに Slide.OnChange が動作したのであれば、変数 PointUp は0のはずなので、変数 Point の結果は0となるはずです。
また、 "Button3" を押したときの動作の Point の最終結果は100ではなく、60が設定されているはずです。
このことから、まず対象コントロールの動作プロパティないの式が評価されてから、その式によって生じた他コントロールの動作が順次動作されていくのではないか?と私は考えました。
* あくまで実際の動作からの私の想定であり、公式のドキュメントなどにて記載されていることではないことにご注意ください。
この予想を "Button3" を押したときの動作の内部の動き(予想)に当てはめると恐らく以下のような動作をしているのではないでしょうか。
- 変数
valの値が1に設定される - 1によって、Slider の値が変更されたので
Slider.OnChangeの動作がスタックされる - 変数
PointUPの値が10に設定される - 変数
valの値が5に設定される - 4によって、Slider の値が変更されたので
Slider.OnChangeの動作がスタックされる - 変数
PointUPの値が50に設定される - 2(もしくは5)によってスタックされている動作、
Slider.OnChangeを実行する。
Slider.OnChangeには変数PointにPointUPの値を加算するようになっている。この時点ではPointUPには50が設定されているため、Pointには、0 + 50で50が設定される - 5(もしくは2)によってスタックされている動作、
Slider.OnChangeを実行する。
Pointには、50 + 50で100が設定される
対処案
これらの結果より、1つのプロパティ内で、対象プロパティの開始、終了を1つの変数で判断させるのは難しいということがわかりました。
そこで、コントリールを追加して、その中で、対象プロパティの開始、終了の判定を行う変数を処理してあげる法則を対処法として思いつきました。
具体的な設定方法は以下となります。

ここで肝となってくるのは、トグル(切り替え)コントロールです。
対象プロパティの処理の開始、終了判定用にそれぞれトグルを追加し、それぞれのトグルが true (チェック)となったときに、開始、終了の判定を行う変数 isChange の値を更新しています。
各コントロールの設定値は以下になります。
Screen.OnVisible
UpdateContext({val:0});
UpdateContext({isChange:false});
UpdateContext({txt:""});
UpdateContext({isStart:false});
UpdateContext({isEnd:false});
UpdateContext({count:0})
Button.OnChange
UpdateContext({isStart:true});
UpdateContext({val:val+1});
UpdateContext({isEnd:true});
Slider.Default
val
Slider.OnChange
If(!isChange, UpdateContext({txt:"execute slider.OnChange"}));
UpdateContext({count:count + 1})
CheckStart.Default
isStart
CheckStart.OnCheck
UpdateContext({isChange:true});
UpdateContext({isStart:false})
CheckEnd.Default
isEnd
CheckEnd.OnCheck
UpdateContext({isChange:false});
UpdateContext({isEnd:false})
実際の動作としては以下となります。
(動画を撮影したときは、Endのトグル(右のやつ)の設定値を記載したテキストがStartになっていました。。。正しくはEndです。)
なるほど pic.twitter.com/jcoQ9Tna2K
— コルネ (@koruneko32767) May 4, 2021
- ボタンが押されたことにより、
Button.OnChangeが動作 - 以下の順で変数が更新
isStartがtrueに設定valに1加算isEndがtrueに設定
- 2-1により、トグル(Start)が
trueになり、startToggle.OnCheckが動作isChangeがtrueに設定isStartがfalseに設定
- 2-2により、
Slider.OnChangeが動作isChangeはtrueなので、If 関数内の式は実行されないcountに1加算
- 2-3により、トグル(End)が
trueになり、endToggle.OnCheckが動作isChangeがfalseに設定isEndがfalseに設定
ただし、この設定のままでは、ボタンが連打されたときに3以降の動作が平行で行われることになり、 isChange の値が Slider.OnChange 実行時に必ず true であると保障されなくなってしまうので、何らかの方法で処理が完了していないのに、続けてボタンが連打される事態を防ぐなどの予防策を設ける必要があります。
— コルネ (@koruneko32767) May 4, 2021
おわりに
ちょっとめんどくさいですが、以上でPower Apps 内で特定の処理が完了したかの監視が行えるようになるかと思います。
もし、私の記載内容で誤っていることや、もっとこうしたほうが良いのでは?や質問などありましたら遠慮なく教えてください。
