Вы можете попробовать что-то вроде кода ниже. Я непосредственно присваиваю текст (вставленный из вашего вопроса) в выражение, но полагаю, что вы загружаете текстовый файл через File.Contents
вместе с Text.FromBinary
или Lines.FromBinary
(или чем-то похожим).
Подход 1
let
textFromFile = "<SUB A=a; B=b; C=c; D=d <END <SUB A=e; B=f; C=g; D=h <END <SUB A=i; B=j; C=k; D=l <END", // copy-pasted from your question
betweenEachSubAndEnd =
let
startIndexes = List.Transform(Text.PositionOf(textFromFile, "<SUB", Occurrence.All), each _ + Text.Length("<SUB")),
endIndexes = Text.PositionOf(textFromFile, "<END", Occurrence.All),
tableOfIndexes = Table.FromColumns({startIndexes, endIndexes}, type table [start = Int64.Type, end = Int64.Type]),
extractText = Table.AddColumn(tableOfIndexes, "extracted", each Text.Range(textFromFile, [start], [end] - [start]), type text)
in extractText,
SplitAndCleanIntoRecords = (textToParse as text) as record =>
let
splitOnVerticalDelimiter = Text.Split(textToParse, ";"),
whitespaceTrimmed = List.Transform(splitOnVerticalDelimiter, Text.Trim),
keyValuePairs = List.Transform(whitespaceTrimmed, each Text.Split(_, "=")),
accumulatedRecords = List.Accumulate(keyValuePairs, [], (recordState, currentPair) => Record.AddField(recordState, currentPair{0}, currentPair{1}))
in accumulatedRecords,
recordColumn = Table.AddColumn(betweenEachSubAndEnd, "toExpand", each SplitAndCleanIntoRecords([extracted]), type record),
expanded =
let
headersToExpand = List.Distinct(List.Combine(List.Transform(recordColumn[toExpand], Record.FieldNames))),
removeOtherColumns = Table.SelectColumns(recordColumn, {"toExpand"}),
expandColumn = Table.ExpandRecordColumn(removeOtherColumns, "toExpand", headersToExpand)
in expandColumn
in
expanded
Я начинаю с такого текста:
и в итоге получится таблица, подобная этой:
Подход 2
let
textFromFile = "<SUB A=a; B=b; C=c; D=d <END <SUB A=e; B=f; C=g; D=h <END <SUB A=i; B=j; C=k; D=l <END A=m; B=n; B=o; C= null<END",
replaceSubAndEnd = List.Accumulate({"<SUB", "<END"}, textFromFile, (textState as text, currentValueToReplace as text) as text => Text.Replace(textState, currentValueToReplace, ";")),
SplitAndTrimEach = (textToSplit as text, delimiter as text) as list =>
let
split = Text.Split(textToSplit, delimiter),
trimmed = List.Transform(split, Text.Trim)
in trimmed,
splitOnVerticalDelimiter = SplitAndTrimEach(replaceSubAndEnd, ";"),
dropEmpty = List.Select(splitOnVerticalDelimiter, each _ <> ""),
keyValuePairs = List.Transform(dropEmpty, each SplitAndTrimEach(_, "=")),
toTable = Table.FromRows(keyValuePairs, {"header", "value"}),
grouped = Table.Group(toTable, {"header"}, {{"columns", each _[value], type list}}),
transformedTable = Table.FromColumns(grouped[columns], grouped[header])
in
transformedTable
(Для реализации откройте редактор запросов, нажмите Advanced editor
, скопируйте и вставьте код выше. Вам нужно будет настроить код для загрузки текстового файла.)