Для чего нужны фигурные скобки в запросе СКД?
Фигурные скобки в запросах СКД представляют собой расширение языка запросов, которое заставляет систему компоновки данных по‑другому трактовать участки запроса: выбрасывать части условий, управлять обязательностью параметров, подключать характеристики и влиять на формирование списка полей отчета.
Обычный запрос в 1С, который вы пишете в модуле, — это жесткая конструкция. Если вы написали:
ГДЕ Склад = &Склад то параметр &Склад должен быть обязательно заполнен. Иначе при выполнении запроса вы получите ошибку.
Если же вы используете фигурные скобки в СКД, вы говорите системе:
«Смотри, вот это условие/поле/таблица — они необязательные. Если пользователь не укажет значение для параметра, просто убери этот кусок из запроса».
Это расширение языка запросов для СКД, и оно работает только в ее контексте. В данной статье мы подробно расссмотрим способы расширения языка запросов с помощью фигурных скобок.
ВАЖНО! Флаг «Автозаполнение»
Прежде чем говорить о расширении языка запросов при помощи использования фигурных скобок, нужно разобраться с флагом «Автозаполнение«. При включенном флаге расширение языка не будет работать. Что же он делает? Он автоматически добавляет параметры для виртуальных таблиц, добавляет доступные поля для выборки и отборов. С одной стороны это очень удобно. Но это также влечет за собой подводные камни.
- Неконтролируемые «дубли» полей: Если вы переименуете поле в запросе (например, зададите псевдоним
Товардля поляНоменклатура), автозаполнение добавит оба варианта. Пользователь увидит в настройках иНоменклатура, иТовар, что может вызвать путаницу. - Неявное наложение отборов: Это наиболее коварная проблема. Если в вашем отчете несколько подзапросов (например, с использованием
ОБЪЕДИНИТЬ), СКД может подставить один и тот же параметр периода во все части запроса. В итоге в разных частях отчета вместо независимых периодов будут одни и те же даты. - Ненужные поля в настройках: Механизм автоматически добавляет все поля из последнего пакета запроса, а также все поля измерений из виртуальных таблиц всех пакетов. В итоге в доступных полях отбора может оказаться много лишних реквизитов, которые только загромождают настройки и могут запутать пользователя.
Поэтому прежде чем использовать фигурные скобки необходимо отключить флаг «Автозаполнение» в конструкторе запроса.

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

Для начала отключаем флаг автозаполнения. Затем переходим на вкладку Компоновка данных, Поля. Далее перетаскиваем вправа поля, которые будут доступны пользователю для Выборки. Если установить для поля галочку «Использовать дочерние«, то в пользовательском режиме в отчете можно будет выбрать поля, входящие в состав текущего. Естественно, такая функция доступна только для полей ссылочного типа. Установим данное свойство для поля Единица измерения.

В итоге получаем слующий результат:

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

В итоге получим такой запрос:
ВЫБРАТЬ
Номенклатура.Наименование КАК Наименование,
Номенклатура.Артикул КАК Артикул,
Номенклатура.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры
{ВЫБРАТЬ
Наименование,
Артикул,
ЕдиницаИзмерения.*,
ВидНоменклатуры}
ИЗ
Справочник.Номенклатура КАК Номенклатура
{ГДЕ
Номенклатура.ВидНоменклатуры.*}В фигурных скобках указаны поля, по которым будет доступен отбор. Теперь это поле доступно на закладке Настройки — Отбор.

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

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

Ну выключит и выключит, что страшного? Но ведь соединение с таблицей остатков все равно будет выполняться, вне зависимости, выводятся из нее поля или нет. Неплохо было бы сделать, чтобы соединение происходило только, если оно необходимо. Как раз за это и отвечает флаг «Обязательная«. Если его снять, то соединение с таблицей будет в квадратных скобках. Если поля из этой таблицы не будут использоваться, то в конечном запросе, который построит СКД, это соединение будет удалено. Получается некое необязательное соединение.
Теперь разберемся с полем «Номер группы«. Но чтобы понять, как оно работает нужно соединиться еще с какой нибудь таблицей. Допустим, с виртуальной таблицей регистра сведений Цены номенклатуры Срез последних. Если мы пометим эту таблицу также как необязательную, то в графе «Номер группы» напротив каждой из таблиц появится цифра 1.

Если так и оставить, то соединение с обоими таблицами будет обособлено фигурными скобками:
Справочник.Номенклатура КАК СпрНоменклатура
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки({(&Период)}, ) КАК ТоварыНаСкладахОстатки
ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры25.СрезПоследних КАК ЦеныНоменклатуры25СрезПоследних
ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры25СрезПоследних.Номенклатура}
В этом случае, даже если в пользовательском режиме убрать поля, используемые в таблице ТоварыНаСкладахОстатки, а оставить только поля таблицы ЦенаНоменклатуры25СрезПоследних, обе таблицы будут иметь соединение в конечном запросе СКД. Происходит это потому что они имеют «одинаковый уровень группы». Чтобы сделать их независимыми друг от друга необходимо задать разное значение номера группы, например, 1 и 2. Тогда каждое соединение будут обособленно собственными фигурными скобками. И как следствие — если оставить поля только одной таблицы, то только она и будет присоединена в итоговом запросе СКД.
Справочник.Номенклатура КАК СпрНоменклатура
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки({(&Период)}, ) КАК ТоварыНаСкладахОстатки
ПО СпрНоменклатура.Ссылка = ТоварыНаСкладахОстатки.Номенклатура}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры25.СрезПоследних КАК ЦеныНоменклатуры25СрезПоследних
ПО СпрНоменклатура.Ссылка = ЦеныНоменклатуры25СрезПоследних.Номенклатура}
Подключение характеристик
Фигурные скобки в запросе СКД используются также для подключения характеристик объектов. Об этом можно узнать в отдельной нашей статье.