Power BIでSharePointにあるファイルをそのまま結合しちゃってませんか？

## こんな人に読んでほしい
よく hogehogeData_yyyyMMdd.csv　のような毎日出力されるファイルをPower BI で扱うことのある人が対象です。
すでにSharePoint Online（以下SPO）のドキュメントライブラリに、大量のデータがあるなかで、特定の条件のファイルだけを対象としたいとき、取り込みの順番をしくじるといつまでもダウンロードが止まらないという事態に陥ります。そういうのに困っている人向けの記事です。

### まとめるとこんな感じの内容です
- 使うのは１ファイルだけなのに結合しちゃダメ
- 決まったファイルならSharePoint フォルダではなくWEBを使おう
- 日付で絞ったなら、展開前に動的参照できるようにひと工夫
- Date Created列を使えないならファイル名つかえば？

## サンプルデータ
以下のような簡単なCSVデータを用意しました。testSite>ドキュメント>tmp フォルダに毎日販売データが追加されるようなシチュエーションです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/0ef0ce04-e082-4f55-4493-cc66f5bb9b9b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/6e0ea228-9cd8-03c6-8737-69c90151cd63.png)



## 大量のログファイルのうち、対象は１つだけなのに結合しちゃだめ
### データの中の特定の日付だけをレポートしたいっていう場合
あなたならどうしますか？
まずは残念なケースから。やりがちだけれどやっちゃダメ。SPOフォルダから結合したあとの絞り込み。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/85556c4b-fc64-c5c7-6615-702607fc0626.png)

SPOフォルダを選んだあと、ファイルが置いてあるドキュメントライブラリで絞り込み。ここまでは許そう。
しかしそのあとコンテンツの結合ボタンを押してしまうと・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/86adc159-4212-ac7f-5890-776856754f3a.png)

指定したドキュメントライブラリにあった、たくさんのCSVファイルが結合されます。全部使って分析するならいいのですよ。でも、いまやろうとしているのは、１ファイルだけの分析です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/76a58bab-0a5c-4780-0d2f-cd6776d6fbb0.png)

そして営業日でフィルタリングしちゃう。まあ、いいんだけどさ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/d963fdc7-c1e5-e776-fdf8-2f5fa56d7fc0.png)

今はファイルの数がそれほど多くないので良いとして、これが巨大なファイルを大量に保存されている場所だったらどうでしょう？　Power BI デスクトップの場合、いちどすべてのファイルがダウンロードされたうえで、絞り込みがなされます。これって通信インフラと時間の無駄遣い。もったいないです。


### 特定の１ファイルって決まっているならWEBをつかおう。
今回は日付がついたログのようなファイルをサンプルにしていますが、たった１ファイルを選択するためにSPOフォルダをつかうのはもったいないです。こういうときには、WEBをつかってファイルのURLを指定して取ってくるほうがよいです。

まず、SPOフォルダの中でとってきたいファイルのURLを調べます。これには、ファイルの三点リーダーから「詳細」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/0680e997-29f5-f320-b236-f1bc687f6511.png)

画面右端の詳細画面を一番下までスクロールすると、ファイルのURL（パス）が取得できます。（ファイルのリンクを取得しちゃうと純粋なファイルのURLが取れないので注意！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/6909fc0d-1dd9-c9d2-12cb-93dccc02b9f9.png)

こんどは、データソースに「WEB」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/02bea598-3585-86bf-e06c-8cd5266c492a.png)

先ほど取得したファイルのパスを貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/70669683-9706-7d80-4b75-1da62cf45971.png)

コンテンツへのアクセス認証を求められたら、「組織アカウント」を選択します。なぜなら、SharePointの領域は組織の人しかアクセスできない領域だからです。「匿名」というのはブラウザで誰でもURLを入力したらアクセスできる領域のこと。Yahooニュースなんかを取ってくるような場合は匿名でOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/bf064488-4913-db84-dd23-de99ad13aeba.png)

もともとURLを直接指定しているので、フォルダで絞り込む必要はありません。１ファイルを狙い撃ちで指定する場合にはSharePoint上のファイルであってもWEB取り込みを使いましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/969609b0-a3ae-95c0-9434-2c48ef683f0e.png)

### フォルダの中で一番新しいファイルだけを参照する場合
先ほどは参照するファイルを狙い撃ちしましたが、毎日増えていくログの中のなかから最新のものだけをチェックしたいという場合もあるでしょう。動的に１ファイルだけを選ぶにはコツがあります。

今回はSharePointフォルダーから始めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/92b4b0b3-54dd-bbd6-8757-b21a34782d43.png)

この後フォルダで絞り込むまでは同じ。最新のものを取得するので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/3794fa0f-4786-5fda-0a14-7243ca8e8405.png)

最新のファイルだけを取得したいので、Date createdの列を「最も遅い」でフィルタリングします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/a8fbe97f-3f49-9c88-932c-dac42fe89303.png)

一番最近作成されたファイルだけが残りました。ファイルが一つだけなので結合する必要はありません。Content列の「Binary」をクリックするとファイルが展開されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/15728d6b-5aa5-39a5-d2a7-cd8f3af71509.png)

１ファイルだけが展開されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/44e39063-5f09-95f2-809a-8d9fa6e8bb5b.png)

しかし、喜んだのもつかの間。次の日のログがSPOフォルダに追加されるとどうなるでしょうか。最新のファイルはhogeLog_20240509.csvのはずなのに、20240508のファイルがエラーに表示されてますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/27964a0e-2bb6-5678-0f4e-a8a6184c0a9e.png)

Power BI デスクトップで更新してみるとエラーになりました。どうしてでしょうか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/de4d4f72-5625-29b6-c30a-d85c89deb2b0.png)

クエリの中身を詳細エディタで開いてみると、20240508のファイル名が指定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/67df4401-31cd-b0a6-ba54-5d024f81be94.png)

ちょっとクエリのステップを戻ってみてみましょう。最新日付でフィルタリングしているので、20240508のファイルは既に最新ではありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/1c1fb051-9c5a-fbd7-974b-618835f224cd.png)

次のステップでは、20240508ファイルが存在しないので、CSVを展開するため、参考にしようとしているファイルが見つからず、エラーになってしまっているんですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/f5c8e167-df57-d407-7c70-11ea6e3f27bc.png)

こういう時には、クエリを書き換えましょう。「フィルターされた行1」というのはエラーが出ていたひとつ前のステップの名前です。前のステップで絞り込まれたファイルの中の最初に出てくるファイルのことを{0}のようにあらわしています。0番目のコンテンツだから後ろに[Content]とつけます。すると、CSV変換の参考にするファイルが動的に指定することができました。先ほどまでは20240508を参照していましたが、今回は自動的に20240509を参照してくれるようになってます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/1f3e1824-450d-347e-22fc-a4cfea2e8a65.png)

無事に取得することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5285de3d-7b7a-686e-1898-3aa7bbcd320c.png)



### 必用なぶんだけを取り込もう
実際のログ取得では、ある程度の期間についてファイルを取得したいことが多いです。必要な日数分を絞り込んでから結合させましょう。こんな風に書きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/834e7d63-29cb-7048-e8d3-72e148a5c35c.png)
```
= Table.SelectRows(フィルターされた行, each Date.IsInPreviousNDays(Date.AddDays([Date created], -1), 2))
```
こちらの式では、本日を含む2日間だけを絞り込めます。たとえば何年分もログがあるフォルダに対して、過去31日間のようにしたければ最後の2の部分を書き換えればよいですね。

### 参考までに、クエリの中の値はパラメータ（変数）にすることもできます。
「パラメーターの管理」から「新しいパラメーター」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/b47e27e9-4eed-d851-05a4-b26e0ad503c9.png)

パラメーターには適当な名前を付けて、種類は10進数。仮の現在の値を入力してOKをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5ace0f7f-51fd-02eb-7e92-4569f715aad0.png)

クエリの表示されている場所にパラメーターも表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/314224b4-a780-c28b-b99e-1d605a7a60c1.png)

パラメーターにつけた名前は、数字の代わりに使うことができます。図のように書き換えてやると、パラメーターに設定した4という数字で過去4日分のデータを取得する指定ができたことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/19812985-75fd-2635-5bd1-c12aad672593.png)

これの何がうれしいかというと、パラメーターはPower BI デスクトップから発行してPower BI サービスにアップロードしたあとで、ブラウザ上で変更することができるんです。

つまり、大量のデータを更新したい場合に、Power BI デスクトップでは直近数日の少ないデータで処理をしておいて、発行（アップロード）したあとにパラメーターを大きな数字に変更すれば、作業がぐっとしやすくなります。

実際にマイワークスペースに発行してみました。セマンティックモデルの三点リーダーから「設定」を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/662d8dee-dc8e-54aa-f5ed-5a45fbddd33e.png)

先ほど設定したパラメーターの名前と、値が表示されていますね。クラウド上ではこの値を大きく変えてから更新をかければオッケーです。運用上もいちいちPower BI デスクトップで変更をして発行をし直したりする必要がありませんから便利ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/2ec9180a-f3ba-f5a6-8725-cbe7fe3e582e.png)



### Date Createdが使えないならファイル名から
実はサンプルのCSVファイルは本日まとめて作ったので、日付がいずれも同じ日です。これでは正確に取り込みたい日数を指定できません。PowerShellでまとめてログを取ったときなんかにはファイル作成日が同じになっちゃうのでこれまでの方法が使えないんですね。
今回の例では、ファイル名に日付が入っています。これをうまく使いましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/aaaa4724-0c5e-dd67-6009-7c12c24b1b11.png)

ファイル名が表示されているName列を選択し、「列の追加」> 「例からの列」> 「選択範囲から」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5ec176d6-d470-bf0a-7dc9-539275e47aa0.png)

追加する列名を「日付」に変えて、任意の行の空欄をクリックすると、Name列に表示されているファイル名がコピーされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/de4a6693-a16b-f2cf-17c0-2ec5f6296fc4.png)

表示されているファイル名の一つを、日付の形になるように手で変更してやります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/d3dc27e5-c1a7-b7d2-8eb2-ae4a19c4b123.png)

今回は最初の行だけではうまく変換できなかったので、2行目もファイル名の数字部分を参考に日付のように手で変更してやると、次の瞬間、他の行がファイル名から日付部分を取ってくるような変換をしてくれました。変換式が表示されてます。ファイル名が一定の法則に従っているならこの方法はとても有効です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/c1d120db-0cfd-3993-521d-3d1f4e9f01d0.png)

日付の形になったのですが、初期状態では列はテキスト型になっています。日付/時間型に変更してやります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/5a383e46-7078-bdf4-8233-0785b5ef4316.png)

あとは、さきほどDate createdを指定していた部分のクエリを[日付]に書き換えると、ファイル名に従った範囲指定ができるようになりました。日付で絞る場合には、先にお伝えしたようにCSV変換の参照ファイルがフィルタ範囲外に出ても問題ないように、ファイル名指定を 「前クエリの名前{0}[content] 」のように書いてエラー回避するのを忘れずに。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285141/8ef9a125-b6a0-aab6-a193-cd0b4ad2b954.png)

## まとめ
SharePointフォルダ指定の取り込みはとても便利ですが、フォルダ全体を取り込んでからフィルタリングをするのはもったいないです。ファイル単位ならば、必要な範囲のファイルを選択してから取り込むことで、処理がぐっと軽くなります。
パラメーターを使った後で範囲を変更できる方法も非常に便利なので、ぜひ試してみてください。

## 動的な指定
ファイルを絞り込む場合に、参考にしていたファイルが見つからずにエラーとなってしまうケースが時々あります。ファイルにかぎらず、例えばExcelファイルを指定していたときに、シート名が変わってしまっている場合にもこの何番目という指定は役に立ちます。

Excelのシート名違いについても以前に記事を書いていますので、参考にしてもらえると嬉しいです。

https://qiita.com/DaddyDaddy/items/a5c621ac72b01637135a