Edited at

【#PowerApps】PowerAppsでタイマーコントロールを使わずにタイマーコントロールよりも高速なループを実行する方法


概要

 PowerAppsを利用していてループ処理を実装する場合通常であればタイマーのRepeatプロパティをtrueにし、OnTimerEndプロパティなどを利用して疑似的に処理を行います。

 しかし、Durationに制限があるため、ループの速さには上限があります。(基本的にはこの速度で十分ですが...)ゲームやアニメーションをPowerAppsで実装した場合、どうしてもこの遅さがネックになってくる場合があります。そこで今回は、とあるコントロールを利用して、タイマーコントロール(以下タイマー)よりも高速なループ処理を実装します。


成果

 こちらの動画をどうぞ



実装

 何のコントロールを利用するかですが、利用するのは【スライダーコントロール(以下スライダー)】の【OnChangeプロパティ】です。


OnChangeプロパティ

 そのコントロール(今回はスライダー)の値が変化したときにそこに書かれた処理が実行されます。

つまり、OnChangeプロパティの中で、スライダーの値を変更してしまえばループになるということです。

値変更 → 変更を感知してOnChange → Onchangeプロパティで値変更 → 変更を感知してOnChange ...

設定は簡単で以下の通りに設定します。

App OnStart = Set(glbValue,0);Set(glbIsStop,true)

今回は分かりやすくグローバル変数に設定していますが、コンテキスト変数でも構いません。

slider1.OnChange = If(!glbIsStop,Set(glbValue,glbValue + 1))

Default = glbValue

さすがに処理を止められないと困るので、glbIsStop がfalseの時だけ実行できるようにします。

今回のように 「!」を論理式の頭につけることで、true false の結果が逆になります。

一応以下のように書いても結果は変わりません。

If(glbIsStop,"",Set(glbValue,glbValue + 1))

この「Set(glbValue,glbValue + 1)」の後にそれぞれループを行いたい処理を書く形になります。

最後に実行できるようにボタンを配置して完成です。

Button1 OnSelect

Set(glbIsStop,!glbIsStop);If(!glbIsStop,Reset(Slider1))


なぜReset()を行う?

ここが今回の鍵で、ただスライダーを止めるだけだと、当然次の処理が実行されません。

Reset()を行うと、OnChangeプロパティも実行される為、このような処理が必要になってきます。

つまり「If(!glbIsStop,Reset(Slider1))」はスライダーの OnChangeプロパティを実行している、ととらえていただいて構いません。


注意点

 気を付けるのは、タイマーと違って、アプリの編集中でも処理が実行される点です。きちんと止めないと処理によっては大変なことになるので気を付けましょう。


まとめ

今まで

PowerAppsのループ処理 = タイマー

これから

PowerAppsのループ処理 = スライダー(OnChangeプロパティがあるコントロール)

(タイマーループの方がいい場合もあります。(スライダーループは速度が端末次第で変わるため))

今回作成したサンプルはこちらからDLできます。

https://powerusers.microsoft.com/t5/Community-Apps-Gallery/Loop-faster-than-Timer-Control/m-p/256147#M136