プログラミング経験がある人ほど、Power Appsで最初に探すのが「変数はどこにあるのか」です。ところが公式ドキュメントには、こう書かれています。

「一般的には、変数の使用を避けてください」

これはPower Appsの設計思想そのものを表しています。この記事では、なぜ避けるべきなのか、それでも必要になる場面、そして使ったときに起きる落とし穴を解説します。

なぜ「変数を避けろ」なのか

公式ドキュメントは、変数の説明を始める前にこう問いかけます。「Excelで何をしようとしているか?」

Excelには変数がありません。セルに =A1+A2 と書けば、A1やA2が変わるたびに自動で再計算されます。結果を記憶しておく必要がないのです。

Power Appsも同じ仕組みです。ラベルのTextプロパティに TextInput1 + TextInput2 と書けば、入力が変わるたびに自動で更新されます。変数に入れて管理する必要がありません。

公式はこの方式の利点をこう説明しています。

  • 値の出どころが1か所に定まる——ラベルの中身を知りたければ、そのTextプロパティを見ればよい
  • 従来のプログラミングでは、プログラムのどこからでも値を書き換えられるため、いつどこで変わったのか追跡が難しい
  • 1行の式で済むため、コードが増えず、同期がずれる心配もない

「式で書けることは、式で書く」——これがPower Appsの作法です。

それでも変数が必要になる場面

公式も「必要なエクスペリエンスを作成できるのは変数だけ」という場合があると認めています。典型はユーザーの操作履歴に依存する値です。

公式が挙げている例が、電卓の累計です。「追加」ボタンを押すたびに合計が増えていく——この値は、他のコントロールの値からは計算できません。「77を2回足した」のか「24と130を足した」のか、結果の154からは区別できないからです。

つまり「ボタンを押した回数」のような、画面上のどこにも残らない情報を保持したいとき、変数が必要になります。

変数は3種類ある

種類 使える範囲 設定する関数 用途
グローバル変数 アプリ全体 Set 画面をまたいで使う値
コンテキスト変数 その画面のみ UpdateContext
Navigate
画面内の一時的な状態、画面間の値の受け渡し
コレクション アプリ全体 Collect
ClearCollect
表形式のデータを保持する

書き方にも違いがあります。グローバル変数は Set( 変数名, 値 ) ですが、コンテキスト変数はレコード形式UpdateContext( { 変数名: 値 } ) と書きます。

使い分けの基準はシンプルです。その画面でしか使わないならコンテキスト変数、画面をまたぐならグローバル変数、複数行のデータを扱うならコレクションです。

なお Navigate で画面を移動する際にコンテキスト変数を設定できます。これは他の言語で関数に引数を渡すのに近い使い方です。

落とし穴①|コレクションは委任されない。しかも警告が出ない

これが最も危険な罠です。公式ドキュメントに明記されています。

「コレクションは、レコードの静的なメモリ内リストであり、委任に参加できません。委任の警告は表示されません」

委任(デリゲーション)とは、絞り込みをデータ側にやってもらう仕組みです。委任が効かないと、最初の500件しか処理されず、結果が欠けます

通常、委任できない式を書くと黄色い三角の警告が出ます。ところがコレクションを使った場合、この警告すら表示されません

つまり次のような事態が起こります。

  • 大量のデータを ClearCollect でコレクションに読み込む
  • そのコレクションに対して絞り込みを行う
  • 警告は出ない。テスト時のデータが少なければ正常に動く
  • 本番でデータが増えると、結果が欠ける

「動いているように見えるが、実は不完全」という最悪の状態になり得ます。データ量が増える見込みがあるなら、コレクションに読み込んでから処理する設計は避けるべきです。

落とし穴②|型は勝手に決まる

Power Appsの変数は宣言が不要です。Set( X, 1 ) と書いた時点で、Xは数値型の変数として確立されます。

便利な反面、問題も起きます。別の場所で Set( X, "Hello" ) と書くと、型が矛盾してエラーになります。

しかも公式によれば、その式が実際に実行されるかどうかは関係ありません。アプリ内のどこかにそう書かれているだけでエラーになります。

変数名を使い回すときは、常に同じ型の値を入れる必要があります。

落とし穴③|使ってはいけない変数名がある

公式が「使用しないでください」と明示している名前があります。アプリのプロパティと衝突し、予期しない動作を招くためです。

ActiveScreen / Height / Width / Theme / DesignHeight / DesignWidth / MinScreenHeight / MinScreenWidth / SizeBreakpoints / StudioVersion / Testing ほか

HeightやWidthは、うっかり使ってしまいそうな名前です。変数名には用途がわかる具体的な名前を付けるほうが安全です。

落とし穴④|アプリを閉じると消える

基本的な仕様ですが、見落とされがちです。変数はアプリの実行中のみメモリに存在し、閉じると値は失われます。初期値はすべて空白(Blank)です。

値を残したいなら、データソースに保存する必要があります。

  • PatchCollect でデータソースに書き込む
  • SaveData でローカル端末に保存する

ただし SaveDataLoadData には重要な制限があります。公式に「Power Apps Mobileで機能しますが、Power Apps StudioまたはWebプレーヤーでは機能しません」と記載されています。

つまりブラウザで動かしているうちは、この保存機能はテストできません。モバイルアプリ前提の機能である点に注意が必要です。

設計の指針

  1. まず式で書けないか考える——コントロールのプロパティに直接式を書けば、変数は不要なことが多い
  2. 画面内で完結するならコンテキスト変数——影響範囲が狭いほど、後から追いやすい
  3. 大量データをコレクションに入れない——委任が効かず、警告も出ない
  4. 変数名は具体的に——予約語を避け、用途がわかる名前にする
  5. 残したい値はデータソースへ——変数はアプリを閉じれば消える

変数を多用したアプリは、後から見たときに「この値がどこで変わったのか」が追えなくなります。公式が避けるよう勧めているのは、この保守性の問題があるためです。

よくある質問

Q. SetとUpdateContextはどちらを使うべきですか?

その画面でしか使わないならUpdateContext(コンテキスト変数)です。影響範囲が画面内に限定されるため、後から追跡しやすくなります。画面をまたいで使う値だけをSet(グローバル変数)にします。

Q. コレクションと変数はどう違いますか?

コレクションは表形式のデータを扱います。複数行・複数列のデータを保持できる点が、単一の値を持つ変数との違いです。

Q. 同じ名前の変数を作ってしまったらどうなりますか?

コンテキスト変数が優先されます。グローバル変数やコレクションを明示的に参照したい場合は、あいまいさを解消する演算子を使います。ただし混乱の元なので、名前は分けるべきです。

Q. 変数の中身を確認する方法はありますか?

Power Apps Studioのメニューから「変数」を開くと、グローバル変数・コンテキスト変数・コレクションの一覧と、それぞれがどこで定義され使われているかを確認できます。

Q. 変数を削除するにはどうしますか?

その変数を設定している関数(Set・UpdateContext・Collect など)をすべて削除します。変数は明示的に宣言するものではないため、設定箇所がなくなれば存在しなくなります。参照している箇所もエラーになるので、併せて削除が必要です。

まとめ

  • 公式は「一般的には、変数の使用を避けてください」と明記している。Power AppsはExcelと同じ自動再計算のモデル
  • 変数が必要なのはユーザーの操作履歴に依存する値など、式では計算できない場合
  • 種類はグローバル変数(Set)・コンテキスト変数(UpdateContext)・コレクション(Collect)の3つ
  • 最大の罠はコレクション——委任されないうえ、警告すら表示されない
  • 型は暗黙的に決まるため、同じ変数名に違う型を入れるとエラーになる
  • HeightWidthなど使ってはいけない変数名がある
  • 変数はアプリを閉じると消える。SaveDataはモバイルでのみ動作する

アプリの作成手順はキャンバスアプリの作り方入門、委任の詳細はデータソース選びと委任をご覧ください。

参考・出典