【PowerBI】サーバー上の複数のCSVファイルをデータソースにしたい場合の構成

# はじめに
PowerBIにはWeb版のPowerBI Service／デスクトップ版のPowerBI Desktopがあり、
接続先データソースのバリエーションはデスクトップ版の方が豊富という特徴があります。
そのため、Webで見たいレポートも開発自体はデスクトップで行い、Webに発行して使うケースが多いようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/816a3488-73cb-8ba3-b6f3-56041061e8ec.png) [^1]

今回、次のような要件で構成を考えました。

- データソースはフォーマットの異なる複数のCSVファイル
- 各CSVファイルは週ごとに新しいデータを差分で追加したい
- その際、過去データとkeyが同じデータは新しい方で上書きしたい（差分更新）
- ファイルの配置先は運用担当全員が操作可能なサーバー上にしたい
- 最終形はPowerBI Serviceに発行してデータソースをスケジュール更新したい
- リアルタイム性は不要でコスト面重視

同じような要件で考えている方に参考にしていただければと思います！

※SharePointを使用するため、Microsoft365を契約していない会社の場合は別の方法をとった方がよいかもしれません。

# 構成図
データソースにSharePointを使用し、CSVのフォーマットごとにフォルダを分ける構成にします。各CSVの週ごとの差分データは、年月日のタイムスタンプを付与してフォルダに格納していきます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/905ff0ed-02df-ae70-3968-caba434e998a.png" width="700px" />

図には表されていませんが、開発時のみPowerBI Desktopを使用し、リリース以降はPowerBI Serviceのスケジュール更新でデータ連携をします。

# 構築の流れ

## リソースを配置する
SharePoint上に、データソースのフォーマットごとにフォルダ分けをしてCSVファイルを配置します。

今回は、以下の構成でフォルダを作成しました。
ドキュメント>Test>Fruitsの下にタイムスタンプ付きのCSVファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/7b9c1ee6-e728-0e22-ad23-6388a83256c3.png)

中身は、その日のフルーツの価格をまとめた次のようなテーブルとします。

**FruitsPrice_20220722.csv**
|key|name|price|
|----|----|----|
|1|apple|200|
|2|orange|150|
|3|lemon|100|

**FruitsPrice_20220729.csv**
|key|name|price|
|----|----|----|
|1|apple|180|
|2|orange|170|
|4|melon|1000|


同様に、野菜の価格をまとめたVegetablesフォルダも作成しファイルを2つ配置しておきます。
(ドキュメント>Test>Vegetables>VegetablesPrice_YYYYMMDD.csv)

## リソースと接続する
PowerBI Desktopでデータを取得する際、
ファイル>SharePointフォルダーを選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/53a27307-819d-1ed1-2082-900c68216393.png" width="500px" />


サイトURLに接続先SharePointを指定します。
ここでフォルダパスまで入力すると上手くいかないので、あくまでサイトのURL（/sites/XXXXまで）を入力します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/d7d58376-f663-edfb-b10d-37605e542b08.png" width="650px" />

Microsoft365のアカウントでログインします。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/76789bf2-f426-42b8-7d2a-bafc1a9a9a81.png" width="650px" />

すると、接続先SharePointのファイルが取得できます！
階層の情報は**Attributes**列の右に隠れている**Folder Path**列で管理されており、**Name**列には全階層の全てのファイルが並ぶ形になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/4e288358-80fc-bef4-e0cd-a931adfe3c85.png" width="700px" />

「データの変換」をクリックするとPowerQueryの画面が開くので、ここから必要なフォルダを絞り込んでいきます。

## フォルダを絞り込んでデータを取り込む
データインポート後、「データの変換」をクリックして開いた直後のPowerQueryの画面がコチラです。
ここからは、画面上部のツールと表の上にある式を使って必要なフォルダを特定し、データに加工を施す作業です。
![スクリーンショット 2022-08-05 185705.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/7a226096-be48-d543-6639-bb9fe845c7c8.png)

Folder Path列の「▼」をクリックし、テキストフィルターから「指定の値を含む」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/5a6d52ca-0dd2-a329-4907-8d4e11cdc302.png" width="500px" />

今回はFruitsのフォルダを取得したいので、「指定の値を含む」に"Fruits"を設定します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/de282ab4-12fc-7b45-4ebb-c6ccf6686079.png" width="700px" />

これで、Fruitsフォルダの2ファイルを取得できました。
類似の名前のフォルダがある場合は、/Fruits/と区切り文字も含めて設定すると確実です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/57ca2193-6132-57a3-26a1-e0d313021074.png" width="800px" />

次にファイルの中身を開いていきます。Content列にある「ファイルの結合」ボタンをクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/bac8dc03-8dae-ba08-3560-998e333d1a4c.png" width="700px" />

文字化け等の問題がなければそのままOKをクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/574489e7-248d-bac4-9b90-5eed3ab1b285.png" width="700px" />

これで、SharePoint上のFruitsフォルダにある2つのファイルの中身を
PowerBI上で1つのテーブルとして扱えるようになりました！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/c9244815-eee3-1316-515b-e284da8feb8d.png" width="900px" />

## 日付の新しい方のデータで上書きする

上書きする際の判断に使用するキー列を選択し、行の削除>重複の削除を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/e33959e9-1c1d-b805-b686-ec27c6867ad4.png" width="900px" />

これで、各キーごとに最新のレコードを残すことができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/df88a9fd-53c9-f0f4-9724-1d95ecbc9e4d.png)

## 同じ設定を流用して別のフォルダからCSVを取り込む
ホーム>管理>複製をクリックすると、
先ほど作成したフルーツデータの「データ取得→フォルダ絞り込み→日付順に上書き」のステップが丸ごと複製されテーブルが作成されます。
※コピー時は名前が(2)などとなってしまうので、画面右の**クエリの設定**からわかりやすい名前に変えましょう…

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/5a4890a8-e998-be45-035e-4f7d57d4c388.png" width="900px" />

この状態で、フォルダ絞り込みの条件を変えれば取得元のフォルダを変更することができます。
画面右の**適用したステップ**で「フィルターされた行」を選択し、
画面中央の式を直接編集してFruitsだったところをVegetablesに変更します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/f2c8a877-5b6b-f618-fba3-5a2957dac510.png" width="950px" />

そうすると、データソースVegetablesに対しても、先ほどのFruitsと全く同じように加工された状態にしてくれます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/70bc01ac-0e13-3f04-5fab-8480ca449d28.png" width="950px" />
※Vegetablesのデータは、この時点で日付の古い方のデータが採用されてしまっています。
この場合の対処は別の記事に記載します。

データフォルダが3つ以上ある場合も同じように複製していけばOKです♪
後続処理が違う、差分更新チェックのKey名が異なる、などの場合も
複製した後で不要なステップを削除したり、重複削除の式の条件を直接編集するのがスムーズかと思います。

ここまでの処理が終わったら、画面左上の「閉じて適用」をクリックしてPowerBIの画面へ戻ります。

## 取り込んだデータを確認する
FruitsとVegetablesの2テーブルができていることが確認できました♪
（PowerQueryで名付けた名前がテーブル名になるため、この画像ではYASAIになっています^^;）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/f6ebb1bc-5d10-3377-490e-912d6f63b881.png" width="900px" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/88d0cb5d-4c5e-f7c9-c3a3-c9e2473c1033.png" width="900px" />

## Web発行後、データソースの資格情報を更新する
最後に、Webへの発行後、PowerBI ServiceからSharePointに接続する認証を済ませます。

設定画面から
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/b9f57837-e6f8-c471-00f0-bdbd250a0a3f.png" width="900px" />

**データソースの資格情報**でエラーが出ているかと思いますので、
「資格情報を編集」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/211f793f-e6ec-c8da-2af1-49f1adcffa6c.png" width="900px" />

「OAuth2」、「Organizational」で組織のアカウントを使ってサインインします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/ac3655f9-56f4-3b4c-98fc-66c089a41104.png" width="400px" />

無事に更新されたら、後はWeb側でスケジュール設定をして自動でデータソースをSharePointと同期していくことが可能です！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1021040/f683de49-85f0-3d26-b19b-955c8c470759.png" width="900px" />

# まとめ
Microsoft365を使用している社内で運用する場合、かなりお手軽な構成かと思います。
データ基盤から構築するほどのデータ量ではないけど何か分析したい、Excelレポートから乗り換えたい、などなど…ぜひお試しください♪


[^1]: [Power BI Desktop と Power BI サービスの比較](https://docs.microsoft.com/ja-jp/power-bi/fundamentals/service-service-vs-desktop)