我有一个用例,其中有多个列包含要动态扩展的记录。意味着要扩展的列的名称不是硬编码的。
Expanded = Table.ExpandRecordColumn(Source, "HardcodedColumnName", {"fieldname"}, {"fieldname"}),
下面的我的M代码可以基于转换表动态扩展记录。但是我也无法理解如何动态扩展列名。对于上下文,我的实际数据集有很多列需要扩展,并且列的数量会随时间而变化。我正在寻找扩展所有这些列的可扩展方法。
let
//Use-case: dynamically expand 'name for 'user' and 'timezone' for 'city',
// i e expand records w/o hardcoded column- or field names
Source = Table.FromRecords(
{
[key = 1, user = [id = 10, name = "Wayne Carter"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]],
[key = 2, user = [id = 20, name = "Hugh Jass"], city = [id = 1, name = "Milan", timezone = "Central European Time"]],
[key = 3, user = [id = 30, name = "Ben Dover"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]]
}),
//Table controls which attribute to expand
TransformationTable = Table.FromRecords(
{
[field = "user", attribute = "name"],
[field = "city", attribute = "timezone"]
}),
//Transformation table lookup
AttributeLookup = (parameter as text) =>
let
value = Table.SelectRows(TransformationTable, each ([field] = parameter))[attribute]{0}
in
value,
//These rows are hardcoded for columns 'user' and 'city' - how to make this dynamic?
ExpandedTable1 = Table.ExpandRecordColumn(Source, "user", {AttributeLookup("user")}, {AttributeLookup("user")}),
ExpandedTable2 = Table.ExpandRecordColumn(ExpandedTable1, "city", {AttributeLookup("city")}, {AttributeLookup("city")}),
in
ExpandedTable2
我认为您可以使用下面的代码来实现这一目标:
let
someTable = Table.FromRecords({
[key = 1, user = [id = 10, name = "Wayne Carter"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]],
[key = 2, user = [id = 20, name = "Hugh Jass"], city = [id = 1, name = "Milan", timezone = "Central European Time"]],
[key = 3, user = [id = 30, name = "Ben Dover"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]]
}),
expansionMap = [
user = {"name"},
city = {"timezone"}
],
dynamicallyExpanded = List.Accumulate(Record.FieldNames(expansionMap), someTable, (tableState as table, recordColumnName as text) as table =>
let
fieldNamesToExpand = Record.Field(expansionMap, recordColumnName),
fieldNamesAfterExpansion = fieldNamesToExpand,
expanded = Table.ExpandRecordColumn(tableState, recordColumnName, fieldNamesToExpand, fieldNamesAfterExpansion)
in expanded
)
in
dynamicallyExpanded
expansionMap
是record
,其中:user
,city
)映射到包含记录的列的名称(需要扩展){"name"}
和{"timezone"}
)映射到嵌套字段(最终将成为扩展表中的列)。expansionMap
中的字段名称,同时迭代扩展每个指定的记录列。id
记录列中扩展user
,并在id
记录列中扩展city
,我想您应该最终得到一个错误(假设已经有一个名为id
的列)。为了避免这种情况,您可以实施一些逻辑来重命名扩展的列,使它们不匹配任何现有的列名。例如,您可以将代码中的相关行更改为:fieldNamesAfterExpansion = List.Transform(fieldNamesToExpand, each Text.Combine({recordColumnName, _}, ".")),
。这不是真正的动态。也就是说,您在编写代码时就已经知道记录列的名称(要扩展)。但是,如果我正确理解了您的问题,那么您只想通过某种抽象结构来表示您的记录列,并编写一些可以使用/处理该结构的代码。