PowerApps│書き込みしやすい選別したユーザー群のコレクションを作成する方法

こんにちは、あんこ先生です。

Power Appsでユーザー群を扱うとき、Office365グループコネクタでメンバーをどさっと取ってくる、よくやりますよね。

でも「あの人だけグループに入ってないから候補に出てこない」「ゲストの人が拾えない」って、地味に詰まりがちなんです。

わたしも一度、登録してほしい人がどうしても出てこなくて、軽く沼りました。

この記事を読み終えると、グループで取れないユーザーを手動でぽちぽち選んでコレクションにまとめ、SharePointのユーザー列にそのまま書き込めるようになります。

しかも一度作った一覧を起動時に自動で再現して、毎回作り直さなくていい形まで持っていきます。

例によってコピペで試せるようにしておきますね。

結論から先に
Office365ユーザーコネクタで人を検索してコレクションに足し、その中身をOnStartにClearCollectとして焼き込めば完成です。あとは書き込み先のユーザー列の形にだけ気をつければOKです。
この記事の前提
・Office365ユーザーコネクタ と SharePointコネクタ をアプリに追加していること
・設定でモダンコントロールをオンにしていること
・書き込み先のSharePointリストに「ユーザー(人物)列」がひとつあること
・標準コネクタだけで完結させたい人向けです

そもそも、なぜグループだと取れない人が出るの?

Office365グループコネクタが返してくれるのは、あくまで「そのグループのメンバー」です。

つまりグループに入っていない人は、どう頑張っても出てきません。

たとえば、別部署からスポットで手伝ってくれる人、外部のゲストユーザー、まだグループに追加されていない新入りさん、このあたりが取りこぼしの常連です。

そこで今回は、グループ任せをあきらめて、必要な人だけ手で選んでコレクションに持つ作戦でいきます。

グループコネクタそのものの基本は、PowerApps│全社員を把握!Office365ユーザー&グループコネクタの使い方でまとめているので、まだの方はそちらもどうぞ。

おおまかな流れ

やることは3ステップだけです。

  • STEP1:コレクションの器を、ユーザー列の形にそろえる
  • STEP2:メンテ画面で検索して、追加・削除する
  • STEP3:完成した一覧をOnStartに焼き込む

最後に、できあがったコレクションをユーザー列へ書き込むところまで確認していきますね。

STEP1:コレクションの器をユーザー列の形にそろえる

ここが一番大事なところです。

SharePointのユーザー列に書き込めるレコードの形は、実は決まっています。

そしてOffice365グループコネクタは形が違って書き込めないんですよね。

コレクションをこの形にそろえておけば、そのままPatch関数に渡せて、ぐっと楽になりますよ。

//ユーザー列に渡せる1レコードの形
{
    '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
    Claims: "i:0#.f|membership|user@contoso.com",
    Department: "",
    DisplayName: "表示名",
    Email: "user@contoso.com",
    JobTitle: "",
    Picture: ""
}

この中で主役はClaimsです。

i:0#.f|membership|のうしろに、その人のサインイン名(メール形式のUPN)をくっつけたものが、ユーザー列の一意キーになります。

ここがズレると別人扱いになってしまうので、いちばん気を遣うポイントです。

SharePointのユーザー列に書き込むだけが目的ならClaims以外は空でもOKです。

今回は選択肢にもしたいのでちゃんと他の列も埋めていきますね。

STEP2:メンテ画面で検索して追加・削除する

次に、人を探して足していく専用の画面(scrManualUsers)を作ります。

検索ボックスとしてテキスト入力コントロール(txtSearch)をひとつ置きます。

そして検索結果を出すギャラリーコントロール(galSearchResults)のItemsプロパティに、Office365ユーザーコネクタの検索を入れます。

//galSearchResults の Items(入力した文字で社内ユーザーを検索)
Office365Users.SearchUser({searchTerm: txtSearch.Text, top: 50})

検索結果の各行に、追加用のモダンボタンコントロール(アイコンは="Add")を置きます。

そのボタンのOnSelectプロパティで、Claimsをキーにして重複を避けつつ、colManualUsersへ追加します。

//追加ボタン btnAdd の OnSelect(同じ人は二重に入れない)
With(
    { upn: Lower(ThisItem.UserPrincipalName) },
    If(
        CountRows(Filter(glbManualUsers, Claims = "i:0#.f|membership|" & upn)) = 0,
        Collect(
            colManualUsers,
            {
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & upn,
                Department: Coalesce(ThisItem.Department, ""),
                DisplayName: ThisItem.DisplayName,
                Email: Coalesce(ThisItem.Mail, ThisItem.UserPrincipalName),
                JobTitle: Coalesce(ThisItem.JobTitle, ""),
                Picture: ""
            }
        )
    )
)

UPNをLower関数で小文字にそろえているのは、大文字小文字の違いで同じ人を別人と数えないためです。

追加済みの一覧は、別のギャラリーコントロール(galManualUsers)のItemsにcolManualUsersを入れて映します。

各行の削除ボタン(アイコンは="Delete")のOnSelectは、これだけでOKです。

//削除ボタン btnRemove の OnSelect
Remove(colManualUsers, ThisItem)
ここが落とし穴
Office365ユーザーコネクタの検索は、検索文字を入れて初めて当たりが返ります。txtSearchが空っぽのままだと、結果が出なくて「あれ動かない?」となりがちです。まずは名字を1〜2文字打って試してみてくださいね。

STEP3:完成した一覧をOnStartに焼き込む

ここまでで一覧は作れますが、このままだとアプリを閉じると消えてしまいます。

毎回ぽちぽち作り直すのは、さすがにしんどいですよね。

そこで、いま作った中身をClearCollectの命令文そのものに変換して、OnStartに貼り付けてしまいます

変換には、複数行のテキスト入力コントロール(txtOutput、Modeは=TextMode.MultiLine)をメンテ画面に置いて、Defaultプロパティに次の式を入れます。

//txtOutput の Default(コレクションを ClearCollect 文字列に変換)
"ClearCollect(colManualUsers," &
Concat(
    colManualUsers,
    "{'@odata.type':""#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser"",Claims:""" & Claims & """,Department:""" & Department & """,DisplayName:""" & DisplayName & """,Email:""" & Email & """,JobTitle:""" & JobTitle & """,Picture:""""}",
    ","
) & ")"

あとは、txtOutputに出てきたClearCollect(...)をコピーします。

Copy関数を使うのもいいですね。

それをアプリのOnStartプロパティにそのまま貼り付ければ、おしまいです。

貼り付け後はこんなイメージになりますよ。

//App の OnStart(次回からはこれだけでコレクションが復活)
ClearCollect(
    colManualUsers,
    {
        '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
        Claims: "i:0#.f|membership|user1@contoso.com",
        Department: "", DisplayName: "ユーザー1", Email: "user1@contoso.com",
        JobTitle: "", Picture: ""
    }
)

これで次回からは、メンテ画面を開かなくても、起動時にcolManualUsersが勝手に再現されます。

できたコレクションをユーザー列に書き込む

仕上げに、コレクションをSharePointのユーザー 列へ書き込みます。

複数人を入れられる人物列なら、テーブルをまるごと渡すだけです。

//複数人OKのユーザー列に、一覧をまるごと書き込む
Patch(リスト名, Defaults(リスト名), { 担当者: colManualUsers })

1人だけ入れる単一の人物列なら、コレクションから1件選んで渡します。

//単一ユーザー列に、ドロップダウンで選んだ1人を書き込む
Patch(リスト名, { 担当者: LookUp(colManualUsers, Email = drpSelect.Selected.Email) })

ユーザー列への書き込みでつまずいたら、PowerApps│様々なアプローチでユーザー列に書き込む方法に他のやり方もまとめてあるので、合わせて見ると安心ですよ。

検索しても出てこない人がいるときは?

検索しても候補に出てこない人は、たいていゲストユーザー(外部の人)です。

その場合は、検索に頼らず手入力で1件作ってしまうのが早いです。

STEP1の形のうち、ClaimsのUPNとEmailにその人のメールアドレスを入れて、DisplayNameに表示名を入れれば、ユーザー列には十分通ります。

ひとことメモ
編集する人が多い、件数も多い、という場合は、OnStartに焼き込む代わりに専用の設定リストをSharePointに用意して、OnStartで読み込む形にすると保守がぐっと楽になります。

写真列も追加しておきたい場合

ギャラリーに写真も載せたい場合、都度コネクタ使っちゃうと処理が重くなりますよね。

そんなときはこのコレクションの次ステップで写真列を追加しておきましょう。

最初は時間がかかるけど、その後アプリのどこで写真を使ってもコネクタは利用しないのでサクサクです。

ただ人数がめちゃくちゃ多い場合は向きません。

多くて20人ぐらいまでですね。

//画像列を変数に格納
ClearCollect(colMembers,
AddColumns(colSelectUsers,
Photo,IfError(
Office365ユーザー.UserPhotoV2(ThisRecord.Email),
Blank()
)
)
);

選別したユーザー群のコレクションを作成する方法のまとめ

今回は、グループで取れないユーザーをコレクションでまとめて、ユーザー列に書き込む方法を紹介しました。

ポイントは3つでしたね。

  • コレクションの形をSharePointリストのユーザー列にそろえる(鍵はClaims)
  • Office365ユーザーコネクタで検索して、重複なしで足していく
  • できた一覧をClearCollect文に変換して、OnStartに焼き込む

まずはSTEP1をコピペして、1人だけ手入力で作ってPatchが通るかこっそり試してみてください。

ユーザー列への書き込みでつまずいたら、こちらも合わせてどうぞ。

それでは、また次の記事でお会いしましょう。

ABOUT US
七草あんこ
非IT系中間管理職やってます。社命によりoffice365を主軸とした業務改善プロジェクトメンバーに任命されたことでPowerAppsと出会えました。いまではビジネス・プライベートを問わず、欠かせないツールになっています。導入初期やアプリ作成時に遭遇した諸問題の解決法とサンプルアプリの作り方を紹介していきます。主にTwitterで情報収集しているので不明点など呟いているとお邪魔するかもしれません。