Мы часто сталкиваемся с необходимостью фильтровать данные из виртуальных таблиц 1С по нескольким условиям одновременно. Автор темы на форуме столкнулся с распространенной проблемой при попытке передать несколько параметров напрямую в виртуальную таблицу Остатки регистра накопления, получив ошибку "Исправьте текст запроса!". Давайте подробно разберем, почему возникает такая ситуация и как правильно реализовать множественную фильтрацию, чтобы запрос был не только рабочим, но и высокопроизводительным.
Изначальный запрос автора, который вызвал ошибку, выглядел так:
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО=&ЦФО, СтатьяЗатрат=&СтатьяЗатрат) КАК БюджетПредприятияОстатки
Эта конструкция не работает, потому что синтаксис языка запросов 1С для виртуальных таблиц, таких как Остатки регистра накопления, предполагает определенный набор параметров. Виртуальная таблица Остатки имеет два основных параметра:
&Дата в нашем примере), который определяет момент времени, на который необходимо получить остатки.Условие.Мы не можем произвольно добавлять параметры типа ЦФО=&ЦФО и СтатьяЗатрат=&СтатьяЗатрат в список после первого параметра, разделяя их запятыми. Вместо этого, все условия фильтрации по измерениям должны быть объединены в рамках одного второго параметра — параметра Условие.
Корректный способ передачи нескольких условий в виртуальную таблицу Остатки заключается в объединении всех фильтров внутри параметра Условие с помощью логического оператора И (AND). Рассмотрим, как это выглядит на практике:
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО=&ЦФО И СтатьяЗатрат=&СтатьяЗатрат) КАК БюджетПредприятияОстатки
Обратите внимание, что оба условия ЦФО=&ЦФО и СтатьяЗатрат=&СтатьяЗатрат теперь объединены оператором И и составляют единый второй параметр виртуальной таблицы. Именно такой синтаксис является корректным и позволяет платформе 1С правильно интерпретировать и применять фильтры на уровне СУБД.
В ходе обсуждения на форуме возникла мысль использовать секцию ГДЕ основного запроса для фильтрации данных, например, так:
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(&Дата) КАК БюджетПредприятияОстатки
ГДЕ
БюджетПредприятияОстатки.ЦФО = &ЦФО
И БюджетПредприятияОстатки.СтатьяЗатрат = &СтатьяЗатрат
Несмотря на то что такой запрос будет работать, он крайне не рекомендуется к использованию в большинстве случаев и может привести к серьезным проблемам с производительностью. Давайте выясним причину:
Когда мы передаем условия в параметры виртуальной таблицы (через параметр Условие), платформа 1С генерирует SQL-запрос к базе данных, который сразу же включает эти фильтры. Это означает, что СУБД выбирает и обрабатывает только те данные, которые соответствуют нашим условиям, существенно сокращая объем обрабатываемой информации. Это и есть принцип "фильтрации на самом раннем этапе", который является краеугольным камнем оптимизации запросов.
Если же мы используем секцию ГДЕ для фильтрации данных, полученных из виртуальной таблицы без параметров, происходит следующее:
ГДЕ. Это означает, что часть работы по фильтрации, которую могла бы сделать СУБД гораздо эффективнее, перекладывается на платформу 1С.Участники форума справедливо отмечали, что за использование ГДЕ вместо параметров ВТ можно "получить люлей от начальства" и что "Толстый танк приедет и скажет писать заявление", подчеркивая серьезность проблемы производительности.
СУБД (например, PostgreSQL, MS SQL Server) имеют очень сложные и оптимизированные механизмы для обработки запросов с фильтрацией на ранних этапах. Передавая условия непосредственно в параметры виртуальной таблицы 1С, мы даем возможность СУБД максимально эффективно использовать свои индексы и стратегии выполнения запросов. Запрос, сгенерированный 1С на основе параметров ВТ, будет значительно более эффективным, чем запрос, где фильтрация происходит после выборки большого объема данных.
Когда мы работаем с конструктором запросов в 1С, часто условия, которые мы задаем на закладке "Условия", автоматически помещаются в секцию ГДЕ. Это происходит по умолчанию и может ввести в заблуждение. Чтобы добиться правильного поведения, необходимо вручную отредактировать запрос, перенеся условия из секции ГДЕ в параметр Условие виртуальной таблицы, как мы рассмотрели выше.
Обычно конструктор запросов позволяет явно задать параметры виртуальной таблицы. Для виртуальной таблицы Остатки регистра накопления мы должны указать:
&КонецПериода.ЦФО = &ЦФО И СтатьяЗатрат = &СтатьяЗатрат.Убедитесь, что вы правильно используете логические операторы И, ИЛИ, НЕ для построения сложных условий внутри параметра Условие.
Давайте рассмотрим несколько примеров использования параметра Условие для различных сценариев фильтрации.
1. Фильтрация по нескольким значениям одного измерения (оператор В):
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО В (&СписокЦФО)) КАК БюджетПредприятияОстатки
Здесь параметр &СписокЦФО должен быть коллекцией значений (например, массив или список значений).
2. Сложное условие с И/ИЛИ:
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(
&Дата,
(ЦФО = &ЦФО1 И СтатьяЗатрат = &СтатьяЗатрат1)
ИЛИ (ЦФО = &ЦФО2 И СтатьяЗатрат = &СтатьяЗатрат2)
) КАК БюджетПредприятияОстатки
Для более сложных комбинаций условий мы можем использовать скобки для группировки.
3. Использование Не равно:
ВЫБРАТЬ
БюджетПредприятияОстатки.ЦФО КАК ЦФО,
БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО <> &ИсключаемоеЦФО) КАК БюджетПредприятияОстатки
Таким образом, мы выяснили, что для эффективной фильтрации данных в виртуальных таблицах 1С по нескольким измерениям необходимо использовать единый параметр Условие. Объединяйте все необходимые фильтры с помощью логических операторов И, ИЛИ и НЕ внутри этого параметра. Избегайте использования секции ГДЕ основного запроса для фильтрации данных, которые можно отфильтровать непосредственно в виртуальной таблице, чтобы обеспечить максимальную производительность и оптимальную работу с базой данных. Такой подход позволит нам создавать быстрые и надежные запросы, что является залогом стабильной работы системы 1С.