(2020/10/02)
キーワード数に依存しない記述方法を補足に追記しました。
G〇〇gle 検索のようなものを作ります(見た目的な意味で)。
どうも、じゅんじゅんです。
先日より Teams 上で Power Apps アプリが作成できるようになり、Search 関数を用いた文字列の部分一致検索ができるようになりました。 jn.hateblo.jp
これを機に、検索機能を持ったナレッジ共有アプリを作る方が増えるのではないかと勝手に予想しております。
ということで、せっかくなので日頃よくお世話になっている某検索サイトのように、複数のキーワードをスペース区切りで OR 検索(あるいは AND 検索)できると便利だなと思い、作ってみました。
(以下動画は Teams + Power Apps ではないですが、Teams + Power Apps でも同じことができます)
CDS で Filter 関数の in が委任できると、and / or 検索の記述がちょっとスマートになる(?)
— Jun’ichi Kodama (@KodamaJn) 2020年9月29日
欲しいものが記録された CDS のエンティティから、テキスト入力した複数の文字(全角スペース区切り)を and / or 検索してみた
エンティティ:BirthdayPresent
フィールド:PresentName#PowerApps pic.twitter.com/YhLzYhek07
目次
- まずはデータと検索窓の用意まで
- フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(固定ワード編)
- 検索窓から複数のキーワードを抽出する方法
- フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(検索窓を利用編)
- 補足
- おわりに
- 参考文献
まずはデータと検索窓の用意まで
前回の記事の "事前準備" まで行います(以下参照)。 https://jn.hateblo.jp/entry/2020/09/26/164959#%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99
今回は、"AND_OR検索" というテーブルを作成し、既存の "件名" 列に今食べたいものを登録してみました。
そして、画面の上部あたりにテキストボックスを挿入しておきます。
こんな感じで検索ワードを入れたら、下部の Gallery をフィルタリングできるようにします。
フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(固定ワード編)
実は前回の記事で、部分一致には Search 関数が使えることをご紹介しました。
Search 関数は、1 つの関数で検索したい列を複数指定できるというメリットがある一方で、Search 関数 1 つで複数ワードの検索はできないため、Search 関数で複数ワードの検索を実現するには Search 関数をネストする必要があります。
参考:
複数キーワードによる検索 - Japan Power Platform User Group コミュニティサイト
そこで今回は、部分一致検索ができるもう一つの方法として、in 句を使用します。
in 句は、Filter 関数内で
Filter(テーブル名, "検索したいキーワード" in 検索したい列名)
と記載することで、検索したい列の中に検索したいキーワードが含まれるレコードを抽出してくれるものです。
※列名は右辺です。列名を左辺に書くと警告が出て正常に機能しませんのでご注意ください。
以下はキーワード:"焼" で検索する場合の記述方法
なお、Search 関数で
Search(テーブル名, "検索したいキーワード", "検索したい列名")
と記載すると、先ほどの Filter と同じ結果が得られます。
(ただし Search 関数の列名は二重引用符で囲まれている必要がある点に注意)
さて、本題です。
Filter 関数では、検索に複数の条件を指定することができます。 早速、条件を追加してみましょう。
Filter(AND_OR検索, "焼" in 件名, "牡蠣" in 件名)
"焼き牡蠣" だけ残りました。
Filter 関数で指定した複数の条件は、AND 検索となるのです。
そこで、これを OR 検索に置き換えます。
OR 検索にするには、複数の条件を Or 関数で囲えば OK です。
(r が小文字であることに注意)
Filter(AND_OR検索, Or( "焼" in 件名, "牡蠣" in 件名 ) )
無事、"焼" または "牡蠣" が含まれるレコードが抽出できました。
複数キーワードの部分一致 OR 検索ができたところで、このキーワードを最初に用意した検索窓(テキストボックス)から抽出する方法について考えます。
検索窓から複数のキーワードを抽出する方法
ここでは、2つの工程に分けて考えます。
- テキストボックスの値をスペースで分割する(分割された各キーワードが格納されたテーブルになる)
- 1.のテーブルから1つずつキーワードを抜き出す
1. テキストボックスの値をスペースで分割する
ここでは、Split 関数を利用します。
Split 関数 - Power Apps | Microsoft Docs
テキストボックスに "焼 牡蠣" と記載されている場合(半角スペース区切り)、
Split(テキストボックス名.Value, " ")
と書くと、
Result |
---|
焼 |
牡蠣 |
というテーブルが取得できます。
2. 1.のテーブルから1つずつキーワードを抜き出す
ここでは、FirstN 関数と Last 関数を利用します。
これは、Qiita の Power Apps タグで不動の1位を誇るやまさん (@yamad365) の以下の記事がすべてですので、ご一読ください。
qiita.com
これを踏まえて。
テキストボックスに記載されたキーワードの N 個目は、以下のように表すことができます。
// 1個目 Last(FirstN(Split(テキストボックス名.Value, " "), 1)).Result // 2個目 Last(FirstN(Split(テキストボックス名.Value, " "), 2)).Result // 3個目 Last(FirstN(Split(テキストボックス名.Value, " "), 3)).Result ...
フィルタリングで複数キーワードの部分一致 OR 検索を実現する方法(検索窓を利用編)
これまでの内容を組み合わせて、検索窓(テキストボックス)から複数のキーワードを抽出して部分一致 OR 検索を行います。
ただ、検索窓にいくつキーワードが入力されるかが分からないため、Filter 関数をどのように書いたらよいか分からないですよね。
ということで、ちょっと実験。
試しに5つのキーワードを抽出できる用意をし、5つ未満のキーワードを入力した場合にどのような値が抽出できるかを試してみます。
まずは、5つのキーワードを入力した状態。
キーワードを1つ減らしてみます。
おや?
どうやら、FirstN 関数で指定した位置がテーブルの値の個数を超えた場合は、一番最後の値になるようです。
同じ値で OR 検索しても結果に変わりはないはずなので(例えば「焼 焼」と検索しても、結果は「焼」を検索した結果になる)、この方法は使えそうです。
ということで、これを Filter 関数に適用すると、以下のようになります。
Filter(AND_OR検索, Or( Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 1)).Result in 件名, Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 2)).Result in 件名, Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 3)).Result in 件名, Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 4)).Result in 件名, Last(FirstN(Split(Microsoft_CoreControls_TextBox2.Value, " "), 5)).Result in 件名 ) )
これで、5つまでのキーワードはこの記載で対応できます。
補足
AND 検索と併用したい方は、トグルスイッチなどを追加し、そのスイッチの値に応じて Filter 処理を分岐するとよいです(あまりスマートではありませんが。。)。
全角と半角のスペース両方に対応させたい場合は、どちらかに置換してから Split しましょう。(以下は全角スペースを半角スペースに置換してから Split する例)。
Split(Substitute(テキストボックス名.Value, " ", " "), " ")
参考:Replace および Substitute 関数 - Power Apps | Microsoft Docs
Gallery の Items の書き方を工夫すると、キーワード数に依存しないフィルタリングができるようになります(下図参照)。
(Hiro さん、アドバイスいただきありがとうございます!)
アップしていただいた方法そのままでできましたー!
— Jun’ichi Kodama (@KodamaJn) October 2, 2020
(ついでに Form 側もいじって書き換えられるようにしてみた)
なるほどー。こう書けば Sequence 使わなくても Split した各値に対して Filter してくれるのですね。知らなかった😲 https://t.co/6Rg0111d2k pic.twitter.com/wkxNRAFtuL
おわりに
Power Apps で Google 検索のような複数ワードの部分一致 OR 検索を行う方法をご紹介しました。
普段慣れ親しんでいる UI に近づけるというのは、利用ユーザーの操作負担を減らすのに効果的だと思いますので、是非チャレンジしてみてください。
欲しいアプリは欲しい人が作る時代へ。
何かヒントになれば幸いです。