Страницы: 1
RSS
Поиск вхождений текста и создание столбца по условию в PQ, Просматриваем столбец, если находим одну из «кодовых фраз», то возвращаем «результат» по таблице соответствия.
 
Добрый день!

Обрабатываю банковскую выписку. Хочу автоматизировать заполнение дополнительных столбцов, значения в которых зависит результатов поиска соответствия.

Подскажите, пожалуйста, как реализовать на PQ создание такого столбца по таблице соответствия.

Чтобы избежать множества if, пытался решить задачу в помощью List.Accumulate. Но смог заменить только часть текста, а не всю ячейку.

Подробности в прилагаемом файле.
Спасибо.
Изменено: avbook - 04.02.2026 17:20:46
 
Добрый день, avbook. В файле пишите, что надо что-то "помещать" в столбцы Контрагент и СтатьяБюджета (которых нет в выписке), а на деле пытаетесь заменить текст в столбце Назначение платежа. Так что вам надо на самом деле? И что делать, если найдется несколько соответствий (а вдруг)? Брать первое попавшееся?
Пришелец-прораб.
 
Цитата
AlienSx написал:
Так что вам надо на самом деле?
AlienSx, на самом деле у меня есть выписка из клиент банка. Мне нужно ее преобразовать в таблицу, которую я потом загружаю в учетный файл Excel. В зависимости от назначения платежа определяются Контрагент, Статья бюджета и др. поля (столбцы) для аналитики. Эти столбцы добавляются к существующей выписке. Оригинальное назначение платежа тоже остается.

Если найдется два соответствия, то брать первое. Такая ситуация, конечно, возможна. Тогда придется регулировать ее порядом строк в таблице соответствия? Я не тестировал этот случай.

По поводу моего файла. Хоть я и делаю замену, PQ создает новый столбец, и это ок. Этот способ я нашел в видео от Николая Павлова на этом сайте. И хотел заменить Text.Replace на что-то другое, но не получилось. А сам файл выложил, чтобы лучше объяснить свой вопрос.
 
avbook,
См. Выписка (2) Столбцы H (Контрагент) и I (СтатьяБюджета)

P.S. Если правильно понял из Вашего объяснения.  
 
List.Accumulate здесь не при делах. Нужен List.PositionOf
код
Изменено: AlienSx - 04.02.2026 21:33:46
Пришелец-прораб.
 
Ivan.Z, большое спасибо!
Ваш код работает. Вы очень помогли.

У меня 2016 Excel. При открытии файла было предупреждение, что запрос сделан в более старшей версии Excel и может не работать. Я проверил - на первый взгляд, все работает. Такое сообщение можно игнорировать?

Если есть возможность, пожалуйста, расскажите кратко, почему несколько операторов "in"? Спасибо.
 
Цитата
AlienSx написал:
List.Accumulate здесь не при делах. Нужен List.PositionOf
AlienSx, , и Вам большое спасибо!
Ваш код формирует сразу 2 столбца. Это здорово. Хотя, если понадобиться три, мне будет сложновато его подредактировать...

Подскажите, пожалуйста, в данном случае, в чем преимущество  List.PositionOf?
Спасибо.
 
Цитата
avbook написал:
Подскажите, пожалуйста, в данном случае, в чем преимущество  List.PositionOf?
в сравнении с чем?
Пришелец-прораб.
 
Цитата
AlienSx написал:
в сравнении с чем?
С List.Accumulate.  Вы говорите, что эта функция не подходит для этой задачи.
Коллега прислал решение, где она используется.  Сообщение 4 в этом чате выше.

Я пока не так глубоко знаю PQ и поэтому хотел бы разобраться более подробно.
Изменено: avbook - 04.02.2026 23:35:12
 
avbook, посмотрите вот этот видосик (извините, что youtube). Классика. У вас какая задача? Пройтись по всему справочнику или найти первое вхождение и остановиться? List.Accumulate (как его не улучшай, чтобы он не делал лишних операций по поиску, если значение уже найдено) все равно  будет исправно идти по справочнику от начала и до самого конца. И зачем? List.PositionOf (с Occurrence.First в данном случае) или, как у автора видео, List.Skip остановятся, если значение найдено.
Цитата
avbook написал:
Коллега прислал решение
которое еще и 2-ды бежит по справочнику (это уже не имеет отношения к List.Accumulate).
Пришелец-прораб.
 
Цитата
написал:
Такое сообщение можно игнорировать?
Да. В Вашей версии все работает. В данном случае, сообщение информационное.
Изменено: Ivan.Z - 05.02.2026 07:36:37
 
avbook,
Цитата
написал:
пытался решить задачу в помощью List.Accumulate
я доработал Вашу логику решение задачи.

AlienSx абсолютно прав. Его вариант решение лучше и правильней, в контексте поставленной задачи.
Если чешется затылок, расчесывать все тело не нужно точно)
 
Цитата
Ivan.Z написал:
я доработал Вашу логику решение задачи.
строго говоря, при небольшом справочнике List.Accumulate будет отрабатывать не сильно медленнее. Проблема Вашего решения в первую очередь не в List.Accumulate, а в том, что справочник создается заново при каждом к нему обращении. Справочник надо создать один раз в запросе и потом на него ссылаться (+ буфер, если это не record), а не вызывать функцию создания всякий раз. Вот такой код
list accumulate

отработает вполне себе быстро на справочнике с примерно 100 строк и 10 000 строк в выписке. По сравнению с List.PositionOf скорость упадет, но не катастрофически. И только с ростом словаря это будет замедляться.
А вот зачем Вы стали последовательно создавать столбцы, вызывая справочник всякий раз - это не поддается разумному объяснению. Плюс эта "пурга" c let ... in   8-0  Впервые встречаю такой "стиль"  :) Но это уже дело вкуса. Если Вам так удобнее и понятнее - да пожалуйста.
Пришелец-прораб.
 
AlienSx, ну, критика по существу. Спасибо.

"Мы все учились понемногу, чему-нибудь и как-нибудь"
 
Цитата
AlienSx написал:
на справочнике с примерно 100 строк и 10 000 строк в выписке
Мои объемы раза в 4 меньше. Поэтому быстродействие не так важно.
 
Коллеги, спасибо всем за реальную помощь!

AlienSx, спасибо за видео. Я тоже думал использовать Split. :)
Ваш второй вариант работает. Мне он более понятен, т.к использует знакомую List.Accumulate.

Насколько понимаю, оба Ваших Варианта создают доп. столбцы одновременно – это должно ускорять выполнение запроса при больших объемах.
А также – Ваш код несложно доработать, если количество этих доп. столбцов изменится. Верно?
 
Цитата
avbook написал:
это должно ускорять выполнение запроса при больших объемах.
нет. Я просто не вижу другого решения, кроме как найти строку из справочника и добавить ее в выписку полностью (за исключением первого значения). В зависимости от типа строк в справочнике (список списков или список записей) применяем нужную функцию по разделению столбца на несколько.
Цитата
avbook написал:
если количество этих доп. столбцов изменится.
просто читаем имена столбцов в справочнике и используем их. Вполне себе обычная операция. Одно условие - ключевое значение должно идти первым. Попробуйте вот этот код (я перешел на списки вместо записей)
без имен столбцов справочника

А если забыть про List.Accumulate, то вот так пошустрее будет
list.skip
Изменено: AlienSx - 06.02.2026 07:43:51
Пришелец-прораб.
 
AlienSx, еще раз спасибо. Несколько вариантов - есть из чего выбрать.

Вопрос offtop, если можно.
Верно ли я понимаю, что если просматриваемый столбец и столбец с условиями содержат не фразы, а только слова, то проще и быстрее будет воспользоваться объединением таблиц join?
 
Цитата
avbook написал:
проще и быстрее будет воспользоваться объединением таблиц join?
проще - да. Быстрее, чем то, что есть сейчас - скорее всего. Но при таком раскладе могут быть и другие подходы к решению.
Пришелец-прораб.
 
Цитата
AlienSx написал:
Но при таком раскладе могут быть и  другие подходы к решению
Интересно и познавательно.
Страницы: 1
Читают тему
Наверх