#PowerApps アプリ経由のみSharePointリストに投稿・更新できるようにする

# 概要
- SharePointリストの更新権限は管理者のみとし、利用者はアプリ経由でしか更新できない仕組みを作る方法です。
- 今回は最近登場したPowerAppsV2トリガーを使って簡単に実装します。
- 承認フローなどで承認後のアイテム(添付ファイル含)は編集してほしくないといった場合に利用可能です。
<br>

以前はPowerAppsトリガーと子フローを使って実現する方法がありましたが、
ソリューションの利用が必要で、組織によっては利用できなかったりしました。

# 方法

## SharePointの設定
リストの詳細設定で編集のアクセス権をなしに設定しておきます。
これでサイトのメンバーであっても書き込みはできなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ed2a47bc-0659-3e35-02f7-ba1193204ae4.png)

今回のAutomateフローの管理者は、リストの管理者となりフルコントロール権限を付与されている必要があります。
※フルコントロール権限では以下の権限により上記の編集不可設定を無視できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/69888a84-51e6-266b-7393-1236f9350d88.png) 

## Power Automateの設定
PowerAppsV2トリガーを使ったインスタントフローを作成します。
PowerAppsから入力したいフィールドに合わせ、入力パラメータを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/fadb201f-9345-81bb-1bea-4477cf93c008.png)

※仕様上1フィールドずつパラメータを設定します。
今回は既存レコードの更新(編集)として3つのパラメータを設定しました。
「Title」、「添付ファイル(File)」、「レコードID(Id)」

SharePointの既存のアイテムを更新する場合は、以下のように行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/bddcffd0-d98e-ab0c-87d4-369829f89acc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/66940b8c-64c9-c085-673a-cf77a72c8c44.png)
新規アイテムを投稿する場合は、Idが空かどうか判定して、アイテムの作成アクションを使います。


次に、フロー詳細画面から「使用する接続」の設定を編集し、この接続(所有者)を使用するように設定します。
これで誰がPowerAppsを使用しても、Automate内では所有者の接続情報を使用してアクションを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/02ecfb66-c399-77dd-7571-5827d6904e85.png)
接続設定の開き方→https://docs.microsoft.com/ja-jp/power-automate/create-team-flows

所有者の権限を利用するため、SharePoint側で編集制限をかけていても制限を無視して書き込み可能です。
ただし、SharePointリストの登録者/更新者列がフロー所有者の情報になるため、必要に応じて任意の列にフロー実行者名を格納します。
※Office365ユーザーの取得などを利用し、接続情報は実行者の情報とします。

ちなみに、以前のPowerApps(V1)トリガーではこの設定がなく、強制的にアプリ利用者の接続情報を使用されていました。

## Power Appsの設定
SharePointリストをもとに適当なアプリを作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/0cb5413f-1d05-490c-bebc-d0a789ed4831.png)

入力フォームを作成し、以下のように登録ボタンからPower Automateを呼び出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/56c379c3-d548-70ed-3bf0-5c707786bffd.png)

※オプション引数は{paramName:Value}で指定
※添付ファイルは{name:fileName, contentBytes:fileValue}のスキーマで指定。


以上でアプリ経由でのみリストを更新可能な仕組みの完成です。
ドキュメントライブラリでも同様の方法で対応可能だと思います。


# 複数フィールドを一括送信したい
上記の方法では、フォームコントロールのSubmitForm関数が使えないので、入力項目が増えると大変です。
そこで、フォームのFrom.Updatesプロパティをつかってフィールドの内容を一括送信します。

## PowerAppsの設定

SharePointリストをデータソースとして以下のようなフォームを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/7c1e4d4f-7c58-b11f-6c2b-fe0333314e62.png)

保存ボタンは以下のように設定します。
これにより、レコードの内容をテキスト形式でAutomateフローに送信します。

```JavaScript
//フォームのUpdatesをjsonに変換してフローに渡す
ClearCollect(colUpdates,Form1.Updates);
With(
    {_json:JSON(colUpdates,JSONFormat.IgnoreBinaryData)},
    //[]を削除してレコードとして送信
    UpdateListsItem.Run(First(Match(_json,"^\[(.+)\]$").SubMatches).Value)
);
Notify("登録が完了しました。");
Back();

```

## 解説
Form.Updatesプロパティにより入力内容をレコード型として取得可能です。
ただし、そのままではAutomateに送信できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/ba55f5ab-8609-52a4-e08f-86181a3b5ad2.png)

json関数を使うとレコード型をテキストに変換できますが、仕様上コレクション型しか受け付けません。
よって、一旦コレクションにセットしています。
```ClearCollect(colUpdates,Form1.Updates);```

その後json関数でテキスト化します。
ただし、戻り値は[]で囲われた配列スキーマとなります。
Automate側での処理を簡単にするため正規表現をつかって[]の内側だけ取り出します。
```UpdateListsItem.Run(First(Match(_json,"^\[(.+)\]$").SubMatches).Value)```

すると、以下のようなレコード型のJSONができあがります。

```JSON
{"ApprovalDate":"2022-01-03","ApprovalRoute":{"Id":1,"Value":"マネージャー"},"SenderName":"自動入力されます\naa","Title":"Items"}
```


## Power Automateの設定

PowerAppsV2トリガーとし、入力パラメータとしてUpdatesのレコードを受け取れるよう設定します。
添付ファイルは含まれないので任意でパラメータを追加してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/c5e732ee-39b0-5e2a-f89d-3da29209e3bc.png)

次に、Updatesの内容を扱いやすくするためJSONの解析を行います。
スキーマは一旦テスト実行してトリガーの出力を確認し、サンプルから作成に貼り付けて生成すると良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/bd091d4b-9af0-2bbd-8fc8-243a16da4af6.png)

ここで注意点ですが、PowerApps側でフィールドを未入力にしてしまうとjsonの値が「null」となり、jsonの解析でエラーとなっていまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/80690dfd-d75c-6d4d-993b-865036db84b1.png)

nullを許容したいフィールドは、スキーマを手動で編集し以下のようにtypeにnullを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/e28507de-9820-7a39-e6de-68e80ce6b2b1.png)

最後に、JSONの解析の出力からフィールドを選択しSharePointにセットしていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293667/1a8d5f23-ecc9-8062-705c-cbc2178def9c.png)

参照列や選択肢列はIdやValuueをセットします。選択ミスに注意です。


# あとがき
SharePointリストを使って添付ファイルを管理する場合、利用者に編集権限があると、ファイルを開いただけで意図せず編集されてしまったりして厄介です。
登録は利用者が行い登録後の編集はさせたくないといった場合はこのような方法が有効かと思います。

# 参考
ソリューションと子フローを使った方法は以下の記事で詳しく解説されています。

https://qiita.com/miu200521358/items/39381a41c73210200b15