А хочется в одну строку... Можно ли в функции Table.ReplaceValue указать сразу несколько значений для замены? И можно ли в Table.ReplaceValue при поиске указывать "любой" символ? Например, "Игрушка * медведь", где * может быть любое кол-во символов, например, белый или черный или бурый.
Такой код работает. А можете пояснить суть записи (value, old, new) ? Я правильно понял, что это вызов функции value определяющее выражение которой указано после => и эта функция возвращает единственное значение new ? Но не понятно как работает 4й параметр в функции ReplaceValue, ведь Значение это #"Убрать!@#" , старое значение это @!#", а новое это "." и тут по идее функция должна быть закрыта. Replacer.ReplaceValue(value as any, old as any, new as any) as any
И ещё я заметил что функция убирает знак ", причём я не прошу PQ его удалять (указываю символы <)(> ), ну или получается, что прошу (ведь без "" указать значения нельзя), но как тогда быть если символ " нужно сохранить в тексте?
Код
let
Источник = Excel.CurrentWorkbook(){[Name="Остатки"]}[Content],
#"Замена <)(>" = Table.ReplaceValue(Источник,"<)(>", "!",(value, old, new)=>Text.Combine(Splitter.SplitTextByAnyDelimiter(Text.ToList(old))(value),new),{"Наименование"})
in
#"Замена <)(>"
Цитата
Андрей VG написал: Максим, а не проще ли было Код ? 1Text.Remove(value, Text.ToList(oldValue)) У ТС же просто удаление символов?
Как написать данную конструкцию я пока что не понял, надо дальше вникать в синтаксис языка.... Да, суть задачи - удалить ненужные символы.
Примитивное исследование показало, что по умолчанию в функции Table.ReplaceValue используется например, функция Replacer.ReplaceText, принимающая на вход 3 аргумента, в справке по ней обозванные как value, old, new. При этом понятно, что раз мы указываем в Table.ReplaceValue название функции без прямой передачи этих аргументов, значит, Table.ReplaceValue передает эти аргументы где-то внутри, хотя по сути мы их задаем там же в общих аргументах - имя столбца, старое значение, новое значение. Но сама функция замены нас не устроила, поэтому создали свою функцию, которая также берет три аргумента, в том же порядке. Код функций (в сокращенном представлении) пишется как (arg1, arg2, ..., argN) => function body. Можно задать типы аргументов и тип возвращаемого значения.
Приветствую всех форумчан! Нужна помощь в написании кода в Power Query замены фрагмента списка, при том что заменяемый фрагмент содержит внутри те же разделители, что и весь список. То есть в ряду ячейки содержат список ответственных, разделенных запятыми: {МВД,МИД, акиматы Алматы, Нур-Султана и областей, НБ}, {Акиматы областей,гг. Алматы, Нур-Султана,МВД,МИД, НБ}, и так далее и требуется замена по таблице соответствия: акиматы Алматы, Нур-Султана и областей = МИО Акиматы областей,гг. Алматы, Нур-Султана =МИО Понятно, что имеется значительно больше чем две строки как в основной таблице, так и в таблице соответствия. А так получается, что делаю порядка 300 шагов по замене,что сильно тормозит запрос. И нашел пока единственный выход: на основе этих шагов создал таблицу соответствия полного текста ячеек с исправленными вручную, убрал эти шаги через через слияние. запросов. Понимаю, что нужно организовать внутри функции Table.ReplaceValue цикл перебора, но увы не обладаю достаточными знаниями в создании вложенных функций, а тем более с учетом преобразований в лист, преобразованием форматов на лету и так далее. Буду рад любой методической помощи, так как на этом примере хочу понять механизм таких формул и преобразований. P.S. В теме "Замена значений в PowerQuery, Заменить несколько значений в столбце одним шагом в PQ" решение касается только замены всей ячейки.
Андрей VG,рахмет (спасибо). Сейчас пытаюсь определиться с логикой Вашего кода. arturH также отправил свой вариант с рекурсией. У нас уже ночь. Все остается на завтра. Еще раз спасибо за оперативный ответ.
Андрей VG,приветствую. Попытаюсь изложить понимание Вашего решения: 1.Преобразуем таблицу соответствия в Список: List.Buffer(Table.ToRecords(Источник)) 2. Группируем таблицу исходных данных по столбцу, подлежащему исправлению.Заодно определяем эти группировки как ключ, то есть уникальные. В созданном столбце temp храним сгруппированные таблицы. 3. Преобразуем исходную таблицу формулой Table.TransformColumns, используя в качестве функции трансформации выражение, заключенное в фигурные скобки. 4. В фигурных скобках работает пользовательская функция (source), которая использует в качестве вычисляемого выражения для первой функции List.Accumulate с объявленными аргументами (acc, pair) для листа функцию замены пар Text.Replace(acc, pair[ВХОД], pair[ВЫХОД]). Вот тут мне и возникли вопросы:то что Text.Replace передает пары в функции аккумулятора понятно, но где здесь исходный источник, ведь для накопления берется лист ПОДСТАНОВКА. А исходный текст используется только в самой трансформации. Или эта конструкция работает в итерации: вначале пара из таблицы соответствия (тип List) для замены, потом это передается в исходный текст с накоплением переданной пары в аккумуляторе, потом возвращаемся к аккумулятору, тот запрашивает новую пару (??? - по строке вниз или не совпадающей с уже накопленными парами) и по этой новой паре идет замена в функции трансформации. 5. Разворачиваем полученную на предыдущем шаге таблицу: разворачиваются таблицы столбца temp с колонками "Программы","Задачи" в одноименные столбцы новой таблицы. 6. Приводим таблицу в завершенный вид. Приношу извинения за возможно технически неграмотный текст, но я не спец в языках программирования. Я чаще всего использую готовые модули с общим пониманием концепта решения. НО... эффективное использование возможностей PQ, PPivot и PBI, на мой взгляд, требуют понимания нюансов соответствия типа данных используемым переменных, понимания механизмов, в том числе внутренних, работы той или иной функции. Иначе как делал я 300 и более шагов, так и буду. И тогда смысл использования надстроек пропадает окончательно. Надеюсь с помощью формучан всетаки освоить хоть какие-то азы
AzatKukanov написал: Вот тут мне и возникли вопросы:то что Text.Replace передает пары в функции аккумулятора понятно, но где здесь исходный источник, ведь для накопления берется лист ПОДСТАНОВКА.
(source) => // текущее значение для замены подается в качестве аргумента на функцию трансформатор для Table.TransformColumns List.Accumulate(ПОДСТАНОВКА, // итератор, проходит по каждой записи списка source, // текущее стартовое значение = (source), (acc, pair) => // acc = source на первом шаге итерации, будет постоянно меняться так как является одним из аргументов функции Text.Replace, // pair = текущему значению из списа-итератора Text.Replace(acc, // является текстом в котором ищется значение для замены pair[ВХОД], // что ищем pair[ВЫХОД])) // на что заменяем