TripPin パート 3 - ナビゲーション テーブル

このマルチパート チュートリアルでは、Power Query 用の新しいデータ ソース拡張機能の作成について説明します。 このチュートリアルは順番に実行することを目的としています。各レッスンは前のレッスンで作成したコネクタに基づいて構築され、コネクタに新しい機能が段階的に追加されます。

このレッスンの内容:

  • 固定クエリ セットのためにナビゲーション テーブルを作成する
  • Power BI Desktop でナビゲーション テーブルをテストする

このレッスンでは、前のレッスンで作成した TripPin コネクタにナビゲーション テーブルを追加します。 コネクタに OData.Feed 関数を使っていた場合 (パート 1) は、OData サービスの $metadata ドキュメントから派生したナビゲーション テーブルを "無料で" 受け取りました。 Web.Contents 関数 (パート 2) に進むと、組み込みのナビゲーション テーブルを失いました。 このレッスンでは、Power BI Desktop で作成した固定クエリ セットを使い、Power Query に適切なメタデータを追加して、データ ソース関数の [ナビゲーター] ダイアログをポップアップ表示します。

ナビゲーション テーブルの使用については、ナビゲーション テーブルのドキュメントを参照してください。

コネクタでの固定クエリの定義

REST API のシンプルなコネクタは、それぞれからテーブルが返される固定クエリ セットと考えることができます。 これらのテーブルは、コネクタのナビゲーション テーブルを使って検出できるようになります。 基本的に、ナビゲーターの各項目は、特定の URL と一連の変換に関連付けられています。

まず、(前のレッスンで) Power BI Desktop で作成したクエリをコネクタ ファイルにコピーすることから始めます。 TripPin Visual Studio プロジェクトを開き、Airlines および Airports クエリを TripPin.pq ファイルに貼り付けます。 次に、これらのクエリを 1 つのテキスト パラメーターを受け取る関数に変えることができます。

GetAirlinesTable = (url as text) as table =>
    let
        source = TripPin.Feed(url & "Airlines"),
        value = source[value],
        toTable = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        expand = Table.ExpandRecordColumn(toTable, "Column1", {"AirlineCode", "Name"}, {"AirlineCode", "Name"})
    in
        expand;

GetAirportsTable = (url as text) as table =>
    let
        source = TripPin.Feed(url & "Airports"),
        value = source[value],
        #"Converted to Table" = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
        #"Expanded Column1" = Table.ExpandRecordColumn(#"Converted to Table", "Column1", {"Name", "IcaoCode", "IataCode", "Location"}, {"Name", "IcaoCode", "IataCode", "Location"}),
        #"Expanded Location" = Table.ExpandRecordColumn(#"Expanded Column1", "Location", {"Address", "Loc", "City"}, {"Address", "Loc", "City"}),
        #"Expanded City" = Table.ExpandRecordColumn(#"Expanded Location", "City", {"Name", "CountryRegion", "Region"}, {"Name.1", "CountryRegion", "Region"}),
        #"Renamed Columns" = Table.RenameColumns(#"Expanded City",{{"Name.1", "City"}}),
        #"Expanded Loc" = Table.ExpandRecordColumn(#"Renamed Columns", "Loc", {"coordinates"}, {"coordinates"}),
        #"Added Custom" = Table.AddColumn(#"Expanded Loc", "Latitude", each [coordinates]{1}),
        #"Added Custom1" = Table.AddColumn(#"Added Custom", "Longitude", each [coordinates]{0}),
        #"Removed Columns" = Table.RemoveColumns(#"Added Custom1",{"coordinates"}),
        #"Changed Type" = Table.TransformColumnTypes(#"Removed Columns",{{"Name", type text}, {"IcaoCode", type text}, {"IataCode", type text}, {"Address", type text}, {"City", type text}, {"CountryRegion", type text}, {"Region", type text}, {"Latitude", type number}, {"Longitude", type number}})
    in
        #"Changed Type";

次に、これらのデータ セット クエリにリンクする固定テーブルを作成するモック ナビゲーション テーブル クエリを記述してインポートします。 これを TripPinNavTable と呼びます。

TripPinNavTable = (url as text) as table =>
    let
        source = #table({"Name", "Data"}, {
            { "Airlines", GetAirlinesTable(url) },
            { "Airports", GetAirportsTable(url) }
        })
    in
        source;

最後に、メインのデータ ソース関数として使う新しい共有関数 TripPin.Contents を宣言します。 また、[データの取得] ダイアログに表示されないように TripPin.Feed から Publish の値を削除します。

[DataSource.Kind="TripPin"]
shared TripPin.Feed = Value.ReplaceType(TripPinImpl, type function (url as Uri.Type) as any);

[DataSource.Kind="TripPin", Publish="TripPin.Publish"]
shared TripPin.Contents =  Value.ReplaceType(TripPinNavTable, type function (url as Uri.Type) as any);

Note

DataSource.Kind との関連付けの有無にかかわらず、拡張機能で複数の関数に shared とマークすることができます。 ただし、関数を特定の DataSource.Kind と関連付ける場合、各関数には名前と種類が同じ 必須の パラメーター セットを指定する必要があります。 これは、データ ソース関数のパラメーターを組み合わせて、キャッシュされた資格情報を検索するときに使う 'キー' を作成するためです。

TripPin.query.pq ファイルを使って TripPin.Contents 関数をテストすることができます。 次のテスト クエリを実行すると、資格情報のプロンプトとシンプルなテーブル出力が表示されます。

TripPin.Contents("https://services.odata.org/v4/TripPinService/")

TripPin Table.

ナビゲーションテーブルの作成

便利な Table.ToNavigationTable 関数を使用して、静的テーブルを Power Query がナビゲーション テーブルとして認識できる形式にフォーマットします。 この関数は Power Query の標準ライブラリの一部ではないため、そのソース コードを .pq ファイルにコピーする必要があります。

このヘルパー関数を配置したら、次に TripPinNavTable 関数を更新してナビゲーション テーブル フィールドを追加します。

TripPinNavTable = (url as text) as table =>
    let
        source = #table({"Name", "Data", "ItemKind", "ItemName", "IsLeaf"}, {
            { "Airlines", GetAirlinesTable(url), "Table", "Table", true },
            { "Airports", GetAirportsTable(url), "Table", "Table", true }
        }),
        navTable = Table.ToNavigationTable(source, {"Name"}, "Name", "Data", "ItemKind", "ItemName", "IsLeaf")
    in
        navTable;

テスト クエリを再度実行すると、列がさらに追加されて、前回と同様の結果が得られます。 TripPin Table2.

Note

Visual Studio では [ナビゲーター] ウィンドウは表示されません。 [M Query Output]\(M クエリ出力\) ウィンドウには、常に基となるテーブルが表示されます。

拡張機能を Power BI Desktop カスタム コネクタにコピーし、[データの取得] ダイアログから新しい関数を呼び出すと、ナビゲーターが表示されます。

TripPin Navigator.

ナビゲーション ツリーのルートを右クリックして [編集] を選ぶと、Visual Studio 内で実行したものと同じテーブルが表示されます。

TripPin Query.

まとめ

このチュートリアルでは、拡張機能にナビゲーション テーブルを追加しました。 ナビゲーション テーブルは、コネクタを使いやすくするための重要な機能です。 この例のナビゲーション テーブルには 1 つのレベルしかありませんが、Power Query UI は、(不規則であっても) 複数のディメンションを持つナビゲーション テーブルの表示をサポートしています。

次のステップ

TripPin パート 4 - データ ソース パス