Рекурсия, Folder.Contents или побеждаем слишком длинные имена файлов
#АнатомияФункций - Folder.Contents
Всем привет!
Продолжаем тему рекурсии. Сегодня побеждаем слишком длинные имена файлов, а для этого вместо Folder.Files используем Folder.Contents и пишем рекурсивный обход содержимого.
Что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Folder.Contents
Всем привет!
Продолжаем тему рекурсии. Сегодня побеждаем слишком длинные имена файлов, а для этого вместо Folder.Files используем Folder.Contents и пишем рекурсивный обход содержимого.
let
from = Folder.Contents("C:\Users\muzyk\Desktop\папка1"),
f=(x)=>[a=Table.SelectRows(x,(r)=>r[Extension]<>""),
b=Table.SelectRows(x,(r)=>r[Extension]="")[Content],
c=if b={} then x else @f(List.Accumulate(b,a,(s,c)=>[a=try Table.RowCount(c) otherwise 0,
b=if a=0 then s else s&c][b]))][c],
to=f(from)
in
to
Что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
19 - На М - Рекурсия, Folder.Contents или побеждаем слишком длинные имена
Продолжаем тему рекурсии. Сегодня побеждаем слишком длинные имена файлов, а для этого вместо Folder.Files используем Folder.Contents и пишем рекурсивный обход содержимого.
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40…
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40…
Получаем форматы для ячеек - жирный шрифт, жёлтая заливка и т.д.
#АнатомияФункций - Xml.Tables, Xml.Document
Всем привет!
Пришло время ответить на вопрос - можно ли получить данные только из ячеек, залитых жёлтым, или с красным шрифтом, или жирным и т.п. Глобально – можно., но…
Получилось долго, потому как там всё непросто - так что решайте сами, надо ли вам оно )))
Вот код:
Ну а что тут к чему – смотрим почти час на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Xml.Tables, Xml.Document
Всем привет!
Пришло время ответить на вопрос - можно ли получить данные только из ячеек, залитых жёлтым, или с красным шрифтом, или жирным и т.п. Глобально – можно., но…
Получилось долго, потому как там всё непросто - так что решайте сами, надо ли вам оно )))
Вот код:
let
file = File.Contents("путь/файл.xlsx"),
unz = fxUnzip(file),
book = Table.SelectRows(Excel.Workbook(file,false),(r)=>r[Kind]="Sheet"),
style = Xml.Tables(unz{[Name="xl/styles.xml"]}[Value]),
cellstyle=Table.Buffer(style{[Name="cellXfs"]}[Table]{0}[xf]),
font=style{[Name="fonts"]}[Table]{0}[font],
fill=style{[Name="fills"]}[Table]{0}[fill],
n=1,
sheet=book{n-1}[Data],
sheetdata=Xml.Document(unz{[Name="xl/worksheets/sheet"&Text.From(n)&".xml"]}[Value]){0}[Value]{[Name="sheetData"]}[Value],
f=(x)=>Number.From(x{0}[Attributes]{[Name="s"]}?[Value]?),
tr=Table.TransformColumns(sheetdata,{{"Attributes",(x)=>x{[Name="r"]}[Value]},{"Value",f}}),
dict=Record.FromList(tr[Value],tr[Attributes]),
min=List.Min(List.Transform(tr[Attributes],Number.From)),
add=Table.AddIndexColumn(sheet,"row",min),
tr1=Table.TransformColumns(add,{"row",(x)=>Record.FieldOrDefault(dict,Text.From(x))}),
tr2=Table.TransformColumns(tr1,{"row",(x)=>if x=null then null else cellstyle{x}}),
tr3=Table.TransformColumns(tr2,{"row",(x)=>[a=Number.From(x[#"Attribute:fontId"]?),b=if a=null then null else font{a}[b]][b]}),
skip = Table.PromoteHeaders(Table.Skip(tr3,(r)=>r[Column7]=null)),
to = Table.SelectRows(skip, each ([Column8] = ""))
/*цвет шрифта - tr3=Table.TransformColumns(tr2,{"row",(x)=>[a=Number.From(x[#"Attribute:fontId"]?),b=if a=null then null else font{a}[color]{0}[#"Attribute:rgb"]?][b]})
цвет заливки - tr3=Table.TransformColumns(tr2,{"row",(x)=>[a=Number.From(x[#"Attribute:fillId"]?),b=if a=null then null else fill{a}[patternFill][fgColor]?{0}?{0}?[#"Attribute:rgb"]?][b]})*/
in
to
Ну а что тут к чему – смотрим почти час на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
20 - На М - Получаем форматы для ячеек - жирный шрифт, жёлтая заливка и т.д.
Разбираем ответ на вопрос - можно ли получить данные только из ячеек, залитых жёлтым, или с красным шрифтом, или жирным и т.п.
Получилось долго, потому как там всё непросто - так что решайте сами, надо ли вам оно )))
Кому интересно:
мой курс по Power Query…
Получилось долго, потому как там всё непросто - так что решайте сами, надо ли вам оно )))
Кому интересно:
мой курс по Power Query…
MCMLXXXVIII=1988 или преобразуем римскую запись числа в нормальную
#АнатомияФункций - List.Zip
Всем привет!
Решил разобрать задачку на преобразование римской записи числа в современную. С точки зрения практического смысла занятие сомнительное, но вообще это неплохое упражнение на списки.
Поэтому код:
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - List.Zip
Всем привет!
Решил разобрать задачку на преобразование римской записи числа в современную. С точки зрения практического смысла занятие сомнительное, но вообще это неплохое упражнение на списки.
Поэтому код:
let
unroman=(txt)=>[
dct=[I=1,V=5,X=10,L=50,C=100,D=500,M=1000],
lst=Text.ToList(txt),
tr=List.Transform(lst,(x)=>Record.Field(dct,x)),
zip=List.Zip({tr,List.Skip(tr)&{0}}),
tr2=List.Transform(zip,(x)=>if x{0}<x{1} then -x{0} else x{0}),
to = List.Sum(tr2)][to],
from = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content],
to = Table.AddColumn(from,"arab",(r)=>unroman(r[r]))
in
to
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
21 - На М - MCMLXXXVIII=1988 или преобразуем римскую запись числа в нормальную
Решил разобрать задачку на преобразование римской записи числа в современную. С точки зрения практического смысла занятие сомнительное, но вообще это неплохое упражнение на списки. Кому интересно: мой курс по Power Query - https://akademia-excel.ru/power…
Table.ReplaceRows и слияние записей – или нестандартное преобразование при группировке
#АнатомияФункций - Table.ReplaceRows
Всем привет!
Подкинули интересную задачку на группировку – ничего сложного, просто преобразование по условию и разное для первой и последующих строк. Чего-то накатило сделать через Table.ReplaceRows. По этому поводу код:
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Table.ReplaceRows
Всем привет!
Подкинули интересную задачку на группировку – ничего сложного, просто преобразование по условию и разное для первой и последующих строк. Чего-то накатило сделать через Table.ReplaceRows. По этому поводу код:
let
from = Excel.CurrentWorkbook(){[Name="headcount"]}[Content],
f=(x)=>[a=Table.Sort(x,{"headcount_Ставки, ед изм",Order.Descending}),
b=Table.TransformColumns(a,{"Ставки_Основное место",(x)=>"нет,внешний"}),
c=Table.ReplaceRows(b,0,1,{b{0}&[Ставки_Основное место="да,внешний"]}),
d=if List.Contains(x[Ставки_Основное место],"да") then x else c][d],
gr = Table.Group(from,{"Ставки_Позиция","Период_int","Горизонт_маркер"},{"tmp",f}),
to=Table.Combine(gr[tmp])
in
to
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
22 - На М - TableReplaceRows и слияние записей - интересный вариант для группировки
Группируем таблицу и делаем преобразование по условию с использованием TableReplaceRows и слияния записей
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40
а по промокоду buchlotnik получите дополнительную скидку
…
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40
а по промокоду buchlotnik получите дополнительную скидку
…
Record.HasFields или проверка наличия защиты листов книги
#АнатомияФункций - Record.HasFields
Всем привет!
Поскольку мне уже неоднократно задали этот вопрос пишу разбор. Итак задача: надо проверить на всех ли листах в файлах папки стоит «правильная» защита. Правильность в себя включает наличие пароля и возможности сортировки и фильтрации данных. Соответственно, если где-то это не так – нужно вывести список негодников.
Ну ОК, вот код:
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Record.HasFields
Всем привет!
Поскольку мне уже неоднократно задали этот вопрос пишу разбор. Итак задача: надо проверить на всех ли листах в файлах папки стоит «правильная» защита. Правильность в себя включает наличие пароля и возможности сортировки и фильтрации данных. Соответственно, если где-то это не так – нужно вывести список негодников.
Ну ОК, вот код:
let
f=(x)=>[
file = Binary.Buffer(x),
book = Table.SelectRows(Excel.Workbook(file,false),(r)=>r[Kind]="Sheet"),
xml = Table.SelectRows(fxUnzip(file),(r)=>Text.Contains(r[Name],"xl/worksheets/sheet"))[Value],
f=(x)=>Record.HasFields(Xml.Tables(x){[Name="sheetProtection"]}?[Table]?{0}? ?? [],{"Attribute:hashValue","Attribute:sheet","Attribute:sort","Attribute:autoFilter"}),
lst = List.Transform(xml,f),
tbl = Table.FromColumns(Table.ToColumns(book)&{lst},Table.ColumnNames(book)&{"protection"})][tbl],
folder=Folder.Files("путь к папке")[[Folder Path],[Name],[Content]],
tr = Table.TransformColumns(folder,{"Content",f}),
exp = Table.ExpandTableColumn(tr,"Content",{"Item","protection"}),
to = Table.SelectRows(exp,(r)=>r[protection]=false)
in
to
Ну а что тут к чему – смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
23 - На М - Record.HasFields или проверка наличия защиты листов книги
Сегодня проверяем на всех ли листах в файлах папки стоит «правильная» защита. Правильность в себя включает наличие пароля и возможности сортировки и фильтрации данных. Соответственно, если где-то это не так – выводим таблицу с адресами и именами файлов, а…
Словари на записях против Table.Buffer
#АнатомияФункций – приёмы
Всем привет!
Мне опять попалось на глаза странное видео. Ещё раз убедился, что не зря не приветствую рекламу ютуб-каналов в чате.
Пока у меня пригорало записал видос.
Интересующиеся найдут там про Table.Buffer, яркий пример про (x)=> вместо each _ и даже про DateTime.ToText вместо даже не буду говорить чего.
А вообще задачка про на словари на записях (неожиданно, правда?).
Свой код привожу:
А вот не свой не привожу – я против распространения порнографии.
Лайк, коммент, подписка приветствуются )))
Упомянутый в видео мой курс по pq
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – приёмы
Всем привет!
Мне опять попалось на глаза странное видео. Ещё раз убедился, что не зря не приветствую рекламу ютуб-каналов в чате.
Пока у меня пригорало записал видос.
Интересующиеся найдут там про Table.Buffer, яркий пример про (x)=> вместо each _ и даже про DateTime.ToText вместо даже не буду говорить чего.
А вообще задачка про на словари на записях (неожиданно, правда?).
Свой код привожу:
let
tbl=Excel.CurrentWorkbook(){[Name="даты"]}[Content],
tr = Table.TransformColumns(tbl,{"month",(x) as text=>DateTime.ToText(x,"yyyy MMMM")}),
f=(x)=>List.Transform({0..Duration.Days(x{2}-x{1})},(y)=>Text.From(Date.From(Number.From(x{1})+y))),
cmb = Table.CombineColumns(tr,List.Skip(Table.ColumnNames(tr)),f,"tmp"),
exp = Table.ExpandListColumn(cmb,"tmp"),
dict=Record.FromList(exp[month],exp[tmp]),
from = Excel.CurrentWorkbook(){[Name="база"]}[Content],
to = Table.AddColumn(from,"month",(x)=>Record.Field(dict,Text.From(Date.From(x[Дата]))))
in
to
А вот не свой не привожу – я против распространения порнографии.
Лайк, коммент, подписка приветствуются )))
Упомянутый в видео мой курс по pq
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
24 - На M - И снова словари на записях против мышкоклаца
Мне опять попалось на глаза странное видео. Ещё раз убедился, что не зря не приветствую рекламу ютуб-каналов в чате.
Пока у меня пригорало записал видос. Интересующиеся найдут там про Table.Buffer, яркий пример про (x)=˃ вместо each _ и даже про DateTime.ToText…
Пока у меня пригорало записал видос. Интересующиеся найдут там про Table.Buffer, яркий пример про (x)=˃ вместо each _ и даже про DateTime.ToText…
Решаем через Splitter
#АнатомияФункций – приёмы
Всем привет!
В чате уже заметили, что я решил помучить себя и окружающих темой Splitter-ов.
По этому поводу демонстрационный видос
Вот код:
Ну и жду реакции – оно вообще интересно или нет? Потому как если интересно – буду писать развернутый пост на тему.
А так - лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – приёмы
Всем привет!
В чате уже заметили, что я решил помучить себя и окружающих темой Splitter-ов.
По этому поводу демонстрационный видос
Вот код:
let
lst=List.Buffer({"0".."9"," "}),
from = Excel.CurrentWorkbook(){[Name="Таблица1"]}[Content][Custom],
f=(x)=>[a=Splitter.SplitTextByEachDelimiter({"/"},null,true)(x),
b=Splitter.SplitTextByEachDelimiter({" "},null,true)(a{0}),
c=Splitter.SplitTextByCharacterTransition((x)=>not List.Contains(lst,x),lst)(b{0}),
d=Combiner.CombineTextByDelimiter("")(Splitter.SplitTextByDelimiter(" ")(List.Last(c))),
z={x,b{1}&"/c",Number.From(d)}][z],
to = Table.FromList(from,f)
in
to
Ну и жду реакции – оно вообще интересно или нет? Потому как если интересно – буду писать развернутый пост на тему.
А так - лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
25 - На М - Решаем через Splitter
Решил помучить себя и окружающих темой Splitter-ов. По этому поводу демонстрационный видос )))
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40
а по промокоду buchlotnik получите дополнительную скидку
телега тут…
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40
а по промокоду buchlotnik получите дополнительную скидку
телега тут…
Splitter 0 - обзор
#АнатомияФункций - Splitter
Всем привет!
Как следует из названия поста, здесь я подведу итог того, что уже было описано на канале и поделюсь последующими планами. Поехали ))
Мы уже выяснили
- что не функциями Text едиными можно пользоваться при разделении текста
- выяснили, причём неоднократно, что делить текст можно не только по разделителю
- касались вопросов быстродействия при использовании как самих функций, так и в их окружении
-ну и в целом говорили о том, что вообще-то можно по-разному и это дела вкуса/привычки/личных предпочтений
По этому поводу хочется сделать комплексный обзор всех функций класса Splitter.
Привожу план, отдельные пункты которого по мере написания постов будут превращаться в гиперссылки:
1. Splitter.SplitByNothing – смотрим на сплиттер, который «ничего не делает» )
2. Splitter.SplitTextByWhitespace – обсуждаем, что такое Whitespace и зачем нужен аргумент quoteStyle
3. Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter – обсуждаем, только ли в количестве разделителей разница (спойлер – нет)
4. Splitter.SplitTextByEachDelimiter – разбираемся зачем он такой нужен (кто плачет по регуляркам – он нужен)
5. Splitter.SplitTextByCharacterTransition – часто фигурирует в коде, поэтому просто закрепим как/зачем/почему
6. Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths – делим текст по длинам фрагментов
7. Splitter.SplitTextByPositions, Splitter.SplitTextByRanges – делим текст по позициям элементов в нём
Как-то вот так, план амбициозный, ставим лайк, если одобряем.
Надеюсь, будет полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter
Всем привет!
Как следует из названия поста, здесь я подведу итог того, что уже было описано на канале и поделюсь последующими планами. Поехали ))
Мы уже выяснили
- что не функциями Text едиными можно пользоваться при разделении текста
- выяснили, причём неоднократно, что делить текст можно не только по разделителю
- касались вопросов быстродействия при использовании как самих функций, так и в их окружении
-ну и в целом говорили о том, что вообще-то можно по-разному и это дела вкуса/привычки/личных предпочтений
По этому поводу хочется сделать комплексный обзор всех функций класса Splitter.
Привожу план, отдельные пункты которого по мере написания постов будут превращаться в гиперссылки:
1. Splitter.SplitByNothing – смотрим на сплиттер, который «ничего не делает» )
2. Splitter.SplitTextByWhitespace – обсуждаем, что такое Whitespace и зачем нужен аргумент quoteStyle
3. Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter – обсуждаем, только ли в количестве разделителей разница (спойлер – нет)
4. Splitter.SplitTextByEachDelimiter – разбираемся зачем он такой нужен (кто плачет по регуляркам – он нужен)
5. Splitter.SplitTextByCharacterTransition – часто фигурирует в коде, поэтому просто закрепим как/зачем/почему
6. Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths – делим текст по длинам фрагментов
7. Splitter.SplitTextByPositions, Splitter.SplitTextByRanges – делим текст по позициям элементов в нём
Как-то вот так, план амбициозный, ставим лайк, если одобряем.
Надеюсь, будет полезно.
Всех благ!
@buchlotnik
Telegram
Для тех, кто в танке
Table.FromList – пять аргументов счастья
#АнатомияФункций - Table.FromList
Всем привет!
Всё руки не доходили написать про одну из моих любимых функций.
Сначала читаем справку:
Table.FromList(list as list, optional splitter as nullable function, optional…
#АнатомияФункций - Table.FromList
Всем привет!
Всё руки не доходили написать про одну из моих любимых функций.
Сначала читаем справку:
Table.FromList(list as list, optional splitter as nullable function, optional…
Splitter 1 - Splitter.SplitByNothing или сплиттер, который "ничего не делает"
#АнатомияФункций - Splitter.SplitByNothing
Всем привет!
Итак, начинаем разбор с самого простого сплиттера.
В целом все сплиттеры представляют собой замыкания, т.е. в скобках мы передаём аргументы и на выходе получаем функцию. Чтобы эта функция заработала, ей нужно передать анализируемые данные во вторых скобках
Что делает данная функция? Ответ в заголовке – ничего, точнее, она ничего не делает с самим аргументом. Но! Результат разделения по своему смыслу должен порождать список значений, поэтому на самом деле функция превращает переданный ей аргумент в список из одного значения
И вот теперь вопрос – зачем нужен сплиттер, который не меняет исходное значение?
В качестве примера рассмотрим задачу: в таблицу после столбца “d” нужно вставить ещё три столбца ("x","y" и "z") , заполненные нулями.
Стандартное решение через Table.SelectColumns выглядит как-то так:
Но ведь можно использовать и другую логику – разделить этот самый столбец "d"… просто не разделяя его:
Получается сплиттер отработал, на выход был подан список из одного значения, остальные заполнены значением по умолчанию. Получилось весьма лаконично, хотя вариант через Table.SelectColumns всё же работает быстрее.
Справедливости ради стоит отметить, что написать можно было и так
Или даже так
Т.е. вообще без сплиттера. Другое дело, что подобное решение пришло в голову только в рамках размышления о данной функции. Так что вердикт – данный сплиттер точно не бесполезен )))
Видеообзор традиционно смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitByNothing
Всем привет!
Итак, начинаем разбор с самого простого сплиттера.
В целом все сплиттеры представляют собой замыкания, т.е. в скобках мы передаём аргументы и на выходе получаем функцию. Чтобы эта функция заработала, ей нужно передать анализируемые данные во вторых скобках
Splitter.SplitByNothing() //просто сплиттер как функция
Splitter.SplitByNothing()("abc") //вызов его от аргумента "abc"
Что делает данная функция? Ответ в заголовке – ничего, точнее, она ничего не делает с самим аргументом. Но! Результат разделения по своему смыслу должен порождать список значений, поэтому на самом деле функция превращает переданный ей аргумент в список из одного значения
Splitter.SplitByNothing()("abc") //{"abc"}
Splitter.SplitByNothing()(123) //{123}
Splitter.SplitByNothing()({1,2,3}) //{{1,2,3}}
И вот теперь вопрос – зачем нужен сплиттер, который не меняет исходное значение?
В качестве примера рассмотрим задачу: в таблицу после столбца “d” нужно вставить ещё три столбца ("x","y" и "z") , заполненные нулями.
Стандартное решение через Table.SelectColumns выглядит как-то так:
let
from = #table({"a".."h"},List.Repeat({{1..8}},5)),
nms = Table.ColumnNames(from),
lst = {"x","y","z"},
tbl = Table.SelectColumns(from,List.RemoveLastN(nms,(x)=>x<>"d")&lst&List.LastN(nms,(x)=>x<>"d"),MissingField.UseNull),
to = Table.TransformColumns(tbl,List.Transform(lst,(x)=>{x,(i)=>0}))
in
to
Но ведь можно использовать и другую логику – разделить этот самый столбец "d"… просто не разделяя его:
let
from = #table({"a".."h"},List.Repeat({{1..8}},5)),
to = Table.SplitColumn(from,"d",Splitter.SplitByNothing(),{"d","x","y","z"},0)
in
to
Получается сплиттер отработал, на выход был подан список из одного значения, остальные заполнены значением по умолчанию. Получилось весьма лаконично, хотя вариант через Table.SelectColumns всё же работает быстрее.
Справедливости ради стоит отметить, что написать можно было и так
let
from = #table({"a".."h"},List.Repeat({{1..8}},5)),
to = Table.SplitColumn(from,"d",(x)=>{x},{"d","x","y","z"},0)
in
to
Или даже так
let
from = #table({"a".."h"},List.Repeat({{1..8}},5)),
to = Table.SplitColumn(from,"d",(x)=>{x,0,0,0},{"d","x","y","z"})
in
to
Т.е. вообще без сплиттера. Другое дело, что подобное решение пришло в голову только в рамках размышления о данной функции. Так что вердикт – данный сплиттер точно не бесполезен )))
Видеообзор традиционно смотрим на ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
26 - На М - что за зверь Splitter.SplitByNothing
Разбираем работу сплиттера, который "ничего не делает", просто, например, позволяет в одну строчку кода добавить несколько столбцов в таблицу, в конкретное место, да ещё и сразу заполненных значением по умолчанию.
Кому интересно:
мой курс по Power Query…
Кому интересно:
мой курс по Power Query…
Splitter 2 - Splitter.SplitTextByWhitespace, или сплиттер, "делящий по белому пробелу"
#АнатомияФункций - Splitter.SplitTextByWhitespace
Всем привет!
Продолжаем разбор сплиттеров. Сегодняшний наш пациент
Делит строковое значение по whitespace character (пробельному символу) и имеет необязательный аргумент quoteStyle.
Обращаю на это внимание – пробельный символ – это не просто пробел (U+0020), это ещё и горизонтальная табуляция (U+0009), перенос строки (U+000A), возврат каретки (U+000D), неразрывный пробел (U+00A0) – всего 25 символов (по крайней мере в соответствии со стандартом Юникода).
Поэтому
во всех случаях получаем одинаковый результат, причём обратите внимание – последовательность из двух и более пробельных символов рассматривается как один разрыв.
Теперь quoteStyle - представлен в двух вариантах: QuoteStyle.Csv и QuoteStyle.None. Первый используется по умолчанию, т.е.
Это то же самое, что
Рассмотрим разницу на примере:
Т.е. в случае QuoteStyle.Csv, когда встречается кавычка, весь последующий текст оставляется в неизменном виде, пока не встретится следующая кавычка; сами кавычки при этом удаляются.
А в случае QuoteStyle.None кавычки воспринимаются просто как один из символов и если между ними есть пробельные символы – по ним произойдет разделение.
Вот такой, на самом деле весьма полезный сплиттер, если понимать, что он делает и зачем нужен необязательный аргумент )))
Ну а как получить список из всех 25 пробельных символов, не зачитываясь стандартом Юникода, смотрите в обзоре на Ютубе
(и да, я в курсе, что можно было просто залезть в англоязычную википедию - но это скучно и без сплиттеров, вот ))))
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByWhitespace
Всем привет!
Продолжаем разбор сплиттеров. Сегодняшний наш пациент
Splitter.SplitTextByWhitespace(optional quoteStyle as nullable number) as function
Делит строковое значение по whitespace character (пробельному символу) и имеет необязательный аргумент quoteStyle.
Обращаю на это внимание – пробельный символ – это не просто пробел (U+0020), это ещё и горизонтальная табуляция (U+0009), перенос строки (U+000A), возврат каретки (U+000D), неразрывный пробел (U+00A0) – всего 25 символов (по крайней мере в соответствии со стандартом Юникода).
Поэтому
Splitter.SplitTextByWhitespace()("мама мыла раму") //{"мама","мыла","раму"}
Splitter.SplitTextByWhitespace()("мама#(tab) мыла#(tab)раму") //{"мама","мыла","раму"}
Splitter.SplitTextByWhitespace()("мама#(00A0) мыла #(00A0)раму") //{"мама","мыла","раму"}
Splitter.SplitTextByWhitespace()("мама#(cr,lf)мыла#(lf,cr,tab)раму") //{"мама","мыла","раму"}
во всех случаях получаем одинаковый результат, причём обратите внимание – последовательность из двух и более пробельных символов рассматривается как один разрыв.
Теперь quoteStyle - представлен в двух вариантах: QuoteStyle.Csv и QuoteStyle.None. Первый используется по умолчанию, т.е.
Splitter.SplitTextByWhitespace()
Это то же самое, что
Splitter.SplitTextByWhitespace(QuoteStyle.Csv)
Рассмотрим разницу на примере:
Splitter.SplitTextByWhitespace()("ООО ""Рога и копыта"" Москва") //{"ООО","Рога и копыта","Москва"}
Splitter.SplitTextByWhitespace(QuoteStyle.None)("ООО ""Рога и копыта"" Москва") //{"ООО","""Рога","и","копыта""","Москва"}
Т.е. в случае QuoteStyle.Csv, когда встречается кавычка, весь последующий текст оставляется в неизменном виде, пока не встретится следующая кавычка; сами кавычки при этом удаляются.
А в случае QuoteStyle.None кавычки воспринимаются просто как один из символов и если между ними есть пробельные символы – по ним произойдет разделение.
Вот такой, на самом деле весьма полезный сплиттер, если понимать, что он делает и зачем нужен необязательный аргумент )))
Ну а как получить список из всех 25 пробельных символов, не зачитываясь стандартом Юникода, смотрите в обзоре на Ютубе
(и да, я в курсе, что можно было просто залезть в англоязычную википедию - но это скучно и без сплиттеров, вот ))))
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
27 - На М - SplitterSplitTextByWhitespace или сплиттер, "делящий по белому пробелу"
Продолжаем разбор сплиттеров. Сегодняшний наш пациент - SplitterSplitTextByWhitespace.В видео разбираем, что такое Whitespace characters, чем отличается Quot...
Splitter 3 - Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter или когда порядок имеет значение…
#АнатомияФункций - Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter
Всем привет!
Продолжаем разбор сплиттеров. Сегодняшние пациенты:
Первый делит текс по указанному разделителю, второй – по набору разделителей.
Вместо кучи слов смотрим на пример:
to, to1 - поделилось только по пробелу
to2,to3 - сравниваем результат, выясняем, что порядок имеет значение
to4, to5 – просто демонстрация, что набор разделителей может быть разным
Что касается дополнительных аргументов, тоже есть кейс:
to -решили проблему через quoteStyle, to1 – через startAtEnd
Ну и на закуску просто прикольный пример, тоже про сплиттеры )))
А что тут к чему смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter
Всем привет!
Продолжаем разбор сплиттеров. Сегодняшние пациенты:
Splitter.SplitTextByDelimiter(delimiter as text, optional quoteStyle as nullable number) as function
Splitter.SplitTextByAnyDelimiter(delimiters as list, optional quoteStyle as nullable number, optional startAtEnd as nullable logical) as function
Первый делит текс по указанному разделителю, второй – по набору разделителей.
Вместо кучи слов смотрим на пример:
let
from = #table({"num","txt"},{{1,"мама мыла раму"},{2,"мама мыла раму"},{3,"мама,мыла, раму"},{4,"мамаоченьмылачастораму"}}),
to = Table.SplitColumn(from,"txt",Splitter.SplitTextByDelimiter(" ")),
to1 = Table.SplitColumn(from,"txt",Splitter.SplitTextByAnyDelimiter({" "})),
to2 = Table.SplitColumn(from,"txt",Splitter.SplitTextByAnyDelimiter({" "," "})),
to3 = Table.SplitColumn(from,"txt",Splitter.SplitTextByAnyDelimiter({" "," "})),
to4 = Table.SplitColumn(from,"txt",Splitter.SplitTextByAnyDelimiter({" "," ",", ",","})),
to5 = Table.SplitColumn(from,"txt",Splitter.SplitTextByAnyDelimiter({" "," ",", ",",","очень","часто"}))
in
to5
to, to1 - поделилось только по пробелу
to2,to3 - сравниваем результат, выясняем, что порядок имеет значение
to4, to5 – просто демонстрация, что набор разделителей может быть разным
Что касается дополнительных аргументов, тоже есть кейс:
let
from = Excel.CurrentWorkbook(){[Name="Таблица"]}[Content],
to = Table.AddColumn(from,"Номер",(x)=>List.Last(Splitter.SplitTextByDelimiter("ИИН/БИН ",QuoteStyle.None)(x[#"Наименование бенефициара / отправителя"]))),
to1 = Table.AddColumn(from,"Номер",(x)=>List.Last(Splitter.SplitTextByAnyDelimiter({"ИИН/БИН "},null,true)(x[#"Наименование бенефициара / отправителя"])))
in
to1
to -решили проблему через quoteStyle, to1 – через startAtEnd
Ну и на закуску просто прикольный пример, тоже про сплиттеры )))
let
from = Excel.CurrentWorkbook(){[Name="Таблица"]}[Content],
f=(x)=>Function.Invoke(Record.FromList,List.Zip(List.Split(Splitter.SplitTextByAnyDelimiter({", "," "})(x),2))),
tr = Table.TransformColumns(from,{"Данные",f}),
nms = List.Distinct(List.Combine(List.Transform(tr[Данные],Record.FieldNames))),
to = Table.ExpandRecordColumn(tr, "Данные",nms)
in
to
А что тут к чему смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
28 - На М - Splitter.SplitTextByDelimiter, Splitter.SplitTextByAnyDelimiter
Разбираем сразу две функции - Splitter.SplitTextByDelimiter и Splitter.SplitTextByAnyDelimiter;смотрим разницу, решаем кейсы из чата.Кому интересно:мой курс...
Splitter 4 - Splitter.SplitTextByEachDelimiter или когда количество имеет значение…
#АнатомияФункций - Splitter.SplitTextByEachDelimiter
Всем привет!
Продолжаем тему сплиттеров, сегодняшний пациент:
Набор аргументов такой же как и у Splitter.SplitTextByAnyDelimiter.
Существенная разница состоит в том, что в данном случае каждый разделитель из списка используется только один раз, соответственно мы можем поделить текст только по первому или только по последнему пробелу:
Также можно задать список разделителей и делить текст по мере их нахождения в нём:
Демонстрацию работы вышеприведённого кода смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByEachDelimiter
Всем привет!
Продолжаем тему сплиттеров, сегодняшний пациент:
Splitter.SplitTextByEachDelimiter(delimiters as list, optional quoteStyle as nullable number, optional startAtEnd as nullable logical)
Набор аргументов такой же как и у Splitter.SplitTextByAnyDelimiter.
Существенная разница состоит в том, что в данном случае каждый разделитель из списка используется только один раз, соответственно мы можем поделить текст только по первому или только по последнему пробелу:
let
from = Excel.CurrentWorkbook(){[Name="Таблица110"]}[Content],
f=(x)=>Splitter.SplitTextByEachDelimiter({" "},null,true)(x){1},
to = Table.AddColumn(from,"new",(r)=>f(r[#"Наименование бенефициара / отправителя"]))
in
to
Также можно задать список разделителей и делить текст по мере их нахождения в нём:
let
from = Excel.CurrentWorkbook(){[Name="Таблица5"]}[Content][сотрудник],
to = Table.FromList(from,Splitter.SplitTextByEachDelimiter({". "," ",", ",", ",", "}))
in
to
Демонстрацию работы вышеприведённого кода смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
29 - На М - Splitter.SplitTextByEachDelimiter
Разбираем очередной сплиттер - сегодня это Splitter.SplitTextByEachDelimiterКому интересно:мой курс по Power Query - https://akademia-excel.ru/powerquery?gcp...
Всем привет! Как-то плохо идут сплиттеры (мало просмотров что здесь, что на ютубе), отсюда возник вопрос - куда двигаемся дальше и какой будет следующий пост? Ставлю на голосование, потому как аисать контент в пустоту не хочется
Final Results
63%
Splitter 5 - Splitter.SplitTextByCharacterTransition
37%
DateTime.LocalNow vs DateTime.FixedLocalNow - есть ли разница
Splitter 5 - Splitter.SplitTextByCharacterTransition или List vs Text
#АнатомияФункций - Splitter.SplitTextByCharacterTransition
Всем привет!
Продолжаем тему сплиттеров. До этого мы делили текст по разделителю (подстроке), который удалялся в результате разделения. Теперь рассматриваем варианты, когда нужно разделить, но сохранить все символы.
Сегодняшний пациент
Два аргумента - before и after - определяют наборы символов по переходу с которых на которые нужно делить. Каждый аргумент может быть представлен либо списком символов, либо функцией от символа, возвращающей true/false. Ну и смотрим пример:
to – просто делим по двум спискам символов, это самый медленный вариант – поскольку мы перечисляем большое количество символов, предшествующих цифрам
to1 – поступаем умнее – делим по переходу с не цифр на цифры – здесь заменили один список функцией, такое разделение будет идти шустрее
to2 – вспомнили, что «..» - это оператор перечисления, и чтобы он не вычислялся большое количество раз, один раз получили список цифр и запихнули его в буфер – ещё бонус к скорости
и раньше я бы на этом закончил…
НО!
to3 – а кто, собственно, сказал, что проверять нужно именно список… Возьмём текст из 10 цифр и осуществим проверку на нём…
… а что из этого получилось смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByCharacterTransition
Всем привет!
Продолжаем тему сплиттеров. До этого мы делили текст по разделителю (подстроке), который удалялся в результате разделения. Теперь рассматриваем варианты, когда нужно разделить, но сохранить все символы.
Сегодняшний пациент
Splitter.SplitTextByCharacterTransition(before as anynonnull, after as anynonnull) as function
Два аргумента - before и after - определяют наборы символов по переходу с которых на которые нужно делить. Каждый аргумент может быть представлен либо списком символов, либо функцией от символа, возвращающей true/false. Ну и смотрим пример:
let
from = {"GC2SB230","OF+65HB","GC2SB250","GC2KP250S"},
/* надо получить {"GC2SB","OF+","GC2SB","GC2KP"}
- т.е. удалить последний набор цифр и всё, что после него*/
to = List.Transform(from,(x)=>Text.Combine(List.RemoveLastN(Splitter.SplitTextByCharacterTransition({"A".."Z","+"},{"0".."9"})(x),1))),
to1 = List.Transform(from,(x)=>Text.Combine(List.RemoveLastN(Splitter.SplitTextByCharacterTransition((x)=>not List.Contains({"0".."9"},x),{"0".."9"})(x),1))),
lst = List.Buffer({"0".."9"}),
to2 = List.Transform(from,(x)=>Text.Combine(List.RemoveLastN(Splitter.SplitTextByCharacterTransition((x)=>not List.Contains(lst,x),lst)(x),1))),
txt = "0123456789",
to3 = List.Transform(from,(x)=>Text.Combine(List.RemoveLastN(Splitter.SplitTextByCharacterTransition((x)=>not Text.Contains(txt,x),(x)=>Text.Contains(txt,x))(x),1)))
in
to3
to – просто делим по двум спискам символов, это самый медленный вариант – поскольку мы перечисляем большое количество символов, предшествующих цифрам
to1 – поступаем умнее – делим по переходу с не цифр на цифры – здесь заменили один список функцией, такое разделение будет идти шустрее
to2 – вспомнили, что «..» - это оператор перечисления, и чтобы он не вычислялся большое количество раз, один раз получили список цифр и запихнули его в буфер – ещё бонус к скорости
и раньше я бы на этом закончил…
НО!
to3 – а кто, собственно, сказал, что проверять нужно именно список… Возьмём текст из 10 цифр и осуществим проверку на нём…
… а что из этого получилось смотрите в обзоре на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
30 - На М - Splitter.SplitTextByCharacterTransition или List vs Text...
Разбираем работу функции Splitter.SplitTextByCharacterTransition, решаем парочку классических задач, разбираем варианты... и делаем неожиданные выводы по поводу быстродействия....
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/power…
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/power…
List.TransformMany или как ускорить запрос
#АнатомияФункций - List.TransformMany
Всем привет!
Решил записать разбор по поводу сегодняшнего обсуждения в чате - пилим полное декартово через List.TransformMany и разбираемся, почему исходный запрос "тупит" - вышло немножко долго, но на мой взгляд небезынтересно.
Итоговая версия кода:
А всяческие телодвижения, сравнения и комментарии – смотрим в 17:00 на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - List.TransformMany
Всем привет!
Решил записать разбор по поводу сегодняшнего обсуждения в чате - пилим полное декартово через List.TransformMany и разбираемся, почему исходный запрос "тупит" - вышло немножко долго, но на мой взгляд небезынтересно.
Итоговая версия кода:
let
from = Excel.CurrentWorkbook(){[Name="input"]}[Content],
f=(x)=>[a=Text.SplitAny(x{0},"()"),
aa=Text.Split(a{1},", "),
b=Text.SplitAny(x{1},"()"),
c=a{0},
d=List.Last(b),
f=(x)=>Text.Split(b{1},"/"),
g=(x,y)=>[a=c&x&" "&y,b={a,a&" "&d}][b],
e=List.TransformMany(aa,f,g)][e],
to = Table.FromList(List.Combine(Table.ToList(from,f)),(x)=>x,{"Номенклатура","ИД"})
in
to
А всяческие телодвижения, сравнения и комментарии – смотрим в 17:00 на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
31 - На М - List.TransformMany или как ускорить запрос
Решил записать разбор по поводу сегодняшнего обсуждения в чате - пилим полное декартово через List.TransformMany и разбираемся, почему исходный запрос "тупит" - вышло немножко долго, но на мой взгляд небезынтересно
Кому интересно:
мой курс по Power Query…
Кому интересно:
мой курс по Power Query…
Splitter 6 - Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths или когда длина имеет значение…
#АнатомияФункций - Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths
Всем привет!
Продолжаем тему сплиттеров. Сегодня на повестке:
Оба сплиттера вообще не ориентируются на подстроки и конкретные символы – их интересует только необходимая длина подстроки.
Смотрим примеры:
-приводим в божеский вид МАС-адреса (разбираем строку по 2 символа)
- делаем «красивое» текстовое представление чисел (обращаем внимание на второй аргумент – разбираем по тройкам с конца)
- наводим порядок в номерах телефонов (задаём нужные длины с конца, обращаем внимание, что в итоге вынимаются не все символы, а только текст заданных длин):
Как-то так – функции нечасто используемые, но в отдельных случаях прям мастхев)
… демонстрация работы с комментариями, как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths
Всем привет!
Продолжаем тему сплиттеров. Сегодня на повестке:
Splitter.SplitTextByRepeatedLengths(length as number, optional startAtEnd as nullable logical)
Splitter.SplitTextByLengths(lengths as list, optional startAtEnd as nullable logical)
Оба сплиттера вообще не ориентируются на подстроки и конкретные символы – их интересует только необходимая длина подстроки.
Смотрим примеры:
-приводим в божеский вид МАС-адреса (разбираем строку по 2 символа)
let
from = #table({"MAC"},{{"001A2B3C4D5E"},{"0815752B9ADC"},{"096C2ABD7534"}}),
f=(x)=>Combiner.CombineTextByDelimiter("-")(Splitter.SplitTextByRepeatedLengths(2)(x)),
to = Table.TransformColumns(from,{"MAC",f})
in
to
- делаем «красивое» текстовое представление чисел (обращаем внимание на второй аргумент – разбираем по тройкам с конца)
let
from = #table({"num"},{{1},{12},{123},{1234},{12345},{1234567},{12345678}}),
f=(x)=>Text.Combine(Splitter.SplitTextByRepeatedLengths(3,true)(Text.From(x))," "),
/*хотя можно и Number.ToText(x,"N0")*/
to = Table.TransformColumns(from,{"num",f})
in
to
- наводим порядок в номерах телефонов (задаём нужные длины с конца, обращаем внимание, что в итоге вынимаются не все символы, а только текст заданных длин):
let
from = #table({"tel"},{{"+79871234567"},{"89876543210"}}),
f=(x)=>[a=Splitter.SplitTextByLengths({2,2,3,3},true)(x),
b=Text.Format("+7 (#{0}) #{1}-#{2}-#{3}",a)][b],
to = Table.TransformColumns(from,{"tel",f})
in
to
Как-то так – функции нечасто используемые, но в отдельных случаях прям мастхев)
… демонстрация работы с комментариями, как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
32 - На М - Splitter.SplitTextByRepeatedLengths, Splitter.SplitTextByLengths
Разбираем очередную порцию разделителей - на повестке Splitter.SplitTextByRepeatedLengths и Splitter.SplitTextByLengths.
Обещанная сцыль на сумму прописью - https://t.me/pbi_pq_from_tank/119
Кому интересно:
мой курс по Power Query - https://akademia-ex…
Обещанная сцыль на сумму прописью - https://t.me/pbi_pq_from_tank/119
Кому интересно:
мой курс по Power Query - https://akademia-ex…
Splitter 7 - Splitter.SplitTextByPositions, Splitter.SplitTextByRanges или и вот так тоже можно
#АнатомияФункций - Splitter.SplitTextByPositions, Splitter.SplitTextByRanges
Всем привет!
Завершая тему сплиттеров, рассматриваем следующих пациентов:
Первый аргумент – список, второй необязательный позволяет смотреть с конца. Базовые примеры можно посмотреть в справке – там особо обсуждать нечего. А вот интересненькое давайте порешаем.
Кейс 1 – разобрать текст, не затирая теги (или по простому – поделить текст по позициям одного разделителя и по позициям следующим за другим разделителем):
Кейс 2 – пишем отсутствующий в 2016 Splitter.SplitTextByCharacterTransition:
Кейс 3 – делим текст по цифро-дефисовой последовательности, заканчивающейся точкой:
Кейс 4 – эту задачку мы уже разбирали – только теперь решим её по-другому и выясним, что Splitter.SplitTextByRanges никакой не сплиттер, а профессиональный «выниматель подстрок» :
Как вы догадываетесь, подробное описание того, что тут к чему, смотрим на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Splitter.SplitTextByPositions, Splitter.SplitTextByRanges
Всем привет!
Завершая тему сплиттеров, рассматриваем следующих пациентов:
Splitter.SplitTextByPositions(positions as list, optional startAtEnd as nullable logical)
Splitter.SplitTextByRanges(ranges as list, optional startAtEnd as nullable logical)
Первый аргумент – список, второй необязательный позволяет смотреть с конца. Базовые примеры можно посмотреть в справке – там особо обсуждать нечего. А вот интересненькое давайте порешаем.
Кейс 1 – разобрать текст, не затирая теги (или по простому – поделить текст по позициям одного разделителя и по позициям следующим за другим разделителем):
let
txt= "<info><recnumber=1 type=A date=12.04.2012><name><first>Имя1</first><last>Фамилия1</last><medium>Отчество1</medium></name><doc><type>паспорт</type><number>23465</number></doc></info><info><recnumber=2 type=D date=15.04.2012><name><first>Имя2</first><last>Фамилия2</last><medium>Отчество2</medium></name><doc><type>св-во</type><number>98745</number></doc></info>",
pos = Text.PositionOf(txt,"<",Occurrence.All),
pos1 = List.Transform(Text.PositionOf(txt,">",Occurrence.All),(x)=>x+1),
lst = List.Sort(List.Distinct(pos&pos1)),
splt=Splitter.SplitTextByPositions(lst)(txt),
to = List.Select(splt,(x)=>Text.Trim(x)<>"")
in
to
Кейс 2 – пишем отсутствующий в 2016 Splitter.SplitTextByCharacterTransition:
let
txt = "картошка 123морковка 29свёкла 11лук 14чеснок 13",
lst = Splitter.SplitTextByRepeatedLengths(1)(txt),
zip = List.Zip({lst,{""}&List.RemoveLastN(lst,1)}),
f=(x)=>Text.Contains("0123456789",x),
g=(x)=>not f(x{0}) and f(x{1}),
pos = List.PositionOf(zip,g,Occurrence.All,(c,v)=>v(c)),
to = Splitter.SplitTextByPositions(pos)(txt)
in
to
Кейс 3 – делим текст по цифро-дефисовой последовательности, заканчивающейся точкой:
let
txt = "1. Текст 1-1. Текст с пробелами 1-2. текст с числами 123 2. ещё текст 3. текст. 4. а текст-то бывает разный... издевательство 5. например с числами 2.5 12. и номеров много 123. очень много 1234. прям совсем",
f=(x)=>Text.Contains("0123456789.-",x),
g=(x)=>Text.Contains("0123456789",x),
lst=Splitter.SplitTextByRepeatedLengths(1)(txt),
tbl = Table.FromList(lst,(x)=>{f(x),g(x),x="."},{"flag","num","dot"}),
add = Table.AddIndexColumn(tbl,"ind"),
gr = Table.Group(add,"flag",{{"pos",(x)=>x{0}[ind]},{"dot",(x)=>List.Last(x[dot])=true},{"nums",(x)=>List.AnyTrue(x[num])}},GroupKind.Local),
pos = Table.SelectRows(gr,(x)=>x[dot] and x[nums])[pos],
to = Splitter.SplitTextByPositions(pos)(txt)
in
to
Кейс 4 – эту задачку мы уже разбирали – только теперь решим её по-другому и выясним, что Splitter.SplitTextByRanges никакой не сплиттер, а профессиональный «выниматель подстрок» :
let
from = Excel.CurrentWorkbook(){[Name="Таблица110"]}[Content],
f=(x)=>[a=Splitter.SplitTextByRepeatedLengths(1)(x),
b=(x)=>Text.Contains("0123456789 ",x),
c=List.Zip({a,{""}&List.RemoveLastN(a,1)}),
d=Text.PositionOf(x,"бит/с",Occurrence.Last),
e=List.PositionOf(c,null,Occurrence.All,(c,v)=>b(c{0}) and not b(c{1})),
f=List.Max(e,null,(x)=>if x > d then 0 else x),
g={{0,Text.Length(x)},{f,d-f-2},{d-1,6}},
z=Splitter.SplitTextByRanges(g)(x)][z],
splt = Table.SplitColumn(from,"Custom",f,{"Custom","скока","чего"}),
to = Table.TransformColumns(splt,{"скока",Number.From})
in
to
Как вы догадываетесь, подробное описание того, что тут к чему, смотрим на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
33 - На М - Splitter.SplitTextByPositions, Splitter.SplitTextByRanges или и вот так тоже можно
Завершаем тему сплиттеров - последние два пациента - Splitter.SplitTextByPositions, Splitter.SplitTextByRanges.
Решаем четыре кейса:
– поделить текст по позициям одного разделителя и по позициям следующим за другим разделителем;
– пишем отсутствующий в 2016…
Решаем четыре кейса:
– поделить текст по позициям одного разделителя и по позициям следующим за другим разделителем;
– пишем отсутствующий в 2016…
LocalNow vs FixedLocalNow или который час?
#АнатомияФункций - DateTime.LocalNow, DateTime.FixedLocalNow, DateTimeZone.UtcNow, DateTimeZone.FixedUtcNow , DateTimeZone.LocalNow, DateTimeZone.FixedLocalNow
Всем привет!
В каментах просили разобрать разницу между функциями получения текущих даты и времени. Базово функций три:
DateTime.LocalNow – возвращает системные дату и время;
DateTimeZone.LocalNow – возвращает системные дату, время и часовой пояс
DateTimeZone.UtcNow – возвращает всемирное координированное время
При этом у каждой есть её фиксированный вариант - DateTime.FixedLocalNow, DateTimeZone.FixedLocalNow, DateTimeZone.FixedUtcNow.
Идея фиксации состоит в том, что в ходе запроса функция вычисляется ровно один раз и уже не меняет своё значение при множественных вызовах.
Давайте сравним:
На каждом шаге запроса вы сможете увидеть значение, отличающееся от единицы – происходит множественный вызов функции, соответственно значения отличаются (вообще они отличаются в долях секунды, поэтому если вас интересует только текущая дата – это ни разу не принципиально)
Но при этом фиксированные варианты дадут:
Т.е. видим, что действительно на каждом шаге ровно одно уникальное датавремя.
Если кому-то принципиальны доли секунды и он уже побежал переписывать все свои запросы – остановитесь! И посмотрите следующий код:
Т.е. если вы, как и я, являетесь противниками множественных вызовов и используете переменные (в данном случае now), то проблемы у вас нет – функция вызывается один раз при вычислении переменной. Заодно это немного (процентов на 5%) ускоряет вычисления – мелочь, а приятно.
Ну и раз уж нас интересует прям точное время, то нельзя не вспомнить, что, например, в командировке у вас может измениться часовой пояс и могут «поехать» вычисления. В этой ситуации целесообразно это учитывать и в переменную засовывать функции, учитывающие часовой пояс, результат выполнения которых можно пересчитать на интересующий. В примере ниже в переменных оказывается Питерское время, даже если я в Шанхае:
Как-то так. Нет «правильных» или «неправильных» функций, есть вполне конкретное их поведение, которое нужно учитывать при написании кода )))
Ну а разбор всего этого безобразия смотрите, как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - DateTime.LocalNow, DateTime.FixedLocalNow, DateTimeZone.UtcNow, DateTimeZone.FixedUtcNow , DateTimeZone.LocalNow, DateTimeZone.FixedLocalNow
Всем привет!
В каментах просили разобрать разницу между функциями получения текущих даты и времени. Базово функций три:
DateTime.LocalNow – возвращает системные дату и время;
DateTimeZone.LocalNow – возвращает системные дату, время и часовой пояс
DateTimeZone.UtcNow – возвращает всемирное координированное время
При этом у каждой есть её фиксированный вариант - DateTime.FixedLocalNow, DateTimeZone.FixedLocalNow, DateTimeZone.FixedUtcNow.
Идея фиксации состоит в том, что в ходе запроса функция вычисляется ровно один раз и уже не меняет своё значение при множественных вызовах.
Давайте сравним:
let
tr = List.Count(List.Distinct(List.Transform({1..100000},(x)=>DateTime.LocalNow()))),//<>1
tbl = Table.RowCount(Table.Distinct(Table.FromList({1..100000},(x)=>{DateTime.LocalNow()}))),//<>1
acc =List.Count(List.Distinct(List.Accumulate({1..1000},{},(x,y)=>x&{DateTime.LocalNow()})))//<>1
in
acc
На каждом шаге запроса вы сможете увидеть значение, отличающееся от единицы – происходит множественный вызов функции, соответственно значения отличаются (вообще они отличаются в долях секунды, поэтому если вас интересует только текущая дата – это ни разу не принципиально)
Но при этом фиксированные варианты дадут:
let
tr = List.Count(List.Distinct(List.Transform({1..100000},(x)=>DateTime.FixedLocalNow()))),//1
tbl = Table.RowCount(Table.Distinct(Table.FromList({1..100000},(x)=>{DateTime.FixedLocalNow()}))),//1
acc =List.Count(List.Distinct(List.Accumulate({1..1000},{},(x,y)=>x&{DateTime.FixedLocalNow()})))//1
in
acc
Т.е. видим, что действительно на каждом шаге ровно одно уникальное датавремя.
Если кому-то принципиальны доли секунды и он уже побежал переписывать все свои запросы – остановитесь! И посмотрите следующий код:
let
now = DateTime.LocalNow(),
tr = List.Count(List.Distinct(List.Transform({1..100000},(x)=>now))),//1
tbl = Table.RowCount(Table.Distinct(Table.FromList({1..100000},(x)=>{now}))),//1
acc =List.Count(List.Distinct(List.Accumulate({1..1000},{},(x,y)=>x&{now})))//1
in
acc
Т.е. если вы, как и я, являетесь противниками множественных вызовов и используете переменные (в данном случае now), то проблемы у вас нет – функция вызывается один раз при вычислении переменной. Заодно это немного (процентов на 5%) ускоряет вычисления – мелочь, а приятно.
Ну и раз уж нас интересует прям точное время, то нельзя не вспомнить, что, например, в командировке у вас может измениться часовой пояс и могут «поехать» вычисления. В этой ситуации целесообразно это учитывать и в переменную засовывать функции, учитывающие часовой пояс, результат выполнения которых можно пересчитать на интересующий. В примере ниже в переменных оказывается Питерское время, даже если я в Шанхае:
let
now = DateTime.From(DateTimeZone.SwitchZone(DateTimeZone.UtcNow(),3)),
now1 = DateTime.From(DateTimeZone.SwitchZone(DateTimeZone.LocalNow(),3)),
now2 = DateTime.From(DateTimeZone.SwitchZone(DateTimeZone.FixedUtcNow(),3)),
now3 = DateTime.From(DateTimeZone.SwitchZone(DateTimeZone.FixedLocalNow(),3))
in
now3
Как-то так. Нет «правильных» или «неправильных» функций, есть вполне конкретное их поведение, которое нужно учитывать при написании кода )))
Ну а разбор всего этого безобразия смотрите, как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
34 - На М - Который час? или LocalNow vs FixedLocalNow
Разбираем, есть ли разница между DateTime.LocalNow и DateTime.FixedLocalNow. А ещё зачем нужны DateTimeZone.LocalNow и DateTimeZone.UtcNow (ну и их "Fixed" аналоги).
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40…
Кому интересно:
мой курс по Power Query - https://akademia-excel.ru/powerquery?gcpc=9ae40…
Xml.Document vs Xml.Tables, рекурсивный обход и слетевшая кодировка
#АнатомияФункций - Xml.Document
Всем привет!
В чат подкинули задачку про сбор данных из xml. Вроде всё просто, но пришлось повозиться с именами файлов, осуществить рекурсивный обход и оформить пару функций. По этому поводу код:
Ну а что тут к чему смотрите, как всегда, на Ютубе (https://youtu.be/OsfOCQZvBRM)
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций - Xml.Document
Всем привет!
В чат подкинули задачку про сбор данных из xml. Вроде всё просто, но пришлось повозиться с именами файлов, осуществить рекурсивный обход и оформить пару функций. По этому поводу код:
let
f=(x)=>Text.FromBinary(Text.ToBinary(x,866)),
g=(x)=>[a=Table.Buffer(x[[Name],[Value]]),
b=Table.SelectRows(a,(r)=>r[Value] is table),
c=Table.SelectRows(a,(r)=>not (r[Value] is table)),
d=if Table.RowCount(b)=0 then a else c & @g(Table.Combine(Table.ToList(b,h)))][d],
h=(x)=>Table.TransformColumns(x{1},{"Name",(r)=>x{0}&"/"&r}),
from = Folder.Files("C:\Users\muzyk\Desktop\XML_файлы")[[Name],[Content]],
tr = Table.TransformColumns(from,{{"Name",f},{"Content",(x)=>Record.FromTable(g(Xml.Document(x)))}}),
nms = List.Distinct(List.Combine(List.Transform(tr[Content],Record.FieldNames))),
to = Table.ExpandRecordColumn(tr,"Content",nms)
in
to
Ну а что тут к чему смотрите, как всегда, на Ютубе (https://youtu.be/OsfOCQZvBRM)
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
35 - На М - Xml.Document vs Xml.Tables, рекурсивный обход и слетевшая кодировка
Решаем несложную задачку по сбору информации из Xml-файлов, просто они немножко кривые и придётся поколдовать с названиями, рекурсией и вообще)))
Желающие поддержать мою деятельность:
канал с учебными видео - https://sponsr.ru/pq_m_buchlotnik/
Ну и мало…
Желающие поддержать мою деятельность:
канал с учебными видео - https://sponsr.ru/pq_m_buchlotnik/
Ну и мало…
Удаление пустых строк (а на списках точно быстрее?)
#АнатомияФункций – List.RemoveMatchingItems, List.RemoveNulls, List.Repeat, Record.FromList
Всем привет!
В чате задали вопрос про удаление пустых строк, а именно: является ли мышкоклацный код слишком навороченным:
Ответ – нет, вполне прозрачный и логичный код, достаточно универсальный.
Но вот если в таблице пустые строки содержат только null (а именно так было у автора вопроса), то действительно, можно и подсократить:
А сократив, стоит задуматься о вычислительной эффективности и, например, переписать так:
А ещё лучше так:
Ну а насколько лучше получился код и вообще, что тут к чему смотрите , как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – List.RemoveMatchingItems, List.RemoveNulls, List.Repeat, Record.FromList
Всем привет!
В чате задали вопрос про удаление пустых строк, а именно: является ли мышкоклацный код слишком навороченным:
let
laiyuan = Excel.CurrentWorkbook(){[Name="biao"]}[Content],
jieguo = Table.SelectRows(laiyuan, each not List.IsEmpty(List.RemoveMatchingItems(Record.FieldValues(_), {"", null})))
in
jieguo
Ответ – нет, вполне прозрачный и логичный код, достаточно универсальный.
Но вот если в таблице пустые строки содержат только null (а именно так было у автора вопроса), то действительно, можно и подсократить:
let
laiyuan = Excel.CurrentWorkbook(){[Name="biao"]}[Content],
jieguo = Table.SelectRows(laiyuan,(j)=>List.RemoveNulls(Record.ToList(j))<>{})
in
jieguo
А сократив, стоит задуматься о вычислительной эффективности и, например, переписать так:
let
laiyuan = Excel.CurrentWorkbook(){[Name="biao"]}[Content],
liebiao = List.Buffer(List.Repeat({null},Table.ColumnCount(laiyuan))),
jieguo = Table.SelectRows(laiyuan,(j)=> Record.ToList(j)<> liebiao)
in
jieguo
А ещё лучше так:
let
laiyuan = Excel.CurrentWorkbook(){[Name="biao"]}[Content],
jilu = Record.FromList(List.Repeat({null},Table.ColumnCount(laiyuan)),Table.ColumnNames(laiyuan)),
jieguo = Table.SelectRows(laiyuan,(j)=>j<>jilu)
in
jieguo
Ну а насколько лучше получился код и вообще, что тут к чему смотрите , как всегда, на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
YouTube
36 - На М - Удаление пустых строк (а на списках точно быстрее?)
Решаем простую типовую задачку по удалению пустых строк и выясняем так ли плох мышкоклац, заодно немножко угораем по-китайски )))
Желающие поддержать мою деятельность:
канал с учебными видео - https://sponsr.ru/pq_m_buchlotnik/
Ну и мало ли интересно:
телега…
Желающие поддержать мою деятельность:
канал с учебными видео - https://sponsr.ru/pq_m_buchlotnik/
Ну и мало ли интересно:
телега…
Удаляем текст в скобках (без регулярок и СМС)
#АнатомияФункций – приёмы
Всем привет!
Сегодня разбираем задачку «Как можно в столбце удалить все значения в скобках?».
Для начала решим «строго по условию»:
Делим строго по скобкам… но как-то сложно и медленно.
ОК, что насчёт рекурсии?
Так, как минимум, быстрее, да и поприкольнее.
Вот только надо ли оно всё?
Если больше не к чему привязаться – надо, а в конкретном случае можно:
Бонус на формулах и объяснение того, что тут к чему, как всегда, смотрим на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik
#АнатомияФункций – приёмы
Всем привет!
Сегодня разбираем задачку «Как можно в столбце удалить все значения в скобках?».
Для начала решим «строго по условию»:
let
f=(x)=>[a=List.Transform(List.Split({-1}&List.RemoveLastN(Text.PositionOfAny(x,{"(",")"},Occurrence.All),1),2),(x)=>{x{0}+1,x{1}-x{0}-1}),
b=Text.Combine(Splitter.SplitTextByRanges(a)(x))][b],
from = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
to = Table.TransformColumns(from,{"Столбец1",f})
in
to
Делим строго по скобкам… но как-то сложно и медленно.
ОК, что насчёт рекурсии?
let
f=(x)=>[a=Text.PositionOf(x,"("),
b=if a = -1 then x else @f(Text.RemoveRange(x,a,Text.PositionOf(x,")")-a+1))][b],
from = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
to = Table.TransformColumns(from,{"Столбец1",f})
in
to
Так, как минимум, быстрее, да и поприкольнее.
Вот только надо ли оно всё?
Если больше не к чему привязаться – надо, а в конкретном случае можно:
let
f=(x)=>Text.Combine(List.Transform(Text.Split(x,", "),(x)=>Text.Split(x,"("){0}),", "),
from = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
to = Table.TransformColumns(from,{"Столбец1",f})
in
to
let
f=(x)=>Text.Combine(List.Select(Text.SplitAny(x,"(,"),(x)=>not Text.Contains(x,")")),","),
from = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
to = Table.TransformColumns(from,{"Столбец1",f})
in
to
let
f=(x)=>Text.Combine(List.Alternate(Text.SplitAny(x,"(,"),1,1,1),", "),
from = Excel.CurrentWorkbook(){[Name="Таблица2"]}[Content],
to = Table.TransformColumns(from,{"Столбец1",f})
in
to
Бонус на формулах и объяснение того, что тут к чему, как всегда, смотрим на Ютубе
Лайк, коммент, подписка приветствуются )))
Надеюсь, было полезно.
Всех благ!
@buchlotnik