1С.Разбираем многоуровневую шапку
#1C - шапка
Всем привет!
Многоуровневые шапки таблиц, выгруженных из 1С никогда не добавляют счастья (Примеры таких таблиц найдете в Первом комментарии к посту.)
Зачастую пользователь начинает «руками» исправлять шапку таблицы, чтобы привести ее в удобную форму для дальнейшей работы.
Со своей стороны предложим несколько способов в помощь:
1. Для простой многоуровневой шапки таблицы, когда заполнены все заголовки полей (см. Пример1 в приложении) на просторах интернета можно увидеть такое:
Коротко про подход: Транспонируем таблицу, комбайним через разделитель , снова транспонируем и поднимаем заголовки. Далее таблицу можно свернуть для работы со сводной:
2. Для шапки, в которой заполнены не все поля (см. Пример 2) можно воспользоваться следующим кодом:
Подход так же не сложный: «Откусили» шапку, преобразовали и приставили заново к телу таблицы.
Но что если уровней в таблице три и более или структура шапки похожа на таблицу в Примере 3 ?
3. На помощь может прийти решение, которое в большинстве случаев преобразует шапку таблицы в «плоский» формат:
Разберем данный код.
Эта функция анализирует первые несколько строк таблицы table, указанных в параметре num, далее по столбцам идёт объединение текста с использованием в качестве разделителя параметра delim. Опционально четвертый параметр fill позволяет задать строковое значение, которое будет использовано для заголовков нижних уровней в случае их отсутствия в данном столбце.
lst: Преобразуем в список строки таблицы с шапкой
delim: Опрашиваем входящий параметр-разделитель и при его отсутствии устанавливаем пробел
g: проверка параметра fill и если оно ненулевое, то добавляем к значению поля параметр, переданный в функцию fnParshead.
f: на вход подаем два списка, связываем попарно и обрабатываем.
gen: Генератор, который собирает список для будущего заголовка таблицы в комплексе с функциями f и g.
Попробуйте на приложенных примерах разобрать каждый подход. И если что-то окажется полезным – значит все было не зря.
В большей степени пост предназначен для начинающих и продолжающих изучать функциональное программирование, хотя и профессионалы, надеюсь, смогут найти тут для себя что-то интересное.
Примеры, представленные выше показывают, как через редактор можно решить насущную задачу по разбору многоуровневой шапки. Так же предлагаю попробовать решить приложенные примеры, не прибегая к коду:
(
С уважением к Вам. @CubRoot
PS^ Михаил, спасибо за помощь )
#1C - шапка
Всем привет!
Многоуровневые шапки таблиц, выгруженных из 1С никогда не добавляют счастья (Примеры таких таблиц найдете в Первом комментарии к посту.)
Зачастую пользователь начинает «руками» исправлять шапку таблицы, чтобы привести ее в удобную форму для дальнейшей работы.
Со своей стороны предложим несколько способов в помощь:
1. Для простой многоуровневой шапки таблицы, когда заполнены все заголовки полей (см. Пример1 в приложении) на просторах интернета можно увидеть такое:
from=ИсточникДанных,
t=Table.Transpose(from),
mergecol = Table.CombineColumns(t,{"Column1", "Column2"},Combiner.CombineTextByDelimiter(".", QuoteStyle.None),"Headers"),
tr=Table.Transpose(mergecol),
to=Table.PromoteHeaders(tr)
Коротко про подход: Транспонируем таблицу, комбайним через разделитель , снова транспонируем и поднимаем заголовки. Далее таблицу можно свернуть для работы со сводной:
Table.UnpivotOtherColumns ()
2. Для шапки, в которой заполнены не все поля (см. Пример 2) можно воспользоваться следующим кодом:
from = ИсточникДанных,
lst=Table.ToColumns(Table.Range(from,0,2)),
newl=Table.ToList(Table.FillDown(Table.FromList(lst,(x)=>x),{"Column1"}),(x)=>x),
tr=List.Transform(newl,(x)=>Text.Combine(x,".")),
to=Table.RenameColumns(Table.Range(from,2),List.Zip({Table.ColumnNames(from),tr}))
Подход так же не сложный: «Откусили» шапку, преобразовали и приставили заново к телу таблицы.
Но что если уровней в таблице три и более или структура шапки похожа на таблицу в Примере 3 ?
3. На помощь может прийти решение, которое в большинстве случаев преобразует шапку таблицы в «плоский» формат:
fnParsHead=(table,num,optional delim,optional fill)=>
[ lst = List.Buffer(Table.ToColumns(Table.Range(table,0,num))),
delim = if delim=null then " " else delim,
f=(x,y)=>List.Accumulate( List.Zip({x,y}),
[i=false,j={}],
(s,c)=>[i=s[i]=true or c{0}<>null,j=if i then s[j]&{c{0}} else s[j]&{c{0}??c{1}}]
)[j],
g=(x)=>if fill=null then Text.Combine(x,delim) else Text.Combine(List.ReplaceValue(x,null,fill,Replacer.ReplaceValue),delim),
gen = List.Generate( ()=>[i=0,l=lst{i},o=l],
(x)=>x[i]<List.Count(lst),
(x)=>[i=x[i]+1,l=lst{i},o=f(l,x[o])],
(x)=>g(x[o])
),
out = Table.RenameColumns(Table.Range(table,num),List.Zip({Table.ColumnNames(table),gen}))][out],
from=ИсточникДанных,
to=fnParsHead(from,3,".")
Разберем данный код.
Эта функция анализирует первые несколько строк таблицы table, указанных в параметре num, далее по столбцам идёт объединение текста с использованием в качестве разделителя параметра delim. Опционально четвертый параметр fill позволяет задать строковое значение, которое будет использовано для заголовков нижних уровней в случае их отсутствия в данном столбце.
lst: Преобразуем в список строки таблицы с шапкой
delim: Опрашиваем входящий параметр-разделитель и при его отсутствии устанавливаем пробел
g: проверка параметра fill и если оно ненулевое, то добавляем к значению поля параметр, переданный в функцию fnParshead.
f: на вход подаем два списка, связываем попарно и обрабатываем.
gen: Генератор, который собирает список для будущего заголовка таблицы в комплексе с функциями f и g.
Попробуйте на приложенных примерах разобрать каждый подход. И если что-то окажется полезным – значит все было не зря.
В большей степени пост предназначен для начинающих и продолжающих изучать функциональное программирование, хотя и профессионалы, надеюсь, смогут найти тут для себя что-то интересное.
Примеры, представленные выше показывают, как через редактор можно решить насущную задачу по разбору многоуровневой шапки. Так же предлагаю попробовать решить приложенные примеры, не прибегая к коду:
(
мышкоклацем
) – что получится?С уважением к Вам. @CubRoot
PS^ Михаил, спасибо за помощь )