Power BI のセマンティックモデルから自動でCSVファイル化してSharePointフォルダに保存させる方法

## こんな方のための記事
Power BIで見える化しているけれど、月々のスナップショットをデータとして取っておきたい人や、扱っているデータが大きすぎるので、サマリーだけをCSVファイルにして定期的に自動更新させたいようなケースにお勧めです。

## サンプルデータを用意します。
ご自身のデータがあればそちらを使っていただいてOKです。今回は軽く試してみるために、Power BI Desktopで最初に出てくるサンプルデータを使ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/40f58cbf-bef8-2cfd-e654-fc239afe7383.png)

展開してテーブルに年、月、Product、Salesの合計を並べてみました。
これで月ごとの各製品の売上合計を表す表ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/41b8f12c-7c19-e194-b815-15071e9bc937.png)

CSVファイルにして保存したいですが、その際に合計欄は不要なので、ビジュアルの書式設定で合計欄を消しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5271ab7d-3023-dc1b-f2cd-6c5e17685baf.png)

## セマンティックモデルから切り出す
データの準備ができたら、適当な名前で保存して「発行」します。
Power BI Desktopから発行すると、Power BI サービス上で「セマンティックモデル」と「レポート」が作成されます。データと見栄えに分かれるんですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/77ab3fda-5746-edac-60a4-b366e9c9f38a.png)

データはクラウド上のセマンティックモデルに用意できました。このセマンティックモデルは、データもクラウド上にあるならば自動更新で最新の状態に保つことができます。余談ですが、データがオンプレ上にある場合も、[オンプレミスデータゲートウェイ](https://learn.microsoft.com/ja-jp/data-integration/gateway/service-gateway-onprem,"オンプレミスデータゲートウェイ")をつかって更新することができます。

もういちどPower BI Deskotopに戻って、[表示]>[パフォーマンスアナライザー]>[記録の開始]>[ビジュアルを更新します]>[停止]の順にクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/43c0e9e8-7b4b-47a6-9b4e-e5478118c40c.png)

パフォーマンスアナライザーには、開いていたページにあるオブジェクトの表示にかかった時間などが表示されます。このなかから「テーブル」の部分を展開してみると、[クエリのコピー]というものがあります。こちらをクリックしてコピーできたら、メモ帳などに貼り付けておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/94eacc5a-683b-edd8-81f9-e185356089a7.png)

## Power Automateでクラウドフローをつくる
ブラウザから、下記をひらいてPower Automateを使います。
https://make.powerautomate.com
[+作成]>[スケジュール済みクラウドフロー]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/3a3a77ca-a85e-5963-e475-1bf7baefb70c.png)

クラウドフローに名前をつけて、定期実行する間隔を指定します。下の図の例では、毎週日曜日の朝10時に実行させています。これはCSV出力をするタイミングで指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/b1109be5-afe4-f564-43b1-eb8b9603c994.png)

Power BIコネクターのなかから「データセットに対してクエリを実行する」アクションを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/2ebf8648-b437-bfe7-a335-c30202e02f83.png)

データを取り出したいセマンティックモデルがあるワークスペースとセマンティックモデル（昔の名前はデータセット）を選択したあと、クエリテキストの欄に先ほどメモ帳に貼り付けておいたDAXクエリをペタリと貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/af14c580-eb78-bc44-f58a-5b2659c4d04c.png)

ここまでできたら、一度テスト実行してみましょう。クエリーをもとに結果がJSON形式で返ってきています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/48c3ec42-a5b0-9526-039a-a21f7679ef73.png)

出力結果をテキストエディタで見てみると、今回は5列ごとに値がまとまっていることがわかります。このままCSV化してもいいのですが、列名がちょっとね・・・。

そこで「選択」を使います。
マップの部分にはCSVのヘッダーにつけたい列名を入力し、値には式を入れていきます。あらかじめクエリの結果をメモ帳などに貼っておき、元の列名を下記のように式に入れ込みます。

```
item()?['元の列名']
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/4940b879-7330-397f-2564-c18597d34140.png)

丁寧に列名を変換する式を「選択」に割り当てたら、その結果を「CSVテーブルの作成」に渡します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/24a5b0cc-ca1d-298d-9249-fad3c3ea994a.png)

テストしてみると、JSONから列名が修正され、その結果がカンマ区切りのCSV状態になっていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/35db444b-a35f-e97a-f9d0-7f3b57bc1bf0.png)

## ファイルに日付をいれよう
クラウドフローで作成したCSVファイルはそのままSharePoint Onlineのドキュメントライブラリに保存することができます。この時に使うのがSharePointの「ファイルの作成」です。
ファイル名には日付をいれてやりたいので、「変数を初期化する」を使って日付文字列を作ってやりましょう。テキスト型にして式には下のように指定します。
```
convertFromUtc(utcNow(),'Tokyo Standard Time','yyyyMMdd')
```
日付の文字列化の取り扱いについては、日本時間とUTC標準時の変換などがちょっとややこしいところです。このあたりもう少し知りたい方はこちらの記事をブログ記事をぜひお使いください。はい。私のブログです。「モカ式　UTCNOW」で検索すると見つけやすいです。

→　[モカ式:Power AutomateでUTC時間を日本時間に関数をつかって変換したい](https://mocabrown.com/blog/archives/6273 "モカ式:Power AutomateでUTC時間を日本時間に関数をつかって変換したい")


## SPOフォルダへのCSVファイル書き出し
あとは「ファイルの作成」に保存する場所と動的に変わる日付変数を使ったファイル名と、CSV化したコンテンツを指定してやるだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/bca570e4-95d0-3162-4b00-9f997740a2db.png)

成功です？　むむ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/9c148a78-b37d-dca0-9733-f3f74e88c75d.png)

ヘッダー部分の日本語が文字化けしてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/ed0dfcd1-98fd-20bc-7764-912b50b91acc.png)
こんな時は慌てず騒がず、こちらの記事を参考にしましょう。はい。私のブログです。困ったときは「モカ式　文字化け」で検索してご活用ください。

→　[モカ式：Power AutomateでCSVが文字化けする場合の対策](https://mocabrown.com/blog/archives/6754 "モカ式：Power AutomateでCSVが文字化けする場合の対策")


記事にありますとおり、秘密の文字列を式にしてコンテンツの前に貼り付けます。
```
decodeUriComponent('%EF%BB%BF')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/e51a647a-e7f0-59bb-b4d8-b33ac60bb4cf.png)

無事にCSV出力できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5e0e104f-f082-ce59-0bd7-85d8dca5c7ec.png)

## まとめ
Power BI レポートでCSV化したい形をテーブルにしてやると、そのレポート画面を構成しているDAXクエリをPower AutomateのPower BIコネクタにある「データセットに対してクエリを実行する」アクションに使うことができます。　データセット（現セマンティックモデル）から、その一部を表示させるという役割をDAXクエリが行っているので、同じことなんですね。

DAXクエリはなかなか難解ですが、[パフォーマンスアナライザー]から取得することができます。取得する前に合計欄などは不要であれば消しておきましょう。残しておくとそのビジュアルがそのまんまCSVファイルの中にも表れてしまいます（笑）

Power BI デスクトップ上でテーブル表示させる際に、フィルターなどで必要な部分だけが表示されるように工夫しておくと、CSVファイルに対してもフィルタ化することができます。

何日前指定などもPower BIのフィルターでは簡単に指定できます。DAXクエリになると、その部分も式と数字になります。ということは、Power Automateの上ではその部分を状況に応じて変更するなんてことも簡単に行えますから、いろいろ応用が利きそうです。

クラウドフローで定期実行しているので、セマンティックモデルの更新タイミングもCSV出力に合わせたいような場合は、Power BI側での自動更新は止めて、クラウドフローの中でついでにデータセットの更新もクラウドフローの中で行って、失敗した場合にはチャネルへ報告するような仕組みも加えておくと安心です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/d05d4973-81eb-585e-3de2-d0c73a7e3596.png)

簡単な割にPower Automateのなかでのクエリ実行は便利な機能ですので、ぜひ使ってみてください。

## じつは・・・
このPower Automateでの直接クエリ実行をしらなかったので、同じことをPower BI Report Builderを使って実現させていました。
https://mocabrown.com/blog/archives/6427
学びは無駄にはなりません。