Динамически вставляйте новые столбцы в Excel Power Query и сортируйте пары столбцов по горизонтали - PullRequest
0 голосов
/ 24 февраля 2019

Я озадачен требованием и, похоже, не могу его пройти (я пытался обыскать интернет, и сам не могу его исправить, учитывая мой ограниченный опыт работы с Power Query).Я мог бы сделать это с помощью VBA, но количество записей, которые нужно обработать, составляет полмиллиона записей!

Итак, вот упрощенная задача под рукой.Есть два столбца - «Подстрока» и «Основная строка», как показано ниже [Input] :

Substring   Main String
AB|CDE      ABCDEF
ABC|DE|GH   ABCDEFGHI
A|BC|X|YZ   ABCDYZ

В столбце Substring есть мини-подстроки, разделенные разделителем (|).Эти мини-подстроки могут быть или не быть найдены в основной строке.Вывод в конце должен выглядеть следующим образом [Ожидаемый вывод] :

Substring   Main String   MSS1  ML1   MSS2  ML2   MSS3  ML3   MSS4  ML4
AB|CDE      ABCDEF        CDE   3     AB    2     
ABC|DE|GH   ABCDEFGHI     ABC   3     DE    2     GH    2     
A|BC|X|YZ   ABCDYZ        BC    2     YZ    2     A     1     X     0

(Примечание: MSS и ML в заголовках столбцов обозначают соответственно Mini Substring и Match Length)

Количество мини-подстрок может варьироваться, поэтому в строке, содержащей максимальное количество мини-подстрок, будет определяться количество столбцов MSS и ML.В этом случае в третьем ряду их четыре, поэтому в каждом столбце было четыре столбца MSS и ML.

Мало того, последовательность этих мини-подстрок должна быть такой, чтобы те, которые имеют наибольшую совпадающую длину, были помещены в крайнюю левую пару столбцов MSS и ML.И затем те, которые имеют наименьшую длину, должны перейти на крайнюю правую пару столбцов MSS и ML.И все между ними должно развиваться в таком порядке.

Я дошел до стадии, когда токовый выход выглядит следующим образом [Промежуточный выход] :

Substring   Main String   MSS1  MSS2  MSS3  MSS4
AB|CDE      ABCDEF        AB    CDE
ABC|DE|GH   ABCDEFGHI     ABC   DE    GH
A|BC|X|YZ   ABCDYZ        A     BC    X     YZ

Динамическая вставкастолбцы ML сразу после соответствующих столбцов MSS - это проблема, от которой я не могу пройти.И я уверен, что их сортировка по горизонтали по рангу совпадающих длин (т. Е. Длин тех мини-подстрок, которые нашли совпадение в основной строке) также будет другой проблемой.Вот силовой запрос, который я мог бы придумать, который сгенерировал [Промежуточный вывод] .

let
    Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
    #"Changed Type" = Table.TransformColumnTypes(Source,{{"Sub String", type text}, {"Main String", type text}}),
    #"Duplicated Column" = Table.DuplicateColumn(#"Changed Type", "Sub String", "For Split"),
    #"Added Custom" = Table.AddColumn(#"Duplicated Column", "Split Count", each List.Count(Text.Split([Sub String],"|"))),
    #"Reordered Columns" = Table.ReorderColumns(#"Added Custom",{"Split Count", "Sub String", "Main String", "For Split"}),
    #"Max No Of Splittable Columns" = List.Max(#"Reordered Columns"[Split Count]),
    #"List Of MSS Columns" = List.Transform({1..#"Max No Of Splittable Columns"}, each "MSS"&Text.From(_)),
    #"Split Columns By Delimiter" = Table.SplitColumn(#"Reordered Columns","For Split",Splitter.SplitTextByDelimiter("|"), #"List Of MSS Columns"),
    #"Removed Columns" = Table.RemoveColumns(#"Split Columns By Delimiter",{"Split Count"})
in
    #"Removed Columns"

Не могли бы вы помочь мне выйти из этого?Вы можете легко сказать, что я новичок в Power Query, поэтому я очень ценю любую помощь, которую я могу получить.Спасибо!

1 Ответ

0 голосов
/ 25 февраля 2019

Этот код должен работать:

let
    Source = Excel.CurrentWorkbook(){[Name="Table"]}[Content],
    temp = Table.AddColumn(Source, "temp", each
[a = List.Select(Text.Split([Substring], "|"), (sub)=>Text.Contains([Main String], sub)),
b = List.Transform(a, each Text.From(Text.Length(_))),
c = Table.AddColumn(Table.AddIndexColumn(Table.FromList(a), "i", 1, 1), "key", each "MSS" & Text.From([i])),
d = Table.AddColumn(Table.AddIndexColumn(Table.FromList(b), "i", 1, 1), "key", each "ML" & Text.From([i])),
e = Table.Sort(Table.Combine({c,d}),{"i"}),
f = Table.Pivot(e[[key],[Column1]], List.Distinct(e[key]), "key", "Column1"),
count = List.Count(a)][[f],[count]]),
    expand = Table.ExpandRecordColumn(temp, "temp", {"count", "f"}),
    final = Table.ExpandTableColumn(expand, "f", List.Buffer(Table.ColumnNames(Table.Sort(expand,{"count", 1}){0}[f])))
in
    final

first

В порядке убывания длин:

let
    Source = Excel.CurrentWorkbook(){[Name="Table"]}[Content],
    temp = Table.AddColumn(Source, "temp", each
[a = List.Select(Text.Split([Substring], "|"), (sub)=>Text.Contains([Main String], sub)),
b = Table.TransformColumnTypes(Table.Sort(Table.AddColumn(Table.FromList(a), "len", each Text.Length([Column1])), {{"len", 1},{"Column1",0}}), {"len", type text}),
c = Table.AddColumn(Table.AddIndexColumn(Table.FromList(b[Column1]), "i", 1, 1), "key", each "MSS" & Text.From([i])),
d = Table.AddColumn(Table.AddIndexColumn(Table.FromList(b[len]), "i", 1, 1), "key", each "ML" & Text.From([i])),
e = Table.Sort(Table.Combine({c,d}),{"i"}),
f = Table.Pivot(e[[key],[Column1]], List.Distinct(e[key]), "key", "Column1"),
count = List.Count(a)][[f],[count]]),
    expand = Table.ExpandRecordColumn(temp, "temp", {"count", "f"}),
    final = Table.ExpandTableColumn(expand, "f", List.Buffer(Table.ColumnNames(Table.Sort(expand,{"count", 1}){0}[f])))
in
    final

second

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...