Power Apps ボタンの自己選択による疑似ループ処理

Power Apps
この記事は約5分で読めます。

Power AppsでのCopilot連携がプレビューとなったタイミングでボタンの自己呼出しが可能になりました。
これにより、今までタイマーでしか実現できなかった疑似ループがボタンでも実現可能になりました。
今回は、ボタンを疑似ループ化する際のサンプルコード並びにメリット・デメリットを紹介します。


ターゲットユーザー:開発者

ボタンによる疑似ループの基本形

以前のボタンは自身を選択する動作はエラーとなっていました。
現在は自身を選択することが可能になりましたので、OnSelectプロパティに以下を記述することでループ可能となります。

Select(Self)

上記コードにより自身が選択された瞬間に再度自身を選択します。
選択されるたび自身を再選択するわけですので、この1行のみでは無限ループとなりますし、実際には何もしません。

通常、どのループ処理においても終了条件を設定することが必須ですのでScreen.OnVisibleにもコードを追加し、Button.OnSelectを修正してみます。

/*
    Screen.OnVisible
*/
Set(_Limit, 10);  // ループの終了値
Set(_Step, 1);  // ループごとの増減値
Set(_SEQ, 0);  // 現在のループ回数
Set(_Result, 0);  // 処理結果

/*
    Button.OnSelect
    _Limitまでの総和を求める
*/
If(
    _SEQ < _Limit,

    Set(_SEQ, _SEQ + _Step);
    Set(_Result, _Result + _SEQ);
    Select(Self);
)

/*
    画面にTextCanvasを設置し以下を設定
*/
Text =_Result

この段階では多くの課題が残ります、重大な課題として以下が挙げられます。

  • ボタンを際限なくクリック・タップできてしまうため何度でも実行される。
  • 内部に変数の初期化を行う処理を条件なしに記述すると毎回初期化されてしまう。
  • 画面を移動しない限り各変数の値がリセットされない。
  • 2回目以降の実行結果が保証されない。(実際には追加され続けます)

完全なボタンループの基本形(パターン①)

ボタンコントロール=押すことのできるコントロールということでボタン単体でのループを構築しがちですが、実はそこが落とし穴となっています。
起動用のボタン(または数式) + ループ処理を行うボタンという構成で構築してみます。

コントロール担う処理名前Visible
TEXTINPUTループ回数の入力Limit1true
ボタン変数の初期化とループの開始BtnStartLooptrue
ボタンループ処理BtnLoop1false
TextCanvas結果の表示Result1true
/*
    App
*/
Formulas =_Step = 1;    // 定数として定義

/*
    Screen(任意の画面)
*/
OnVisible =Set(_IsCalc, false);    // ループの実行中

/*
    BtnStartLoop
*/
OnSelect |
    =Set(_Limit, Limit1.Value);
    Set(_SEQ, 0);
    Set(_Result, 0);
    Select(BtnLoop1);
    Set(_IsCalc, true);
DisplayMode =If(_IsCalc, DisplayMode.Disabled, DisplayMode.Edit)    // ループ中は無効

/*
    BtnLoop1
*/
If(
    _SEQ < _Limit,

    Set(_SEQ, _SEQ + _Step);
    Set(_Result, _Result + _SEQ);
    Select(Self);,

    Set(_IsCalc, false);    // 起動ボタンの有効化
)

/*
    Result1
*/
Text =_Result
  • ループの制御用に起動ボタンを設置しました。起動時にすべての変数が初期化されます。
  • ループ回数を指定できるようTextInputを設置しました。
  • ループ中を示す変数を設けて起動ボタンの動作を制限しています。

完全なボタンループの基本形(パターン②)

アプリデザイン上の理由でボタンを表示できない場合のループ起動例

コントロール担う処理名前Visible
TEXTINPUTループ回数の入力と変数の初期化、ループの起動Limit2true
ボタンループ処理BtnLoop2false
TextCanvas計算結果の表示Result2true
/*
    App
*/
Formulas =_Step = 1;    // 定数として定義

/*
    Limit2
    入力後0.5秒待つ
*/
OnChange |
    =Set(_Limit, Self.Value);
    Set(_SEQ, 0);
    Set(_Result, 0);
    Select(BtnLoop2);
TriggerOutput = 'TextInputCanvas.TriggerOutput'.Delayed

/*
    BtnLoop2
*/
If(
    _SEQ < _Limit,

    Set(_SEQ, _SEQ + _Step);
    Set(_Result, _Result + _SEQ);
    Select(Self);
)

/*
    Result2
*/
Text =_Result

まとめ

今回はボタンでのループ処理について紹介しました。
タイマーを使った場合と大きく違う点は「遅延を設定することが出来ない」ということです、遅延しないためタイマーを使うよりパフォーマンスが向上します。

今回紹介したボタンループや以前の記事で紹介したStartプロパティでのタイマーループRepeatプロパティでのタイマーループでは自身を再呼出しする方法で疑似ループを実現してます。
つまり再帰関数のような動作を実現可能です、関数の定義が出来ないPower Appsでハノイの塔や8クイーン巡回などの再起プログラムの実現が出来ます。
手間とパフォーマンスを無視すればアニメーション化して教育プログラムとして利用するなど可能性が広がります。

この記事を書いた人

岩本敏彦
タイトルとURLをコピーしました