Привет! С помощью дипсика создали код на М, который раскрывает все сложенные таблицы из загруженных из папки файлов xml. Код работает но очень долго. При тестировании были несколько ошибок, который ДипСик успешно поправил. Нет ли у кого-то, друзья, какого-нибудь более изящного, но главное, менее затратного варианта? просто файлов всего 20+, а когда будет 200 даже не представляю как оно должно будет работать.
В последней строке кода (FinalResult = IterativeExpand(Source, 1, 12)) 12 - это максимальное количество циклов, которое можно изменять, но вручную.
В последней строке кода (FinalResult = IterativeExpand(Source, 1, 12)) 12 - это максимальное количество циклов, которое можно изменять, но вручную.
| Код |
|---|
(tbl as table) =>
let
Source = tbl,
// Функция для очистки имен столбцов
CleanColumnName = (name) =>
let
// Заменяем проблемные символы на подчеркивания
Cleaned = Text.Replace(name, ":", "_"),
Cleaned2 = Text.Replace(Cleaned, "/", "_"),
Cleaned3 = Text.Replace(Cleaned2, ".", "_"),
Cleaned4 = Text.Replace(Cleaned3, "-", "_"),
Cleaned5 = Text.Replace(Cleaned4, " ", "_")
in
Cleaned5,
// Функция для проверки наличия табличных столбцов
HasTableColumns = (inputTable) =>
let
ColumnNames = Table.ColumnNames(inputTable),
HasTables = List.AnyTrue(List.Transform(ColumnNames, each
let
firstValueRaw = try Table.FirstValue(Table.SelectColumns(inputTable, _)) otherwise null,
// Заменяем пустые строки на null
firstValue = if firstValueRaw = "" then null else firstValueRaw
in
firstValue <> null and Value.Is(firstValue, type table)))
in
HasTables,
// Функция для преобразования пустых строк в null в табличных столбцах
ReplaceEmptyStrings = (inputTable) =>
let
ColumnNames = Table.ColumnNames(inputTable),
// Находим столбцы, которые могут содержать таблицы
PotentialTableColumns = List.Select(ColumnNames, each
let
firstValueRaw = try Table.FirstValue(Table.SelectColumns(inputTable, _)) otherwise null,
firstValue = if firstValueRaw = "" then null else firstValueRaw
in
firstValue <> null and Value.Is(firstValue, type table)),
// Заменяем пустые строки на null в этих столбцах
ResultTable = List.Accumulate(
PotentialTableColumns,
inputTable,
(state, column) =>
Table.TransformColumns(state, {{
column,
each if _ = "" then null else _,
type any
}})
)
in
ResultTable,
// Функция для раскрытия всех табличных столбцов за один проход
ExpandAllTables = (inputTable) =>
let
// Сначала заменяем пустые строки на null
CleanedTable = ReplaceEmptyStrings(inputTable),
// Находим все табличные столбцы
ColumnNames = Table.ColumnNames(CleanedTable),
TableColumns = List.Select(ColumnNames, each
let
firstValueRaw = try Table.FirstValue(Table.SelectColumns(CleanedTable, _)) otherwise null,
// Заменяем пустые строки на null
firstValue = if firstValueRaw = "" then null else firstValueRaw
in
firstValue <> null and Value.Is(firstValue, type table)),
// Раскрываем все табличные столбцы за один проход
ExpandedTable = List.Accumulate(
TableColumns,
CleanedTable,
(state, column) =>
let
SampleValueRaw = try Table.FirstValue(Table.SelectColumns(state, column)) otherwise null,
// Заменяем пустые строки на null
SampleValue = if SampleValueRaw = "" then null else SampleValueRaw,
IsTableValue = SampleValue <> null and Value.Is(SampleValue, type table),
ResultTable = if not IsTableValue then
state
else
let
NestedColumns = Table.ColumnNames(SampleValue),
CleanedNestedColumns = List.Transform(NestedColumns, each CleanColumnName(_)),
PrefixedColumns = List.Transform(CleanedNestedColumns, each CleanColumnName(column) & "_" & _),
Expanded = Table.ExpandTableColumn(state, column, NestedColumns, PrefixedColumns)
in
Expanded
in
ResultTable
)
in
ExpandedTable,
// Итеративный процесс раскрытия таблиц с проверкой завершения
IterativeExpand = (inputTable, iteration, maxIterations) =>
let
// Проверяем, есть ли еще табличные столбцы
HasTables = HasTableColumns(inputTable),
// Проверяем, не достигли ли мы максимального количества итераций
ShouldContinue = HasTables and iteration < maxIterations,
Result = if not ShouldContinue then
inputTable
else
let
Expanded = ExpandAllTables(inputTable),
NextIteration = @IterativeExpand(Expanded, iteration + 1, maxIterations)
in
NextIteration
in
Result,
// Запускаем процесс с максимальным количеством итераций = 10
FinalResult = IterativeExpand(Source, 1, 12)
in
FinalResult |
Изменено: - 20.09.2025 10:29:25