
今回はPowerApps のPatch関数を検証してみます。
Patch関数はExcelとかにはない、コレクションなどのデータベースを操作するというPowerApps独特の考え方に加えて、使い方も2種類あるのでとっつきにくいかもしれませんが、理解してしまえば難しくない関数ですので、身構えずに見ていきましょう!
PowerAppsに必須の知識PowerFX対応の学習本はこちら
PowerApps学習の本命・実際のアプリももらえる学習本
PowerApps学習方法一覧

Patch関数とは
概要
Patch関数についてMicroSoftの公式では次のように解説されています。
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-patch
相変わらずよくわからない解説ですね。
そもそも英語のPatchとはどういう意味でしょうか。調べてみるとPatchには当て布やつぎあてという意味があります。
そこから転じてパソコン業界ではPatchというと「データのバグを修正する」「データを更新する」というような意味になっています。
よく、パッチを適用するなどと言いますがデータを更新するという意味であることがわかると思います。
PowerAppsにおけるPatch関数はデータを修正するということで、コレクション内のレコードを更新、修正することができます。また、空のレコードを作成することもできます。
レコードが更新できる関数なのは便利で良いのですが更新するには二つの方法がありこれがこのPatch関数を複雑にしています。 それぞれ分けて理解しましょう。

二つの使い方の解説
Patch関数でレコードを更新するには二つの方法があります。
一つがレコードを一つ設定しその中身を更新していく方法 、もう一つが二つ以上のレコードを指定しそのレコードの内容を結合していく方法になります。
二つの使い方の使い分けは引数と呼ばれる"()"内の値の内容で動作内容が変わりますので覚えておいてください。
レコードを更新する場合の使い方
レコードを一つ選択しそのデータの中身を指定して更新していく方法で、Patch関数の基本となる使い方です。レコードの更新というと一番思いつきやすい方法です。
入力内容
Patch(テーブル名,更新するレコード,更新後のレコード[,更新後レコード, …])
で入力します。
更新するレコードがコレクション内にあるためLookUp関数などのレコードを戻り値としている関数を使う必要があります。
第3引数の更新後のレコードに更新したい内容を入力します。レコード内の操作は{列名:データ内容・・・}で表現することができますので、更新したい「列名:更新後の内容」を{}の中に書いていきます。また、更新したい列が複数ある場合は,(カンマ)でつなげることができますので{列名1: 値1,列名2:値2...}と続け記述することが可能です。
動作内容
更新するレコードが更新後のレコードの内容に書き変わっていきます。
第4引数以降にもレコードを設定することが可能のため更新後のレコードの内容が重複している場合には後ろにある引数によって上書きされていきます。
戻り値と動作結果
戻り値は更新後のレコードとなりますが、Patch関数はコレクションなどのデータベースの操作ができます。戻り値を使わずともコレクション内のレコードは更新されています。
レコードの内容を結合していく場合の使い方
レコードを二つ以上指定し、レコードの内容を統合していく方法です。
概念を理解すれば難しくないのですが、理解するには少し癖のある考え方かもしれません。
入力内容
Patch(レコード,レコード[,レコード, …])
で指定します。こちらもレコードについてはLookUpなどを使っても構いませんが、使い方の目的を考えた場合{}によるレコードの指定も必要となります。
動作内容
第一引数のレコードの中身と第二引数のレコードの中身を比較し、第一引数のレコードにない列(属性)のものが第二引数にある場合はその属性が第一引数のレコードに追加されます。すでに第一引数と第二引数のレコードの両方に同じ列(属性)の内容がある場合は第二引数の内容に上書きされます。
注意が必要なのはレコード同士を比較する方法ではテーブルの中身が更新されないということです。この場合には戻り値を変数などで受けてあげる必要がありますので注意してください。
レコードが三つ以上ある場合は第一引数と第二引数の比較の結果を今度は第三引数と比較しますその結果を次の引数のレコードと比較していくという動作を続けて最終的に比較するレコードがなくなるまで実行されます。
例えば第一引数に①のレコード第二引数に②のレコード、第三引数に③のレコードが入っていた場合を見てみましょう。
①
列1 | 列2 |
---|---|
A | B |
②
列1 | 列2 |
---|---|
C |
③
列3 |
---|
D |
これは初めに第一引数と第二引数を比べ列2が重複していますので列2を第二引数の内容に更新します(内容は以下の通り)。
列1 | 列2 |
---|---|
A | C |
次に比べた結果のレコードと第三引数のレコードを比べます。ここでは列3の内容がないので列3の内容が追加され最終的には
列1 | 列2 | 列3 |
---|---|---|
A | C | D |
という内容になります。
戻り値
戻り値は更新後のレコードとなります。レコードを結合する使い方は元のコレクション内のレコードを更新していませんので注意してください。
二つの使い方の引数の比較
Patch(テーブル名,更新するレコード,更新後のレコード[,更新後レコード, …])
Patch(レコード,レコード[,レコード, …])
引数で指定する一つ目がテーブルかどうかが大きな違いとなります。テーブルの場合とレコードの場合で動作内容が変わっていくということを認識しておきましょう。
実際に使ってみる
実際の使い方を見ていきます。
元となるコレクションとして
ClearCollect(テーブルA,{ID:1,NAME:"AA"},{ID:2,NAME:"BB"},{ID:3,NAME:"CC"})
を実行し以下のようなコレクションを作ります。
ID | NAME |
---|---|
1 | AA |
2 | BB |
3 | CC |
レコードの一部を更新したい場合
IDが1のレコードのNAMEをAA2に変更したい場合
Patch(テーブルA,LookUp(テーブルA,ID=1),{NAME:"AA2"})
で実行することでテーブルAの内容が以下のように更新されます。
ID | NAME |
---|---|
1 | AA2 |
2 | BB |
3 | CC |
また、
UpdateContext({変数:Patch(テーブルA,LookUp(テーブルA,ID=1),{NAME:"AA2"})})
とすることでテーブルが更新されるとともに変数にレコードが格納されます。
レコードを新規作成する場合
レコードを追加する場合は
- 中身が空白のレコードを作成
- 1.で作ったレコードの中身を更新する
という手順になります。
空のレコードはDefaults関数で作製することができます。Defaults関数は引数にテーブルを指定することでテーブルに対応した空のレコードを作成してくれる関数になります。
したがって
Defaults(テーブルA)
を実行すると以下のような空のレコードが作成されます。
ID | NAME |
---|---|
Null | Null |
この空のレコードに対して更新作業を行うことでレコードの追加をすることができます。
Patch関数の第二引数にレコードを指定(今回は空のレコード)し、第三引数に更新内容を記述すればよいので、次のように記述することでID4、NAMEがDDというレコードを追加することができます。
Patch(テーブルA,Defaults(テーブルA),{ID:4,NAME:"DD"})
レコードを結合する方法
最後にレコードを結合し更新する方法を見てみましょう。
この方法を使うことで関連する二つ以上のテーブルの内容を連結させることなどもできます。
まず初めに連結させるテーブルをもう一個作成するため
ClearCollect(テーブルB,{ID:1,AGE:"10"},{ID:2,AGE:"20"},{ID:3,AGE:"30"})
を実行し以下のテーブルを作成します。
ID | AGE |
---|---|
1 | 10 |
2 | 20 |
3 | 30 |
次に
Patch(LookUp(テーブルA,ID=1),LookUp(テーブルB,ID=1))
を実行してみます。
それぞれのLookUpで指定したレコードは次の通りになります。
1 | AA |
1 | 10 |
当然のことながら両方ともIDが1のものをレコードとしてしているため両方ともID列が存在しています。この二つのレコードを比較し第一引数のレコードにAGEの列がないため第二引数のAGEの内容が追加されそれが戻り値として返ってきます。
この場合はテーブルAもテーブルBもコレクション自体は更新されないので変数などで受け止める必要があります。