はじめに
Power Apps で重複しているデータを取り除いて表示させる色々な方法を纏めています。
ただ最初に断っておくと、これはこうすればやりたいことできるよ。ってことを纏めただけで私自身このやり方をどんなときでも推奨しているわけではありません。
本当にロジックで解消するべき問題なのか?データ設計見直したほうがいいのではないか?改修に掛かるコストや費用対効果、運用面でのことなどを考慮したうえで採用するようにしましょう。
重複を削除する
1つのフィールドに対して重複を削除する
これはPower Apps に存在する数式、Distinct 関数を利用します。
これは公式のDocs に記載されている通りですね。
Docs に記載されている通りの説明になりますが、
- コレクション(データソース)を定義します。
* 後述の説明のために公式docs とは少し内容を変えています。(Tokyo, Japan を追加)
ClearCollect( CityPopulations, { City: "London", Country: "United Kingdom", Population: 8615000 }, { City: "Berlin", Country: "Germany", Population: 3562000 }, { City: "Madrid", Country: "Spain", Population: 3165000 }, { City: "Hamburg", Country: "Germany", Population: 1760000 }, { City: "Barcelona", Country: "Spain", Population: 1602000 }, { City: "Munich", Country: "Germany", Population: 1494000 }, { City: "Tokyo", Country: "Japan", Population: 14043239 }, { City: "Tokyo", Country: "Japan", Population: 14043239 } );
- 上記データをデータテーブルに表示させます。
DataTable1.Items
CityPopulations
- 重複削除後のデータをデータテーブルに表示させます。
今回重複を判定するのはCountry
フィールドです。
DataTable2.Items
Distinct(CityPopulations, Country)
- この式の結果は
Result
として返ってくるので、フィールドはResult を選択します。
複数のフィールドに対して重複を削除する
先ほどは Country
フィールドのみに対して重複チェックしましたが、今度は City
と Country
フィールドに対して重複チェックしてみようと思います。
先ほどのDistinct 関数を使ったやり方ですと、Formula 部分に重複をチェックしたいフィールドを &
で続けて設定してあげます。
Distinct(CityPopulations, City & Country)
ただし、こちらの結果は以下のようにくっつけたフィールドの文字列が結合された形式で返ってきてしまいます。
なので、少し見やすい形式に直してあげます。
ForAll( Distinct(CityPopulations, City & "," & Country), With( {SplitResults:Split(ThisRecord.Result, ",")}, { City: Last(FirstN(SplitResults, 1)).Result, Country:Last(FirstN(SplitResults, 2)).Result } ) )
行っていることを日本語にすると、
City
とCountry
の文字列を,
で結合して重複を削除します。- 1の結果より得られたテーブルを1レコードずつ評価します。
- 評価の内容としては、まず結合された文字列をSplit 関数を使って分解します。
- このままだとテーブルの中にテーブルが含まれていますし、列名も適切なものではありません。
なので、レコードを定義して適切な値をそれぞれ設定してあげます。
ちょっとめんどくさいですね。
重複を削除した結果をレコード単位で取得する
Distinct 関数でえられた結果は、重複チェックを行ったフィールドだけしか得られませんでした。
しかし、重複削除を行った結果のすべてのフィールドが欲しい。というケースもあるかもしれません。
そういう場合はDistinct 関数は使えないので、独自でロジックを作成してあげます。
やり方としては、
- 重複チェックを行いたいコレクションのレコード数分レコードを評価する(レコードすべてについて1レコードずつ評価を行う)。
- Nレコード目の評価を行う場合は、先頭からNレコード目までのテーブルを比較対象とし、Nレコード目の重複チェック対象のフィールドの値が既に存在しているかチェック(自身を含むので1でないかを判断)。
- 上記の結果、存在していなけばNレコード目の値をセットし、存在していれば空レコードをセットする。
- 結果として、重複していたところは空レコードがセットされているので、空レコードを除外する。
となります。
これを実際の式にすると以下のようになります。
Filter( ForAll( Sequence(CountRows(CityPopulations)), With( {tmpCol:FirstN(CityPopulations, ThisRecord.Value)}, If( CountIf(tmpCol, Country = Last(tmpCol).Country) = 1, Last(tmpCol) ) ) ), !IsBlank(ThisRecord) )
おわりに
以上、Power Apps で重複データを取り除く色々な方法でした。
そこまで深く考えて作成したロジックじゃないので、もっと最適な方法もあるかもです。