PowerAppsでデータソースから特定の文字列を"含まない"レコードを抽出する

突然ですが、クレープっておいしいですよね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/0d108a8a-3f2e-8d07-04c0-5e13707589b2.png)


で、クレープって、同じ味でも

- アイスが含まれないもの
- アイスが含まれるもの

が両方選べるお店ってありますよね。
そういう場合、アイスが含まれるものの商品名は、含まれないものの名前に"アイス"や"クリーム"という名前が付け加えられていたりします。

例：

- アイスが含まれないもの：いちごクレープ
- アイスが含まれるもの：いちご”アイス”クレープ

ということで、ここではクレープの名前を例に、「特定の文字列が含まれるもの」と、「特定の文字列が含まれないもの」を抽出する処理を紹介します。
前者はググればすぐ見つかりますが、後者はちょっと見つけにくいので、簡単にまとめてみました。
（ピンと来る方にはすぐ分かるノウハウかと思いますが^^;）

<br>

### 使用するデータ
アプリの OnStart 処理で以下のコレクションを宣言しておきます。


```:OnStart
ClearCollect(SampleData,
{Name:"チョコバナナクレープ",       Price:380},
{Name:"チョコバナナアイスクレープ", Price:480},
{Name:"いちごクレープ",             Price:420},
{Name:"いちごアイスクレープ",       Price:520},
{Name:"宇治抹茶クレープ",           Price:610},
{Name:"宇治抹茶アイスクレープ",     Price:710}
)
```

<br>

### 特定の文字列が含まれるものを抽出する
私は年間300個以上は確実にアイスを食べるほどアイス好きなので、クレープ名の中からアイスが含まれるクレープを探したいと思います。

これは、Search 関数を使えば簡単に実装できます。
または、Filter 関数でも条件式に in を使用すれば実装可能です。
参考：[PowerApps の Filter、Search、および LookUp 関数](https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/functions/function-filter-lookup)

まずは Search 関数から。
先程宣言しておいたコレクション： SampleData に対して、以下のように　Search 関数を記述します。

```:
Search(データソース名, "探したい文字列", "列名")
```

なので、

```:
Search(SampleData, "アイス", "Name")
```

とすれば、Name 列に”アイス”が含まれるレコードのみを抽出できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/98943d8e-568b-9de1-c3fa-31e5c75184dd.png)
列名（第3引数）を””で囲むのがポイントです。

<br>

また、Filter 関数でも、条件式に in を用いることで、Search 関数と同じように条件指定が可能です。

```:
Filter(データソース名, "探したい文字列" in 列名)
```

なので、

```:
Filter(SampleData, "アイス" in Name)
```

とすれば、先程と同じように Name 列に”アイス”が含まれるレコードのみを抽出できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/a3be98f6-b161-da2c-5e44-5229853c959e.png)
Filter 関数の場合は、列名は””で囲まず直接記述するのがポイントです。

ここまでは、参考ページに記載されている通りなので、簡単ですね^_^

<br>

### 特定の文字列が含まれないものを抽出する
さて、本題です。

私は年間300個以上は確実にアイスを食べるほどアイス好きなのですが（しつこい）、たまにお腹を壊してしまうので、そんな時はアイスを控えたりします。ということで、今度はクレープ名の中からアイスが含まれないクレープを探したいと思います。

で、この方法、先程の参考ページには具体的には記載されてなかったので、ご紹介します。

まずは結論から。
前述の”特定の文字列が含まれるものを抽出する”で紹介した Filter 関数の処理の第2引数を、

```:
Filter(SampleData, Not("アイス" in Name))
```

のように Not 関数で囲うだけで、実現できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405544/d05730d5-9c9f-3582-277d-ec740c0af2b2.png)

<br>

解説します。
※非エンジニア向け（エンジニアの方にとっては「当たり前だよー！」となるかもしれません^_^;）

Filter 関数は、条件を満たすレコードのみ、言い換えると、条件式が true となるレコードのみを抽出します。

よって、最初の”アイスが含まれるものを抽出する”場合、

```:
Filter(SampleData, "アイス" in Name)
```

Name 列に“アイス”が含まれるレコードが true となるため、結果は

```:
"チョコバナナクレープ"       → false
"チョコバナナアイスクレープ" → true
"いちごクレープ"            → false
"いちごアイスクレープ"       → true
"宇治抹茶クレープ"          → false
"宇治抹茶アイスクレープ"     → true
```

となります。
Not 関数は、true を false に、false を true に反転させる関数なので、これで囲うことで

```:
Filter(SampleData, Not("アイス" in Name))
```

先程の結果が

```:
"チョコバナナクレープ"       → true
"チョコバナナアイスクレープ" → false
"いちごクレープ"            → true
"いちごアイスクレープ"       → false
"宇治抹茶クレープ"          → true
"宇治抹茶アイスクレープ"     → false
```

のように反転し、アイスが含まれないもののみを抽出できる、という理屈です。


この方法、海外のコミュニティサイトなどでは紹介されていたりするのですが、日本語ではちょっと見つけられなかったので、まとめてみました。

<br>

### 補足
今回のような”特定文字列が含まれるかどうか”の検索は、データソースが SharePoint だと委任問題に引っかかるため、残念ながらあまり有用ではありません。

参考：委任とは？
[PowerAppsで遭遇する５つの委任問題とちょっと強引な回避方法（SharePointリスト利用時）その１](https://qiita.com/KodamaJn/items/4341865e6784847a005d)

ただ、データソースが SharePoint の場合でも、特定の文字列"から始まる"や、特定の文字列”で終わる”かどうかを検索するケースでは、委任問題に引っかからずとも StartsWith 関数や EndsWith 関数が使えますので、そちらをご利用ください。
<br>
ご参考になれば幸いです。