Как настроить отбор по регистратору в параметрах виртуальной таблицы оборотов в 1С?

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

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

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

Почему возникает ошибка при обращении к регистратору

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

  1. Зависимость от параметра «Периодичность». В виртуальной таблице оборотов поле Регистратор физически отсутствует в выборке, если не указана соответствующая детализация. Чтобы платформа включила регистратор в список доступных полей, в параметре Периодичность необходимо явно указать значение Регистратор или Авто. Если выбрана периодичность Месяц, День или параметр оставлен пустым, таблица рассчитывает только сводные агрегаты без детализации по документам.
  2. Составной тип данных. Поле Регистратор всегда имеет составной ссылочный тип, объединяющий все виды документов, являющихся регистраторами для данного регистра. Прямое обращение через точку вида Регистратор.ВидХозяйственнойОперации заставляет платформу выполнять неявное левое соединение (LEFT JOIN) со всеми возможными таблицами документов. Внутри параметров виртуальной таблицы такие конструкции либо вызывают синтаксическую ошибку, либо приводят к критическому падению скорости выполнения запроса.

Способ 1. Использование явного приведения типа через ВЫРАЗИТЬ

Рассмотрим первый вариант решения задачи, когда отбор строится по реквизиту конкретного вида документа. В этом случае в параметрах виртуальной таблицы задаем периодичность Регистратор или Авто и явно приводим составной тип регистратора к конкретному документу с помощью функции ВЫРАЗИТЬ.

Посмотрим на пример текста запроса:


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

Способ 2. Предварительный отбор документов во временную таблицу

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

Рассмотрим по шагам реализацию пакетного запроса:

  1. Первым запросом отбираем ссылки необходимых документов с нужным реквизитом и помещаем результат во временную таблицу ВТ_ОтобранныеДокументы.
  2. Вторым запросом обращаемся к виртуальной таблице оборотов и в параметрах фильтрации указываем условие вхождения Регистратор В (ВЫБРАТЬ Ссылка ИЗ ВТ_ОтобранныеДокументы).

Посмотрим на пример кода пакетного запроса:


ВЫБРАТЬ
    Реализация.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_ОтобранныеДокументы
ИЗ
    Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
    Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода
    И Реализация.ВидХозяйственнойОперации = &ВидОперации
;

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

Способ 3. Запрос к реальной таблице регистра

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

В реальной таблице поле Регистратор доступно всегда, входит в состав кластерного индекса и не требует настройки параметра Периодичность:


ВЫБРАТЬ
    Продажи.Период КАК Период,
    Продажи.Регистратор КАК Регистратор,
    Продажи.Сумма КАК Сумма
ИЗ
    РегистрНакопления.Продажи КАК Продажи
ГДЕ
    Продажи.Период МЕЖДУ &НачалоПериода И &КонецПериода
    И Продажи.Регистратор В (ВЫБРАТЬ ВТ.Ссылка ИЗ ВТ_ОтобранныеДокументы КАК ВТ)

Способ 4. Оптимизация структуры регистра

Если фильтрация по определенному реквизиту (например, ВидХозяйственнойОперации или ДокументПродажи) является регулярным сценарием в отчетах и алгоритмах, рекомендуется пересмотреть структуру метаданных. Добавление соответствующего реквизита или измерения непосредственно в регистр накопления позволяет накладывать отборы в параметрах виртуальной таблицы напрямую без обращения к полям документов.

← На главную