コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

【Power Apps】処理の開始と完了の監視に関して


スポンサードリンク

はじめに

この記事ではPower Apps の Slider.Onchange の動作に関する検証結果を纏めています。

これらの検証の纏めは、特定の処理の開始、完了を監視したい。
という要望に役立つかと思います。

発生した事象

事象としては以下のようなことが発生しました。

前提条件
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 にも記載の、

通常、複数の数式は ; 演算子と一緒にチェーンすることにより評価され、各々を順次に順番に評価します。 ともある通り、順に式が評価されるはずです。
よって以下のような動作になると想像されます。

  1. 変数 isChange の値が true に設定される
  2. 変数 val の値に1が加算される
  3. 2の動作によってSlider にも設定されている val の値が変更されたので、 Slider.OnChange が動作する
  4. Slider.OnChange が動作した結果、 If 関数 内の isChange の値が評価される。
    isChange の値は1で true に設定されており、 ! により否定がとられているので、 "False の場合" の式が実行される。
    ただし、今回は "False の場合" の式が設定されていないため、なにも実行されない。
  5. 変数 isChange の値が false に設定される

しかし実際の動作としては、 Slider.OnChange の動作によって、 !isChangetrue と判断されて、変数 txt に"execute slider.OnChange"が設定されてしまった。

また、この問題に関してふらり さんも検証していただけました。
ありがとうございます!!

これらの結果から、ふらりさんも述べている通り、他コントロールでのSlider の値の変更回数分しっかりトリガーされていることがわかります。

ただ、ここで1つきづいたことがあります。
例えば、 "Button1" を押したときの動作ですが、変数 val の変更に対して、すぐに Slide.OnChange が動作したのであれば、変数 PointUp は0のはずなので、変数 Point の結果は0となるはずです。
また、 "Button3" を押したときの動作の Point の最終結果は100ではなく、60が設定されているはずです。

このことから、まず対象コントロールの動作プロパティないの式が評価されてから、その式によって生じた他コントロールの動作が順次動作されていくのではないか?と私は考えました。
* あくまで実際の動作からの私の想定であり、公式のドキュメントなどにて記載されていることではないことにご注意ください。

この予想を "Button3" を押したときの動作の内部の動き(予想)に当てはめると恐らく以下のような動作をしているのではないでしょうか。

  1. 変数 val の値が1に設定される
  2. 1によって、Slider の値が変更されたので Slider.OnChange の動作がスタックされる
  3. 変数 PointUP の値が10に設定される
  4. 変数 val の値が5に設定される
  5. 4によって、Slider の値が変更されたので Slider.OnChange の動作がスタックされる
  6. 変数 PointUP の値が50に設定される
  7. 2(もしくは5)によってスタックされている動作、 Slider.OnChange を実行する。
    Slider.OnChange には変数 PointPointUP の値を加算するようになっている。この時点では PointUP には50が設定されているため、 Point には、 0 + 5050が設定される
  8. 5(もしくは2)によってスタックされている動作、 Slider.OnChange を実行する。
    Point には、 50 + 50100が設定される

対処案

これらの結果より、1つのプロパティ内で、対象プロパティの開始、終了を1つの変数で判断させるのは難しいということがわかりました。
そこで、コントリールを追加して、その中で、対象プロパティの開始、終了の判定を行う変数を処理してあげる法則を対処法として思いつきました。

具体的な設定方法は以下となります。

f:id:koruneko:20210505052956p:plain

ここで肝となってくるのは、トグル(切り替え)コントロールです。
対象プロパティの処理の開始、終了判定用にそれぞれトグルを追加し、それぞれのトグルが 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です。)

  1. ボタンが押されたことにより、 Button.OnChange が動作
  2. 以下の順で変数が更新
    1. isStarttrue に設定
    2. val に1加算
    3. isEndtrue に設定
  3. 2-1により、トグル(Start)が true になり、startToggle.OnCheck が動作
    1. isChangetrue に設定
    2. isStartfalse に設定
  4. 2-2により、 Slider.OnChange が動作
    1. isChangetrue なので、If 関数内の式は実行されない
    2. count に1加算
  5. 2-3により、トグル(End)が true になり、endToggle.OnCheck が動作
    1. isChangefalse に設定
    2. isEndfalse に設定

ただし、この設定のままでは、ボタンが連打されたときに3以降の動作が平行で行われることになり、 isChange の値が Slider.OnChange 実行時に必ず true であると保障されなくなってしまうので、何らかの方法で処理が完了していないのに、続けてボタンが連打される事態を防ぐなどの予防策を設ける必要があります。

おわりに

ちょっとめんどくさいですが、以上でPower Apps 内で特定の処理が完了したかの監視が行えるようになるかと思います。

もし、私の記載内容で誤っていることや、もっとこうしたほうが良いのでは?や質問などありましたら遠慮なく教えてください。


スポンサードリンク