見出し画像

PowerAppsでSharePointリストを更新するアプリ作ってみたら、ユーザーの更新でネットワークエラー!解決奮闘記!

こんにちは(^^)/ アイシーティーリンクの三好です。
今回はPowerAppsでSharePointリストを操作するアプリで、リスト側に「ユーザーとグループ」列を使用している場合のコントロールについて、中々うまくいかず、泥沼にハマってしまったのですが、試行錯誤してようやく抜け出したのでそのハマりポイントと解決した方法について備忘録的に記載したいと思います。
※我流なのでもっとスマートな正解があるかもしれません(笑)

同じような事象で悩んでいる人も多いと思いますので、本ブログで解決の糸口になれば幸いです(^^)/

◆やりたいこと

SharePointリストの内容をPowerAppsアプリで表示して、
更新または新規作成をしたい。

  • SharePointリストの名称・・・サンプルリスト

  • PowerAppsアプリの名称・・・サンプルアプリ

  • ユーザー名はEntraIDに登録されているユーザーアカウントをプルダウンメニューから選択

  • コンボボックスはSharePointリスト上の選択肢メニューから選択

  • テキストボックスはフリーワード入力

最後に「ボタン」を押してSharePointリストに新規登録または更新したい

実行させる動作

新規レコード作成

  • 「+」をクリックして空白のフォームを表示

  • 各項目を入力し「ボタン」を押して新レコードとして追加

既存レコード更新

  • ギャラリーで既存レコードを選択し詳細をフォームに表示

  • 各項目を変更し「ボタン」を押して既存レコードを更新

◆前提

今回の前提は次の通り

  • データベースはSharePointListsを使用

  • EntraIDに登録されているユーザー(Office365ユーザー)から選択

  • PowerAppsでギャラリーとフォームを使用しPatch関数で更新

  • プルダウン表示するユーザーはフィルタリングして表示


◆準備

SharePointリスト

  • SharePointListsで「サンプルリスト」というリストを作成

  • リストの項目と列の種類は以下の通り
    「ID」・・・自動採番
    「user1」・・・ユーザーとグループ
    「user2」・・・ユーザーとグループ
    「Category」・・・選択肢
    「Usecase」・・・1行テキスト
    ※「タイトル」は不要のため非表示にしておきます。

サンプルリスト


PowerApps

  • PowerApps「サンプルアプリ」というアプリを作成
    ※今回は「タブレット」サイズで作成しています

  • 「ギャラリー」「フォーム」「ボタン」「+」を設置
    ※「タイトル」「添付ファイル」は不要のため削除しています。

  • データの追加(Office365ユーザー)

  • コントロールの名前は次の通り
    「user1」・・・DataCardValue2
    「user2」・・・DataCardValue3
    「Category」・・・DataCardValue5
    「Use case」・・・DataCardValue6
    「ボタン」・・・Button1
    「ギャラリー」・・・Gallery1
    「フォーム」・・・Form1

サンプルアプリ
Office 365ユーザーを追加しておきます

◆ハマった事象について

  1. ユーザー名を選択しPatch関数を実行するとエラーが発生する

  2. 選択したユーザーを削除して空白で登録することができない

"Patch関数の使用中にネットワークエラーが発生しました:要求された操作は無効です"

原因

  1. 取得時の注意(items)
    ユーザーを選択する際、E-mail(Claims)を指定する必要がある

  2. 更新時の注意(Patch)
    Office365ユーザーのユーザー情報は複数項目の情報を持っているため、更新する際はそれらの項目について値がなくても記載する必要がある

◆各コードの解説

では、ここから実際に入力したコードを開設していきます。
Office365ユーザーを参照してSharePointリストの「ユーザーとグループ」列に登録するこのコントロールにはかなりクセがあります。
1つのデータ(ユーザー情報)に複数の要素(表示名、メールアドレス、UPN、会社名・・・等の情報)を持っているということがキーになります。

"varITEM"という任意の名前で変数セット

新規作成の時、各コントロールを空白にするための変数

"varSubmit"という任意の名前で変数セット

Patch関数を使用してデータを更新した後の情報をフォーム内のコントロールに反映させるための変数

user1/user2の”item”コントロールについて

Office365ユーザー.SearchUser()
そのまま使用すると、上位 100 件までしか検索しないため「{top:999}」を記載しています
※最大 999 件まで可能

CompanyName = "アイシーティーリンク株式会社"
項目で絞り込むことができます。
この場合、Office365ユーザーの会社名に"アイシーティーリンク株式会社"と入力されているアカウントのみでフィルターしています

他にも様々な項目でフィルターが可能です
Department = "企画営業部"
JobTitle = "代表取締役"

また、OR関数を使用することで複数項目で絞り込むことも可能
Or(JobTitle = "部長",JobTitle = "取締役",Department = "企画営業部")

以下の実際の設定したコードを参照してください。

ボタン"OnSelect"の"Patch関数"について

user1:
{
Value: DataCardValue3.Selected.Mail,
'@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
Claims: "i:0#.f|membership|" & Lower(DataCardValue3.Selected.Mail),
Department: "",
DisplayName: "",
Email: "",
JobTitle: "",
Picture: ""
},

「Office365ユーザー」コネクタで情報を取得してPatch関数で書き込むためには通常のコントロールとは違い、かなり苦労しました。

「Office365ユーザー」コネクタユーザー情報を取得するにはメールアドレスで取得する必要があります。
"items"で
"AddColumns(Table(Filter(Office365ユーザー.SearchUser({top:999}), CompanyName = "アイシーティーリンク株式会社")),Claims,Mail)"
と指定し、「Claims,Mail」の部分でOffice365ユーザーからメールアドレスを抜き出してユーザーを検索しています。

メールアドレスを使用してEntraIDのユーザー情報からユーザーを特定した後は、表示名(DisplayName)や部署名(Department)など、様々な登録情報を表示することが可能になります。
※「フィールドの編集」で詳しく説明しています

また、これらの付加情報で絞り込んで表示させることもできます!
※「user1/user2の”item”コントロールについて」で詳しく説明しています

【Patch関数で書き込む際の注意点】
Email(Claims)だけでなく、他(Department、DisplayName、等)の項目も値はなくても"項目だけ"記載しておく必要があります。

以下の実際の設定したコードを参照してください。

◆各コントロールの設定


”+”アイコン

OnSelect

Set(varSubmit,false);
Set(varITEM,Blank());

Set(varSubmit,false);

ギャラリー

Items

サンプルリスト

OnSelect

Set(varITEM,ThisItem);

Set(varITEM,ThisItem);

コンボボックス(user1, user2)

items

AddColumns(Table(Filter(Office365ユーザー.SearchUser({top:999}), CompanyName = "アイシーティーリンク株式会社")),Claims,Mail)

AddColumns(Table(Filter(Office365ユーザー.SearchUser({top:999}), CompanyName = "アイシーティーリンク株式会社")),Claims,Mail)

Default
DefaultSelectedItems

user1の場合
If(varSubmit = true, Parent.Default, varITEM.user1)

user2の場合
If(varSubmit = true, Parent.Default, varITEM.user2)

//user1の場合
If(varSubmit = true, Parent.Default, varITEM.user1)

//user2の場合
If(varSubmit = true, Parent.Default, varITEM.user2)

Reset

true

IsSerchable

true


カード(user1, user2)

Required

true


フィールド > 編集(user1, user2)

レイアウト:二重線
主要なテキスト:DisplayName
副次的なテキスト:Department
Serchfield:DisplayName

以上のようにするとプルダウンで表示させたときに
1行目に表示名
2行目に部署
のように表示され、同姓同名の社員がいる場合などに便利です

1行目に表示名、2行目に部署名が表示されます

コンボボックス(Category)

Default
DefaultSelectedItems

If(varSubmit = true, Parent.Default, varITEM.Category)

If(varSubmit = true, Parent.Default, varITEM.Category)

テキストボックス(Use case)

Default

If(varSubmit = true, Parent.Default, varITEM.'Use case')

If(varSubmit = true, Parent.Default, varITEM.'Use case')

フィールドの設定

item

Gallery1.Selected


ボタン

OnSelect

コード上ではエラー表示されていないので合っているようだが・・・
Patch(
    サンプルリスト,
    If(IsBlank(varITEM), Defaults(サンプルリスト), varITEM),
    {
    Category:{Value:DataCardValue5.Selected.Value},
    'Use case':DataCardValue6.Text,

    user1:
            {
                Value: DataCardValue2.Selected.Mail,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue2.Selected.Mail),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            },
        
    user2: 
            {
                Value: DataCardValue3.Selected.Mail,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue3.Selected.Mail),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            }
    )
    
 });
 Set(varSubmit,true);
このコードを実行するとエラーが出てしまう・・・
戻ってみるとコード上でエラーがでている。
しかし適当なところで改行して元に戻すとやはりエラーは消える


そこで、エラーの原因を探るべく、エラーモニターを開いて確認してみます

モニターを開くと新しいタブに監視用のタブが開きます

監視用モニターを開いた状態で再度「ボタン」を押してPatch関数を実行

すると、エラー項目が4行表示されており、やはりPatchの実行でエラーが出ています。
Category列で「Network」を選択し > 詳細 > "data":{・・・
をクリックして詳細を表示させます

すると、"Claims"の行にメールアドレスが表示されていない、
さらに"message"に"指定されたユーザーが見つかりません"
と書いてありますので、ユーザーが正しく取得できていないようです。
恐らくこれがネットワークエラーの原因と思われます。

そこで試行錯誤してたどり着いた解決策は、表示用のコントロールと書き込み用のコントロールを分けてみたところ解決できました。
あまりスマートではないかもしれませんが今のところこの方法でやりたいことが出来るようになりました。

フォーム(Form1)を選択し、フィールドの追加で新たに
「user1」と「user2」を追加します。

新たに「user1」と「user2」が追加されました
「user1」(増分)・・・DataCardValue1として追加されました
「user2」(増分)・・・DataCardValue4として追加されました

ということで新たにコントロールが増えたので名前を整理します

  • コントロールの名前は次の通り
    「user1」・・・DataCardValue2
    「user2」・・・DataCardValue3
    「user1」(増分)・・・DataCardValue1
    「user2」(増分)・・・DataCardValue4
    「Category」・・・DataCardValue5
    「Use case」・・・DataCardValue6
    「ボタン」・・・Button1
    「ギャラリー」・・・Gallery1
    「フォーム」・・・Form1

※増分コントロールは、最後に"Visible"を"false"に設定し非表示にします。

増分コントロールの設定項目は何もしなくても大丈夫です
itemsは初期設定のまま次のようになっていることを確認してください

items

user1の場合
Choices([@サンプルリスト].user1)

user2の場合
Choices([@サンプルリスト].user2)

コントロールを増やしたので、Patch関数の内容も見直します。
「user1」と「user2」のみ、If文を入れ子で二つ使用して、下図のように設定します。
すると追加した増分のコントロールだけ、エラーが出ています。
原因は当初コントロールの参照先(items)が「Office365コネクタ」で
増分の参照先(items)がSharePointListsの「ユーザーとグループ列」を参照しているため、なぜか項目の名称が「Email」と「Mail」の違いがあり、それが原因でエラーとなっています。

増分のコントロールだけエラー表示がでています
増分コントロール(SharePointリスト)のユーザーとグループ列を参照の場合
当初コントロール(Office365コネクタ)を参照の場合
正しく設定すると、無事にエラーが消えました

増分コントロールの「.Mail」を「.Email」に修正すると
Patch関数(ボタン)を実行するとエラーにはならず、無事正常にSharePointリストに更新ができました!

モニター上でもエラー表示されず、「成功」となっています。

ステータスは全て成功となりました

詳細も"Claims"行に正しくメールアドレスが入っており、その下の各項目にも正常に情報が反映していることが確認できます。

ユーザー情報も取得できているようです

これで完成!
としたかったのですが、実は最後にもう一つ課題が残っています。
実はこのままだと、入力したユーザー名を削除して空白として更新することが出来ないのです。
コントロール上で「×」を押してユーザー名を消して「ボタン」を押すと、なぜかSharePointリスト上の値を再表示してしまいます。
ということはSharePointリスト上の値を削除できていないという事ですね。

結論

この事象を対策するには、入れ子にした2回目のIF文では"Email"ではなく"DisplayName"にすることで対応できました。
これですべて思い通りの動作になりました!!
(;´・`)> ふぅ長かった・・・

完成!

Patch関数の全体は次のとおりです

Patch(
    サンプルリスト,
    If(IsBlank(varITEM), Defaults(サンプルリスト), varITEM),
    {
    Category:{Value:DataCardValue5.Selected.Value},
    'Use case':DataCardValue6.Text,

    user1: If(
            IsBlank(DataCardValue2.Selected.Mail),

            If(IsBlank(DataCardValue2.Selected.DisplayName),
            Blank(),
            {
                Value: DataCardValue1.Selected.Email,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue1.Selected.Email),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            }),
            {
                Value: DataCardValue2.Selected.Mail,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue2.Selected.Mail),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            }
        ),
        
    user2: If(
            IsBlank(DataCardValue3.Selected.Mail),

            If(IsBlank(DataCardValue3.Selected.DisplayName),
            Blank(),
            {
                Value: DataCardValue4.Selected.Email,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue4.Selected.Email),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            }),
            {
                Value: DataCardValue3.Selected.Mail,
                '@odata.type': "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
                Claims: "i:0#.f|membership|" & Lower(DataCardValue3.Selected.Mail),
                Department: "",
                DisplayName: "",
                Email: "",
                JobTitle: "",
                Picture: ""
            }
    )
    
 });
 Set(varSubmit,true);

これでようやくやりたいことが出来るようになりました!

最後に増分のコントロール2つを非表示にして完成です。

増分のカード(user1, user2)

Visible

false

以上!今回初めてPowerAppsにチャレンジして、いきなり困難に直面しましたが、奮闘したおかげで変数の設定や、モニターの見方など複合的にかなりたくさんの知見を広める結果になりとても達成感がある内容となりました!

同じ問題で悩んでいる方の問題解決につながれば幸いです
それではまた次回お会いしましょ~う(^^)/

この記事が気に入ったらサポートをしてみませんか?