PowerAppsで1万件を超えるデータを扱うときの動作を調べてみた

#概要
SharePointリストをデータソースとするアプリでレコード数が増えた場合の動作について気になったので調べてみました。

#準備
PowerShellとPnPを使ってSharePointに1万件を超えるデータを登録しました。
※大量に登録するならCSOMを使った方がいいようです。　PnPだと一件ずつとなり1件1～2秒、完了するのに数時間かかりました😂
上記をデータソースとするキャンパスアプリを作成しました。
複数のレコードを使用するギャラリーやコンボボックスといったコントロールを配置して動作を調べます。

#コントロール別の動作

##ギャラリーコントロール
+ ギャラリーコントロールのソースに上記のリストを指定
+ データ表示、検索などが正常に動作するか検証

###動作確認
+ `CountRows(Gallery1.AllItems)`でギャラリーの行数を確認すると、最初は先頭の100件のみが取得される。
+ スクロールしていくと次の100件が取得が取得され表示される(無限スクロールのような動作)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/32c6fb15-88e9-988d-6c0b-15c7f5538382.png)

+ ただし差分の100件のみを取得している訳ではなく、APIに対してはTopNの形で先頭データから再要求されている。つまり1000件なら1000件分のデータが取得される。
+ どこまでいけるか確認した結果、5000件でエラーが表示されそれ以上読み込みできませんでした。(SharePoint側の制限) 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/8dc58770-9aa0-fee3-3c1a-a55a89a8a6dc.png)

+ 委任さえできれば1万件を超えるデータでもフィルター可能でした。
　なので委任で少数データに絞り込めるようにさえしていれば、データが万単位に増えても問題なさそうです。
 ※委任できるデータ型と関数は次のページにまとめられています。
 [Connector reference SharePoint](https://docs.microsoft.com/en-us/connectors/sharepointonline/)
+ ただし検索ワードをテキストボックスにバインドし、StartWithで検索すると文字入力がもたついたので、検索ボタンで検索開始するようにしたほうが良かったです。

##ギャラリーの中の画像コントロール
ついでに、ギャラリーの中に画像コントロールを配置しImageに`First(Thisitem.添付ファイル).Value`を設定し、その動作も確認してみました。

###動作確認
+ ギャラリーを表示又はスクロールした際、レコード1件1件にAPI要求され、取得した画像はblobに格納される。こちらはスクロール時差分の100件のみ要求。
+ スクロールを続けると短時間にAPIコールしすぎ途中429エラーも発生。
 　https://docs.microsoft.com/ja-jp/azure/logic-apps/handle-throttling-problems-429-errors
+ 画像コントロールのImageは添付ファイルの有無に関わらずAPIコールされるので、Imageに設定する関数は、以下のように添付ファイルの有無を確認し、添付がある場合のみ取得するようにしたほうが良いと思いました。
 
```
If(ThisItem.添付ファイルあり,First(ThisItem.添付ファイル).Value)
```
※PCだと添付ファイルのAbsoluteUriを指定してもいいのですが、APIを介さないため認証できないのか、スマホやTeamsからだと画像が表示されなかったのでValueを指定しています。

##コンボボックス
- SharePointの参照列を使って親子関係のあるデータを扱うときの話です。
- 参照列を含むリスト(子テーブル)のEditFormを作成したとき、参照列のフィールドは自動的にコンボボックスが生成されます。
- 参照先のテーブル(親テーブル、又はマスター)が1万件を超えている場合の動作を確認してみました。
- テーブル同士の紐付けを数値列でやる場合は関係ありません。

###準備 
- 先程の1万件超のリストを親テーブルとする小テーブルを追加作成、参照列をとして親テーブルのID列を参照する形にしました。(一対多の関係)
- 検証アプリでは、親テーブル(左のギャラリー)をクリックしたときに、紐づく子テーブルのレコードが表示されるようにしました。(右のギャラリー)
- そして、＋アイコンで新規登録画面である子テーブルのEditFormに移動します。参照列は自動的にコンボボックスとして生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/b8317e83-a804-d941-c93d-421fe13d9403.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/2cb03cda-0eca-5f8b-ad0c-919ec94ed4d3.png)

###動作確認
+ 参照列をコンボボックスで表示する場合、下記のようなエラーが発生しました。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/972d0f11-4fb8-7ca3-86f0-3e375dc7fbef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/60014bc2-5e25-aa1b-aac1-70d3bd04d2c7.png)

###対応方法
+ EditFormのDataCardからコンボボックスを削除しテキストボックスに変更します。名前を「TextInput_ParentId」としてDefaultにGallery_Parent.Selected.Id(親ギャラリーのID)を設定。
+ DataCardのUpdadeに以下のおまじないを入力(参照列は{ID:id , Value:value}のオブジェクト)

```
{  
   '@odata.type' : "#Microsoft.Azure.Connectors.SharePoint.SPListExpandedReference",  
   Id:TextInput_ParentId.Text,  
   Value:TextInput_ParentId.Text
}
```
参照列の参照列は親テーブルのIDにしているので、IDもValueも同じものを指定します。
コンボボックスによる選択はできませんが、これで親テーブルに紐づくデータを登録できます。

###参考
- 検証アプリの右のギャラリーのItemsは`Filter(ChildTable, ParentId.Value = Text(Gallery_Parent.Selected.Id))`です。
- 参照列のIdは委任できませんが参照列.Valueだと委任可能です。
- 親テーブルの参照は参照列ではなく数値列でやってもいいのですが、参照列にすることで親テーブルのキー列以外の情報も表示できるので便利です。 


##DataTable
簡単にしか検証してませんが
- ギャラリーコントロールとは異なり500件ごとに取得される。 
- こちらは差分の500件のみ取得される。
- 多分5000件以上スクロールできるが、5000件間近でメモリ不足によりフリーズ

# 自分の勘違いとおぼえ書き
この検証をやるまで色々勘違いをしていましたので覚え書きです。
・ギャラリーコントロールは500件又は2000件までしか表示できない→5000件までいける
・SharePointが2000件を超えると、委任しても先頭2000件のデータしか利用できない→1万件でもそれ以上でも(多分)委任さえできれば利用できる。
・テキスト列は委任できない→一行テキストなら委任可能。=やStartWithで委任可能。
・画像コントロールのImageは添付ファイルがある場合だけリクエストされる→添付があるかに関わらずリクエストされる。

#参考情報
今回の検証は以下の動画を参考にさせていただきました。
https://www.youtube.com/watch?v=X99bx3vOEWM&feature=emb_logo
https://www.youtube.com/watch?v=UaBmVUQx_Fk&t=1426s