- 記事一覧 >
- ブログ記事

Power Appsのギャラリーでエクセル風 編集可能なグリッドテーブルを作成 2/2
はじめに
前回記事「Power Appsのギャラリーでエクセル風 編集可能なグリッドテーブルを作成 1/2」の続きです。
今回は、行の追加、行の削除を可能にして、完成させます。
行の追加ボタン作成
前回記事で編集機能が実装できたので、行の追加機能を追加します。
編集ボタンの横に新規追加ボタンを置きます。
ここで、新規追加ボタンは編集ボタンの位置へ配置し、編集ボタンは、右にずらします。
アイコンは、「追加」で検索します。
アイコンとラベルは、ico_New、lbl_New と名付けます。
■ ico_New
4040loc_GalleryMode=Blank()■ lbl_New
"新規追加"FontWeight.Bold40ico_New.X + ico_New.Widthico_New.Yico_New.Visible■ ico_Edit
lbl_New.X + lbl_New.Width + 30ico_New.Y■ lbl_Edit
ico_Edit.X + ico_Edit.Widthico_New.Y■ ico_Save
ico_New.Xico_New.Y■ lbl_Save
ico_Save.X + ico_Save.Widthico_New.Y行の追加ボタン実装
行の追加ボタンをクリックしたら、行の追加モードになるようにします。
OnSelect で コレクション col_Updates を空のレコード2件とします。
■ ico_New
ClearCollect(col_Updates, {ID:1},{ID:2});
UpdateContext({loc_GalleryMode: "New"});ClearCollect(col_Updates, {ID:1},{ID:2}); は、ID のみ存在する空のレコード2件です。loc_GalleryMode は、"Edit" だけでしたが、行の追加モード "New" を導入します。
■ lbl_New
Select(ico_New)これだけの場合、見た目は、何も起きません。
行の追加モードの場合、ギャラリーの表示を loc_GalleryMode と連動させます。
■ gal_EditableTable
If(loc_GalleryMode="New", col_Updates,'Members')loc_GalleryMode="New" のとき、ギャラリーのデータソースを col_Updates にするという意味になります。loc_GalleryMode="New" 以外の時のデータソースは、SharePoint の Members リストです。
ギャラリーの Items プロパティは、データソースを意味します。
次に、txt_MemberID、txt_Name、txt_Age について、行の追加モードの時でも編集可能にします。
■ txt_MemberID、txt_Name、txt_Age
If(loc_GalleryMode in ["New", "Edit"], DisplayMode.Edit,DisplayMode.View)
loc_GalleryMode in ["New", "Edit"]は、loc_GalleryMode = "New" Or loc_GalleryMode = "Edit"と同じ意味です。loc_GalleryModeを2回書くのを避ける書き方になります。
このままでは、2行までしか追加できませんので、2行目を変更したら、3行目が出現するようにします。
■ txt_MemberID、txt_Name、txt_Age
With(//With関数。この()内だけで使える変数を定義。
{wLastID: Last(col_Updates).ID},//With()内だけで使える変数。wLastID=col_Updatesの最後のレコードのID
If(loc_GalleryMode="New" And ThisItem.ID=wLastID, Collect(col_Updates, {ID: wLastID+1}))
//loc_GalleryMode="New"かつ最後の行が編集されたとき、col_Updatesに最後のID+1のレコードを追加
);With( レコード、数式 ) で With() 内だけで使える変数 wLastID を定義しています。wLastID は、col_Updates の最後のレコードの ID です。(1,2,3... の連番の一番大きい値)If(loc_GalleryMode=... 部分は、数式で、loc_GalleryMode="New" かつ最後の行が編集されたとき、col_Updates に {ID: 最後のID+1} のレコードを追加しています。ThisItem.ID は、ギャラリーの現在行の ID、Collect は、レコードの追加関数です。(ClearCollect の場合は、追加ではなく、最初から作り直しです。)col_Updates にレコードを追加して、なぜ、ギャラリーの空行が増えるかというと、New モードの時は、ギャラリーのデータソースが col_Updates だからです。
垂直ギャラリーの表示行数は、データソースのレコード数と連動する性質ですので、col_Updates の行が増えれば、ギャラリーの表示行も増えます。
OnChange は、入力中ではなく、内容が確定したときに発動します。(エンターキーを押したり、他へフォーカスが移った時です。)
まだこの段階では、見た目だけ追加できるようになって、実際に、データソースの SharePoint の Members リストに追加できるわけではありません。
次で実際に追加できる機能を実装します。
行の追加機能実装
編集の時に表示していた保存、キャンセルアイコンを New モードのときでも表示するようにします。
■ ico_Save
loc_GalleryMode in ["New", "Edit"]保存ボタンの OnSelect の動作を New モード、Edit モードのときで分けます。
■ ico_Save
//Newモード、Editモードでcol_Updatesへの扱いを変える
If(
//Newモードの場合
loc_GalleryMode="New",
//追加箇所の記録
ForAll(//ForAll一番目の引数=テーブル構造のデータ
gal_EditableTable.AllItems As NewRows,//ギャラリー内の全てのレコードが対象。NewRows として定義
Patch(col_Updates,
LookUp(col_Updates, ID=NewRows.ID), {//LookUp(col_Updates, ID=NewRows.ID)は、ID以外何も入っていないレコード(New画面を開いたときとOnChangeでIDだけ入れている。)
MemberID: NewRows.txt_MemberID.Text,//該当ID行の入力内容
Name: NewRows.txt_Name.Text,
Age: Value(NewRows.txt_Age.Text)
})
);
UpdateIf(col_Updates, true, {ID: Blank()});//ID列を消去。trueは、全レコードという意味。
//Remove(col_Updates, Last(col_Updates))//最後のレコードは、必ず空白行のため、削除。
RemoveIf(col_Updates, IsBlank(MemberID) And IsBlank(Name) And IsBlank(Age))//空白行、削除。
//実は問題有り:New モードに切り替えた時、最初の状態で2行空行があり、そのまま保存ボタンを押すと、1行空レコードが残る。
//他にも、一度入力して、全部消した行も追加対象になる。
//→RemoveIfで空行を捉えて、消す仕様とする。
,
//Editモードの場合
loc_GalleryMode="Edit",
//ここは、編集のときの内容と同じ
ForAll(
Filter(
gal_EditableTable.AllItems,
tog_isChanged.Value
) As ChangedRows,
Patch(col_Updates,
Defaults(col_Updates), {
ID: ChangedRows.ID,
MemberID: ChangedRows.txt_MemberID.Text,
Name: ChangedRows.txt_Name.Text,
Age: Value(ChangedRows.txt_Age.Text)
})
)
);
// SharePointのMembersリストをcol_Updatesを使って書き換え
// (Membersリスト隠し列のIDとcol_UpdatesのIDの値が一致した行が書き換わる。col_UpdatesのIDが空白の場合、行追加。)
Patch(Members, col_Updates);
Clear(col_Updates);//編集追加箇所の記録をクリア
// Viewモードに戻す。
UpdateContext({loc_GalleryMode: Blank()});参考元記事(https://www.matthewdevaney.com/power-apps-excel-style-editable-table-part-2)の方は、Remove(col_Updates, Last(col_Updates))
になっていたのですが、一度入力したところの入力内容を消してそのまま登録すると、空行が登録されるため、RemoveIf(col_Updates, IsBlank(MemberID) And IsBlank(Name) And IsBlank(Age))
として、空行は登録対象にしないようにしました。
以下のイメージで追加されます。
キャンセルボタンは、編集の時と同じコードで問題なく、変更無しです。
■ ico_EditCancel
// テキスト入力をリセットして、Defaultの値に戻す。
// Defaultの値とは、データソース(SharePointのMembersリスト)の値のこと。
//txt_MemberID、txt_Name、txt_Age 各々の Reset プロパティを
//loc_ResetTextInputs とするため、これでリセットの意味になる。
UpdateContext({loc_ResetTextInputs: true});
UpdateContext({loc_ResetTextInputs: false});
//編集箇所の記録をクリア
Clear(col_Updates);
// Viewモードに戻す。
UpdateContext({loc_GalleryMode: Blank()});行の削除ボタン作成
変更機能が実装できたので、行の追加機能を追加します。
編集ボタンの右側に削除ボタンを置きます。
アイコンは、「ごみ箱」で検索します。(注意:「ゴミ箱」ではないです。)
アイコンとラベルは、ico_Delete、lbl_Delete と名付けます。loc_GalleryMode に "Edit", "New" に加えて、"Delete" を設けます。
■ ico_Delete
4040lbl_Edit.X + lbl_Edit.Width + 30ico_New.YUpdateContext({loc_GalleryMode: "Delete"});
UpdateContext({loc_IsDeleteMode: true});loc_GalleryMode=Blank()■ lbl_Delete
"削除"FontWeight.Bold40ico_Delete.X + ico_Delete.Widthico_New.Yico_Delete.VisibleSelect(ico_Delete)削除ボタンを押したときに出現するボタンを設置します。
削除ボタンを押したときに出現するボタンは、以下の3種類です。
・削除確定ボタン: 押したら、削除対象に指定した行が消えます。
・削除キャンセルボタン: 押したら、削除操作が取りやめになります。
・削除行選択ボタン: 削除アイコンが各行に配置されます。押したら、削除対象行として選択されます。
各々、以下のように命名します。
・削除確定ボタン: ico_ConfirmDelete(「チェック」アイコン)、lbl_ConfirmDelete
・削除キャンセルボタン: ico_CancelDelete(「キャンセル」アイコン)、lbl_CancelDelete
・削除行選択ボタン: ico_DeleteLine(「ごみ箱」アイコン)
各々、配置します。(とりあえず、配置のみです。)
削除行選択ボタンは、ギャラリー内に配置します。手動でドラッグして、行の右側に持ってきます。
■ ico_ConfirmDelete
4040ico_New.Xico_New.Y■ lbl_ConfirmDelete
"削除確定"40FontWeight.Boldlbl_New.Xico_New.YSelect(ico_ConfirmDelete)ico_ConfirmDelete.Visible■ ico_CancelDelete
4040ico_Edit.Xico_Edit.Y■ lbl_CancelDelete
"削除キャンセル"40FontWeight.Boldlbl_Edit.Xico_New.YSelect(ico_CancelDelete)ico_CancelDelete.Visible配置が終わったら、このような状態になります。
重なっていますが、この後 Visible を調整して対処します。
フラグまとめ
行の削除機能実装前に、何をやっているのか分かりにくくなりますので、行の削除機能で新たに登場するフラグを交えて、先にまとめを載せます。
✔:表示 ❌:非表示
新規追加1:新規追加ボタンクリック直後
新規追加2:新規追加画面で、ごみ箱アイコンをクリック直後
編集1:編集ボタンクリック直後
編集2:編集画面で、ごみ箱アイコンをクリック直後
削除:削除ボタンをクリック直後
| View | 新規追加1 | 新規追加2 | 編集1 | 編集 2 | 削除 | |
|---|---|---|---|---|---|---|
| loc_GalleryMode | Blank() | "New" | "New" | "Edit" | "Edit" | "Delete" |
| loc_IsDeleteMode | false | false | true | false | true | true |
| 新規追加ボタン | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
| 編集ボタン | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
| 削除ボタン | ✔ | ❌ | ❌ | ❌ | ❌ | ❌ |
| 右側のごみ箱アイコン | ❌ | ✔ | ✔ | ✔ | ✔ | ✔ |
| 保存ボタン | ❌ | ✔ | ❌ | ✔ | ❌ | ❌ |
| キャンセルボタン | ❌ | ✔ | ❌ | ✔ | ❌ | ❌ |
| 削除確定ボタン | ❌ | ❌ | ✔ | ❌ | ✔ | ✔ |
| 削除キャンセルボタン | ❌ | ❌ | ✔ | ❌ | ✔ | ✔ |
行の削除機能実装
ico_DeleteLine について、クリックされたら、col_DeleteRecords コレクションにクリックされた行のデータを格納するようにします。
■ ico_DeleteLine
If(Self.Icon=Icon.Trash, Collect(col_DeleteRecords, ThisItem), Remove(col_DeleteRecords, ThisItem));
If(CountRows(col_DeleteRecords)>0 Or loc_GalleryMode="Delete", UpdateContext({loc_IsDeleteMode: true}), UpdateContext({loc_IsDeleteMode: false}))ThisItem は、ギャラリーの現在の行を意味します。
クリックされたアイコンがごみ箱アイコン:col_DeleteRecords に現在行データを追加
クリックされたアイコンがキャンセルアイコン:col_DeleteRecords から現在行データを削除
としています。If(CountRows(... のところは、削除対象が1件以上あったり、Delete モードのとき、loc_IsDeleteMode を true に切り替えています。
この時点では、loc_GalleryMode="Delete" だけで削除モードだと分かるのですが、この後、編集モード、行追加モードでも削除機能を有効にするため、別の変数 loc_IsDeleteMode で現在削除操作中なのかを判定しています。
さらに、ico_DeleteLine について、クリックされたら、キャンセルアイコン(× 型のアイコン)になるようにします。
キャンセルアイコンは、コードでアイコンを書き換えています。
■ ico_DeleteLine
If(ThisItem in col_DeleteRecords, Icon.Cancel, Icon.Trash)現在行が col_DeleteRecords に含まれていない場合、ごみ箱アイコン、含まれている場合、キャンセルアイコンを設定しています。
現在行が col_DeleteRecords に含まれている場合、削除対象行なのですが、アイコンの形状以外に削除対象として選択された行が分かりやすくなるように、テキスト入力の色を変えます。
■ txt_MemberID、txt_Name、txt_Age
If(ico_DeleteLine.Icon=Icon.Trash, Color.White, RGBA(238, 204, 204, 1))RGBA(238, 204, 204, 1) は赤っぽい色です。
ico_DeleteLine の表示非表示を調整します。
■ ico_DeleteLine
loc_GalleryMode in ["Delete","Edit"] Or (loc_GalleryMode="New" And ThisItem.ID<Max(col_Updates,ID) And CountRows(col_Updates)>1)編集、削除画面のときは、無条件で表示、新規追加画面のときは、一番下の空白行以外(ThisItem.ID<Max(colUpdates,ID))かつ空白行含め2行以上あるときに表示としています。
ico_ConfirmDelete、ico_CancelDelete の表示非表示は、表示モード(loc_GalleryMode)ではなく、loc_IsDeleteMode で切り替えます。
■ ico_ConfirmDelete、ico_CancelDelete
loc_IsDeleteMode新規追加と編集の時に表示される 保存ボタンとキャンセルボタンの表示について、削除操作中は非表示にします。
■ ico_Save
loc_GalleryMode in ["New", "Edit"] And !loc_IsDeleteMode! は true, false の反転です。
削除確定ボタンを押したときに、削除対象レコードをデータソース(SharePoint Members リスト)または、col_Updates(追加中レコード)から削除するようにします。
■ ico_ConfirmDelete
//削除対象レコードをデータソース(SharePoint Membersリスト)から削除
If(
loc_GalleryMode in ["Delete", "Edit"],
Remove('Members', col_DeleteRecords)//削除、編集モードの時は、こちらが実行されて、直接削除
,
Remove(col_Updates, col_DeleteRecords)//新規追加モードの時は、こちらが実行されて、col_Updates(追加中レコード)から削除
);
Clear(col_DeleteRecords);//削除対象レコードをクリア
UpdateContext({loc_IsDeleteMode: false});//削除操作中解除
If(loc_GalleryMode="Delete", UpdateContext({loc_GalleryMode: Blank()}));//削除モードの時は、Viewモードに戻す。編集モードのとき、保存ボタンを押さなくても、削除確定ボタンを押したときにデータソース( SharePoint Members リスト)から削除されます。
削除キャンセルボタンを押したときに、削除操作中状態を解除します。
■ ico_CancelDelete
Clear(col_DeleteRecords);//削除対象レコードをクリア
UpdateContext({loc_IsDeleteMode: false});//削除操作中解除
If(loc_GalleryMode="Delete", UpdateContext({loc_GalleryMode: Blank()}));//削除モードの時は、Viewモードに戻す。最後に、今のモードが View なのか、新規追加なのか、編集なのか、削除なのか、分かりにくくなっていますので、ラベルで表示するようにします。lbl_CurrentMode を追加します。
「モード」と表示されてもユーザーには分からないと思いますので、デバッグ表示的なつもりです。
■ lbl_CurrentMode
$"モード:{
Switch(loc_GalleryMode ,
"New", "新規追加",
"Edit", "編集",
"Delete", "削除",
"View"
)
}"$"文字列{数式}" の書き方です。"文字列" & 数式 と同じ意味です。どちらの書き方でも、数式は、文字列を返さないといけません。
動作確認/動作例
新規追加
↓
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0012 | Harper Khan | 21 |
を追加すると見せかけて、やめる。
↓
保存ボタンを押して、
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0030 | Mason Hernandez | 22 |
追加
↓
編集
↓
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0012 | Sophia Patel | 29 |
削除
↓
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0005 | Oliver Davis | 37 |
を
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0005 | Harper Khan | 21 |
に変更して、保存
↓
削除
↓
| メンバーID | 名前 | 年齢 |
|---|---|---|
| 0001 | Jackson Parker | 37 |
| 0003 | Emily Foster | 27 |
を選択して、削除確定
できました!

その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。













