Почему не работает отбор в секции ГДЕ при обращении к виртуальной таблице регистра 1С?

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

В процессе написания запросов в 1С можно столкнуться с ситуацией, которая на первый взгляд кажется нелогичной. Например, мы пытаемся получить данные из виртуальной таблицы остатков регистра накопления и накладываем простое условие в секции ГДЕ, но запрос возвращает пустой результат, хотя мы точно знаем, что данные, удовлетворяющие условию, в базе есть. Рассмотрим, почему так происходит и как правильно конструировать такие запросы.

Проанализируем типичную проблему: есть запрос к виртуальной таблице РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.Остатки. В секции ГДЕ мы устанавливаем отбор по измерению ДоговорКонтрагента, передавая в параметр конкретный договор. В результате запрос ничего не находит. Давайте разберемся, в чем кроется причина и как это исправить.

Анализ проблемы: разница между параметрами виртуальной таблицы и условием ГДЕ

Ключ к пониманию проблемы лежит в механизме работы виртуальных таблиц в 1С. Когда мы пишем запрос, есть два основных способа отфильтровать данные из виртуальной таблицы:

  1. Через параметры самой виртуальной таблицы. Это основной и правильный способ для отбора по измерениям регистра.
  2. Через секцию ГДЕ в основном тексте запроса. Этот способ предназначен для фильтрации уже полученного и агрегированного результата.

Давайте посмотрим на пример запроса, который работает некорректно:


ВЫБРАТЬ
    ВзаиморасчетыОстатки.Контрагент,
    ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток
ИЗ
    РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.Остатки КАК ВзаиморасчетыОстатки
ГДЕ
    ВзаиморасчетыОстатки.ДоговорКонтрагента = &ДоговорКонтрагента

Почему этот запрос не возвращает данные? Процесс его выполнения выглядит так:

  1. Сначала платформа 1С обращается к виртуальной таблице ...Остатки без каких-либо условий по измерениям. Она вычисляет остатки по всем договорам, контрагентам и т.д., которые есть в регистре на текущий момент.
  2. В результате формируется временная таблица с итоговыми данными. Важный момент: если поле ДоговорКонтрагента не было указано в списке полей ВЫБРАТЬ и не участвовало в группировках, его может просто не быть в этой результирующей таблице. Виртуальная таблица отбирает только те поля, которые явно запрошены или необходимы для расчета итогов.
  3. И только после этого к полученному результату применяется условие из секции ГДЕ. Так как в результирующем наборе поля ДоговорКонтрагента, скорее всего, нет, то и фильтровать по нему невозможно. Результат — пустая выборка.

Иными словами, ГДЕ — это постфильтрация. Она работает с тем, что уже посчитала и вернула виртуальная таблица. Если нужного поля для фильтрации в этом результате нет, отбор не сработает.

Правильное решение: использование параметров виртуальной таблицы

Чтобы запрос работал корректно и, что не менее важно, оптимально, условия по измерениям регистра необходимо передавать непосредственно в параметры виртуальной таблицы. Это сообщает платформе, что данные нужно отфильтровать до того, как будут рассчитываться итоги.

Синтаксис обращения к виртуальной таблице остатков выглядит так: ИмяРегистра.Остатки(Период, Условие).

Посмотрим на правильный вариант того же запроса:


ВЫБРАТЬ
    ВзаиморасчетыОстатки.Контрагент,
    ВзаиморасчетыОстатки.СуммаВзаиморасчетовОстаток
ИЗ
    РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.Остатки(
            ,
            ДоговорКонтрагента = &ДоговорКонтрагента) КАК ВзаиморасчетыОстатки

В этом случае происходит следующее:

  1. Платформа 1С "видит" условие ДоговорКонтрагента = &ДоговорКонтрагента еще до обращения к данным.
  2. Она формирует оптимальный SQL-запрос к базе данных, который сразу выбирает из таблицы движений регистра только записи, относящиеся к нужному договору. Это возможно благодаря тому, что измерения регистра проиндексированы.
  3. Только после этого по отобранному, значительно меньшему набору данных рассчитываются остатки.

Такой подход гарантирует не только корректность результата, но и значительно более высокую производительность.

Влияние на производительность: почему параметры — это важно

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

Золотое правило работы с запросами к регистрам: всегда используйте параметры виртуальных таблиц для наложения отборов по измерениям. Секция ГДЕ должна использоваться для фильтрации по полям-ресурсам (например, СуммаОстаток > 1000) или по другим вычисляемым полям, которые получаются уже после работы виртуальной таблицы.

← На главную