Разработчики 1С нередко сталкиваются с ситуацией: запрос, идеально работающий в обычной консоли запросов, при переносе в схему компоновки данных (СКД) возвращает пустой результат либо ведет себя некорректно. Особенно часто такая проблема возникает при работе с виртуальными таблицами регистров накопления и сведений, когда разработчик пытается фильтровать данные по периоду через дату регистратора.
Разберем детально механизм работы компоновщика данных, выясним причину такого поведения и рассмотрим правильные варианты настройки запроса в СКД.
В отличие от консоли запросов, которая выполняет переданный текст запроса напрямую «как есть», СКД работает принципиально иначе. Компоновщик макета СКД анализирует состав выбранных пользователем полей, настройки группировок, отборов и доступных параметров, после чего на лету перестраивает исходный текст запроса перед отправкой в СУБД.
Если в наборе данных включен признак Автозаполнение, система автоматически:
ГДЕ.НачалоПериода и КонецПериода) с параметрами виртуальных таблиц.Если в тексте запроса разработчик убирает параметры из заголовка виртуальной таблицы и пытается вручную прописать условие вида ГДЕ Регистратор.Дата МЕЖДУ &НачалоПериода И &КонецПериода, возникает логический конфликт с механизмами автозаполнения СКД, что приводит к некорректной генерации результирующего SQL-запроса и пустой выборке.
Обращение к реквизиту через точку от ссылочного поля (Регистратор.Дата) в запросах 1С вызывает неявное соединение (LEFT JOIN) с таблицами всех возможных документов, которые могут выступать регистраторами для данного регистра. Это влечет за собой следующие проблемы:
Период. Фильтрация по полю Регистратор.Дата не использует индекс по периоду таблицы регистра.Для того чтобы параметры виртуальной таблицы применялись гибко и динамически (только тогда, когда они заданы в отчете), необходимо использовать синтаксис расширения языка запросов СКД — фигурные скобки {}.
Посмотрим на пример правильного описания виртуальной таблицы оборотов:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура КАК Номенклатура,
ПродажиОбороты.КоличествоОборот КАК КоличествоОборот,
ПродажиОбороты.СуммаОборот КАК СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты({(&НачалоПериода)}, {(&КонецПериода)}, Регистратор, {УсловиеПолей}) КАК ПродажиОбороты
Рассмотрим, как это работает:
{(&НачалоПериода)} и {(&КонецПериода)} сообщает СКД, что если соответствующие параметры заданы и включены в настройках отчета, они будут переданы в параметры виртуальной таблицы.Регистратор позволяет получать детальные данные с точностью до документа-регистратора, сохраняя корректную работу итогов.Если в схеме компоновки данных используются стандартные параметры периода, достаточно явно указать их в параметрах виртуальной таблицы без лишних условий в секции ГДЕ:
ВЫБРАТЬ
ТоварыНаСкладахОбороты.Склад КАК Склад,
ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
ТоварыНаСкладахОбороты.Регистратор КАК Регистратор,
ТоварыНаСкладахОбороты.Период КАК Период,
ТоварыНаСкладахОбороты.КоличествоОборот КАК КоличествоОборот
ИЗ
РегистрНакопления.ТоварыНаСкладах.Обороты(&НачалоПериода, &КонецПериода, Регистратор, ) КАК ТоварыНаСкладахОбороты
Проанализируем ключевые настройки для этого варианта на вкладке Параметры в СКД:
НачалоПериода и КонецПериода должны иметь тип Дата (или СтандартныйПериод для удобства пользователя).Период на вкладке Наборы данных рекомендуется проверить заполнение роли поля, указав соответствующий тип периода (например, Регистратор или ПериодСекунда).Если требуется полностью исключить вмешательство генератора СКД в текст запроса, выполним следующие шаги:
{ВЫБРАТЬ ...}, {ГДЕ ...}.