はじめに
この記事では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 内で特定の処理が完了したかの監視が行えるようになるかと思います。
もし、私の記載内容で誤っていることや、もっとこうしたほうが良いのでは?や質問などありましたら遠慮なく教えてください。