Table.TransformColumnTypes vs Table.TransformColumns - преобразование пачкой и причём тут локаль?

#АнатомияФункций – custom



Всем привет!



Оказалось, что кто-то всё ещё читает старый добрый Танк )))

По этому поводу подкинули вопрос, как оказалось вот по этому посту.



Суть – надо преобразовать типы столбцов пачкой. Это не проблема, проблема в том, что при преобразовании чисел где-то нужна русская локаль, а где-то вполне себе иностранная. TransformColumnTypes при этом содержит локаль в третьем аргументе и подразумевает, что она одна.



По этому поводу получился код:

let

lst={{{"Дата"},Date.From},

{{"Проживают","Комнат","Хозпостройки","Год","МПИ"},Int64.From},

{{"P по "},Number.From},

{{"Площадь"},(x)=>Number.FromText(x,"en")}},

tbl=Excel.CurrentWorkbook(){[Name="table"]}[Content]

in

fnTableTransformColumnTypes(tbl,lst,Text.From)


lst - идея в том, что у нас есть список списков из списка и функции – где список содержит ключевые слова, по которым мы определяем нужный столбец, а функция отвечает за преобразование. При этом функции .From автоматом зададут типы столбцов после преобразования. При этом смотрим на Number.FromText – туда мы передали локаль, в то время как обычный Number.From будет работать с текущей. Ну и в целом такой список не обязательно писать ручками – вполне можно получать из какой-нибудь таблицы преобразований.

tbl – подключение к таблице



ну и далее вызываем загадочную fnTableTransformColumnTypes от полученных таблицы и списка, а в третий аргумент отправили Text.From – преобразование по умолчанию.

Что под капотом у функции:

(tbl as table, lst as list, def as function) =>

[f=(x)=>{x,List.Skip(lst,(j)=>not List.Contains(j{0},x,(x,y)=>Text.Contains(y,x))){0}?{1}? ?? def},

nms = Table.ColumnNames(tbl),

tr = List.Transform(nms,f),

to = Table.TransformColumns(tbl,tr)][to]


f – функция, которая сооружает из аргумента x список вида {x,функция}. Функцию мы находим во втором аргументе lst – для этого идём по нему и проверяем первый элемент (список ключевых слов) на наличие нужного текста – если нашли, возвращаем второй элемент – функцию, если ничего не найдено – возвращаем функцию по умолчанию

nms – получаем список имён полей таблицы

tr – ну и выясняем как какой столбец надо преобразовать

to - полученный список преобразований отправляем в Table.TransformColumns, получая на выходе таблицу с преобразованными и типизированными столбцами.



Как-то так – немножко неочевидно, но Table.TransformColumns позволила нам преобразовать всё пачкой, но при этом использовать другую локаль для части столбцов.



Надеюсь, было полезно.

Всех благ!

@buchlotnik