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 中编写的查询(上一课中)复制到连接器文件中。 在 Visual Studio Code 中打开 TripPin 项目,并将航空公司和机场查询粘贴到 TripPin.pq 文件中。 然后,可以将这些查询转换为采用单个文本参数的函数:

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);

注意

扩展可以将多个函数标记为 shared,可以将或者不将它们与 DataSource.Kind 相关联。 但是,将函数与特定 DataSource.Kind函数相关联时,每个函数必须具有名称和类型相同的必需参数集。 这是因为数据源函数参数会组合在一起,生成用于查找缓存凭据的“密钥”。

使用 TripPin.query.pq 文件完成所有更改并测试 TripPin.Contents 函数后,生成连接器。 可以继续使用以前创建的凭据,也可以设置一个新凭据,然后评估当前 Power Query 文件。

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

TripPin 表。

创建导航表

使用便捷的 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。

注意

看不到“导航器”窗口显示在 Visual Studio Code 的 PQTest 结果窗口中。 M 查询输出窗口始终显示基础表。

如果将扩展复制到 Power BI Desktop 自定义连接器并从“获取数据”对话框调用新函数,就会看到导航器出现。

TripPin 导航器。

如果右键选择导航树的根目录并选择“编辑”,就会看到与 Visual Studio 中相同的表。

TripPin 查询。

结束语

在本教程中,你向扩展添加了导航表。 导航表是使连接器更易于使用的关键功能。 在本例中,导航表只有一个级别,但 Power Query UI 支持显示具有多个维度的导航表(即使这些表层次结构不规则)。

后续步骤

TripPin 第 4 部分 - 数据源路径