Power Apps のギャラリーのフィルターまとめ


# はじめに

例えば、以下のようなお問い合わせを管理する Power Apps キャンバスアプリを作る際、ギャラリーに表示しているデータを、ステータスやお問い合わせ種別、担当者などでフィルターをしたいといった相談をいただくことがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5f16e26c-7af3-7609-c217-65696a593d25.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b242b972-8fdc-b6a9-4ef0-1d63c8550535.png)

もちろん、上記のようなアプリ以外でも、ギャラリーに表示しているデータをフィルターをしたいという相談をいただくことは沢山あるため、改めて、よくあるシナリオについて整理してみます。

:::note
ギャラリーでデータのフィルターをする際は、ギャラリーの`[Items]`プロパティを変更します。例えば、フィルターをせず全データを表示する場合は、`[Items]`プロパティにリストの名前を代入しますが、フィルターをする際は、`[Items]`プロパティに Filter 関数を使った式を代入します。

* 全データを表示する場合
```
問い合わせリスト
```

* 自分が登録したデータだけ表示する場合
```
Filter(
    問い合わせリスト,
    登録者.Email = gblCurrentUser.mail
)
```

:::

# 自分が登録したデータだけ、または、自分が担当者のデータだけ表示する

こちらの記事でも紹介した、Office 365 ユーザーコネクターを使います。コネクタ―の使い方については、こちらの記事をご確認ください。

https://qiita.com/Takashi_Masumori/items/92f4772a73d7f05e6690

まず、App の `[OnStart]` 、つまり、アプリ起動時にアプリ利用者のプロフィール情報を取得して変数に格納するようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f1756fc9-4275-5603-79c1-5c4c54879e63.png)

```
Set(
    gblCurrentUser,
    Office365ユーザー.MyProfileV2()
);
```

:::note
User().Email でも実現可能です。
:::

SharePoint リストに既定で存在する登録者列、つまり、自分が登録したデータだけ表示するような場合は、以下のような式でフィルターします。

```
Filter(
    問い合わせリスト,
    登録者.Email = gblCurrentUser.mail
)
```


次に、ユーザーとグループという種類の列 (今回は、お問い合わせの担当者) を元に、自分が担当者となっているデータだけ表示したい場合は、以下のような式でフィルターします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/88495778-d8ad-7e52-dabf-9801df38cea5.png)

こちらの場合、以下のような式となります。上記登録者とほとんど同じような書き方になります。

```
Filter(
    問い合わせリスト,
    担当者.Email = gblCurrentUser.mail
)

```

以下のように、自分が担当者となっているデータだけが表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a43f32d5-931f-a170-b4f9-b2eb89d57975.png)

# 選択肢列でフィルター

以下のような選択肢列を使う際、選択肢列の項目 (今回は、お問い合わせのステータス) でフィルターをしたいという場合があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a1bcb7d4-7c95-8ba4-c12d-005a23ae0103.png)

まず、コンボボックスを追加します。しかし、このコンボボックスの`[Items]`プロパティに何を入れるか迷う方もいると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/298260ac-42ab-0224-3383-ad61036ec53c.png)


以下のような文言を入れれば動作するのですが、いきなりこれを書ける人はいないと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e5da10ce-8f8a-0fa7-00fe-c36647b6eb4c.png)

そのため、よく使う簡単な方法として、以下のように、一旦別のページにフォームコントロールを追加し、該当の列の`[Items]`プロパティの値をコピーします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/900b42b2-e4ea-49d6-4fc6-b0b4aa0a15b9.png)

今回はこちらをコピーし、不要になったらページごとあとで消します。

```
Choices([@問い合わせリスト].OData__x30b9__x30c6__x30fc__x30bf__x30)
```

:::note warn
以下で触れている通り、列名を日本語で作成したため上記のような文言となっています。
:::
https://qiita.com/Takashi_Masumori/items/e3f99db1436d186adcde

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/9fed401f-1ca7-500d-1a99-5821351cfc40.png)

ギャラリー側の`[Items]`プロパティを以下のようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/35c2a8a6-bb55-213f-4da7-68f22ca32973.png)

列名.Value = コンボボックス名.Selected.Value と書くのがポイントです。

```
Filter(
    問い合わせリスト,
    ステータス.Value = cmbStatus.Selected.Value
)
```

上手くフィルターされたようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/56ffe397-d637-9b8b-0923-3454c943f55a.png)

# 選択していない際はフィルターしない

ここであることに気づきます。
以下のように何も選択しない場合、データが全く表示されなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8e5ca99e-ae9f-e578-ed37-995500257ebf.png)

出来れば、何も選択していない際は、フィルターせずに全部表示してほしいと思います。
この場合、ギャラリー側の`[Items]`プロパティを以下のように書き換えます。

```
Filter(
    問い合わせリスト,
    IsBlank(cmbStatus.Selected.Value) || ステータス.Value = cmbStatus.Selected.Value
)
```
これにより、何も選択していない場合はフィルターをせず全て表示されるようになりました。
なぜこれで動作するのか最初はピンとこないかもしれませんが、一つ目の条件に一致した場合、後続の処理をしない動きとなるところがポイントです。

そのため、何も選択していない時は一つ目の条件に一致し、結果的に何もフィルターしないことになります。いずれにせよ、個人的に、この構文は覚えておいた方がいいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/86e8159c-cd0e-13a2-f72e-0349f54629cc.png)

# 選択肢列で複数選択したい

例えば、以下のように、複数のステータスを選択してフィルターしたい場合です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/bd1671db-f964-1f10-0399-67222420c583.png)

こちらの構文は以下のような感じです。

```
IsBlank(cmbStatus.Selected.Value) || ステータス.Value in cmbStatus.SelectedItems.Value
```

コンボボックスで選択した複数の値 (例：対応中、完了) の中に、各行のステータス.Value の値 (例：完了) が存在するかという意味になります。

# ユーザーとグループ列でフィルター

次に、担当者の列でフィルターをしたい場合についてです。
こちらは、ユーザーとグループ列で作成されております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/88495778-d8ad-7e52-dabf-9801df38cea5.png)

今回は、こちらの列に存在する担当者でフィルターするようにしたいと思います。

::: note
例えば、その他のシステムのデータから連携して SharePoint リストを作成する場合、ユーザーの名前はそちらのシステムで保持している名前となるため、テキスト型となることが考えられます。このような場合も同様のアプローチとなります。
:::

::: note
担当者のようなユーザー情報でフィルターしたい場合、ユーザーテーブルを別に持ち、リレーションシップの設定をして、そちらをベースにフィルターするという方法もあります。
しかし、このような簡易的なアプリでユーザーテーブルを別途作成してメンテナンスするのは面倒な場合もあると思います。 そのような際は、今回紹介するような方法が代替案となります。
:::

## ユーザーフィルター用のデータの作成

`[App]`の`[OnStart]`に以下のような処理を書きます。

```
ClearCollect(
    colPersonInCharge,
    Distinct(
        問い合わせリスト,
        担当者.DisplayName
    )
)
```

結果的に以下のようなコレクションが作成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b94b165d-e3be-64f5-1c3f-39649b32a14a.png)

ポイントは、Distinct 関数で重複を排除することです。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-distinct

※今回は、同姓同名は置いておきます

## コンボボックスの作成

コンボボックスはシンプルです。以下のように、作成したコレクションを`[Items]`プロパティに設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f5d14676-6c88-a64c-7c2e-d208c9894815.png)

`[SelectMultiple]`は false にしておきます。

## ギャラリーの設定

ギャラリーの`[Items]`プロパティを以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a172ba1f-cd2c-a01c-e681-dacb96aacb6f.png)

```
Filter(
    問い合わせリスト,
     IsBlank(cmbPersonInCharge.Selected.Value) || 担当者.DisplayName = cmbPersonInCharge.Selected.Value
)
```

問題なく動作しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e38c45b6-85e4-8bcc-5310-5784d65bc42e.png)

# 複数の列でフィルターしたい

複数の列でフィルターしたい際は、式をカンマでつなぎます。

```
Filter(
    問い合わせリスト,
    IsBlank(cmbPersonInCharge.Selected.Value) || 担当者.DisplayName = cmbPersonInCharge.Selected.Value,
    IsBlank(cmbStatus.Selected.Value) || ステータス.Value in cmbStatus.SelectedItems.Value
)
```

今回の場合は、担当者とステータスでフィルターしています。上述した構文により、例えば、担当者は何も選択しておらず、ステータスだけ選択した場合にも動作します。

以下イメージです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/77395c57-9280-76ff-dc40-991b64a1d872.png)


どちらも選択されている際も以下の通り動作します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b1d6a430-e720-26b3-c87c-102639f1e1c2.png)

# 複数選択可能な選択肢列のフィルター

以下のように、複数選択可能にしている列をベースにフィルターする方法についてです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/44ab0a7b-d599-e3e5-7586-aebbba6556f6.png)

まず、これまでと同様に、コンボボックスを追加し、`[SelectMultiple]`は false にしておきます。

※こちらが true の場合、テーブル対テーブルの比較になるため、in での比較が出来ないです

その上で、以下のような構文でフィルターします。

```
 IsBlank(cmbQuestionProduct.Selected.Value) || cmbQuestionProduct.Selected.Value in お問い合わせ種別.Value
```

ギャラりーの`[Items]`プロパティは以下のような感じです。

```
Filter(
    問い合わせリスト,
    IsBlank(cmbPersonInCharge.Selected.Value) || 担当者.DisplayName = cmbPersonInCharge.Selected.Value,
    IsBlank(cmbStatus.Selected.Value) || (ステータス.Value = cmbStatus.Selected.Value),
     IsBlank(cmbQuestionProduct.Selected.Value) || cmbQuestionProduct.Selected.Value in お問い合わせ種別.Value
)
```

:::note warn
SharePoint リストでは、現状、in は委任できないため注意が必要です。

:::
https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#power-apps-%E3%81%AF-sharepoint-%E3%81%AE%E6%A9%9F%E8%83%BD%E3%81%A8%E6%93%8D%E4%BD%9C%E3%82%92%E5%A7%94%E4%BB%BB%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99



# 日付でのフィルター

よく、期間でフィルターしたいという要望もいただきます。こちらは結構簡単です。

まず、日付の選択コントロールを挿入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f19881b2-94a9-6ad4-d73a-8c7e5203e857.png)

:::note
モダンコントロールにも日付のコントロールがあります。興味があればこちら側を利用ください。
:::

https://qiita.com/Takashi_Masumori/items/ae700eeb59ee54ca6bbc

以下のような感じで配置します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/7fec752c-7ee7-6eeb-7930-c15bce25e0eb.png)

例えば、解決希望日 (日付型) をベースにフィルタ―したい場合の構文は以下のような感じです。

```
 (解決希望日 >= DatePickerStart.SelectedDate And 解決希望日 <= DateAdd(
        DatePickerEnd.SelectedDate,
        1
    ))
```

全体像としては以下のような感じです。

```
Filter(
    問い合わせリスト,
    IsBlank(cmbPersonInCharge.Selected.Value) || 担当者.DisplayName = cmbPersonInCharge.Selected.Value,
    IsBlank(cmbStatus.Selected.Value) || ステータス.Value in cmbStatus.SelectedItems.Value,
    IsBlank(cmbQuestionProduct.Selected.Value) || cmbQuestionProduct.Selected.Value in お問い合わせ種別.Value,
    (解決希望日 >= DatePickerStart.SelectedDate And 解決希望日 <= DateAdd(
        DatePickerEnd.SelectedDate,
        1
    ))
)
```

※Today() 関数を利用した場合、以下のように、0:00 となっているため、一応、DateAdd 関数で 1 日プラスしています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/375f5976-416e-4c29-ef66-52632b40bc2e.png)

# 検索との組み合わせ

検索と組み合わせる際は、まず、テキスト入力コントロールを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1664e519-7155-ca26-b66c-0e5d1237ba98.png)

検索には Search 関数を使います。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-filter-lookup

Search 関数は以下のような感じで使います。

```
Search(データソース,検索文字列,検索対象列)
```

※検索対象列は複数選択可能

今回は、以下のような感じで、Search 関数でフィルターの結果を囲みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/766be7e2-45b6-59f4-5a0f-e0be0f0a1933.png)

```
Search(
    Filter(
        問い合わせリスト,
        IsBlank(cmbPersonInCharge.Selected.Value) || 担当者.DisplayName = cmbPersonInCharge.Selected.Value,
        IsBlank(cmbStatus.Selected.Value) || ステータス.Value in cmbStatus.SelectedItems.Value,
        IsBlank(cmbQuestionProduct.Selected.Value) || cmbQuestionProduct.Selected.Value in お問い合わせ種別.Value,
        (解決希望日 >= DatePickerStart.SelectedDate And 解決希望日 <= DateAdd(
            DatePickerEnd.SelectedDate,
            1
        ))
    ),
    TextInputSearch.Text,
    "OData__x8a73__x7d30_"
)
```

:::note
ついでにその他フィルターなども組み合わせています。
:::

::: note warn
列名を日本語で作成しているため、**"OData__x8a73__x7d30_"** のような列名の表記になっています。
:::
https://qiita.com/Takashi_Masumori/items/e3f99db1436d186adcde

::: note warn
SharePoint リストでは Search や in は現状委任できないためご注意ください。
:::
https://learn.microsoft.com/ja-jp/connectors/sharepointonline/#power-apps-delegable-functions-and-operations-for-sharepoint

動作確認してみます。問題なく動いているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1b6de898-0a41-589a-5615-4ec81e93e696.png)

# まとめ

お問い合わせを管理する Power Apps キャンバスアプリを例に、ギャラリーのデータを色々フィルターする方法について紹介しました。

データのフィルターをすることはよくあり、個人的にも相談受けることが沢山あるため、参考にしていただければ幸いです。