表列按值分解到其他列及其值

我有这种表,如果看,它代表了产品的规格

在这里输入图像说明

第一列为SKU,第二列为规格说明书标题,值为0或1作为可选参数(如果缺less,则默认为1),用“〜”分隔,ech选项与^

我想分割它与SKU和每个规格标题作为列标题和值的表,因为它的价值

我设法编写这个代码将其分割为具有潜在规格的logging,并将每个规范和logging与标题和值分离,以及如何寻求帮助

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 

好的,我希望你整晚都还是需要这个。 :))非常有趣的任务,我必须说!

我假定“〜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接受表,以及应用于列值的列名和函数列表。 所以它将几个嵌套函数应用到每行的“规格”字段的值 。 这些函数执行以下操作:List.Select返回非空值的列表,这些值是通过将Text.Split函数应用到具有“ ”s的“Specifications”字段的值而获得的:

  Text.Split( Text.Replace(_, ":", "") , "~") 

每个关键字意味着以下函数应用于每个处理过的值(可以是字段,列,行/logging,列表项,文本,函数等),用下划线表示。 这个下划线可以被一个函数replace:

  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步骤返回一个包含两列的表:“零件号”和“规格”,其中包含列表列表。 每个列表都有两个值:列名称和值。 发生这种情况是因为“规格”字段中的初始值必须被分割两次:首先将其分割成“〜1 ^”对,然后每对被“〜”分割。 所以现在我们在每个嵌套列表中都有列名和它的值,现在我们必须将它们全部转换成一个表。

ConvertToTable :我们再次应用TransformColumns,使用每行“规格”字段的function(记住,列表清单)。 我们使用Table.FromColumns,因为它将列表作为参数,并返回一个表,其中第一行是列标题,第二行是它们的值。 然后,我们将第一行提升为标题。 现在我们有一个表,“规格”字段包含具有可变列数的嵌套表。 我们必须把它们放在一起。

ExpandedSpecs :Table.TransformRows将转换函数应用于表中的每一行(作为logging)(在它被标记为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. ) 

它返回一个表(每行有一行),我们在UnionTables步骤中使用Table.Combine进行组合 。 这将导致一个表格包含组合表格中的所有列,而在其中一些列中没有这样的列时为空值。

希望能帮助到你。 🙂

一个TextToColumns VBA解决scheme是非常简单的,如果我明白你问MSDN的Range.TextToColumns