Зачем в параметрах виртуальной таблицы СКД указывать {Неопределено КАК Поле2}?

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

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

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

Для того чтобы понять природу возникновения этой конструкции, проанализируем поведение системы компоновки данных при работе со встроенным механизмом автозаполнения. Когда мы создаем набор данных типа «Запрос» и оставляем включенным флаг «Автозаполнение» (что делается в 95% случаев для экономии времени), СКД берет на себя управление параметрами запроса.

Если в тексте запроса используется виртуальная таблица среза последних или остатков, например:


Выбрать
    ВалютыСрезПоследних.Валюта,
    ВалютыСрезПоследних.Курс
Из
    РегистрСведений.КурсыВалют.СрезПоследних() Как ВалютыСрезПоследних

Препроцессор СКД автоматически модифицирует этот запрос перед отправкой в СУБД. Платформа принудительно подставит в параметры виртуальной таблицы глобальный параметр периода. Итоговый запрос будет выглядеть примерно так: РегистрСведений.КурсыВалют.СрезПоследних(&Период). Это поведение влечет за собой две серьезные проблемы:

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

Разбор работы конструкции {Неопределено КАК Поле2}

Выясним причину, почему именно выражение {Неопределено КАК Поле2} решает описанные проблемы. Разберем эту синтаксическую конструкцию по элементам:

В момент компоновки макета и генерации финального SQL-запроса СКД анализирует фигурные скобки. Видя, что внутри передано фиксированное значение Неопределено, не привязанное к пользовательским настройкам, СКД просто удаляет эту конструкцию из итогового текста. На уровне СУБД выполняется чистый запрос без ограничений по периоду, гарантирующий получение самого актуального среза.

Альтернативные варианты и их сравнение

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

  1. Полное отключение автозаполнения в СКД: Можно снять флаг Автозаполнение для всего набора данных. Однако в этом случае разработчику придется вручную настраивать роли всех полей, описывать доступные поля выбора, отборы и параметры. Для сложных запросов это колоссальный объем рутинной работы, поэтому ради одной виртуальной таблицы отключать автозаполнение нерационально.
  2. Использование скрытого технического параметра: Мы можем написать СрезПоследних(&ТехническийПериод). Затем на вкладке «Параметры» в СКД для параметра &ТехническийПериод установить флаг «Ограничение доступности» (чтобы скрыть его от пользователя) и жестко прописать в качестве значения пустую дату или значение Неопределено. Этот способ абсолютно рабочий, но он требует выполнения лишних действий в нескольких вкладках конструктора и оставляет в схеме неиспользуемый технический параметр.
  3. Жесткое указание Неопределено без фигурных скобок: Написание СрезПоследних(Неопределено) без фигурных скобок лишает запрос гибкости. На некоторых версиях СУБД или старых релизах платформы прямая передача литерала Неопределено в качестве даты может вызывать ошибки приведения типов на уровне базы данных или приводить к неоптимальному плану выполнения запроса.

Практический пример применения

Проанализируем практическую ситуацию. Представим, что мы разрабатываем отчет по продажам за произвольный период, в котором также нужно вывести самую актуальную цену номенклатуры (действующую на текущий момент времени, а не на момент продажи). Нам необходимо соединить обороты продаж с актуальным срезом цен.

Для решения этой задачи мы напишем следующий запрос:


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

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

Использование этого приема позволяет сохранить лаконичность настроек схемы компоновки данных, не перегружая интерфейс пользователя лишними параметрами и гарантируя корректность получаемых данных.

← На главную