Как запретить СКД автоматически подставлять параметры периода в виртуальные таблицы запроса?

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

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда система проявляет «излишний интеллект». Одной из таких особенностей является автоматическая подстановка значений периода (Начало периода и Конец периода) во все виртуальные таблицы регистров, используемые в запросе. Рассмотрим подробнее, почему это происходит и как мы можем взять управление параметрами под свой контроль.

Механизм автоматического заполнения в СКД

Проанализируем ситуацию: когда в схеме компоновки данных на закладке «Наборы данных» установлена галочка «Автозаполнение», СКД берет на себя функции по модификации вашего текста запроса перед его отправкой в СУБД. Если в тексте запроса встречается обращение к виртуальной таблице, например, РегистрНакопления.Закупки.Обороты, система автоматически пытается связать параметры этой таблицы со стандартными параметрами отчета НачалоПериода и КонецПериода.

Даже если вы оставили скобки параметров пустыми, как в примере ниже:


ИЗ
    РегистрНакопления.Закупки.Обороты(,, Регистратор, ) КАК ЗакупкиОбороты

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

Решение 1: Использование расширения языка запросов (Фигурные скобки)

Разберем самый гибкий и «правильный» способ управления параметрами — использование фигурных скобок {}. Это расширение языка запросов специально создано для того, чтобы подсказать компоновщику макета, как именно нужно обрабатывать те или иные части запроса.

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


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

В этом случае СКД перестанет принудительно подставлять значения из стандартных &НачалоПериода и &КонецПериода в эту таблицу, если вы явно не укажете иное в настройках компоновщика. Если же оставить скобки внутри параметров пустыми — Обороты({,,,}) — система полностью проигнорирует автоматическую подстановку для этой конкретной таблицы.

Решение 2: Отключение автозаполнения

Выясним причину, по которой иногда проще полностью отказаться от автоматики. Если ваш запрос сложный, содержит много временных таблиц и вложенных условий, галочка «Автозаполнение» может приводить к непредсказуемым результатам. Отключив её, вы берете на себя обязанность:

Это трудоемкий, но максимально надежный способ для профессиональной разработки сложных отчетов. В этом режиме СКД выполнит запрос «как есть», без скрытых модификаций кода.

Оптимизация: Получение последней записи без виртуальных таблиц

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

Проанализируем альтернативный подход — обращение к основной (физической) таблице регистра. Это позволит избежать лишних вычислений внутри движка 1С:


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

Если же нужно получить последние даты по всему списку номенклатуры, эффективнее использовать вложенный запрос с получением МАКСИМУМ(Период) из физической таблицы регистра накопления, а затем соединить его с этой же таблицей для получения регистратора или цены.

Роли полей и их влияние

В СКД у каждого поля есть свойство «Роль». Если ваше поле в запросе называется Период, система автоматически может назначить ему роль периода. Это заставляет СКД применять к нему фильтры из стандартного периода отчета. Чтобы избежать этого, зайдите в настройки набора данных и проверьте колонку «Роль». Если там указано «Период», попробуйте очистить это значение или настроить его вручную, чтобы СКД не рассматривала это поле как системное ограничение по времени.

Почему создание нового отчета иногда «решает» проблему?

Рассмотрим нюанс, связанный с кэшированием. В платформе 1С настройки компоновщика (пользовательские настройки, настройки параметров) сохраняются отдельно от самой схемы запроса. Если вы долго редактировали один и тот же отчет, в его сохраненных настройках (в кеше или в базе данных под вашим пользователем) могли остаться «старые» привязки параметров. При создании нового отчета с тем же текстом запроса вы получаете «чистую» схему, где настройки параметров еще не инициализированы старыми данными, что и создает эффект «чудесного исправления».

Важные моменты для запоминания:

  1. Галочка «Автозаполнение» — главный виновник автоматической подстановки дат.
  2. Использование {&НачалоПериода} в параметрах виртуальной таблицы — лучший способ точечного контроля.
  3. Для получения «последнего документа» физические таблицы регистров часто работают быстрее виртуальных Обороты.
  4. Всегда проверяйте закладку «Параметры» в СКД, чтобы убедиться, что нужные галочки (например, «Ограничение доступности») установлены верно.
← На главную