Table 列按值拆分为其他列及其值
Table column split by value to other columns and it's values
我有table这种如果看起来代表产品规格
其中第 1 列是 SKU,用作 ID,第 2 列是我们的规格规格标题、值和 0 或 1 作为可选参数(如果缺少,则默认为 1)由“~”分隔,每个选项由 ^ 分隔
我想将其拆分为 table,SKU 和每个规格标题作为列 header,值作为它的值
我设法编写了这段代码,将其拆分为具有潜水规格的记录和堆栈,并将每个规格和记录的标题与值分开,以及如何寻求帮助
let
Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
Type = Table.TransformColumnTypes(Source,{{"Part Number", type text}, {"Specifications", type text}}),
#"Replaced Value" = Table.ReplaceValue(Type,"Specification##","",Replacer.ReplaceText,{"Specifications"}),
SplitByDelimiter = (table, column, delimiter) =>
let
Count = List.Count(List.Select(Text.ToList(Table.Column(table, column){0}), each _ = delimiter)) + 1,
Names = List.Transform(List.Numbers(1, Count), each column & "." & Text.From(_)),
Types = List.Transform(Names, each {_, type text}),
Split = Table.SplitColumn(table, column, Splitter.SplitTextByDelimiter(delimiter), Names),
Typed = Table.TransformColumnTypes(Split, Types)
in
Typed,
Split = SplitByDelimiter(#"Replaced Value","Specifications","^"),
Record = Table.ToRecords(Split)
in
Record
TextToColumns
VBA 如果我理解你的问题,解决方案就简单多了MSDN for Range.TextToColumns
好的,我希望你仍然需要这个,因为它花了整个晚上。 :))
我必须说非常有趣的任务!
我假设 "~1" 总是与 "^" 组合,所以 "~1^ " 始终以字段值结尾。我还假设值中没有 ":",因为所有冒号都被删除了。
IMO,你根本不需要使用 Table.SplitColumn 功能。
let
//replace it with your Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
Source = #table(type table [Part Number = Int64.Type, Specifications = text], {{104, "Model:~104~1^Type:~Watch~1^Metal Type~Steel~1"}, {105, "Model:~105~1^Type:~Watch~1^Metal Type~Titanium~1^Gem Type~Ruby~1"}}),
//I don't know why do you replace these values, do you really need this?
ReplacedValue = Table.ReplaceValue(Source,"Specification##","",Replacer.ReplaceText,{"Specifications"}),
TransformToLists = Table.TransformColumns(Source, {"Specifications", each List.Transform(List.Select(Text.Split(_ & "^", "~1^"), each _ <> "") , each Text.Split(Text.Replace(_, ":", ""), "~")) } ),
ConvertToTable = Table.TransformColumns(TransformToLists, {"Specifications", each Table.PromoteHeaders(Table.FromColumns(_))}),
ExpandedSpecs = Table.TransformRows(ConvertToTable, (x) => Table.ExpandTableColumn(Table.FromRecords({x}), "Specifications", Table.ColumnNames(x[Specifications])) ),
UnionTables = Table.Combine(ExpandedSpecs),
Output = UnionTables
in
Output
更新:
它是如何工作的(跳过明显的步骤):
TransformToLists:TransformColumns 采用 table,以及应用于 的列名和函数列表这个 列的值。所以它将几个嵌套函数应用于每行"Specifications"字段的值。这些函数执行以下操作:List.Select returns non-empty 值列表,按顺序通过将 Text.Split 函数应用于具有“ :"s 已删除:
Text.Split(
Text.Replace(_, ":", "")
, "~")
Each关键字表示后面的函数应用于每一个处理过的值(可以是字段、列、row/record、列表项、文本、函数等),用下划线表示。这个下划线可以用函数代替:
each _ equals (x) => some_function_that_returns_corresponding_value(x)
所以,
each Text.Replace(_, ":", "")
equals
(x) => Text.Replace(x, ":", "") //where x is any variable name.
//You can go further and make it typed, although generally it is not needed:
(x as text) => Text.Replace(x, ":", "")
//You can also write a custom function and use it:
(x as text) => CustomFunctionName(x)
话虽如此,TransformToLists 步骤 returns 具有两列的 table:"Part number" 和 "Specifications",包含列表列出。这些列表中的每一个都有两个值:列名及其值。发生这种情况是因为 "Specifications" 字段中的初始值必须拆分两次:首先它被“~1^”拆分成对,然后每一对被“~”拆分。所以现在我们在每个嵌套列表中都有列名及其值,现在我们必须将它们全部转换为单个 table.
ConvertToTable:我们再次应用 TransformColumns,对每一行的 "Specifications" 字段使用一个函数(记住,一个列表列表)。我们使用 Table.FromColumns,因为它需要列表的列表作为参数,并且它 returns a table 其中第一行是列 headers,第二行是它们的值。然后我们将第一行提升到 headers。现在我们有一个 table 和 "Specifications" 字段,其中包含具有可变列数的嵌套 table。我们必须把它们放在一起。
ExpandedSpecs:Table.TransformRows 将转换函数应用于 table 中的每一行(作为记录) (在代码中它被签名为 x)。您可以像我一样编写自定义函数:
= Table.ExpandTableColumn( //this function expands nested table. It needs a table, but "x" that we have is a record. So we do the conversion:
Table.FromRecords({x}) //function takes a list of records, so {x} means a list with single value of x
, "Specifications" //Column to expand
, Table.ColumnNames(x[Specifications]) //3rd argument is a list of resulting columns. It takes table as an argument, and table is contained within "Specifications" field.
)
它 returns 一个 table 的列表(每行只有一行),我们使用 Table.Combine 在 UnionTables步。这导致 table 具有组合 table 中的所有列,当其中一些列中没有这样的列时为空值。
希望对您有所帮助。 :)
我有table这种如果看起来代表产品规格
其中第 1 列是 SKU,用作 ID,第 2 列是我们的规格规格标题、值和 0 或 1 作为可选参数(如果缺少,则默认为 1)由“~”分隔,每个选项由 ^ 分隔
我想将其拆分为 table,SKU 和每个规格标题作为列 header,值作为它的值
我设法编写了这段代码,将其拆分为具有潜水规格的记录和堆栈,并将每个规格和记录的标题与值分开,以及如何寻求帮助
let
Source = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
Type = Table.TransformColumnTypes(Source,{{"Part Number", type text}, {"Specifications", type text}}),
#"Replaced Value" = Table.ReplaceValue(Type,"Specification##","",Replacer.ReplaceText,{"Specifications"}),
SplitByDelimiter = (table, column, delimiter) =>
let
Count = List.Count(List.Select(Text.ToList(Table.Column(table, column){0}), each _ = delimiter)) + 1,
Names = List.Transform(List.Numbers(1, Count), each column & "." & Text.From(_)),
Types = List.Transform(Names, each {_, type text}),
Split = Table.SplitColumn(table, column, Splitter.SplitTextByDelimiter(delimiter), Names),
Typed = Table.TransformColumnTypes(Split, Types)
in
Typed,
Split = SplitByDelimiter(#"Replaced Value","Specifications","^"),
Record = Table.ToRecords(Split)
in
Record
TextToColumns
VBA 如果我理解你的问题,解决方案就简单多了MSDN for Range.TextToColumns
好的,我希望你仍然需要这个,因为它花了整个晚上。 :)) 我必须说非常有趣的任务!
我假设 "~1" 总是与 "^" 组合,所以 "~1^ " 始终以字段值结尾。我还假设值中没有 ":",因为所有冒号都被删除了。
IMO,你根本不需要使用 Table.SplitColumn 功能。
let
//replace it with your Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
Source = #table(type table [Part Number = Int64.Type, Specifications = text], {{104, "Model:~104~1^Type:~Watch~1^Metal Type~Steel~1"}, {105, "Model:~105~1^Type:~Watch~1^Metal Type~Titanium~1^Gem Type~Ruby~1"}}),
//I don't know why do you replace these values, do you really need this?
ReplacedValue = Table.ReplaceValue(Source,"Specification##","",Replacer.ReplaceText,{"Specifications"}),
TransformToLists = Table.TransformColumns(Source, {"Specifications", each List.Transform(List.Select(Text.Split(_ & "^", "~1^"), each _ <> "") , each Text.Split(Text.Replace(_, ":", ""), "~")) } ),
ConvertToTable = Table.TransformColumns(TransformToLists, {"Specifications", each Table.PromoteHeaders(Table.FromColumns(_))}),
ExpandedSpecs = Table.TransformRows(ConvertToTable, (x) => Table.ExpandTableColumn(Table.FromRecords({x}), "Specifications", Table.ColumnNames(x[Specifications])) ),
UnionTables = Table.Combine(ExpandedSpecs),
Output = UnionTables
in
Output
更新:
它是如何工作的(跳过明显的步骤):
TransformToLists:TransformColumns 采用 table,以及应用于 的列名和函数列表这个 列的值。所以它将几个嵌套函数应用于每行"Specifications"字段的值。这些函数执行以下操作:List.Select returns non-empty 值列表,按顺序通过将 Text.Split 函数应用于具有“ :"s 已删除:
Text.Split(
Text.Replace(_, ":", "")
, "~")
Each关键字表示后面的函数应用于每一个处理过的值(可以是字段、列、row/record、列表项、文本、函数等),用下划线表示。这个下划线可以用函数代替:
each _ equals (x) => some_function_that_returns_corresponding_value(x)
所以,
each Text.Replace(_, ":", "")
equals
(x) => Text.Replace(x, ":", "") //where x is any variable name.
//You can go further and make it typed, although generally it is not needed:
(x as text) => Text.Replace(x, ":", "")
//You can also write a custom function and use it:
(x as text) => CustomFunctionName(x)
话虽如此,TransformToLists 步骤 returns 具有两列的 table:"Part number" 和 "Specifications",包含列表列出。这些列表中的每一个都有两个值:列名及其值。发生这种情况是因为 "Specifications" 字段中的初始值必须拆分两次:首先它被“~1^”拆分成对,然后每一对被“~”拆分。所以现在我们在每个嵌套列表中都有列名及其值,现在我们必须将它们全部转换为单个 table.
ConvertToTable:我们再次应用 TransformColumns,对每一行的 "Specifications" 字段使用一个函数(记住,一个列表列表)。我们使用 Table.FromColumns,因为它需要列表的列表作为参数,并且它 returns a table 其中第一行是列 headers,第二行是它们的值。然后我们将第一行提升到 headers。现在我们有一个 table 和 "Specifications" 字段,其中包含具有可变列数的嵌套 table。我们必须把它们放在一起。
ExpandedSpecs:Table.TransformRows 将转换函数应用于 table 中的每一行(作为记录) (在代码中它被签名为 x)。您可以像我一样编写自定义函数:
= Table.ExpandTableColumn( //this function expands nested table. It needs a table, but "x" that we have is a record. So we do the conversion:
Table.FromRecords({x}) //function takes a list of records, so {x} means a list with single value of x
, "Specifications" //Column to expand
, Table.ColumnNames(x[Specifications]) //3rd argument is a list of resulting columns. It takes table as an argument, and table is contained within "Specifications" field.
)
它 returns 一个 table 的列表(每行只有一行),我们使用 Table.Combine 在 UnionTables步。这导致 table 具有组合 table 中的所有列,当其中一些列中没有这样的列时为空值。
希望对您有所帮助。 :)