Запрос в СКД 1С пишется на том же языке запросов, что и обычный Запрос, но выполняется не напрямую. Система компоновки данных берёт текст набора данных как шаблон: добавляет отборы пользователя, убирает неиспользуемые поля и таблицы, подставляет параметры. Поэтому в наборе данных нельзя писать секции ИТОГИ и АВТОУПОРЯДОЧИВАНИЕ, зато можно использовать расширение языка в фигурных скобках {}.
Если коротко: всё, что касается итогов и порядка, переезжает в настройки отчёта, а всё, что должно быть «по желанию пользователя» (параметр может быть не заполнен, отбор может отсутствовать), оформляется фигурными скобками. Ниже разберу, как это работает и как увидеть, во что СКД превратила ваш запрос.
Наборы данных СКД и место запроса среди них
У схемы компоновки три вида наборов данных:
| Набор | Откуда данные | Когда использовать |
|---|---|---|
| Запрос | Таблицы информационной базы | Почти всегда: это основной источник |
| Объект | Таблица значений или другая коллекция, переданная из кода | Данные, которые нельзя получить запросом: внешние API, расчёты в коде |
| Объединение | Несколько наборов, сложенных как ОБЪЕДИНИТЬ ВСЕ | Свести разнородные источники в одну таблицу |
В девяти отчётах из десяти работает набор «Запрос». Поэтому понимать, чем запрос в СКД отличается от обычного, нужно каждому, кто пишет отчёты.
Чего нельзя в запросе СКД
Два ограничения, о которые спотыкаются чаще всего:
- Секция
ИТОГИне используется. Итоги в СКД считаются по структуре настроек: группировкам, таблицам, диаграммам. Числовые поля описываются на закладке «Ресурсы» с выражением агрегирования, напримерСумма(Количество). АВТОУПОРЯДОЧИВАНИЕне используется. Порядок задаётся на закладке «Сортировка» в настройках варианта и может меняться пользователем.
Всё остальное доступно: пакетные запросы, временные таблицы, СГРУППИРОВАТЬ ПО, ИМЕЮЩИЕ, ОБЪЕДИНИТЬ, виртуальные таблицы регистров, параметры. Параметры, найденные в тексте запроса, СКД сама добавляет на закладку «Параметры».
Ещё одна особенность: СКД анализирует последний пакет запроса. Именно из его секции ВЫБРАТЬ строится список полей набора. Временные таблицы предыдущих пакетов в поля не попадают, они лишь готовят данные.
Автозаполнение: кто описывает поля набора
У набора данных «Запрос» есть флаг «Автозаполнение». Когда он включён:
- СКД разбирает текст и заполняет закладку полей набора по последнему пакету.
- Сама определяет, какие поля можно использовать в отборах, группировках и сортировке.
- Сама решает, в какое место запроса подставить отбор пользователя.
Когда флаг выключен, СКД берёт только то, что явно описано в тексте конструкциями расширения языка. Это нужно, когда автоматика делает не то: например, ставит отбор в итоговый пакет, хотя эффективнее отфильтровать данные ещё во временной таблице или в параметрах виртуальной таблицы. На проектах я выключаю автозаполнение только у тяжёлых отчётов, где расположение отбора критично для скорости, и всегда оставляю в тексте комментарий, зачем это сделано.
Фигурные скобки: расширение языка запросов СКД
Всё, что заключено в {}, — инструкции для компоновщика, а не для СУБД. Краткое описание есть во встроенной справке платформы, раздел про расширение языка запросов для системы компоновки данных. Многие конструкции можно не писать руками, а выставить в конструкторе запроса на закладке «Компоновка данных».
Поля для выбора и отбора
ВЫБРАТЬ
Продажи.Номенклатура КАК Номенклатура,
Продажи.Контрагент КАК Контрагент,
Продажи.Сумма КАК Сумма
{ВЫБРАТЬ
Номенклатура.*,
Контрагент.*,
Сумма}
ИЗ
РегистрНакопления.Продажи КАК Продажи
{ГДЕ
Продажи.Номенклатура.* КАК Номенклатура,
Продажи.Контрагент.* КАК Контрагент}{ВЫБРАТЬ ...} перечисляет поля, которые попадут в набор. Звёздочка после поля разрешает использовать его реквизиты через точку. {ГДЕ ...} перечисляет поля, по которым пользователь может ставить отбор, и показывает компоновщику, куда этот отбор вставлять.
Необязательные условия
Обычное условие с незаполненным параметром даст ошибку при формировании отчёта. Условие в фигурных скобках при незаполненном параметре выбрасывается целиком:
ВЫБРАТЬ
Заказы.Ссылка КАК Заказ,
Заказы.СуммаДокумента КАК Сумма
ИЗ
Документ.ЗаказКлиента КАК Заказы
{ГДЕ
Заказы.Менеджер = &Менеджер,
Заказы.Дата >= &НачалоПериода}Если пользователь не указал менеджера, отчёт покажет заказы всех менеджеров. Это удобнее, чем городить в тексте ГДЕ (&Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка) ИЛИ Заказы.Менеджер = &Менеджер): такое «ИЛИ» мешает СУБД использовать индекс.

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

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




