コルネの進捗や備忘録が記されたなにか

進捗や成果物や備忘録てきななにかを雑に更新していきます。

Power Apps でデータソースから重複を取り除く方法色々


スポンサードリンク

はじめに

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 }
);
  • 上記データをデータテーブルに表示させます。
    f:id:koruneko:20211005012518p:plain

DataTable1.Items

CityPopulations
  • 重複削除後のデータをデータテーブルに表示させます。
    今回重複を判定するのは Country フィールドです。
    f:id:koruneko:20211005013644p:plain

DataTable2.Items

Distinct(CityPopulations, Country)
  • この式の結果は Result として返ってくるので、フィールドはResult を選択します。
    f:id:koruneko:20211005013812p:plain

f:id:koruneko:20211005013828p:plain

複数のフィールドに対して重複を削除する

先ほどは Country フィールドのみに対して重複チェックしましたが、今度は CityCountry フィールドに対して重複チェックしてみようと思います。

先ほどのDistinct 関数を使ったやり方ですと、Formula 部分に重複をチェックしたいフィールドを & で続けて設定してあげます。

Distinct(CityPopulations, City & Country)

ただし、こちらの結果は以下のようにくっつけたフィールドの文字列が結合された形式で返ってきてしまいます。

f:id:koruneko:20211005014834p:plain

なので、少し見やすい形式に直してあげます。

ForAll(
    Distinct(CityPopulations, City & "," & Country),
    With(
        {SplitResults:Split(ThisRecord.Result, ",")},
        {
            City:   Last(FirstN(SplitResults, 1)).Result,
            Country:Last(FirstN(SplitResults, 2)).Result
        }
    )
)

行っていることを日本語にすると、

  1. CityCountry の文字列を , で結合して重複を削除します。
  2. 1の結果より得られたテーブルを1レコードずつ評価します。
  3. 評価の内容としては、まず結合された文字列をSplit 関数を使って分解します。
  4. このままだとテーブルの中にテーブルが含まれていますし、列名も適切なものではありません。
    なので、レコードを定義して適切な値をそれぞれ設定してあげます。

ちょっとめんどくさいですね。

重複を削除した結果をレコード単位で取得する

Distinct 関数でえられた結果は、重複チェックを行ったフィールドだけしか得られませんでした。
しかし、重複削除を行った結果のすべてのフィールドが欲しい。というケースもあるかもしれません。

そういう場合はDistinct 関数は使えないので、独自でロジックを作成してあげます。

やり方としては、

  1. 重複チェックを行いたいコレクションのレコード数分レコードを評価する(レコードすべてについて1レコードずつ評価を行う)。
  2. Nレコード目の評価を行う場合は、先頭からNレコード目までのテーブルを比較対象とし、Nレコード目の重複チェック対象のフィールドの値が既に存在しているかチェック(自身を含むので1でないかを判断)。
  3. 上記の結果、存在していなけばNレコード目の値をセットし、存在していれば空レコードをセットする。
  4. 結果として、重複していたところは空レコードがセットされているので、空レコードを除外する。

となります。
これを実際の式にすると以下のようになります。

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 で重複データを取り除く色々な方法でした。

そこまで深く考えて作成したロジックじゃないので、もっと最適な方法もあるかもです。


スポンサードリンク