- 記事一覧 >
- ブログ記事
PowerApps SharePoint 委任問題(2000件問題)をいろいろな方法で攻略した
はじめに
Power Apps から Share Point のリストを利用すると、時々、
「委任に関する警告です。この数式の強調表示された部分は、大きなデータセットで正常に機能しない可能性があります。」
と表示されることがあります。
これは、重要な警告で、無視すると本当に正常に動かないことになるかもしれません。
書いてある通り、扱うデータ量が大きいと問題になります。
今回、委任問題(2000 件問題)をいくつかの方法で回避することができましたので、それについて、実証実験結果とともに紹介していきたいと思います。
取得系だけではなく、UpdateIf の委任問題(2000 件問題)も回避できることを確認しました。
"委任問題" とタイトルにありつつも、この記事で取り上げるテーマは、委任できるできないの話ではなく、委任できても Share Point のリストについて最大 2000 件までしか扱えないという話です。
例えば、委任できる Filter 関数で 3000 件まで絞り込めるとして、2001 件目からが取得できない問題のことです。
委任問題と 2000 件問題の関係について、こちらの説明が分かりやすかったです。
↓
Power Apps 委任とデータ行の制限(500 件~ 2000 件)の関係を図にまとめてみた
https://ippu-biz.com/development/powerplatform/powerapps/delegation003/
最大 2000 件の 2000 は、別途設定が必要です。以降、設定したものとします。
設定 → 全般 → データ行の制限委任がサポートされていないサーバー ベースの接続から取得する行数を設定します
を 2000 に設定します。
2000 を超えて設定することはできません。
Share Point のリストが必ず 2000 件以下の場合は、最大 2000 件の設定後、この記事のこれ以降のテクニックは必要ありません。対処は、これで完了です。
この記事は、2023 年 8 月現在の状況を元に書いています。
記事を書いておいて、なんですが、可能な限り、この記事のような手段は取らないことを推奨します。つまり、可能であれば、リストの構造だとかを見直して、この記事のような手段からの回避策を模索した方が良いと思います。
この記事のアイデアは、
https://www.matthewdevaney.com/create-power-apps-collections-over-2000-rows-with-these-4-tricks/
を参考にさせていただいています。
Microsoft MVP の Matthew Devaney さんの記事です。
解決案を先にまとめます。各々リンクになっているため、ジャンプ可能です。
リンク | 取得/UpdateIf | 方法/注記 |
---|---|---|
アイデア1 | 取得 | 前半 2000 件+後半 2000 件 対応できるのは 4000 件まで |
アイデア2 | 取得 | Filter を繰り返す 1回の Filter で 2000 件超は想定外 |
アイデア3 | 取得 | Power Automate のフローを利用 Power Automate の 5000 件問題あり |
UpdateIf 1 | UpdateIf | Power Automate のフローを利用 Power Automate の 5000 件問題あり タイムアウトが発生する |
UpdateIf 2 | UpdateIf | 設定で委任できないのを回避 更新対象 2000 件超は不可 |
Power Automate の 5000 件問題(
複数項目の取得
の 上から順に取得 の上限が 5000)は、解決可能なのですが、この記事ではそれについては、省略します。解決方法、詳細は、別記事「Power Automate & Share Pointの5000件問題を攻略した」をご覧ください。
テストデータ
以下のようにシンプルなものとします。
列名 | 型 |
---|---|
分類 | 一行テキスト(細かい設定はデフォルトのまま) |
テスト値 | 数値(細かい設定はデフォルトのまま) |
分類 | テスト値 |
---|---|
A | 1 |
A | 2 |
... | ... |
A | 1000 |
B | 1001 |
B | 1002 |
... | ... |
B | 2000 |
C | 2001 |
C | 2002 |
... | ... |
C | 3000 |
今回、3000 件準備します。
テスト値は、1
~3000
まで 1 刻みの連番が入っているものとします。1
~ 1000
までの分類の値は、A
1001
~ 2000
までの分類の値は、B
2001
~ 3000
までの分類の値は、C
とします。
2000 件問題おさらい
上記データを踏まえて、改めて簡単に説明します。
データの検索、取得について、時間がかかりそうなことは、Power Apps 自身で処理せず、Share Point に委任(依頼)しています。
委任することにより、Power Apps 側でデータを探さずに、Share Point 側でデータを探して、Power Apps が固まったように見えるのを避けるという趣旨があります。
Share Point にとって、データを探すのは朝飯前ですので、Share Point に委任するのは合理的です。
ただし、委任できても 最大 2000 件問題はつきまといます。
ここで、「すみません! 2000 件までしか取得できませんでした!」とか言ってこず、正常に動作したかのように、しれっと 2000 件だけ取得されます。
UpdateIf に関しては、そもそも委任できないため、2001 件目から見えていないに等しいふるまいをします。
ここで、「すみません! 2001 件目からのデータは更新できませんでした!」とか言ってこず、正常に動作したかのようにふるまいます。
2000 件問題確認
まずは、2000 件問題が本当に起きるのか確認です。(起きなかったら、解散撤収です。)
確認方法は、単純で、ボタンの OnSelect でデータセット= Share Point の 3000 件のリスト から全てのデータを参照して、ギャラリーに表示させます。
ClearCollect(col_datalist,datalist)
datalist
は、接続済み Share Point の 3000 件のリストです。col_datalist
は、ギャラリーがデータソースに指定しているコレクションです。
2000 件しか取れていません。 起きました。
「委任できる関数を使っていないからだ!」となるかもしれませんので、念のため、もう1パターンで試します。
ClearCollect(col_datalist,Filter(datalist, テスト値>=0))
特に、委任に関する警告もないですが、これも同じ結果です。2000 件しか取れません。
アイデア1
2000 件問題攻略の1つ目のアイデアは、ID でソートして、
前半 2000 件、後半 2000 件を取得して、計 4000 件まで対応する
というアイデアです。2000 件越え 4000 件までのデータの場合、このアイデアで解決します。
もちろん、4010 個など、4000 件越えの可能性があるデータには、このアイデアは使えません。
ボタンの OnSelect に以下のように実装して、確認します。
// Concurrent で前半、後半取得を同時実行
Concurrent(
// 前半のデータを取れるだけ取得
ClearCollect(
col_datalistChunk1,
Sort(
datalist,
ID,
SortOrder.Ascending
)
),
// 後半のデータを取れるだけ取得
ClearCollect(
col_datalistChunk2,
Sort(
datalist,
ID,
SortOrder.Descending
)
)
);
// ClearCollect は複数のレコードまたはテーブルを指定可能
ClearCollect(
col_datalist2,// ギャラリーのデータソース
col_datalistChunk1,// 前半のデータ
Filter(// 後半のデータから前半のデータを除外
col_datalistChunk2,
Not(ID in col_datalistChunk1.ID)
)
);
Clear(col_datalistChunk1);
Clear(col_datalistChunk2);
datalist
は、接続済み Share Point の 3000 件のリストです。col_datalist2
は、ギャラリーがデータソースに指定しているコレクションです。
動作確認してみます。
3000 件取れ...あれ?
後半部のソートが逆順のため、3000 番目のデータが途中にあります。
後半部のソートを元に戻すように改良します。
Concurrent(
ClearCollect(
col_datalistChunk1,
Sort(
datalist,
ID,
SortOrder.Ascending
)
),
ClearCollect(
col_datalistChunk2,
Sort(
datalist,
ID,
SortOrder.Descending
)
)
);
ClearCollect(
col_datalist2,
col_datalistChunk1,
Filter(
Sort(// 後半データのソートを元に戻す。
col_datalistChunk2,
ID,
SortOrder.Ascending
),
Not(ID in col_datalistChunk1.ID)
)
);
Clear(col_datalistChunk1);
Clear(col_datalistChunk2);
3000 件取得成功!
アイデア2
Filter で個別に取り出して、足し合わせるアイデアです。
例えば、
分類=A 1000 件、
分類=B 1000 件、
分類=C 1000 件
のとき、分類 A, B, C を ForAll で個別にフィルタリングして取り出せば、3000 件取得できます。
Filter で必ずしも 2000 件以下に絞り込めないとき、 例えば、 分類=A 2010 件、 分類=B 1000 件、 分類=C 1000 件 のケースが考えられる場合、このアイデアは使えません。
ボタンの OnSelect に以下のように実装して、確認します。
Clear(col_datalist3);
ForAll(
cmb_selectCategory.SelectedItems.Value,
Collect(col_datalist3, Filter(datalist, 分類=Value))
);
datalist
は、接続済み Share Point の 3000 件のリストです。col_datalist3
は、ギャラリーがデータソースに指定しているコレクションです。cmb_selectCategory
は、分類を選択するコンボボックスです。
コンボボックスは、分類 A, B, C を選択するようになっています。(A, B だけ選択も可)
["A","B","C"]
動作確認してみます。
3000 件取得成功!
アイデア3
Power Automate のフローを呼び出すアイデアです。
フロー作成
まず、Power Automate の フローを作成します。
ざっくりと、以下のような内容のフローになります。
トリガー Power Apps
↓複数項目の取得
で 3000 件すべて取得 ※1
↓変数を初期化する
で取得したデータを JSON 文字列化 ※2
↓PowerApps または Flow に応答する
で JSON 文字列をレスポンス
※1
複数項目の取得
の 上から順に取得 の上限が 5000 件という話もありますが、今回は、3000 件のため、何も考えずに取得しています。詳細は、別記事「Power Automate & Share Pointの5000件問題を攻略した」をご覧ください。
※2
Matthew さんの元記事の場合、
応答- 要求
アクションで取得したデータをダイレクトでレスポンスしています。それで何も問題ないのですが、
応答- 要求
アクションは PLEMIUM のため、今回使わないで、JSON 文字列を応答するようにしました。
変数を初期化する
で種類を 文字列 としつつ、値にオブジェクトや配列を指定すると、JSON 文字列が格納されます。(
PowerApps または Flow に応答する
アクションは、文字列を応答する設定にしました。)
新規作成時は、+作成 → インスタントクラウド フロー → Power Apps を選択します。
今回、複数項目の取得
に関して、上から順に取得=5000
として、5000 件まで取得としました。
ちなみに、Power Apps がトリガーになっていますが、手動起動でテスト可能です。
変数を初期化する
のところで、outputs('複数項目の取得')?['body/value']
が値としてセットされていますが、式に直接書かないと、自動的に Apply to each
が作成されるため、注意が必要です。
なお、フローのレスポンスは、以下のように余分な情報が沢山入った JSON 文字列になります。
今回は簡略化のため、やっていませんが、選択
アクションで絞り込むなどした方が良いと思います。
[
{
"@odata.etag": "\"1\"",
"ItemInternalId": "6016",
"ID": 6016,
"Category": "A",
"TestValue": 1,
"Modified": "2023-MMM-03T07:39:36Z",
"Created": "2023-MM-DDT07:39:36Z",
"Author": {
"@odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|taro_yamada@example.onmicrosoft.com",
"DisplayName": "Taro, Yamada/山田 太郎",
"Email": "taro_yamada@example.onmicrosoft.com",
"Picture": "https://example.sharepoint.com/sites/delegationtest/_layouts/15/UserPhoto.aspx?Size=L&AccountName=taro_yamada@example.onmicrosoft.com",
"Department": null,
"JobTitle": null
},
"Author#Claims": "i:0#.f|membership|taro_yamada@example.onmicrosoft.com",
"Editor": {
"@odata.type": "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedUser",
"Claims": "i:0#.f|membership|taro_yamada@example.onmicrosoft.com",
"DisplayName": "Taro, Yamada/山田 太郎",
"Email": "taro_yamada@example.onmicrosoft.com",
"Picture": "https://example.sharepoint.com/sites/delegationtest/_layouts/15/UserPhoto.aspx?Size=L&AccountName=taro_yamada@example.onmicrosoft.com",
"Department": null,
"JobTitle": null
},
"Editor#Claims": "i:0#.f|membership|taro_yamada@example.onmicrosoft.com",
"{Identifier}": "Lists%252fdatalist%252f6016_.000",
"{IsFolder}": false,
"{Thumbnail}": {
"Large": null,
"Medium": null,
"Small": null
},
"{Link}": "https://example.sharepoint.com/sites/delegationtest/_layouts/15/listform.aspx?PageType=4&ListId=f366d964%2D1222%2D4790%2D95ae%2D2b8d4d484847&ID=6016&ContentTypeID=0x0100007EBECFF99CF34DBA42BF4208A9FC850014B922EF108E614FAF4DF783FC79270A",
"{Name}": "",
"{FilenameWithExtension}": "",
"{Path}": "Lists/datalist/",
"{FullPath}": "Lists/datalist/6016_.000",
"{HasAttachments}": false,
"{VersionNumber}": "1.0"
},
{
"@odata.etag": "\"1\"",
"ItemInternalId": "6017",
"ID": 6017,
"Category": "A",
"TestValue": 2,
...
作ったフローは、有効にしておく必要があります。
Power Apps 側フロー追加
フローを Power Apps で読み込みます。
Power Automate アイコンクリック → +フローの追加 → 先ほどのフロー選択
になります。
このとき、フロー名のスペースが詰められて、認識されますので注意が必要です。
例:Flow A B C
追加 → FlowABC
として呼び出し
Power Apps から呼び出し
ボタンの OnSelect に以下のように実装して、確認します。
Clear(col_datalist4);
ClearCollect(
col_datalist4,
ForAll(
Table(ParseJSON('PowerApp-PowerAutomate連携確認-blog'.Run().result)),
{
Category: Text(ThisRecord.Value.Category),
TestValue: Text(ThisRecord.Value.TestValue)
}
)
);
PowerApp-PowerAutomate連携確認-blog
は、接続済み Power Automate フローです。col_datalist4
は、ギャラリーがデータソースに指定しているコレクションです。
Power Automate フローは、.Run()
で呼び出して、.result
は、フロー側でレスポンスを result
として保存したため、.result
です。
ParseJSON 関数は、設定 → 近日公開の機能 → プレビュー → ParseJSON 関数と型指定されていないオブジェクト → オン が必要です。
ForAll(...
の部分は、戻ってきた json が配列の中に多階層オブジェクトがあるという形で、そのまま扱うのは、難しいため、Category
、TestValue
列を持ったシンプルなテーブル型データに変換しています。
動作確認してみます。
あまり時間かかりませんでしたが...画面外のところに流れる玉が出てきています。玉が出ているときは、バックグラウンドでデータ取得中の意味です。
データ取得中に操作されると都合が悪い場合、画面をロックして、ローディングスピナー表示など、工夫が必要になります。
UpdateIf について
以上、データ取得に関して、3つのアイデアを提示しましたが、データ更新系の UpdateIf について、委任できなく、2000 件問題が発生します。 これも解決したので、2案取り上げます。
RemoveIf も委任できません。
UpdateIf 実装
更新対象テスト値(数値)の範囲のレコードを更新後分類の入力値に書き換えるようにします。
ボタンの OnSelect に以下のように実装して、確認します。
UpdateIf(
datalist,
And(
Value(txt_InputTestValueStart.Text) <= TestValue,
TestValue <= Value(txt_InputTestValueEnd.Text)
),
{Category: txt_NewCategory.Text}
)
datalist
は、接続済み Share Point の 3000 件のリストです。txt_InputTestValueStart
は、更新対象テスト値(数値)の範囲指定最小の値の入力欄です。txt_InputTestValueEnd
は、更新対象テスト値(数値)の範囲指定最大の値の入力欄です。txt_NewCategory
は、分類列を書き換えた後の文字列です。
OK パターン
500 ~ 1000 の分類を XXX
に書き換えてみます。
特に問題なさそうです。
501 レコード書き換えるだけですが、そこそこ時間がかかるため、静止画です。
確認するときのデータの取得処理は、3000 件取得可能にしてあります。
NG パターン1
分類の値は元に戻したとします。
1800 ~ 2300 の分類を XXX
に書き換えてみます。
2001 件目以降が変わっていません!
1800 ~ 2300 を 委任できる関数 Filter で取得する場合、501 件取得のため、取得できます。
UpdateIf でも同じように絞り込んでいるのに 501 件更新できません。
これが、「委任できない」の意味です。
NG パターン2
分類の値は元に戻したとします。
全ての分類を XXX
に書き換えてみます。
OnSelect を以下のように条件を true
として、全てのレコードを対象とします。
UpdateIf(
datalist,
true,
{Category: txt_NewCategory.Text}
)
やっぱり、2001 件目以降が変わっていません!
しかし、安心してください! これを解決する2つの案がありますので、以下やっていきます。
UpdateIf 1
読み込みと同じく、Power Automate のフローを呼び出す方法です。
Power Apps から JSON で更新内容だけ伝えて、Power Automate のフローで、Share Point リストを更新します。
フロー作成
ざっくりと、以下のような内容のフローになります。
トリガー Power Apps
↓JSON の解析
でリクエスト内容を Power Automate の値に落とし込み
↓複数項目の取得
で指定範囲のレコード取得 ※1※2
↓Apply to each
(それぞれに適用する
) でループ ※1
↓項目の更新
で指定 ID のレコードを更新 ※2
↓PowerApps または Flow に応答する
でレスポンス ※3
※1
複数項目の取得
の 上から順に取得 の上限が 5000 件という話もありますが、今回は、3000 件のため、何も考えずに取得しています。解決方法、詳細は、別記事「Power Automate & Share Pointの5000件問題を攻略した」をご覧ください。
(今回は、それに該当しませんが、ライセンス、トリガーによっては、
Apply to each
が 5000 ループを超えるとこけるという話もあります。)
※2
まとめて Share Point リストを更新するアクションが無いため、一件ずつ ID を指定して、更新します。
※3
何も返していませんが、これが無い場合、Power Apps 側に一瞬でレスポンスが返ってしまうため、必要です。
ただし、2分(120 秒)で応答できない場合、タイムアウトします。これは、今回の話題とは関係ないため、見なかったことにします。
参考:
https://powerusers.microsoft.com/t5/Building-Flows/Timeout-on-the-flow/td-p/659983
具体的なフローは、以下です。
+作成 → インスタントクラウド フロー → Power Apps を選択し、作成開始します。
JSON の解析
のスキーマの部分は、以下になります。
{
"type": "object",
"properties": {
"Category": {
"type": "string"
},
"Start": {
"type": "integer"
},
"End": {
"type": "integer"
}
}
}
作ったフローは、有効にしておく必要があります。
Power Apps 側フロー追加
フローを Power Apps で読み込みます。
Power Automate アイコンクリック → +フローの追加 → 先ほどのフロー選択
になります。
Power Apps から呼び出し
ボタンの OnSelect に以下のように実装して、確認します。
UpdateContext(
{
UploadDataJSON: JSON(
{
Start: Value(txt_InputTestValueStart_1.Text),
End: Value(txt_InputTestValueEnd_1.Text),
Category: txt_NewCategory_1.Text
}
)
}
);
'DatalistBulkUpdate-blog'.Run(UploadDataJSON);
DatalistBulkUpdate-blog
は、接続済み Power Automate フローです。txt_InputTestValueStart_1
は、更新対象テスト値(数値)の範囲指定最小の値の入力欄です。txt_InputTestValueEnd_1
は、更新対象テスト値(数値)の範囲指定最大の値の入力欄です。txt_NewCategory_1
は、分類列を書き換えた後の文字列です。UploadDataJSON
は、送信内容の JSON 文字列です
Power Automate フローは、.Run()
で呼び出して、何も受け取らずに更新範囲と更新内容を送信するだけですが、何も受け取らなくても、前述の通り、フローに PowerApps または Flow に応答する
で応答が必要です。
フローの PowerApps または Flow に応答する
から応答があるまでボタンが無効になります。
1800 ~ 2300 更新
動作確認してみます。
UpdateIf も 2000 件の壁を突破しました!
501 レコード書き換えるだけですが、そこそこ時間がかかるため、静止画です。ちなみに、タイムアウトのエラーが表示されましたが、それはそれで複雑な対処が要求されるため、見なかったことにしました。更新には成功していました。Power Automate の実行時間は、約3分でした。
全て更新
1 ~ 3000 すべて更新してみます。
成功しました!
このときもタイムアウトのエラーが表示されましたが、更新には成功していました。Power Automate の実行時間は、約18分でした。
UpdateIf 2
UpdateIf2000 件問題解決2案目です。
この案は設定で解決します。
この案の方が簡単ですが、"試験段階" なのと、3000 件全部書き換えの時にNGでしたので、注意が必要です。
解決方法
設定 → 近日公開の機能 → 試験段階 → UpdateIf と RemoveIf の委任を有効にする を オン
です。
1800 ~ 2300 更新
動作確認してみます。
ここで確認している実装は、NGを確認した Power Automate 未使用の実装のままです。
なんということでしょう。あっけなく、2000 件の壁を突破しました!
実行時間は、数秒でした。
全て更新
2000件超まとめて更新するケースは、動作しません。
1 ~ 3000 すべて更新してみます。
2000 件までしか更新されません!
更新されたときもあったような気がしますが、2000 件超まとめて更新するケースは、Power Automate を使うべきという結論です。
逆に、2001 件目以降のデータも対象として 総件数 2000 件以下をまとめて更新するときは、Power Automate を使用せず、UpdateIf と RemoveIf の委任を有効にする を オン で良いと思います。
まとめると、以下です。
更新データの場所 | 1回の更新件数 | 対処方法 |
---|---|---|
2001 件目以降にある | 2000 件超 | Power Automate のみ |
2001 件目以降にある | 2000 件以下 | Power Automate OR UpdateIf と RemoveIf の委任を有効にする オン※ UpdateIf と RemoveIf の委任を有効にする オンの方がスピードが速い |
2001 件目以降にない | 2000 件超 | あり得ない |
2001 件目以降にない | 2000 件以下 | 何もしなくても UpdateIf で更新可 |
以下です!
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。