2020年4月 3日 (金)

[Power Automate] SharePoint リストアイテムの一括コピー

Power Automate を使ってリスト内のアイテムを一気に他のリストに移動させたいということもあります。しかし、残念なことに、SharePoint Designer で開発するワークフローには存在していた「アイテムのコピー」というアクションは SharePoint コネクターにはありません。

一つ断っておくとすると、SharePoint Designer での開発はサイトを越えた処理は基本的にはできず、SharePoint REST API を使うなどしていましたので、もともとそう高機能だったというわけでもありません。

話を戻しましょう。

Power Automate の場合は元のアイテムのデータをもとに新しいリストにアイテムを新規に作成するという、コピー作成を行うことになります。「移動」にしたければ最後にアイテムを削除すればよい。

まずは機能検証するためにコピーまでとし、元のリストアイテムの削除はしません。これを実現する最も手軽な方法は、次の SharePoint コネクターのアクションを使うことです。

  • 複数の項目の取得 (Get items)
  • 項目の作成 (Create an item)

さて、複数のアイテムがあるのでこれを一気にコピーしたいのですが、とりあえず手動でフローをトリガーしてやることにします。処理が終わったらMicrosoft Teams にチャットメッセージを投稿するようにします。以上を踏まえると以下のようなフローの組み立てがシンプルです。

Bulk List Item Copy 1

さて、フローをテスト実行し、手動開始してみます。今回、元のリストには1,000件以上のアイテムがあります。が、試すと Apply to each では 100件までしか処理していないことが分かります。

Bulk List Item Copy 2

さて、なぜこうなっているのか? 

昔から SharePoint の一括操作(バルク処理)は100がしきい値というのはおなじみのところであり、SharePoint の API もクエリを使って取得するデータの上限は既定値が 100 というのもよくある話。さて、これはどこの設定が関わっているのか確認してみましょう。

先ほどの「複数の項目の取得」の詳細オプションを確認すると「上から順に取得」という項目あります。英語だと Top Count という項目です(英語の方が分かりやすい...)。SharePoint の開発をしたことのある方なら、ここでピンとくるかもしれません。これが要はREST API の引数の $top に当たるわけです。これが既定値のままだと、100アイテムを取得するという既定の動作となるのです。

Bulk List Item Copy 3

この値を2000ほどに変更しておくと、今度は1,000件以上のアイテムが取得できました。

Bulk List Item Copy 6

なお、「上から順に取得」で指定できる上限は SharePoint は一度の呼び出しで最大  5,000までしか取得できません。

そして このアクションのあとに Apply to each を使用しますが、 Office 365 およびフリーのライセンスでは5,000までしか対応していません。これ以上の値を指定したい場合は Power Automate per flow または per user (もしくは Plan2 か Plan1)が必要になります。有料プランであれば上限は100,000 になります。

このことについては詳しくは下記に記載されているので一度目を通しておきましょう。

さて、5,000以上指定したい場合は、上記のライセンスを持っているのであれば、「複数の項目の取得」アクションの設定から、改ページ (Pagination) のしきい値をたとえば20,000などに指定します。

Bulk List Item Copy 4

Bulk List Item Copy 5

改ページをオンにすることで、しきい値の指定がなければすべてのアイテムを、もしくはしきい値があればその値に達するまで呼び出しを続けるようになります。「改ページ(Pagination)」に関しては次のブログに記載されています。

Do Until の利用

ところで Power Automate per user や per flow などの有料プランを持っていない場合に対処方法はあるのか?

Do Until を使う方法であれば、これをクリアできそうです。たとえば、上限である5,000アイテムずつ繰り返し取得して行くというアプローチが取れるようになります。ただし、フローは若干、複雑になります。

まず変数の準備。次のように変数を用意します。

Bulk List Item Copy 7

次に Do Until を挿入します。条件は ItemEmpty が true になるまで。

あとはこのコンテナの中に「複数の項目の取得」アクションと「項目の作成」アクションを挿入します。

Bulk List Item Copy 8

「複数の項目の取得」アクションの設定で改ページをオンにします。しきい値は5,000にしておきます。

Bulk List Item Copy 9

また「複数の項目の取得」アクションのフィルター条件に TargetItemID の値以上を指定します。

Bulk List Item Copy 10

Do Until コンテナ内の処理の続きとして条件を指定します。

Bulk List Item Copy 11

条件は「empty(body('複数の項目の取得')?['value'])」が true です。

「はい」のときは ItemEmpty を true に設定し、「いいえ」のときは TargetItemIDの値に「複数の項目の取得」アクションで取得した最後のIDを格納します。式は次の通り。

last(body('複数の項目の取得')?['value']).id

このIDを使ってスライディングウィンドウを作るイメージです。

全体像は次の通りです。

Bulk List Item Copy 12

謝辞および参考資料

Power Automate を使って SharePoint のアイテムを一括で処理するところで悩んでいたところ、それを Twitter でつぶやいたら Yellow11(@br_Yellow11) さんが助け舟を出してくださいました! 

Do Until の利用か! なるほど、と思い、いろいろと調べていたところ、細かいところが分かったので、忘れないうちに記事にしようと思い立ったわけです。

また、海外の方が書かれている下記の記事も見つけることもでき、これを含めて今回の日本語の記事にまとめました。

How to get more than 5000 items from SharePoint Online in Flow

皆さんのおかげです

Pay it forward !!

コメント

リストの添付ファイルをコピーしたくて、
https://powerusers.microsoft.com/t5/General-Power-Automate/Copy-attachments-from-one-SharePoint-list-to-another-list/td-p/90247
参考に別のリストにコピーする方法は、うまくいきました
ところが、同じ様に、
https://piyushksingh.com/2020/07/17/power-automate-copy-sharepoint-list-attachments/
を参考にして、添付ファイルをドキュメントライブラリに保存しようとすると、殆どのファイルは成功するのですが一部、ファイルはできているのですが、0kByteになってしまって、失敗するファイルがあるのです
PowerAutoateの結果から、失敗を追いかけていくと、書き込みに失敗しているのがわかるのですが、成功しているファイルと失敗しているファイルの何が違うのかがよくわかりません。確かにファイル名に半角カナとか【】とか「」などが入っていたり、中国語の漢字が入っていたりするのですが、リストのコピーはできているので、何が違うのかと・・・
Microsoftに問い合わせた方が良いでしょうか?
何かわかればお願いします。

o0_0oさん、

参考にしたという資料を見ましたが、配列変数に追加しているのはメールにファイル添付したいからなので、添付ファイルをライブラリに作成したいなら、SharePoint コネクターの「ファイルの作成」アクションを使ってみてはいかがでしょうか?
といっても、もともとの手順で失敗するというは、添付ファイルがメールに添付できない可能性があるわけで、それはそれで問題ですね。
私の方では、この例の経験はないので、まずは LogicFlow-ja コミュニティでもっと広い範囲で問題を共有してみてはいかがでしょうか? もしかしたらヒントが見つかるかもしれません。「https://www.facebook.com/groups/logicflowja/

ありがとうございました。
後半は、メールに添付していますが、前半は、Create Fileでファイルを作成しています。
ここまでを、参考にさせていただいたのですが・・・
古いバージョンののSharepointから、オンラインへとコピーにコピーを重ねたものであるため、どこかで、ファイルが壊れたのかもしれません。
とりあえず、エラーの分だけ、手動でコピーしたので、とりあえずは、大丈夫です。
(項目は、1000近くあり、そのうち添付ファイルがあった項目が、650以上ありましたが、エラーは70程度でしたので、全部を手動でコピーするよりは、効率よくできました)

一応、添付ファイルのフォルダのコピーが、以前のバージョン同様に可能なことは、https://www.sharepointdiary.com/2017/01/sharepoint-online-download-attachments-from-list-using-powershell.html
より、確認していたのですが、番号のフォルダでは内容がよくわからないので、リストのTitleをフォルダ名にして保存したいということで、Power Automateを使いました。
フォルダ名、ファイル名までは、コピーできていたので、それほど手間なく、エラー分だけ、コピーできました。

はじめまして。
投稿内容を参考に、Arrayへ保存することができました。
そのあと、CSVへ出力したいと思い、「CSVデータ作成」のコネクタを使用したのですが、
Arrayの項目を出力する方法がわかりません。
(詳細項目を指定しない場合、全項目をCSV出力できます)
お判りになりましたら、ご教授ください。

---------設定内容----------
ヘッダー  値
社員番号  outputs('JoinArrayをラップする')?['OData__x65e5__x4ed8_'])

-------エラー内容-----------
列の値を評価できませんでした: 'プロパティ 'OData__x65e5__x4ed8_' を選択できないため、テンプレート言語式 'outputs('JoinArrayをラップする')?['OData__x65e5__x4ed8_']' を評価できません。整数インデックスを使用して選択できるのは、アレイ要素のみです。

makimakimaさん

記事の内容を参考にしていただいたのですね。
ただ、申し訳ないのですが、あくまでも個人的に共有したいと思ったときに書いているブログでして、
簡単にお答えできそうだとか記事に誤りがあるとかというご指摘であれば、仕事やプライベートの合間を縫って対応することもあるのですが、基本的には個別の課題解決は致しかねますのでご了承ください。