Power AutomateでCSVファイルがSPO上に置かれたら中身を取得するクラウドフロー

## この記事で助かる人
SharePoint OnlineにCSVファイルがアップロードされたことをトリガーにして何かしたい人

## ポイント
+ ファイルのアップロードの検知には、「ファイルが作成されたとき」または「項目が作成された時」が使える
+ CSVファイルをクラウドフロー内にとりこむには「ファイルコンテンツの取得」または「パスによるファイルコンテンツの取得」が使える
+ CSVファイルは、初期化したテキスト変数の値に設定すると、そのまま文字列として扱える

## この記事を書いている人
お仕事でPower Automateを使っていて、この記事は備忘録も兼ねてます。ブログにて、 [クラウドフローのTIPSのようなもの](https://mocabrown.com/blog) を作っていますので、そちらも使ってもらえると嬉しいです。

## 準備
ファイルのアップロードを待ち受けるために、任意のSharePointサイトのドキュメントライブラリに、適当なフォルダを作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/3ddfd89f-cb14-bcdd-4f7d-ddb5d27374b6.png)

テスト用のCSVファイルも用意します。テキストエディタを使って適当なものを用意すれば良いでしょう。今回はこんなものを使いました。
```csv:test.csv
aaa,bbb
111,222
333,444
```
## 方法１　「ファイルが追加されたとき」をトリガーにする
ShaerPointの項目の中で「ファイル」というキーワードで検索してみると、非推奨も含めていくつか見つかります。　まずは、「ファイルが作成されたとき（プロパティのみ）」というのがあるので、これを使ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/f7814e9c-7a27-a5ac-a48c-407e8efd5345.png)

サイトアドレスとファイルを放り込むフォルダを指定します。結果を確認するために、「作成」の中にトリガーで得られた内容を入れておきます。準備ができたら、手動テストをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/21f8e897-3f08-d0ce-3958-352817ef6a7e.png)

トリガーなので、実際に先ほど指定したフォルダに、用意したCSVファイルをアップロードしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/1365f499-6b3c-c056-637d-4934ec9cc744.png)

CSVファイルが指定されたフォルダに入ったことで、クラウドフローが動作しました。ファイルの場所とファイル名がFullPathの項目で取れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/29ec947d-c93c-1238-f3ee-189b49fb3579.png)

## その２「項目が作成されたとき」をトリガーにする
その１のトリガーで動作すれば問題ないのですが、なぜか私が過去何回か同じようなトリガーを使った時に、うまくファイルの追加を検知してくれないという事がありました。
SharePointのフォルダ内に入っているファイルの情報というのは、内部ではSharePointリストを使って管理されています。そのため、リストに項目が追加されたことを検知する方法でも、ファイルが増えたことを検知してトリガーとして使うことができます。

SharePoint上のフォルダをリストとして扱うには、リストのIDが必要です。このIDの取得の方法は、別の記事　[【SharePoint Onlineでサイトページからページ一覧を取得するために管理しているリストのIDを取得したい】](https://qiita.com/DaddyDaddy/items/1918c4fcd68ae93546e7) で紹介しましたので、そちらを参考にしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/b348f9a6-b651-34df-8fe3-538cef21bea5.png)

その１と同じようにファイルのフルパスが取得できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/cb684b6e-21e5-b2f7-2950-84623ecd71aa.png)

## アップロードされたフィイル自体を取得する
アップロードされたことを検知してトリガーを使ったクラウドフローの自動起動ができましたので、今度は実際にアップロードされたファイルの中身を利用するために、クラウドフロー内にファイルを取り込む処理を作ります。

そのためには、「ファイル　コンテンツの取得」アクションを使います。トリガーで取得できた情報の中から、識別子として選択するのがポイントです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/6717dc49-2d60-02e7-418f-3c23829a3b36.png)

ちなみに、別の方法として、「パスによるファイルコンテンツの取得」アクションを使うこともできます。使い方はほとんど同じですが、こちらの場合は「完全パス」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/a351e090-278b-2fd8-e901-2d8622f69829.png)

## CSVを行ごとに処理する
CSVファイルを１行ごとに処理していくには、１行をひとつの配列にしておく必要があります。配列ならばとループ処理をつかって順番に１行ずつ処理ができるようになります。

まず文字列の変数に取得したファイルコンテンツをいれてやります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/15ae75a8-bd19-3c93-b8c8-fdaa72095a76.png)

ファイルの中身がテキストとして取得できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/0244d0b2-2149-7bb6-1a97-6d0bd77554b1.png)

CSVファイルの１行は改行を区切りとしています。区切り文字を指定してテキストファイルを配列にするにはSplit関数をつかいます。
あらかじめ、文字列変数を初期化して、値の中でいちどエンターキーを押します。こうすることで改行コードを変数として再利用ができます。
```
split(variables('CSVファイル'),variables('改行'))
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/af719136-e828-1ac9-0529-d7ab35a2171d.png)


これで実行してみると、各行を１つの配列として取得する事ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/4e0fe249-c80f-fd90-b186-2c9d0b3d4b02.png)

## ループで１行ずつ処理する
１行ごとに１要素の配列にすることができたので、あとはこれをループで回して、取り出したい部分を指定すればよいだけです。
各行は、「,」カンマ区切りで列が表現されているので、こちらもSplit関数を使って配列にしてやります。

ためしに、「作成」をつかって以下の式を実行してみます。

```
 split(item(),',')
 ```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/dd15ad7a-e473-a6da-0da8-d4eedde78c7a.png)

 テスト実行すると、各行の要素がSplit関数によってさらに列として配列に分かれました。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/e5add864-7a81-efea-f44c-406385876c4a.png)

## ヘッダー行は無視する
ここで、aaa,bbb という先頭行はヘッダー（タイトル）なので無視したいです。こういう時にはカウンターと条件を加えましょう。カウンターがゼロの時には処理を行わず、カウンターがゼロ以上ならば動作をさせます。

ループの手前でカウンターを整数の変数として初期化しておきます。値は0にします。

ループのなかでは、このカウンターが0の時には何もしないことで、ヘッダー部分を無視する事ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/c56593d3-3218-0dc5-564b-3bff72face5a.png)

もうひとつのポイントは、CSVのなかの値を取得する部分です。Split関数でカンマ区切りで分けられた値は配列の各要素に入っていますから、１番目（１列目）には[0]、２番目（２列目）には[1]というように添え字をつけてやることで、配列から値を取り出せます。
 ```
 split(item(),',')[0]
 ```


 実行してみるとこんな感じになります。作成２のところには上記の関数が入っているので、ループの２回目には２行目1列目の「111」という値が取れました。配列からの値の取得の方法がわかっていれば、あとはリストやDataverse、Excelファイルなどで書き込むなり処理するなり自由に使えます。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/8eabac76-d977-cdd7-49d0-008a42d0c371.png)
  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/0419de63-3c6f-01e5-fcc9-7e562052bc78.png)

## おわりに
ファイルの取り込みは、トリガーで取得したファイルの場所を使う必要があることと、取得したファイルはそのままテキスト文字列として変数の中で扱えるのがポイントでした。

これがわかるまで、CSVを敬遠していました。さまざまなログはCSVで提供されることが多いので応用範囲は大きいのかと思います。ループは動作が遅いので、この辺りもう一工夫できそうですが、それはまた別の機会に。