Power Automate Desktop CSVの整形

## 概要　　

Excelを介さずPower Automate Desktop（以下PAD)だけでCSVを整形します。[元記事](https://powerusers.microsoft.com/t5/Power-Automate-Desktop/How-to-write-data-in-csv-in-given-format-through-Microsoft-Power/m-p/866451/highlight/true#M2270)は以前コミュニティフォーラムに投稿したものです。日本語環境の問題を加味して加筆しています。

## 今回の作業　　

![010507.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/acf36b96-0f9f-5735-4a24-fabef8850f42.jpeg)

CSV(comma-separated values)はカンマで区切りと改行からならるデータ形式のテキストです。まだまだお目にかかりますが、ケースによっては結構厄介者です。理由はサンプルデータを確認して頂ければと思います。

## 必要な環境および注意点

Power Automate Desktop
Excel（確認用）
メモ帳アプリ（確認用）
2021年4月の情報です。
フローは自己責任で実行してください。

ここに挙げるのはベストプラクティスでもなく、個人の見解としての一例です。
いろいろな方法の中のひとつとして試して頂ければとおもいます。

## サンプルデータの準備

折角なのでPADを実行することでSample.csvを作成します。
データテーブルをハードコードしてCSVに書き込み出力しています。
実行するとデスクトップにSample.csvが作成されます。

データテーブルについては[過去記事](https://qiita.com/sys_zero/items/171d73ba24e123dd1b66)を参照していただければと思います。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/d0a6563a-48c5-2b1a-5511-b4608c474080.png)

```
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.DesktopDirectory SpecialFolderPath=> SpecialFolderPath
SET nan TO $'''%''%'''
SET data TO {['日付', '2021-4-1'], ['名前', '相上夫'], ['---------', '-------------'], ['Total count:', 10], ['count reached.', 5], ['individuals:', 25], ['Information', 'サンプルー２'], ['--------------', nan], [nan, nan], ['日付', '2021-4-5'], ['名前', '柿久家子'], ['---------', '-------------'], ['Total count:', 25], ['count reached.', 2], ['individuals:', 12], ['Information', 'サンプルー６'], ['--------------', nan], [nan, nan], ['日付', '2021-4-6'], ['名前', '指巣施素'], ['---------', '-------------'], ['Total count:', 11], ['count reached.', 22], ['individuals:', 3], ['Information', 'サンプルー７'], ['--------------', nan], [nan, nan] }
File.WriteToCSVFile.WriteCSV VariableToWrite: data CSVFile: $'''%SpecialFolderPath%\\sample.csv''' CsvFileEncoding: File.CSVEncoding.SystemDefault IncludeColumnNames: False IfFileExists: File.IfFileExists.Overwrite ColumnsSeparator: File.CSVColumnsSeparator.SystemDefault
```

フローを実行するとExcelが使える環境下ではデスクトップに次のようにファイルが作成されます。
Excelがインストールされたマシンでは自動的にExcelに関連付けされているかと思います。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ba03cd40-83f1-63a2-9192-bf86b3f1d5a0.png)

~~ダブルクリックでExcelから開くと以下のように文字化けします。~~


![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/a7bd0361-eff2-1a49-b284-4329c329e580.png)

CSVは最初にも述べたようにテキストなので当然文字コードを持っています。CSVは一般的にUTF-8が使われます。
日本語環境のExcelはShift-JISが使われているためそのまま開こうとすると文字化けが起こります。
これを回避するためにはPowerQueryに65001：UTF-8として読み込む必要があります。
EXCELで編集するためにBOM付きUTF-8として保存し直すということも考えられますが以下の理由により却下です。

BOMについて、ウィキペディア[バイト順マーク](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E9%A0%86%E3%83%9E%E3%83%BC%E3%82%AF)から引用いたします。

>BOM（バイトオーダーマーク）についてはUTF-8は文字コードとしてASCIIを前提としたプログラムでもおよそ支障なく動作するように設計されているが、BOMによって正常に処理できなくなる場合がある。Unicodeの規格において、UTF-8においてBOMは容認されるが、必須でも勧められるものでもないとされている[5]。また、データベースやメモリにロードするデータなど、内部的なデータ形式では、プログラムの性能や効率の観点から普通BOMは用いられない。

メモ帳アプリから開くと文字化けなく内容を表示できます。またメモ帳の保存時の通常文字コードはUTF-8になっています。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/daef90e0-98ab-0419-9cc5-d50c93c173d2.png)

前置きが長くなりましたが上記の問題を踏まえてPADの自動化処理の中でPowerQueryを使うのは大変そうだったので、今回のケースではPADに用意されたアクションだけでやってみます。

## フロー作成

今回のフローでは、CSVから読み込んだデータをすべて変数内で処理しCSVに書き込みます。
1度の変形では難しいため2回に分けて目的のデータに整形しています。
「データテーブル列をリストに取得」アクションと「変数を設定」アクションを組み合わせることで変形しています。

![155550.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/5183a02b-7cf0-853f-ade8-41b387bc1b26.jpeg)

![163509.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/3a956d86-bab2-2541-503f-18e39a1f7272.jpeg)


```
Folder.GetSpecialFolder SpecialFolder: Folder.SpecialFolder.DesktopDirectory SpecialFolderPath=> SpecialFolderPath
File.ReadFromCSVFile.ReadCSV CSVFile: $'''%SpecialFolderPath%\\sample.csv''' Encoding: File.CSVEncoding.UTF8 TrimFields: True FirstLineContainsColumnNames: False ColumnsSeparator: File.CSVColumnsSeparator.SystemDefault CSVTable=> CSVTable
Variables.RetrieveDataTableColumnIntoList DataTable: CSVTable ColumnNameOrIndex: 0 ColumnAsList=> ColumnAsList
SET Table1 TO {ColumnAsList[:8] }
Variables.RetrieveDataTableColumnIntoList DataTable: CSVTable ColumnNameOrIndex: 1 ColumnAsList=> ColumnAsList2
SET DataCount TO 0
LOOP LoopIndex FROM 8 TO ColumnAsList.Count STEP 9
    SET Data TO ColumnAsList2[DataCount:LoopIndex]
    Variables.IncreaseVariable Value: DataCount IncrementValue: 9 IncreasedValue=> DataCount
    SET Table1 TO Table1 + Data
END
Variables.RetrieveDataTableColumnIntoList DataTable: Table1 ColumnNameOrIndex: 0 ColumnAsList=> ColumnAsList3
SET Table2 TO {ColumnAsList3 }
LOOP LoopIndex2 FROM 1 TO Table1.Columns.Count - 1 STEP 1
    Variables.RetrieveDataTableColumnIntoList DataTable: Table1 ColumnNameOrIndex: LoopIndex2 ColumnAsList=> ColumnAsList4
    SET Table2 TO Table2 + ColumnAsList4
END
File.WriteToCSVFile.WriteCSV VariableToWrite: Table2 CSVFile: $'''%SpecialFolderPath%\\output.csv''' CsvFileEncoding: File.CSVEncoding.UTF8 IncludeColumnNames: False IfFileExists: File.IfFileExists.Overwrite ColumnsSeparator: File.CSVColumnsSeparator.SystemDefault
```

## まとめ

データの複雑さよるとは思いますがPADの基本機能だけでCSVの整形ができました。
Excel操作を介さずに実行できるため文字コードの問題をクリアできます。
そこまで多くないデータ量であれば他のフローに組み合わせて自動化できそうです。

大量データの場合、速度は期待できません。
そのような場合はやはりPower QueryやPandasでの処理になるかと思います。

## 参考、引用

ウィキペディア[バイト順マーク](https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E9%A0%86%E3%83%9E%E3%83%BC%E3%82%AF)