この記事でできること
最近、Power Appsで自重トレーニング用のアプリを作っています。トレーニング記録を入力するのですが、おおよそ前回と同じくらいの回数を入力することが多く、Defaultの値から離れていると少し手間に感じます。
この記事では、Power AppsのEditFormに以下の3つの機能を追加した実装を紹介します。
- 種目を選ぶだけで前回の回数・セット数が自動で入る
- ボタンで前回値から微調整できる
- 新規入力と編集モードを背景色で見分けられる
今回のサンプルは自作筋トレ記録アプリ「Torelog」での実装ですが、他のEditFormにも応用できる内容です。
完成イメージ

種目を選んだ瞬間に前回の回数とセット数が自動で入り、「<<,<, >, >>」ボタンで数値を微調整できます。また新規入力時は薄緑、編集時は薄青色で背景色が切り替わります。
全体の実装構成
今回の実装で使う変数とコントロールを整理しておきます。
| 変数名 | 種類 | 用途 |
|---|---|---|
| gLastRecord | グローバル変数 | 選択した種目の前回記録を保持 |
| locReps | ローカル変数 | Reps入力欄の値を管理 (ボタン連動) |
| locTotalSets | ローカル変数 | TotalSets入力欄の値を管理(ボタン連動) |
locRepsとlocTotalSetsは、ローカル変数(UpdateContext)として使用するので、App.OnStart ではなく MainScreen.OnVisible で初期化します。
// MainScreen.OnVisible
UpdateContext({locReps: 20, locTotalSets: 3})
実装① 種目を選ぶと前回記録が自動で入る仕組み
OnChangeで最新記録を取得してgLastRecordに保存する。
種目ドロップダウン(ExerciseNameDataCardValue)の OnChange プロパティに以下を設定します。
// ExerciseNameDataCardValue の OnChange
Set(
gLastRecord,
First(
SortByColumns(
Filter(
WorkoutLog,
ExerciseName = ExerciseNameDataCardValue.Selected.タイトル
),
"RecordedAt",
SortOrder.Descending
)
)
);
UpdateContext({
locReps: If(
IsBlank(gLastRecord),
20,
gLastRecord.Reps
),
locTotalSets: If(
IsBlank(gLastRecord),
3,
gLastRecord.TotalSets
)
})
やっていることは2段階です。
まず Filter で選んだ種目の記録だけに絞り、SortByColumns で RecordedAt(記録日時)の降順に並び替えます。その先頭1件を First で取り出して gLastRecord に保存します。
次に UpdateContext で locReps と locTotalSets を更新します。前回記録があればその値、なければデフォルト値(Reps 20・TotalSets 3)をセットします。


locReps・locTotalSetsで入力欄の値を制御する
RepsDataCardValueとTotalSetsDataCardValueの Default プロパティをローカル変数に統一します。
// RepsDataCardValue の Default
Text(locReps)
// TotalSetsDataCardValue の Default
Text(locTotalSets)
ここで Text() で包んでいるのは、EditFormのDataCardValueが Text型を要求するためです。数値をそのまま渡すとエラーになります。
また、編集モードでギャラリーの行をタップした時は、既存レコードの値をローカル変数にロードします。
// WorkoutLogGallery の OnSelect
Set(gSelectedRecord, ThisItem);
UpdateContext({
locReps: ThisItem.Reps,
locTotalSets: ThisItem.TotalSets
})

これで新規モードは「前回記録またはデフォルト値」、編集モードは「既存レコードの値」が入力欄に自動で表示されます。
実装② ボタンで回数・セット数を調整する
ボタンはDataCard直下にXY座標で配置する
DataCard内にボタンを置く際、コンテナでまとめようとするとエラーが起きます。DataCard内にコンテナを挟むと Parent.Default がそのコンテナを参照してしまい、DataCardValueが正しく動かなくなります。
ボタンはDataCard直下にXY座標で直接配置して設置します。


DataCardValueのDefaultはText(locReps)に統一する
各ボタンの OnSelect には UpdateContext で加減算を書きます。
// RepsMinus10Button の OnSelect
UpdateContext({locReps: Max(1, Value(RepsDataCardValue.Text) - 10)})
// RepsMinus1Button の OnSelect
UpdateContext({locReps: Max(1, Value(RepsDataCardValue.Text) - 1)})
// RepsPlus1Button の OnSelect
UpdateContext({locReps: Value(RepsDataCardValue.Text) + 1})
// RepsPlus10Button の OnSelect
UpdateContext({locReps: Value(RepsDataCardValue.Text) + 10})
Max(1, …) を入れることで、0以下にならないようにしています。

実装③ 新規・編集モードを見た目で区別する
新規と編集のどちらで操作しているかをひと目でわかるようにします。
RecordButtonのTextでボタンラベルを切り替えます。
// RecordButton の Text
If(RecordForm.Mode = FormMode.Edit, "✏️ 更新する", "✅ セットを記録")
FormContainerのFillで背景色を切り替えます。
// FormContainer の Fill
If(RecordForm.Mode = FormMode.Edit, gTheme.MainLight, gTheme.NewRecord)



ハマりポイントまとめ
実装中に引っかかったポイントを整理します。
① DataCardValueはText型を要求する
locReps は数値型のローカル変数ですが、DataCardValueの Default に数値をそのまま渡すとエラーになります。Text(locReps) のように Text() で包みます。
② コンテナを挟むとParent.Defaultが壊れる
DataCard内にコンテナを追加してDataCardValueを中に入れると、Parent.Default がコンテナを参照してしまいエラーになります。ボタンはコンテナを使わず、DataCard直下にXY座標で直置きします。
③ SubmitForm後にFormModeがViewに変わる
SubmitFormが成功するとフォームは自動的に FormMode.View に切り替わります。If(RecordForm.Mode = FormMode.New, Patch(…)) のように記録後に判定しようとしても、すでにNewではなくなっています。SubmitFormを呼ぶ前に Set(gIsNew, RecordForm.Mode = FormMode.New) で変数に保存しておく必要があります。

④ キャンセル・記録完了時のlocRepsリセット忘れ
ローカル変数はリセット操作を明示的に書かないと前の値が残ります。CancelIcon・RecordButtonのOnSelectにはそれぞれリセット処理を追加してください。
// CancelIcon の OnSelect
Set(gSelectedRecord, Blank());
ResetForm(RecordForm);
UpdateContext({locReps: 20, locTotalSets: 3})
// RecordButton の OnSelect(末尾に追加)
Set(gSelectedRecord, Blank());
ResetForm(RecordForm);
UpdateContext({locReps: 20, locTotalSets: 3})
まとめ
今回の実装のポイントをまとめます。
- OnChange で前回記録を gLastRecord に保存し、UpdateContext でローカル変数に展開する
- DataCardValueの Default はすべて Text(locReps) 形式で統一する
- 加算減算ボタンはDataCard直下にXY座標で配置する(コンテナ不使用)
- ローカル変数のリセットは記録完了・キャンセルの両方で明示的に書く
- 編集モードとの区別は FormMode.Edit を使ってボタンラベルと背景色で表現する
今回は「前回値の自動参照」と「ボタン」という地味な改善ですが、毎日使うアプリほどこういった入力の手間がじわじわ効いてくるのでおすすめです。
Power Platformを触り始めたばかりの方に向けて、こういった詰まりポイントをこれからも発信していきます。よかったらブログをブックマークして、またのぞきに来てください!
あわせて読みたい
この記事の前に読むとスムーズです。後から直しやすいアプリの設計はこちら。



コメント