Как передать несколько параметров в виртуальную таблицу регистра накопления 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет IT и автоматизация бизнеса
← На главную

Мы часто сталкиваемся с необходимостью фильтровать данные из виртуальных таблиц 1С по нескольким условиям одновременно. Автор темы на форуме столкнулся с распространенной проблемой при попытке передать несколько параметров напрямую в виртуальную таблицу Остатки регистра накопления, получив ошибку "Исправьте текст запроса!". Давайте подробно разберем, почему возникает такая ситуация и как правильно реализовать множественную фильтрацию, чтобы запрос был не только рабочим, но и высокопроизводительным.

Почему не работает прямая передача нескольких параметров?

Изначальный запрос автора, который вызвал ошибку, выглядел так:


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО=&ЦФО, СтатьяЗатрат=&СтатьяЗатрат) КАК БюджетПредприятияОстатки

Эта конструкция не работает, потому что синтаксис языка запросов 1С для виртуальных таблиц, таких как Остатки регистра накопления, предполагает определенный набор параметров. Виртуальная таблица Остатки имеет два основных параметра:

  1. Параметр периода: Первый параметр (&Дата в нашем примере), который определяет момент времени, на который необходимо получить остатки.
  2. Параметр условий: Второй параметр, предназначенный для наложения фильтров на измерения регистра. В синтаксисе запросов 1С этот параметр известен как Условие.

Мы не можем произвольно добавлять параметры типа ЦФО=&ЦФО и СтатьяЗатрат=&СтатьяЗатрат в список после первого параметра, разделяя их запятыми. Вместо этого, все условия фильтрации по измерениям должны быть объединены в рамках одного второго параметра — параметра Условие.

Правильное решение: использование параметра "Условие"

Корректный способ передачи нескольких условий в виртуальную таблицу Остатки заключается в объединении всех фильтров внутри параметра Условие с помощью логического оператора И (AND). Рассмотрим, как это выглядит на практике:


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО=&ЦФО И СтатьяЗатрат=&СтатьяЗатрат) КАК БюджетПредприятияОстатки

Обратите внимание, что оба условия ЦФО=&ЦФО и СтатьяЗатрат=&СтатьяЗатрат теперь объединены оператором И и составляют единый второй параметр виртуальной таблицы. Именно такой синтаксис является корректным и позволяет платформе 1С правильно интерпретировать и применять фильтры на уровне СУБД.

Почему важно использовать параметры виртуальной таблицы, а не секцию "ГДЕ"?

В ходе обсуждения на форуме возникла мысль использовать секцию ГДЕ основного запроса для фильтрации данных, например, так:


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(&Дата) КАК БюджетПредприятияОстатки
ГДЕ
    БюджетПредприятияОстатки.ЦФО = &ЦФО
    И БюджетПредприятияОстатки.СтатьяЗатрат = &СтатьяЗатрат

Несмотря на то что такой запрос будет работать, он крайне не рекомендуется к использованию в большинстве случаев и может привести к серьезным проблемам с производительностью. Давайте выясним причину:

1. Принцип "фильтрации на самом раннем этапе"

Когда мы передаем условия в параметры виртуальной таблицы (через параметр Условие), платформа 1С генерирует SQL-запрос к базе данных, который сразу же включает эти фильтры. Это означает, что СУБД выбирает и обрабатывает только те данные, которые соответствуют нашим условиям, существенно сокращая объем обрабатываемой информации. Это и есть принцип "фильтрации на самом раннем этапе", который является краеугольным камнем оптимизации запросов.

2. Снижение производительности при использовании "ГДЕ"

Если же мы используем секцию ГДЕ для фильтрации данных, полученных из виртуальной таблицы без параметров, происходит следующее:

  1. Избыточный выбор данных: СУБД сначала выбирает все остатки регистра на указанную дату (если не переданы другие фильтры в саму виртуальную таблицу). Это может быть огромный объем данных, если регистр большой.
  2. Дополнительная обработка на уровне 1С: После того как все эти (возможно, избыточные) данные получены, платформа 1С начинает применять к ним фильтры из секции ГДЕ. Это означает, что часть работы по фильтрации, которую могла бы сделать СУБД гораздо эффективнее, перекладывается на платформу 1С.
  3. Передача лишних данных по сети: Все эти избыточные данные сначала передаются от СУБД к серверу 1С (или к клиенту, если запрос выполняется на клиенте). Для больших объемов это существенно увеличивает нагрузку на сеть и время выполнения запроса.

Участники форума справедливо отмечали, что за использование ГДЕ вместо параметров ВТ можно "получить люлей от начальства" и что "Толстый танк приедет и скажет писать заявление", подчеркивая серьезность проблемы производительности.

3. Оптимизация на стороне СУБД

СУБД (например, PostgreSQL, MS SQL Server) имеют очень сложные и оптимизированные механизмы для обработки запросов с фильтрацией на ранних этапах. Передавая условия непосредственно в параметры виртуальной таблицы 1С, мы даем возможность СУБД максимально эффективно использовать свои индексы и стратегии выполнения запросов. Запрос, сгенерированный 1С на основе параметров ВТ, будет значительно более эффективным, чем запрос, где фильтрация происходит после выборки большого объема данных.

Работа с конструктором запросов

Когда мы работаем с конструктором запросов в 1С, часто условия, которые мы задаем на закладке "Условия", автоматически помещаются в секцию ГДЕ. Это происходит по умолчанию и может ввести в заблуждение. Чтобы добиться правильного поведения, необходимо вручную отредактировать запрос, перенеся условия из секции ГДЕ в параметр Условие виртуальной таблицы, как мы рассмотрели выше.

Обычно конструктор запросов позволяет явно задать параметры виртуальной таблицы. Для виртуальной таблицы Остатки регистра накопления мы должны указать:

  1. Первый параметр (Период): Например, &КонецПериода.
  2. Второй параметр (Условие): Здесь мы пишем наши условия, например, ЦФО = &ЦФО И СтатьяЗатрат = &СтатьяЗатрат.

Убедитесь, что вы правильно используете логические операторы И, ИЛИ, НЕ для построения сложных условий внутри параметра Условие.

Примеры использования различных условий

Давайте рассмотрим несколько примеров использования параметра Условие для различных сценариев фильтрации.

1. Фильтрация по нескольким значениям одного измерения (оператор В):


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО В (&СписокЦФО)) КАК БюджетПредприятияОстатки

Здесь параметр &СписокЦФО должен быть коллекцией значений (например, массив или список значений).

2. Сложное условие с И/ИЛИ:


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(
        &Дата,
        (ЦФО = &ЦФО1 И СтатьяЗатрат = &СтатьяЗатрат1)
        ИЛИ (ЦФО = &ЦФО2 И СтатьяЗатрат = &СтатьяЗатрат2)
    ) КАК БюджетПредприятияОстатки

Для более сложных комбинаций условий мы можем использовать скобки для группировки.

3. Использование Не равно:


ВЫБРАТЬ
    БюджетПредприятияОстатки.ЦФО КАК ЦФО,
    БюджетПредприятияОстатки.СтатьяЗатрат КАК СтатьяЗатрат,
    БюджетПредприятияОстатки.БюджетОстаток КАК БюджетОстаток
ИЗ
    РегистрНакопления.БюджетПредприятия.Остатки(&Дата, ЦФО <> &ИсключаемоеЦФО) КАК БюджетПредприятияОстатки

Выводы

Таким образом, мы выяснили, что для эффективной фильтрации данных в виртуальных таблицах 1С по нескольким измерениям необходимо использовать единый параметр Условие. Объединяйте все необходимые фильтры с помощью логических операторов И, ИЛИ и НЕ внутри этого параметра. Избегайте использования секции ГДЕ основного запроса для фильтрации данных, которые можно отфильтровать непосредственно в виртуальной таблице, чтобы обеспечить максимальную производительность и оптимальную работу с базой данных. Такой подход позволит нам создавать быстрые и надежные запросы, что является залогом стабильной работы системы 1С.

← На главную