はじめに
以前マシュマロでこのような質問をいただきました。
こちらについてTwitter のほうで簡単に回答させていただきましたが、今回はもう少し詳しく回答したいと思います。
いいね!したユーザーの数の取得ですかね?
— コルネ (@koruneko32767) July 23, 2021
CountRows(ThisItem.'「いいね!」と評価したメンバー')
みたいな記載方法で取得できると思います。
ここにはいいね!...
続き→https://t.co/X8blCd9o1o#マシュマロを投げ合おう pic.twitter.com/wAzfMW5sJB
SPO リストにレーティング評価機能を追加する
レーティング評価機能といわれてもピンとこない方もいらっしゃると思いますので、こちらの機能の追加方法をまずは紹介したいと思います。
- サイトコンテンツへ移動して、レーティング機能を追加したいリストの「⁝」を選択して「設定」を選択します
- 「全般設定」の「評価の設定」を選択します
- 「評価の設定」を「はい」にします
その次の項目では、評価を「いいね!」か「星評価」にするかが選べます
今回は「いいね!」を選択します
これで「いいね!」フィールドが作成されました。
これでこんな感じで「いいね!」ができるようになりました!
ちなみに「いいね!」をしていないユーザからみると以下のようにみえます。
「いいね!」をするとこんな感じ。
Power Apps でレーティング評価機能を扱う
Power Apps で先ほど作成した「いいね!」フィールドの表示/編集を行っていきます。
前準備として、先ほど作成したリストを「データ」より追加しておいてください。
Power Apps でレーティング評価機能を表示する
ギャラリーを追加して、Items
に先ほど作成したリストを設定します。
ギャラリー内にラベルを追加して、以下のように設定します。
Label.Text
ThisItem.'「いいね!」と評価したメンバー'
そうすると以下のようなエラーになります。
どうやらこちらはテーブルのようですね。
先ほどの式に .
を追加して確認してみると、以下のようなフィールドを確認することができます。
「「いいね!」と評価したメンバー」とかかれているようにこちらには、ユーザ情報が格納されているようですね。
ということは、このテーブル内のレコード数を数えれば「いいね!」をしたユーザの数を取得できそうです。
テーブルのレコード数を数えるにはCountRows 関数を利用します。
Label.Text
CountRows(ThisItem.'「いいね!」と評価したメンバー')
これで「いいね!」の数を取得することができました。
Power Apps でレーティング評価機能を編集する
次にPower Apps から「いいね!」を行えるようにしたいと思います。
今回データの更新にはPatch 関数を利用します。
リストはこのように、自身が「いいね!」を行ったレコード(Title1)と、他のユーザが「いいね!」を行ったレコード(Title2)と、誰も「いいね!」を行っていないレコード(Title3)を用意しておきます。
まずはPower Apps 側でこのリストような表示を行わせたいと思います。
ギャラリーを追加して、"データソース"にSPO リストを設定します。
ギャラリー内には
- タイトルを表示させるラベル
- 「いいね!」を押すための👍アイコン
- 「いいね!」の数を表示するためのラベル
の3つのコントロールを配置します。
それぞれ順に以下のように設定します。
TitleLbl.Text
ThisItem.Title
GoodIcon.Icon
If(CountIf(ThisItem.'「いいね!」と評価したメンバー', Email = User().Email) > 0, Icon.ThumbsUpFilled, Icon.ThumbsUp)
GoodLbl.Text
CountRows(ThisItem.'「いいね!」と評価したメンバー')
タイトルの表示は説明不要かと思います。
また、「いいね!」のカウントも先ほど紹介したので、省きます。
アイコンですが、このように設定することによってアプリを利用しているユーザが「いいね!」を行っている場合は塗りつぶしなしのアイコンになり、ユーザが「いいね!」を行っている場合は塗りつぶしありのアイコンになります。
アプリを利用しているユーザが「いいね!」を行っているか?を判断するためには、SPO リストの「いいね!」列を参照してそのレコードの値にアプリを利用しているユーザのメールアドレスが1つでも登録されていれば、「いいね!」済み。と判断しています。
これによりそれっぽい表示ができました!
続いて、この「いいね!」アイコンが押されたときに「いいね!」を行う。もしくは「いいね!」を取り消す。処理を設定したいと思います。
「いいね!」を行うか取り消すかは、ユーザがそのレコードに「いいね!」済みかどうかで判断すればいいので先ほどの式を利用します。
If( CountIf(ThisItem.'「いいね!」と評価したメンバー', Email = User().Email) > 0, // ユーザが既に「いいね!」済みだった場合 [true の処理], // ユーザが「いいね!」を行っていない場合 [false の処理] )
まずは"ユーザが既に「いいね!」済みだった場合"の処理です。
これは簡単で、既存の「いいね!」したユーザのテーブルからアプリ利用者のユーザのレコードを除外してあげればいいです。
この除外処理にはFilter 関数を利用します。
Patch( RatingSample, LookUp(RatingSample, ID = ThisItem.ID), {'「いいね!」と評価したメンバー':Filter(ThisItem.'「いいね!」と評価したメンバー', Email <> User().Email)} )
次に"ユーザが「いいね!」を行っていない場合"の処理を設定していきます。
これは既存の「いいね!」したユーザのテーブルにアプリ利用者のユーザのレコードを追加してあげればいいです。
ただし追加方法がちょっとめんどくさいです。
まずは、「いいね!」したユーザのテーブルはどうやって設定されているのかをみてみましょう。
画像のように
- Claims
- Department
- DisplayName
- JobTitle
- Picture
の6フィールドで構成されています。
こちらは列の種類を"ユーザ"にした場合と同じ設定になっています。
Patch 関数で更新する場合はこれらのフィールド全てが存在している必要があります。
{ Claims: "i:0#.f|membership|" & Lower(User().Email), Department: Office365ユーザー.MyProfileV2().department, DisplayName: User().FullName, Email: User().Email, JobTitle: Office365ユーザー.MyProfileV2().jobTitle, Picture: User().Image }
このようなレコードを追加してあげます。
これらだけをPatch 関数で渡してしまうとアプリ利用者のユーザのみで上書きしてしまうことになってしまいますので既存テーブルと結合させます。
現時点では、Power Apps で Collect
や ClearCollect
関数でコレクションを作成する以外に既存テーブルに特定のレコードを追加する方法はありません。(ないよね?)
なので、ForAll 関数を活用して疑似的に既存テーブルにレコードを追加してあげます。
やり方は単純で、既存テーブルのレコード数 + 1 だけループさせて、レコード数分は既存テーブルのレコードを評価し、+ 1 分は上記のレコードを評価してあげればよいです。
実際式にすると以下のようになります。
Patch( RatingSample, LookUp(RatingSample, ID = ThisItem.ID), { '「いいね!」と評価したメンバー': With( { rating: LookUp(RatingSample, ID = ThisItem.ID, '「いいね!」と評価したメンバー') }, ForAll( Sequence(CountRows(rating) + 1), If( Value = CountRows(rating) + 1, { Claims: "i:0#.f|membership|" & Lower(User().Email), Department: Office365ユーザー.MyProfileV2().department, DisplayName: User().FullName, Email: User().Email, JobTitle: Office365ユーザー.MyProfileV2().jobTitle, Picture: User().Image }, Last(FirstN(rating, Value)) ) ) ) } )
これで、Power Apps からレコーディング評価機能を編集できるようになりました!
式全文は以下のようになっています。
OnSelect
If( CountIf(ThisItem.'「いいね!」と評価したメンバー', Email = User().Email) > 0, // ユーザが既に「いいね!」済みだった場合 Patch( RatingSample, LookUp(RatingSample, ID = ThisItem.ID), {'「いいね!」と評価したメンバー':Filter(ThisItem.'「いいね!」と評価したメンバー', Email <> User().Email)} ), // ユーザが「いいね!」を行っていない場合 Patch( RatingSample, LookUp(RatingSample, ID = ThisItem.ID), { '「いいね!」と評価したメンバー': With( { rating: LookUp(RatingSample, ID = ThisItem.ID, '「いいね!」と評価したメンバー') }, ForAll( Sequence(CountRows(rating) + 1), If( Value = CountRows(rating) + 1, { Claims: "i:0#.f|membership|" & Lower(User().Email), Department: Office365ユーザー.MyProfileV2().department, DisplayName: User().FullName, Email: User().Email, JobTitle: Office365ユーザー.MyProfileV2().jobTitle, Picture: User().Image }, Last(FirstN(rating, Value)) ) ) ) } ) )
現在確認している不具合
いずれも要検証項目ではありますが、作成を行う過程で以下のような不具合(動作)に遭遇しましたの共有です。
なお、いずれも回避策は見つかっておりません。。。
もし記事をご覧の方で、この不具合に心当たりのある方や回避策の案がある方はコメントいただけますと助かります。
SPO リストに「いいね!」の数が反映されない
Power Apps から「いいね!」を行った場合SPO リストに「いいね!」の数が反映されませんでした。
画像のように、「いいね!」を行ったということだけはわかりますが(ハートが塗りつぶされているため)、「いいね!」のカウントが増えていません。
ただ、こちら「いいね!」が設定されていない。というわけではありません。
こちらの状態で、別のユーザが「いいね!」を行うとそのユーザの「いいね!」 + Power Apps でユーザが「いいね!」を行った数がカウントとして更新されます。
これらの色々試した結果の動作からの推測になりますが、どうやら
- ユーザが「いいね!」を行ったかの判断
-> リスト表示時 - 「いいね!」のカウント
-> リストの「いいね!」を操作時
でそれぞれ値の更新が行われるようです。
Power Apps とSPO リストそれぞれをユーザに操作させる場合はこの点に注意してください。
Power Apps で'「いいね!」と評価したメンバー'列が参照できなくなる
検証のため色々弄っているとPower Apps で'「いいね!」と評価したメンバー'列が参照できなくなるという、大変困った不具合が発生しました。
この状態に陥ると '「いいね!」と評価したメンバー'
でも LikedBy
のどちらでも参照できなくなってしまいます。
また、私が色々試した限りだとこの状態に陥るとどうやってもPower Apps で「いいね!」フィールドを参照できなくなってしまいます。
詰みです。リスト作成し直してください。
リスト作成の際、既存のリストからリストを作成できますが、詰んだリストをコピーして作成してはいけません。
こうして作成されたリストも同様にPower Apps で「いいね!」フィールドが読み込めません。
この大変困った事象の発生条件はまだ特定できていないのですが、以下操作をSPO リストで行いその後Power Apps 側でデータのから対象リストを「最新の情報に更新」すると発生することがありました。(たまに発生しない。。。)
- 評価機能を有効後に列を追加する
- 評価機能を有効後に列を非表示にする(「いいね!」以外の列でも)
これ割と深刻な不具合のような気がするんですよね。。。
ちょっと暇みてMS サポートに確認してみようと思います。
おわりに
以上、Power Apps でレーティング評価機能(いいね!)を扱う方法でした。
この記事のやり方で一応扱えはしますが、最後に記載したような問題があり、実際利用するのはちょっと考えて方がよさそうです。
ただ、この「いいね!」列の実態は「いいね!」したユーザの情報が格納されているだけですので、Power Apps で扱うだけであれば、列の種類「ユーザ」で十分代替可能かと思います。