【发布时间】:2021-08-20 09:51:59
【问题描述】:
问题总结
我的 Power Query 表中有一个包含自定义链接数据类型的列。不需要创建填充所有空值的自定义链接数据类型。相反,如果自定义数据类型中包含的所有值都为 null,我希望列中的值为 null。
背景
我有一个包含 API 响应 JSON 文本的表。此 JSON 文本包含搜索结果列表(也是 JSON 格式),表示与请求中提供的搜索条件匹配的电影。可以有任意数量的搜索结果,包括零。使用 Power Query M,我使用内置解析器解析这些 JSON 文本,该解析器生成一个 list,每个搜索结果包含一个 record。然后我提取list 中的第一个record,将record 扩展为新列,并将这些新列合并为自定义数据类型。
示例
这是一个示例查询,仅模拟我的查询的问题区域。这个例子是完全包含的,可以用来准确地重现我的问题。
let
// These two variables holds the API response JSON text obtained from calls to Web.Contents().
// I've eliminated the actual calls in this example because that part of my query works fine.
Search_Fast_and_Furious_Response =
"{ ""total-results"":""2"", ""results"":[
{ ""title"":""Fast & Furious"", ""year"":""2009"" },
{ ""title"":""The Fast and the Furious"", ""year"":""2001"" } ] }",
Search_mmmmm_Response =
"{ ""total-results"":""0"", ""results"":[] }",
// Create the table to hold the response text.
Source = Table.FromRecords( { [#"API Response"=Search_Fast_and_Furious_Response],
[#"API Response"=Search_mmmmm_Response] }),
// Parse the JSON and put the output (a record) in a new column.
#"Insert Parsed JSON" = Table.AddColumn(Source, "JSON", each Json.Document([API Response])),
// Expand the record in the parsed JSON column. Each field in the record becomes a new column.
#"Expand JSON" = Table.ExpandRecordColumn(#"Insert Parsed JSON", "JSON",
{"total-results", "results"}, {"Result Count", "Results List"}),
// Add a new column to hold the first search result in the responses results list.
// This is also a record, like the parsed JSON two steps ago.
#"Add Result #1 Column" = Table.AddColumn(#"Expand JSON", "Result #1", each
try _[Results List]{0}
otherwise null), // In case the list is empty
// Expand the record in the Result #1 column.
#"Expand Result #1" = Table.ExpandRecordColumn(#"Add Result #1 Column", "Result #1",
{"title", "year"}, {"Title", "Year"}),
// Combine the newly expanded columns into a single column.
// Make the Display Name be the value in the Title field/column,
// and make the Type Name be "Excel.DataType."
// This is what creates the custom linked data type.
#"Combine Result #1" = Table.CombineColumnsToRecord(#"Expand Result #1", "Result #1",
{"Title", "Year"}, [ DisplayNameColumn = "Title", TypeName="Excel.DataType" ])
in
#"Combine Result #1"
in 语句之前最后一行中的列表,ie Table.CombineColumnsToRecord 函数的第四个参数,允许将记录用作 Excel 新的自定义数据类型关联数据功能。我不确定,但我相信 Power Query/Excel 将它们存储为 records 以及其他元数据,例如 DisplayNameColumn 和 TypeName(我确信后者是最重要的部分)。
问题与目标
这是示例查询创建的结果表。右下角的单元格被选中。它的内容显示在图像的底部。单元格本身包含一个值,特别是一条所有值都设置为 null 的记录。因为 Title 字段为 null,所以记录的显示文本为“null”。
下一张图片显示了我想要的输出。再次注意右下角的单元格。这一次,单元格是空的。它不再包含所有值为空的记录;现在它什么都不包含了,所以这个视图中显示的是null,斜体表示一个空值,而不是单词“null”。 (注意:我无法将第一张图像中的“null”单元格更改为文字 null 值,因此为了演示,我只是添加了一个新的 null 值列。)
不幸的是,由于我在try 后面的otherwise 子句,如果API 返回零搜索结果,“结果#1”列可能为空。如果此值在任何行中为 null,则 #"Expand Result #1" 创建的所有新列也将在该行中包含 null。最后,当所有空值在最后一步合并时,我留下了一个带有所有空值的record。相反,我希望实现的是在该单元格中有一个空值(null 类型)。
目前的努力
我尝试了Table.ReplaceValues 函数,将 null 作为新值传递,并将许多不同的值作为旧值(要替换的值)传递,例如具有所有空值的新记录。所有这些尝试要么在语法上不正确,要么导致了预期的和不需要的行为。我也尝试过使用 Power Query GUI 中的“替换值”选项,但结果相同。如果ReplaceValues 不喜欢空值,我还尝试在otherwise 子句中使用不同的值,例如文本类型的“N/A”,然后对该不同的值执行ReplaceValues。这产生了相同的结果。
结论
有什么方法可以用一个奇异的空值替换一条记录——它用空值填充并存储在包含记录的列中?在这种情况下,链接数据类型功能是一个高优先级,因此我更喜欢保留该功能的解决方案(当然欢迎所有解决方案)。
【问题讨论】:
-
具有代表性的数据样本(以 text 形式发布)和预期结果示例将有助于为您提供帮助。阅读How do I Ask a Good Question 和How to create a Minimal, Complete, and Verifiable example 的帮助主题可能会有所帮助。 编辑您的问题以提供更多有用的信息。
-
谢谢@RonRosenfeld!我感谢您的帮助。在阅读了这些页面之后,我相信我已经提供了一个基本完整的“reprex”,尽管我将进一步充实它并以我的示例“从头开始”。我还将包括一个有代表性的数据样本。
-
要检查
Result#1中的值是否为*null*,可以检查Title列的值。例如:if Record.Field([#"Result #1"],"Title")=null then null else [#"Result #1"]但这不会保留数据类型。这有多重要?没有它你能活吗?还是之后设置您的数据类型? -
@RonRosenfeld 再次感谢!我将在第二天左右(目前正在休假)完全回答我自己的问题,但你的建议几乎就是我所做的:我稍后设置我的数据类型。我知道我可以检查 Title 的值为 null,但直到两天前我才想到我可以简单地 wait 来创建数据类型,直到 after我已经处理了空值。我将空行与非空行分离到一个单独的表中,对非空行执行数据类型创建,然后在最后将两个表再次放在一起。
标签: excel type-conversion powerquery record data-conversion