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

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


スポンサードリンク

Power Apps でSPO リストのレーティング評価機能(いいね)を利用する


スポンサードリンク

はじめに

以前マシュマロでこのような質問をいただきました。

https://media.marshmallow-qa.com/system/images/ba74d58c-5dfa-439d-9fcb-5ebc7dd4ae67.png

こちらについてTwitter のほうで簡単に回答させていただきましたが、今回はもう少し詳しく回答したいと思います。

SPO リストにレーティング評価機能を追加する

レーティング評価機能といわれてもピンとこない方もいらっしゃると思いますので、こちらの機能の追加方法をまずは紹介したいと思います。

  1. サイトコンテンツへ移動して、レーティング機能を追加したいリストの「⁝」を選択して「設定」を選択します
    f:id:koruneko:20210804015620p:plain
  2. 「全般設定」の「評価の設定」を選択します f:id:koruneko:20210804020110p:plain
  3. 「評価の設定」を「はい」にします
    その次の項目では、評価を「いいね!」か「星評価」にするかが選べます
    今回は「いいね!」を選択します f:id:koruneko:20210804020207p:plain

これで「いいね!」フィールドが作成されました。
f:id:koruneko:20210804020506p:plain

これでこんな感じで「いいね!」ができるようになりました!

f:id:koruneko:20210804020926g:plain

ちなみに「いいね!」をしていないユーザからみると以下のようにみえます。

f:id:koruneko:20210804021410p:plain

「いいね!」をするとこんな感じ。

f:id:koruneko:20210804021455p:plain

Power Apps でレーティング評価機能を扱う

Power Apps で先ほど作成した「いいね!」フィールドの表示/編集を行っていきます。

前準備として、先ほど作成したリストを「データ」より追加しておいてください。

f:id:koruneko:20210804021839p:plain

Power Apps でレーティング評価機能を表示する

ギャラリーを追加して、Items に先ほど作成したリストを設定します。

ギャラリー内にラベルを追加して、以下のように設定します。

Label.Text

ThisItem.'「いいね!」と評価したメンバー'

そうすると以下のようなエラーになります。

f:id:koruneko:20210804023248p:plain

どうやらこちらはテーブルのようですね。

先ほどの式に . を追加して確認してみると、以下のようなフィールドを確認することができます。

f:id:koruneko:20210804023609p:plain

「「いいね!」と評価したメンバー」とかかれているようにこちらには、ユーザ情報が格納されているようですね。

ということは、このテーブル内のレコード数を数えれば「いいね!」をしたユーザの数を取得できそうです。
テーブルのレコード数を数えるにはCountRows 関数を利用します。

Label.Text

CountRows(ThisItem.'「いいね!」と評価したメンバー')

これで「いいね!」の数を取得することができました。

f:id:koruneko:20210804023919p:plain

Power Apps でレーティング評価機能を編集する

次にPower Apps から「いいね!」を行えるようにしたいと思います。

今回データの更新にはPatch 関数を利用します。

リストはこのように、自身が「いいね!」を行ったレコード(Title1)と、他のユーザが「いいね!」を行ったレコード(Title2)と、誰も「いいね!」を行っていないレコード(Title3)を用意しておきます。

f:id:koruneko:20210812005235p:plain

まずは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つでも登録されていれば、「いいね!」済み。と判断しています。

これによりそれっぽい表示ができました!

f:id:koruneko:20210812010755p:plain

続いて、この「いいね!」アイコンが押されたときに「いいね!」を行う。もしくは「いいね!」を取り消す。処理を設定したいと思います。

「いいね!」を行うか取り消すかは、ユーザがそのレコードに「いいね!」済みかどうかで判断すればいいので先ほどの式を利用します。

If(
    CountIf(ThisItem.'「いいね!」と評価したメンバー', Email = User().Email) > 0,
    // ユーザが既に「いいね!」済みだった場合
   [true の処理],
   // ユーザが「いいね!」を行っていない場合
   [false の処理]
)

まずは"ユーザが既に「いいね!」済みだった場合"の処理です。
これは簡単で、既存の「いいね!」したユーザのテーブルからアプリ利用者のユーザのレコードを除外してあげればいいです。
この除外処理にはFilter 関数を利用します。

    Patch(
        RatingSample,
        LookUp(RatingSample, ID = ThisItem.ID),
        {'「いいね!」と評価したメンバー':Filter(ThisItem.'「いいね!」と評価したメンバー', Email <> User().Email)}
    )

次に"ユーザが「いいね!」を行っていない場合"の処理を設定していきます。
これは既存の「いいね!」したユーザのテーブルにアプリ利用者のユーザのレコードを追加してあげればいいです。
ただし追加方法がちょっとめんどくさいです。

まずは、「いいね!」したユーザのテーブルはどうやって設定されているのかをみてみましょう。

f:id:koruneko:20210812013055p:plain

画像のように

  • Claims
  • Department
  • DisplayName
  • Email
  • 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 で CollectClearCollect 関数でコレクションを作成する以外に既存テーブルに特定のレコードを追加する方法はありません。(ないよね?)

なので、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 リストに「いいね!」の数が反映されませんでした。

f:id:koruneko:20210812020912p:plain

画像のように、「いいね!」を行ったということだけはわかりますが(ハートが塗りつぶされているため)、「いいね!」のカウントが増えていません。

ただ、こちら「いいね!」が設定されていない。というわけではありません。
こちらの状態で、別のユーザが「いいね!」を行うとそのユーザの「いいね!」 + Power Apps でユーザが「いいね!」を行った数がカウントとして更新されます。

これらの色々試した結果の動作からの推測になりますが、どうやら

  • ユーザが「いいね!」を行ったかの判断
    -> リスト表示時
  • 「いいね!」のカウント
    -> リストの「いいね!」を操作時

でそれぞれ値の更新が行われるようです。

Power Apps とSPO リストそれぞれをユーザに操作させる場合はこの点に注意してください。

Power Apps で'「いいね!」と評価したメンバー'列が参照できなくなる

検証のため色々弄っているとPower Apps で'「いいね!」と評価したメンバー'列が参照できなくなるという、大変困った不具合が発生しました。

f:id:koruneko:20210812021118p:plain

この状態に陥ると '「いいね!」と評価したメンバー' でも LikedBy のどちらでも参照できなくなってしまいます。
また、私が色々試した限りだとこの状態に陥るとどうやってもPower Apps で「いいね!」フィールドを参照できなくなってしまいます。
詰みです。リスト作成し直してください。

リスト作成の際、既存のリストからリストを作成できますが、詰んだリストをコピーして作成してはいけません。
こうして作成されたリストも同様にPower Apps で「いいね!」フィールドが読み込めません。

この大変困った事象の発生条件はまだ特定できていないのですが、以下操作をSPO リストで行いその後Power Apps 側でデータのから対象リストを「最新の情報に更新」すると発生することがありました。(たまに発生しない。。。)

  • 評価機能を有効後に列を追加する
  • 評価機能を有効後に列を非表示にする(「いいね!」以外の列でも)

これ割と深刻な不具合のような気がするんですよね。。。
ちょっと暇みてMS サポートに確認してみようと思います。

おわりに

以上、Power Apps でレーティング評価機能(いいね!)を扱う方法でした。
この記事のやり方で一応扱えはしますが、最後に記載したような問題があり、実際利用するのはちょっと考えて方がよさそうです。

ただ、この「いいね!」列の実態は「いいね!」したユーザの情報が格納されているだけですので、Power Apps で扱うだけであれば、列の種類「ユーザ」で十分代替可能かと思います。


スポンサードリンク