ルドルフもわたるふもいろいろあってな

Microsoft 365、Power Platform、PowerShellについて調べたことや検証したことなどを投稿します。技術の話は面白い。

Power Automateを使って既存のSharePointリストをベースに新しいリストを作成する

今回はこの「既存のリストから」ボタンと同じことをPower Automate のフローを使って行います。

フローをGitHubで公開しました。
github.com

今回のフローの元ネタ

今回解説するフローは下記ページを元にしています。解説する内容についても大部分は同じです。
 ※ 一部、配列操作のやりかたを変えている箇所があります。
tomriha.com

フローの概要

SharePoint Online でリストの作成メニューを開くと「既存のリストから」というボタンがあるのが分かります。今回はこの「既存のリストから」ボタンと同じことをPower Automate のフローを使って行います。

そもそも「既存のリストから」からボタンって何?

「既存のリストから」ボタンは名前の通り、既に存在するリストをベースにして新しいリストを作ることを表します。ベースにするリストは、新しいリストを作成するサイトとは別のサイトにあるリストから選択することもできます。

「既存のリストから」ボタンを使ったリストの作成イメージは以下の通りです。

「新規」>「リスト」をクリックします。

「既存のリストから」をクリックします。

ベースにするリストを選択します。

リストの名前を指定して「作成」をクリックします。

作成が完了しました。

既存のリストにあるアイテムはコピーされませんが、列やビューなどのリストの設定は同じであることがわかります。

フローの解説

フロー図

フロー図は以下の通りです。今回のフローは"既存のリストをベースに新しいリストを作成する"仕組みを説明することを目的としたフローです。そのため、トリガーは手動にしています。また、サイトURLやリストURLは変数ではなく各アクションに直接記載しています。

フローを実行

フローを手動で実行します。2秒ほどで処理が完了しました。

リストが作成されました。この動作は先ほどの「既存のリストから」ボタンでリストを作成したときと同じです。

どんな仕組みで「既存のリストから」ボタンと同じことを実現しているのか?

このフローでは「SharePoint に HTTP 要求を送信します」アクションを使って サイト デザインとサイト スクリプトREST API を呼び出しています。
docs.microsoft.com

ベースにするリストを取得:
_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList()

リストを作成:
_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()

ステップごとに解説します。

ステップごとの解説

1. 「SharePoint に HTTP 要求を送信します-コピー元のリストを取得」アクション

これは「SharePoint」>「SharePoint に HTTP 要求を送信します」アクションです。GetSiteScriptFromList() に対してHTTP要求を送り、リストの構成を表すJSONデータを取得します。

取得する対象リストのURLを「ボディ」欄に記載します。

パラメータ:

"inputs": {
"parameters": {
"dataset": "https://<テナント>.sharepoint.com/sites/<サイト>",
"parameters/method": "POST",
"parameters/uri": "_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.GetSiteScriptFromList()",
"parameters/headers": {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose"
},
"parameters/body": "{\n\"listUrl\": \"https://<テナント>.sharepoint.com/sites/<サイト>/Lists/<リスト>/\"\n}"
},
},

APIから取得するJSONデータは以下の通りです。GetSiteScriptFromListというプロパティの値にリストの構成情報が格納されたデータです。
※ データの文字数が多いので画像にしました。

このデータを折り返しをしないで表示すると下図の通りになります。シンプルな構造です。右に向かって果てしなく文字列が続きます。

このデータをそのままリストの作成アクションに渡しても、期待通りにリストは作成されません。リストの作成アクションに必要なのは必要なデータはこのデータの一部です。

具体的には、必要なのはこのプロパティです。

これは「actions」というプロパティです。これがリストの構成情報(正確にはリスト作成処理で行う操作。"リストの作成"や"列の作成"など)を定義したものです。このプロパティの値は配列になっています。
 ※ 下図はAPIから取得したデータを説明のために整形したものです。

この「actions」を以下の書き方でリスト作成のHTTP要求アクションに渡すことでリストの作成が行うことができます。

{"script": "【actions:[操作の配列]】"}

そのために後続のステップでは、APIから取得したJSONデータの整形を行います。

2. JSONデータの整形

これは3つのアクションを使って行います。使用するアクションはいずれも「データ操作」>「作成」です。

アクションごとに解説します。

2-1.「作成-「GetSiteScriptFromList」部分を取得」アクション

このアクションでは、JSONデータの「GetSiteScriptFromList」プロパティの値を取得しています。

この部分です。

この「GetSiteScriptFromList」プロパティの値は、このアクションで取得した時点では文字列データ(string)であることを覚えていてください。

コード:

"inputs": "@body('SharePoint_に_HTTP_要求を送信します-コピー元のリストを取得')?['d']?['GetSiteScriptFromList']",

2-2.「作成 -「$schema」プロパティを削除」アクション

このアクションでは、「GetSiteScriptFromList」の値にあるスキーマ情報を削除しています。この情報はリスト作成アクションの入力情報には不要なためです。

この部分を削除する、ということです。
 ※ 下図は説明のためにデータを整形したものです。

このスキーマ情報の削除のやりかたは 元ネタのブログ とは別の方法で行っています。

元ネタのほうでは、「JSONの解析」→「actions配列の取得」→「actionのプロパティ名のテキストとactions配列を文字列結合」というステップでスキーマ情報を取り除いています。

Power AutomateにはremoveProperty関数を使って指定したプロパティを削除できます。データ整形のステップが少しだけ削減できるので、この関数を使ってスキーマ情報を削除するやりかたに置き換えました。

ポイントはremoveProperty関数を使うために事前準備として、json関数を使用してデータをJSONに変換していることです。


コード:

"inputs": "@removeProperty(json(outputs('作成-「GetSiteScriptFromList」部分を取得')),'$schema')",

2-3.「作成-エスケープシーケンスを追加」

このアクションでは、データをAPIに渡すためにエスケープ文字をいれます。

エスケープする必要がある文字2種類を、replace関数を使ってエスケープ文字をつけた形に置き換えます。

  • 「\」 →「\\」
  • 「”」→「\”」

コード:

"inputs": "@replace(replace(string(outputs('作成_-「$schema」プロパティを削除')),'\\','\\\\'),'\"','\\\"')",

3.「SharePoint に HTTP 要求を送信します -指定したサイトにリストを作成」

これは「SharePoint」>「SharePoint に HTTP 要求を送信します」アクションです。ここまでのステップで整形したデータを ExecuteTemplateScript() に渡します。それによってリストの作成を行います。

コード:

{
"inputs": {
"parameters": {
"dataset": "https://m365x000309.sharepoint.com/sites/DemoCommu",
"parameters/method": "POST",
"parameters/uri": "_api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.ExecuteTemplateScript()",
"parameters/headers": {
"accept": "application/json;odata=verbose",
"content-type": "application/json;odata=verbose"
},
"parameters/body": "{\"script\": \"@{outputs('作成-エスケープシーケンスを追加')}\"}"
},
},
}

そもそも「サイトスクリプト」のAPIを使う方法と「既存のリストから」を使った方法は同じ方法か?

元ネタにさせて頂いたブログを拝見したところ該当する記載があります。ネットワークキャプチャを使って「既存のリストから」を使ったリスト作成の操作を行うと、今回のフローで紹介しているAPIに対して通信を行っているとのことです。そのため、同じ方法と考えてよいと思われます。
tomriha.com

このフローはどんな場面で役にたつのか?

今回のフローでは仕組みの説明のために、ベースとなるリストと作成するリストを1対1にしました。ですが、この方法を使えば「テンプレートを使って複数のサイトに同じ構成のリストを一括作成する」ことが可能です。
リストの自動作成・一括作成を求められるケースは多いと思いますので、選択肢のひとつにいれてみてもよいかと思います。

注意事項

今回挙げたAPIには、新規に作成するリストに引き継げる設定とそうでない設定があります。そのため、運用環境で利用する際には事前に検証を行ってください。
また、この辺りの情報はDocsにも記載があるので参照してください。
docs.microsoft.com

以上です。