2016-11-15 36 views
0

我有臺這樣的,如果外觀和它代表的產品表列的值,其他列分裂,它的價值

enter image description here

,其中第一個列是SKU規範,並作爲ID和第2列美國規格規格標題,值和0或1作爲可選參數(如果缺少,則默認爲1)由「〜」分隔,並且ech選項由^

分隔我想將它拆分爲表格,每個規格標題爲列標題和值,因爲它的值

我設法寫這個代碼把它與俯衝規格拆分記錄,並與來自值爲每個規格和記錄分離標題,以及如何與這個

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 
+0

有一些很好的答案[在這個問題](http://stackoverflow.com/questions/36918354/extract-mobile-numbers-to-other-cells-in-excel)關於在Excel中分割字符串一個分隔符。在那裏的第一個VBA UDF可以做你所需要的很容易,它非常輕巧。 – JNevill

+2

請問您能提供代碼示例表嗎?使用Table.FromRecords或#table({},{{}}) –

+0

同意謝爾蓋,請不要只發布您的輸入數據的屏幕截圖。此外,你可以發佈你的代碼今天返回什麼,你想要它返回什麼樣的輸出? –

回答

1

好吧,我希望你仍然需要這個,因爲它花了整個晚上。 :)) 我必須說的非常有趣的任務!

我認爲「〜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 

UPDATE:

它是如何工作(跳過明顯的步驟):

TransformToLists:TransformColumns需要表,並應用到此列名稱和功能的列表列的值。所以它將幾個嵌套函數應用於每行的「規格」字段的值。這些函數執行以下操作:List.Select返回非空值,其中,爲了通過施加Text.Split函數的「規格」的值所得到的列表具有字段「」 S移除:

Text.Split(
       Text.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,使用每個行的「規格」字段的功能(記住,列表的列表)。我們使用Table.FromColumns,因爲它將列表作爲參數,並返回一個表,其中第一行是列標題,第二行是它們的值。然後我們將第一行提升爲標題。現在我們有一個表格,「規格」字段包含具有可變列數的嵌套表格。我們必須把它們放在一起。

ExpandedSpecs:Table.TransformRows適用改造功能表中的每一行(作爲記錄)(代碼它是作爲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. 
) 

它返回表(讓每個單排)的列表,我們使用Table.Combine在UnionTables一步將它們結合起來。這會導致一個表格包含組合表格中的所有列,而其中一些列中沒有這樣的列時爲空。

希望它有幫助。 :)

+0

看起來是工作。它拋出一個關於重複列「零件號」的錯誤,但我解決了它。 **「〜1」**並不總是符合規範,但是,它總是在**「^」**之前。你能解釋幾件事 - 使用「每個」,下劃線字符「_」和這種收縮「(x)=> Table.ExpandTableColumn」 – NogrTL

+0

我編輯了答案並添加了詳細的解釋。 – Eugene

+0

Thx。現在有機會理解這個每個命令的語法 – NogrTL

0

一個TextToColumns VBA解決方案尋求幫助堆棧要簡單得多如果我明白你在問什麼MSDN for Range.TextToColumns

+0

這是通常的拆分,這就像Power查詢中的「SplitTextByDelimiter」一樣,不會給機會從Value中拆分Spec-Title並保留對零件號的引用。並且我希望它能夠分成(例如 - 我發送的第一行)「零件號」,「型號」,然後用型號規格的零件號和值排它,如果它提供給零件單元 – NogrTL