序
古参アピールというわけではないのですが、Power Apps で複数のレコードをまとめて更新したいとき、従来は、ギャラリーにチェックボックスを配置して更新対象を選択したり、更新するレコードをコレクションに格納したりする方法がよく使われていました。
もちろん、従来の方法でも一括更新は実現できます。しかし、チェックボックスの選択状態を If 関数で判定したり、コレクションへの追加ならびに削除を制御したりと、更新対象を管理するための処理が必要になってしまうことから、こうしたデータの一括操作は、Power Apps 初学者には高難度とされてきた認識です。
ところが、モダンコントロールの「データグリッド」を使えば、部品(コントロール)の配置や処理をかなり簡略化できます。データグリッドには、複数のレコードを選択する機能が標準で備わっており、選択されたレコードを SelectedItems プロパティで取得できる利点があります。
なお、データグリッドの基本的な使い方は上に引いた記事をご一読ください。ここからは最低限の説明に絞って方法を紹介できればと思います。
今回使用する SharePoint リストの名前は 予約一覧 とし、ID、機器、予約者、開始日時、終了日時などの情報を管理しているものとします
1. データグリッドを配置する
最初に、モダンコントロールを利用できるように設定し、キャンバスアプリに「データグリッド」を配置します(※最近のアップデートで「モダンコントロール」の利用可否を簡単に切り替えられるようになりました)
データグリッド(DataGrid1)を配置したら、その Items プロパティにデータソースを指定します。
予約一覧(要するにデータソース名)
続いて、画面右側のプロパティウィンドウで、フォントサイズや必要な列の表示などの設定を行います。最低限、複数選択が「オン」になっていることは確認しておきます。
従来のように、ギャラリー内へチェックボックスを配置したり、OnCheck や OnUncheck に選択状態を管理する数式を記述したりする必要がないのは気楽になったもので、選択中のデータ行(レコード)は以下の数式で取得できるようになりました。
DataGrid1.SelectedItems
この SelectedItems が、選択されたレコードをテーブルとして返しており、更新対象のレコードを取得するために、わざわざコレクションを作成する必要がなくなったわけです。ありがたい。
2. ギャラリーを配置する
続いて、選択したレコードを編集するためのギャラリー(galEditForm)を配置します。データグリッドとは別の画面を新たに用意し、そのスクリーン内に配置すると利用者が分かりやすいと思います。
続いて、配置したギャラリーの Items プロパティに以下を指定することで、データグリッドで選択したレコードがギャラリー内に表示されます。
DataGrid1.SelectedItems
現在は、データ編集用のコントロールを配置していないため何も表示されていませんが、取得自体は完了しています。表示用のコントロールを配置していくことにしましょう。その際、右側のプロパティでレイアウトを「空白」にしておくとスムーズです。
2.1. ギャラリー内にコントロール(部品)を配置する
ギャラリー内に編集用のコントロールを配置していきます。主に、次のコントロールを使用していますが、ここはアプリを使用しているイメージを膨らませつつ自由に変更いただくとよいと思います。
| コントロール | 名前(※変更しています) | 用途 |
|---|---|---|
| テキストラベル | lblReservationID |
レコードの予約 ID を表示 |
| コンボボックス | cmbProduct |
更新前の予約機器名を表示 |
| 日付の選択 | dpStartDate |
更新前の予約開始日を表示 |
| 日付の選択 | dpEndDate |
更新前の予約終了日を表示 |
| コンボボックス | cmbReserver |
更新前の予約者を表示 |
| テキスト入力 | txtPurpose |
更新前の利用目的を表示 |
2.2. ギャラリー内のコントロールを設定する
ギャラリー内にコントロールを配置しただけだと、データグリッドで選択したデータは表示されません。そのため、各コントロールのプロパティをそれぞれ設定する必要があります。
2.2.1. 予約IDを表示する「テキストラベル」の設定
テキストラベルの Text プロパティに、次の数式を入力します。テキスト入力を利用している場合は、Default プロパティに次の数式を入力します。
ThisItem.Title
表示したいデータが貯まっている列を ThisItem.◯◯ という形で呼び出していく設定です。筆者は、予約IDをタイトル列に保存しているので ThisItem.Title となっています。
2.2.2. 予約機器名を表示する「コンボボックス」の設定
続いて、機器を変更するコンボボックスを設定します。今回はモダンコントロールの「コンボボックス」を使用しているので、クラシックコントロールの設定方法とは少し異なっています。
また、コンボボックスの設定は、選択肢として利用したい SharePoint リストの列の「型(列の種類)」によっても少し異なってきます。当記事の「予約機器」を保存している列の型は「一行テキスト」である点にご注意ください。
複数選択を許可しないように、SelectMultiple プロパティを false に設定し、Items プロパティには以下の数式を入力します。今回は Distinct 関数を使用し、既存の予約データから機器名の一覧を取得してみましょう。
Distinct(予約一覧,予約機器)
Distinct 関数を使用すると、機器予約リストに登録されている機器名から重複を除いた一覧を取得できます。なお、Distinct 関数の結果(=戻り値)は、Value という列を持つテーブルになります。そのため、コンボボックスの ItemDisplayText プロパティには、以下を設定します。
ThisItem.Value
最後に、更新対象のデータが表示されるように初期値を DefaultSelectedItems プロパティ設定します。
{Value: ThisItem.予約機器}
ここまで設定できれば、データグリッドで選択したレコードをギャラリーに表示し、各レコードの機器を個別に変更できる状態になります。
Distinct 関数は、大量のデータを扱う場合に注意を要する関数です。また、この方法では既存の予約データに登録されていない機器を選択できません。
2.2.3. 予約開始日/終了日を表示する「日付の選択」の設定
説明の余地はあまりないかもしれませんが、最後に「日付選択」の設定内容にも触れておこうと思います。このコントロールの場合は、DefaultDate プロパティに次の数式を入力するだけでOKです。
ThisItem.予約開始日
表示したいデータが「予約開始日」か「予約終了日」かに応じて設定していくとよいでしょう。
2.2.4. ヘッダーを作ると見栄えが変わる
余談ですが、ギャラリーの上部に「コンテナー」を配置し、その中に列名表示用の「テキストラベル」を配置していくと、アプリの利用者がどんなデータを入力すればよいのか分かりやすくなって便利です。
ギャラリーを使ってヘッダーを作成する方法もありますが、こちらの方が直感的な操作で配置場所を変えられる利点があり、入力データの文字数に応じてレイアウトしやすいです。
3. 更新ボタンを設定する
最後に、更新ボタンを配置します。今回は ForAll 関数と Patch 関数を使用して、ギャラリーに表示されているレコードを更新します。配置したボタンの OnSelect プロパティに、以下の数式を設定します。
ForAll(
galEditForm.AllItems,
Patch(
予約一覧,
ThisRecord,
{
予約機器: cmbProduct.Selected.Value,
予約開始日: dpStartDate.SelectedDate,
予約終了日: dpEndDate.SelectedDate,
予約者: cmbReserver.Selected.Value,
利用目的: txtPurpose.Text
}
)
)
なお、最近のアップデートで、数式を別ウィンドウで書けるようになったため、長い数式の入力には、こちらを利用していくと良いでしょう。
ForAll 関数では、ギャラリーの AllItems、つまり、これから更新する(上書き保存する)内容を参照しており、Patch 関数では、SharePoint リストのどの列にそれらを登録するのかを設定しています。
ThisRecord
なお、ThisRecord は、更新しようとしている内容がどの行番号に該当するのかをチェックしているイメージです。仮に、更新履歴としてデータを貯めておきたい(新規登録したい)場合は、ThisRecord の代わりに Deafaults 関数を利用します。
Defaults(データソース) //更新履歴を保存するためのリストがあると良いですね
これで一括更新の基本的な処理は完成です。なお、上記は基本的な更新処理の例に絞っています。
実際の業務アプリでは、IfError 関数による更新エラーの検出、正常にデータが更新されたことを示す Notify 関数での表示、Refresh 関数による更新完了後の再読み込みなど、必要に応じて追加するとより良いでしょう。
上から3行分をテストで更新してみました。
上手く更新されていました。
4. 補足
4.1. Choices 関数
今回は「予約機器」列を「一行テキスト」で作成しているため、コンボボックスの選択肢を Distinct 関数で作成しましたが「予約機器」列が「選択肢」であれば、Choices 関数を使用できます。
Choices(機器予約リスト.予約機器)
Choices 関数を利用した場合、ItemDisplayText プロパティの設定も Value ではなく「リストの列名」となります。
ThisItem.予約機器
また、テキスト列と選択肢列では、Patch 関数に渡す値の形式が異なる点に注意してください。数式がエラーを吐く場合は「登録しようとしているデータの型」と「登録先の列の型」が異なっているケースがほとんどです。
4.2. 備品マスタは作成した方がよい
また、今回のように、既存の予約データから Distinct 関数で機器名を抽出する方法は、簡単に実装できるという利点があります。
その一方で、あるタイミングで新しい予約機器の追加があった場合、その機器が予約データに一度も登録されていなければ、Distinct 関数で取得した一覧には表示されないという問題点もあります。
また、既存の予約データに登録されている機器名に表記ゆれがあると、それぞれ別の選択肢として表示されてしまうというデメリットもあるため、機器の情報を管理するマスタを作成し、予約データと機器情報は分けて管理し、コンボボックスには「機器情報マスタ」を紐付けるのが望ましいと思われます。
4.3. 大量のレコードを更新する場合の注意点
今回紹介した方法は、少数のレコードを選択して編集する場面を想定しています。ForAll 関数は大規模なデータに対応しておらず、また、ギャラリーの AllItems はギャラリーに読み込まれたレコードを返すため、必ずしも Items に含まれるすべてのレコードを返すわけではありません。
そのため、大量のレコードを一度に選択ならびに更新する場合には、更新対象がすべて読み込まれているかどうかも含めて検証する必要があります。
加えて、ForAll 関数を利用することによる更新は、ネットワークが不安定な場所で利用するなどがあると、一部のレコードだけ更新に失敗する可能性があります。
したがって、業務アプリとして使用する場合は、更新件数、エラー処理、更新後の確認方法などを要件に応じて設計することが重要...と、考えています。
特に根拠はありませんが、せいぜい10件前後の更新に留めておき、この件数を超える場合には Power Automate と併用した更新作業も視野に入れると安定すると思います。
結
今回は、データグリッドコントロールを使って、複数のレコードを一括更新する方法をご紹介しました。以前から Power Apps では、ギャラリーやチェックボックス、コレクションを使ってデータの一括更新を実装できましたが、データグリッドの登場によって、更新対象のレコードを選択するための仕組みを自分で作り込む必要がなくなり、より少ない設定と数式で実現できるようになった印象です。
もちろん、従来の方法を使い続けるのも1つの選択肢です。これから一括更新機能を実装するのであれば、データグリッドの活用も検討してみてはいかがでしょうか。
















