Power Automate for desktop「CSVファイルのデータテーブルをSQLで操作する方法」

## 概要

「CSVファイルのデータテーブルをSQLで扱いたい」といった質問をPower Automate for desktopのフォーラムで何度となく見かけました。しかし明確な解決方法が書かれていることを見たことがありません。Learnには[「CSV ファイルを Excel スプレッドシートに変換」](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/how-to/convert-csv-excel)記述と[「Excel ファイルで SQL クエリを実行する」](https://learn.microsoft.com/ja-jp/power-automate/desktop-flows/how-to/sql-queries-excel)がありますがCSVのファイルのデータテーブルを直接SQL操作する記述はありません。私自身もPowerShellを使って処理していました。カスタムアクション作ろうかと思ったのですが、その前にもう一度検証したところODBCドライバ経由で普通に操作できるではないですか。そこで今回はデータベースアクションでCSVファイルのデータテーブルをSQL操作する方法を紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/751eb2d4-325b-4880-b084-5e2324982fcb.png)


## 注意事項、実行環境

- 2023年5現在、Power Automate for desktopのLearnでは見当たらないで内容ですので自己責任でお願いいたします。
- そもそも暗黙知レベルでしたらごめんなさい。
- 様々な条件を検証していないので、試した方はレスで教えていただけたら嬉しいです。
- Windows 11 Home 22H2
- Powwer Automate for desktop 2.32.111.23124　インストール版
- Microsoft 365 開発者プログラム

## 重要なポイント

**対象CSVを開いたままだとエラーになります。フローを動かすときは必ず閉じておく必要があります。**

## 検証１SELECT WHEREなどフィルター処理

1. サンプルデータを用意します。今回はKaggleの[winemag-data_first150k.csv](https://www.kaggle.com/datasets/zynicide/wine-reviews?resource=download)で検証しました。任意で用意して頂ければと思います。私の用途では15万行くらい動けば問題ないのでこのデータをお借りして試しました。
1. ドキュメントフォルダーに「SampleCSV」フォルダーを作成し格納します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/a81d0155-2365-fe4f-e25f-c398957d4ef2.png)

1. [winemag-data_first150k.csv](https://www.kaggle.com/datasets/zynicide/wine-reviews?resource=download)のコピーを作成しファイル名から記号を削除したものを用意します。理由は後述。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/da9d4e4f-74fa-c03b-fc0d-ca7097decd38.png)

1. フローを作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/757b8184-d70f-a5f9-5e8e-a066b8d3f9fa.png)

1. 「SQL接続を開く」アクションで接続文字列を作成します。「Microsoft OLE Provider for ODBC Drivers]を選択して「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/3d914b78-5153-143e-556b-c98e436f61ec.png)
1. データリンクプロパティが開いたら「接続文字列使用する」を選択し「ビルド」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/f9df5b8f-23ac-1881-9398-e4c6505b131f.png)
1. 先ほどの「SampleCSV」フォルダーを指定して新規作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/1b8694ee-6a1e-02cf-9b9f-842ef2e8cad9.png)
 Microsoft Access Text Driver(*.txt,*.csv)を選択して「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/f0d20a26-5bff-02c1-681e-87edbef92fd0.png)

1. データソースの新規作成で適宜「参照」から適宜名前を付けて「保存」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ec1fd196-3562-a7da-e6b6-920785ab2d94.png)
1. 「次へ」で進み完了を押して詳細を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/7c38acdc-d01b-e253-b125-c9e24b241fb3.png)

1. オプションを展開します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ede1738f-d707-ce4f-eb5e-3f6b1df6848b.png)
1. 「現在のフォルダーを使用する」のチェックを**外し**CSVを格納するフォルダーを指定します。今回は「SampleCSV」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/580aa273-f7d6-a490-fc64-c27b10616589.png)

1. 「書式の定義」に移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/076be0aa-1ad4-036a-d849-351f57cd810a.png)
1. CSVに合わせて各項目を変更しておきます。SHIFT-JISの場合はANSIを選ばないと文字化けします。今回は列名の見出しがあるのでチェックを付け、日本語でないのでOEMにしました。推量をクリックすると列データの型が推察されるようです。なおデフォルトはANSIで列名の見出しにチェックを付けました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/0f00c877-b581-b8dd-2594-bbb1fe974c87.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/350a3b88-52bb-b028-df9b-9f47ddf921d6.png)
1. 接続文字列が入っているのが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/85518447-66a9-1bb8-59a5-6a807958d95c.png)
1. OKで進むと「SQLを開く」アクションに接続文字列が記述されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/a9b5c928-dd40-78ed-168e-5d7a9c7d04f7.png)
1. 「SQLステートメントの実行」アクションに記述してみます。少しデータが多いので列と行をフィルター次のようにフィルターしました。FROM節でCSV名を指定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ee9c595b-843b-d35e-dcbe-9824affdde0a.png)
1. 「SQL接続を閉じる」アクションで接続を閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/66ec65c0-834f-9d2e-92b7-bef516f7caf3.png)
1. 動作確認します。うまく動作しそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/2ef4e873-e77e-90aa-672d-5175d1c5c5d7.png)
1. 記号付きのCSVを試してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/c832059e-c390-8f05-123d-bba3219946c6.png)
1. ファイル名に記号（－）が含まれるとエラーになりました。（アンダーバー「_」）だけ混ざったファイル名も試したところ使えるようです。その他の記号は試してないので注意が必要です。どなたか知見があればご連絡いただければ幸いです。この辺にありそうで見つけられませんでした。また記号ファイルやファイル名に予約語が含まれる場合FROM句以降のファイル名をダブルクォーテーション「”」で囲むことで動作しました。

 https://learn.microsoft.com/ja-jp/sql/odbc/microsoft/text-file-format-text-file-driver?source=recommendations&view=sql-server-ver16

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/0dd5bde8-cdd8-516a-e760-c34e4781680b.png)


## 検証2 複数テーブルを結合してみる

1. 検証1で使用したSampleCSVフォルダーにサンプルデータを追加します。今回は次のような簡単なデータをmaster.csvと
transaction.csvして保存しました。この二つのテーブルを結合してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/c37df922-e494-f9c2-6135-361698b21b5a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ed11f6ed-b4dd-e524-d130-b4b4eb8bb332.png)


1. フローを作成します
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/f87dc388-1ba1-70cc-1f98-03dcd9468d83.png)

1. 「SQLの接続を開く」アクションの接続文字列は検証1の文字列をそのまま使います。
検証１で使った「ＳＱＬ接続を開く」アクションをコピペしました。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/4717c681-7178-138f-02e7-0df41adeb818.png)

1. 「SQLステートメントの実行」アクションに商品コードに商品名、単価などのマスタデーターを結合するように書いてみます。テーブルの指定はCSVのファイル名です。また+5日ShippingDate列とsubtotal列を追加しようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/ae8f6d05-40ac-b8e8-debc-ad56ded61fb5.png)

    ```sql
    SELECT T1.orderID ,T1.date AS orderDate, T1.date +5 AS shippingDate, T1.code, T2.name ,
    T2.price, T1.value, (T2.price*T1.value) AS subtotal
    FROM "transaction.csv" AS T1
    LEFT JOIN "master.csv" AS T2 
    ON T1.code=T2.code;
    ```
1. 「SQL接続を閉じる」アクションで接続を閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/66ec65c0-834f-9d2e-92b7-bef516f7caf3.png)

### 結果

普通につかえるじゃないか・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680039/c7bd4b7b-8c2e-b2cf-639c-221a83411a62.png)


## まとめ

CSVファイルのデータテーブルをODBCドライバ経由でデータベースアクションを用いて操作できました。決まったフォルダーにデータCSVを入れておけば扱える点が非常に便利だと思いました。しかしPower Automate for desktopのLearnには記事がないので困った人も多いのではないでしょうか。フォーラムでもSQL CSV等の検索ワードではまともな回答が見つからなかったので使えないと思い込んでいました。（もしかして自分だけ？）
今回のハマりどころは「CSVファイルを開いているとフロー実行ではエラーになる」と、「マイナス記号がファイル名に含まれるとエラーになる」でした。


世間ではAIだのCopilotなどと騒がれていますが私の生息する区域ではCSVが飛び交うんですよ・・・APIでつながる世界線とかどこにあるんですか・・・。いまさら何やってるんだよとか言わないで下さい！泣きます。

ついでにお願いです。CSVをPower Automate for desktopのSQLアクションで扱う知見が少ないのでこうしたほうが良いとか、ここおかしいとか、こんなの試したとかレス頂けたら嬉しです。　おわり