NEXTSCAPE blog

株式会社ネクストスケープの社員による会社公式ブログです。ネスケラボでは、社員が日頃どのようなことに興味をもっているのか、仕事を通してどのような面白いことに取り組んでいるのかなど、会社や技術に関する情報をマイペースに紹介しています。

MENU

Power BIで「ファイルの結合」を使うとき何が起こっているか、ついでにカスタム関数

寒いですね。

ブーツタイプのルームシューズのあたたかさと脱ぎづらさの間で日々煩悶している、DX-HR推進室の堀越です。

本記事は「NEXTSCAPE Advent Calender 2021」の18日目です。

Power BI のフォルダーコネクタは便利

Power BI ではローカルフォルダーやSharePointフォルダーをデータソースに指定することができます。

同じ構造ならば、追加データの入ったファイルをフォルダに追加していけるので、便利に使っています。

 

docs.microsoft.com

docs.microsoft.com

こちらのQiita記事で丁寧に解説してくださっています。

qiita.com

qiita.com

 

SharePointフォルダーからデータを取得してみましょう。

f:id:ns_horikoshi:20211217221506p:plain

SharePoint フォルダーのコネクタはサイトのコンテンツをすべて読みこんでくれるのでフィルターが必要です。

今回はFolder Pathでフィルターしました。

目的のファイルのみを絞り込むことができたら、Content列のここ(「ファイルを結合」ボタン)を押すと…

 

f:id:ns_horikoshi:20211218021506p:plain

こんなウィンドウが出て

f:id:ns_horikoshi:20211218150512p:plain

OKをクリックすると、フォルダ内のファイルがまとめて1つのクエリとして開かれます。

f:id:ns_horikoshi:20211218151922p:plain

うん、便利ね。

「ファイルの結合」を使うとき、何が起きているのか?

ところでContent列で「Fileの結合」をクリックしたあとに、ステップがいくつか増えています。

f:id:ns_horikoshi:20211218152451p:plain

作った覚えのないクエリも作成されています。

f:id:ns_horikoshi:20211218152409p:plain

Docmentを見てみます。

docs.microsoft.com

 

f:id:ns_horikoshi:20211219010823p:plain

 

ふむ!わかりません。

わからなくてもレポートは作れますが、この記事では一つずつ見ていきます。

1. 自動的に作成されるステップ

①フィルター選択された非表示のFile

f:id:ns_horikoshi:20211218213212p:plain

隠しファイルを除外してくれているようです。

Attributes列には各行Recordが入っていますが、これを展開した際のHiddenフィールドがtrueでない行をフィルターしています。
クエスチョンマークは列が存在しなくてもエラーにせずnullを返します。

SharePointフォルダをデータソースにすると、ここのRecordには

Size、Content Type、Kind の3つしか格納されていませんが、クエスチョンマークのおかげでエラーになりません。

f:id:ns_horikoshi:20211218213314p:plain

 

ローカルフォルダをデータソースとしたとき、隠しファイルのAttributes列のRecordを展開すると、こんな感じになっていました。

f:id:ns_horikoshi:20211218212208p:plain

 

Recordを展開しなくても、中身のフィールドをフィルター条件にできるんですね。

ちなみにここのステップの歯車マークをクリックすると、以下のウィンドウが出てきます。

謎しかなく、この記事を書くために調べるまでは何をしているかなんとなくしかわかっていませんでした。

f:id:ns_horikoshi:20211218214129p:plain

 

②カスタム関数の呼び出し

f:id:ns_horikoshi:20211218221204p:plain

「ファイルの変換」という列が追加されて、各行にTableが格納されています。

Table.AddColumn(table as table, newColumnName as text, columnGenerator as function, optional columnType as nullable type) as table 

Table.AddColumn を使って、

1つ目の引数で、列追加する対象のテーブル名(直前のステップ名)、

2つ目で、追加する列の名称("ファイルの変換"列)、

3つ目で、列の中身を作成するためのカスタム関数を指定しています。

 

ここはあとで探るとして、先に行きましょう

 

③名前が変更された列

f:id:ns_horikoshi:20211218213856p:plain

見たままですね、わかりやすく"Source"を付けてくれています。

 

④削除された他の列

f:id:ns_horikoshi:20211218214234p:plain

ファイル名もいらないなーってときは、「ファイルの変換」列だけを残すように編集してしまいましょう。

 

⑤展開されたテーブル列

f:id:ns_horikoshi:20211218220550p:plain

 

「ファイルの変換」列に格納されていた各行のTableが展開されて、いよいよファイルの中身がすべて見られるようになりました。

Table.ExpandTableColumn を使って、各行に格納されているTableを展開しています。

Table.ExpandTableColumn(table as table, column as text, columnNames as list, optional newColumnNames as nullable list) as table 

1つ目の引数で、処理する対象のテーブル名、

2つ目でさらに列名、

3つ目で展開した後の列名をリストで渡します。Table.ColumnNames(ファイルの変換(#"サンプル ファイル")はサンプルファイルから列名をリストで取得しています。

 

⑥変更された型

f:id:ns_horikoshi:20211218224603p:plain

すべての列に対して、データ型の検出と変更を行っています。

これで自動的に追加されたステップは終わりです。

 

2. 自動的に作成されるクエリ

次はクエリを見ていきます。

「クエリ1からファイルを変換する」フォルダに、「ヘルパークエリ」フォルダと、「サンプルファイルの変換」クエリが入っています。

f:id:ns_horikoshi:20211218152409p:plain

「ファイル」「変換」が多すぎてこんがらがるので、クエリ名を変えました。

f:id:ns_horikoshi:20211218225545p:plain

 

①カスタム関数「ファイルの変換」

f:id:ns_horikoshi:20211218233851p:plain

パラメーターで指定したバイナリファイルをExcelとして開き、

financialsテーブルを取得して返却しています。

ここでもう一度、このカスタム変数を呼び出している側を見てみます。

f:id:ns_horikoshi:20211218234824p:plain

each #"ファイルの変換(カスタム関数)"([Content])

ここや、「カスタム関数の呼び出し」ウィンドウでもわかるように、

Content列のBinaryをパラメーターとして渡し、Financialsテーブルを受け取る、という動きを行ごとに繰り返しているのがわかりました!

 

②サンプルファイル

f:id:ns_horikoshi:20211218230807p:plain

このフォルダの「最初のファイル」が入っています。{}の中は行のインデックス値です。

 

サンプルファイルは何に利用されるのかというと、カスタム関数呼び出し側でテーブルを展開するときの列名リストを取得に使われています!大事!

f:id:ns_horikoshi:20211218235542p:plain

 

「ファイルの結合」ボタンをクリックしたときに、こんなウィンドウが出ましたよね。

実はここでサンプルファイルの選択をしていたのです。

f:id:ns_horikoshi:20211218230448p:plain

ここで「最初のファイル」以外、例えば2013年のファイルを選択すると、

f:id:ns_horikoshi:20211218231202p:plain

サンプルファイルの中身はこうなります。

f:id:ns_horikoshi:20211218231531p:plain

 

※ちなみにこのサンプルファイルはバイナリです。

バイナリのクエリを作るには、Content列のBinaryをクリックします。

f:id:ns_horikoshi:20211218232638p:plain

ファイルの中身が展開されるので、「インポートされたExcelブック」のステップを削除します。

f:id:ns_horikoshi:20211218232822p:plain

f:id:ns_horikoshi:20211218233056p:plain


②パラメーター1(サンプルファイル)

f:id:ns_horikoshi:20211218233244p:plain

f:id:ns_horikoshi:20211218233531p:plain

カスタム関数で利用するパラメーターです。

①のサンプルファイルがデフォルトで設定されています。

サンプルファイルを複数作ると、このように選ぶことができます。

※ここで規定のファイルを変更しても、カスタム関数呼び出し側で列名リストを取得する際に利用するファイルは変わりません。

 

④サンプルファイルの変換

「ファイルの変換」カスタム関数の出力結果の見本であると同時に、

ここで行った設定の変更を「ファイルの変換」カスタム関数にも反映してくれます。

f:id:ns_horikoshi:20211219001757p:plain

 

ソース = Excel.Workbook(パラメーター1, null, true),

バイナリファイルパラメーターの指定、ファイルの形式の指定

f:id:ns_horikoshi:20211219001001p:plain

financials_Table = ソース{[Item="financials",Kind="Table"]}[Data]

開くテーブルの指定

f:id:ns_horikoshi:20211219001252p:plain

 

Excelファイルだとあまり恩恵はないかもしれないですが、

例えばCSVファイルだとこのあたりが変更できたりします。

f:id:ns_horikoshi:20211219001413p:plain

 

おまけ:カスタム関数も便利

「ファイルの結合」はちょっと複雑ですが、カスタム関数とは、他のクエリからパラメーターを渡すことで呼び出し可能なクエリ、だと思っています。

行ごと、もしくはクエリごとに同じような処理をしなければならないときに便利です。

①カスタム関数の作成

クエリの詳細エディターでパラメーターを定義すると、勝手にアイコンが変更されてカスタム関数になります。

f:id:ns_horikoshi:20211219003732p:plain

上記は、開始日と終了日を渡すことで、その期間内のデータを取得するSQLを使ったカスタム関数です。

f:id:ns_horikoshi:20211219004422p:plain

ここでパラメーターを入力して「呼び出し」をクリックすると、実行結果が新規クエリとして追加されます。

f:id:ns_horikoshi:20211219005122p:plain

 

②カスタム関数の呼び出し

さて、週の開始日と終了日のあるテーブルがここにあります。

f:id:ns_horikoshi:20211219005212p:plain

「列の追加」タブから「カスタム変数の呼び出し」をクリックします。

f:id:ns_horikoshi:20211219005420p:plain

テーブルの列をカスタム関数のパラメーターとして指定できます。

f:id:ns_horikoshi:20211219005535p:plain

各行の指定列をパラメータとしたカスタム関数の実行結果が列追加されます。
今回のカスタム関数の取得結果は1行ですがテーブルなので、テーブル型の列が追加されています。

f:id:ns_horikoshi:20211219005622p:plain

テーブル列を展開すると、期間ごとの値が取れています!

f:id:ns_horikoshi:20211219005654p:plain



まとめ

むやみに長くなってしまいました。

フォルダーコネクタおよびファイルの結合は便利ですが、ヘルパークエリ内でエラーが発生することもたまにあるので、

中身で何をしているか知っておくのもいいかなと思っています。

先日 レポート更新時にこんなエラーが出ました。

Column 'XXXXXXX' in Table 'XXXXXXX' contains blank values and this is not allowed for columns on the one side of a many-to-one relationship or for columns that are used as the primary key of a table.

Desktopで開いてみると、「サンプルファイルの変換」でエラーになっていて、データソースのフォルダ内に異なる文字コードのファイルが追加されたことが原因でした。

 

カスタム関数も堂々とリボンにある割には長らく謎のままの機能だったので、うまく使っていきたい所存です。