Зачем нужны фигурные скобки в запросах 1С и как от них избавиться?

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

При анализе готовых отчетов, динамических списков или типовых конфигураций разработчики часто сталкиваются с конструкциями запросов, заключенными в фигурные скобки {...}. Попытка скопировать такой запрос в консоль запросов или выполнить его обычным объектом Запрос нередко вызывает вопросы: откуда берутся эти скобки, какую роль они играют и как их правильно убрать или настроить через конструктор запроса. Разберем детально назначение этого синтаксиса и особенности его поведения.

Что означают фигурные скобки в языке запросов 1С

Символы фигурных скобок {...} представляют собой синтаксис расширения языка запросов платформы 1С:Предприятие. Данный механизм используется такими подсистемами и объектами платформы, как:

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

Когда фигурные скобки обрамляют предложение соединения, например:


{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации
ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность
    И ШтатноеРасписаниеОрганизаций.ПодразделениеОрганизации = РаботникиОрганизации.ПодразделениеОрганизации}

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

Кроме того, данный механизм используется для управления правами доступа на уровне записей и метаданных (RLS): если у пользователя нет прав на чтение необязательной таблицы, но поля из нее не выводятся в отчет, отчет выполнится без ошибки нарушения прав.

Как избавиться от фигурных скобок

Проанализируем практические способы управления фигурными скобками в запросе в зависимости от стоящей задачи.

Способ 1. Настройка обязательности таблицы в конструкторе запроса

Если текст запроса редактируется в конфигураторе или в конструкторе запроса СКД, управлять скобками можно интерактивно:

  1. Откроем конструктор запроса и перейдем на вкладку Компоновка данных (или на вкладку Построитель в случае использования построителя отчета).
  2. Перейдем на вложенную закладку Таблицы.
  3. Найдем в списке нужную таблицу соединения (в примере — РаботникиОрганизации).
  4. Установим флаг в колонке Обязательная.
  5. Нажмем ОК. Конструктор автоматически снимет фигурные скобки с данного соединения, оставив стандартное ЛЕВОЕ СОЕДИНЕНИЕ.

Способ 2. Ручное редактирование текста запроса

Если запрос переносится в модуль для выполнения через объект Запрос и динамическая оптимизация СКД не требуется, фигурные скобки вокруг соединения можно удалить вручную в текстовом редакторе. Соединение останется частью запроса и будет выполняться безусловно:


// Было:
// {ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации ПО ...}

// Стало:
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(КОНЕЦПЕРИОДА(КОНЕЦПЕРИОДА(&Период, МЕСЯЦ), МЕСЯЦ), ) КАК РаботникиОрганизации
    ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность
        И ШтатноеРасписаниеОрганизаций.ПодразделениеОрганизации = РаботникиОрганизации.ПодразделениеОрганизации

Как обычный объект «Запрос» интерпретирует фигурные скобки

Посмотрим, что происходит, если выполнить запрос с фигурными скобками через стандартный Запрос во встроенном языке без предварительного удаления скобок:

  1. Необязательные соединения: конструкция {ЛЕВОЕ СОЕДИНЕНИЕ ...} парсером стандартного запроса воспринимается как обычное соединение. Платформа просто игнорирует фигурные скобки и выполняет всё, что находится внутри них, как обязательную часть запроса.
  2. Секции расширения полей, условий и упорядочивания: конструкции {ВЫБРАТЬ ...}, {ГДЕ ...}, {УПОРЯДОЧИТЬ ПО ...} и {ХАРАКТЕРИСТИКИ ...} объектом Запрос игнорируются вместе со всем их содержимым. Если условие или параметр были объявлены исключительно внутри {ГДЕ ...}, в обычном запросе они учитываться не будут.

Ошибки проектирования при использовании необязательных таблиц

Разберем типичную ошибку проектирования запроса, встречающуюся на практике. Посмотрим на фрагмент исходного запроса:


{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций.СрезПоследних(...) КАК РаботникиОрганизации
    ПО ШтатноеРасписаниеОрганизаций.Должность = РаботникиОрганизации.Должность}
ГДЕ
    НЕ РаботникиОрганизации.Сотрудник ЕСТЬ NULL

В данном случае соединение заключено в фигурные скобки как необязательное, однако в блоке ГДЕ присутствует жесткое условие на поле РаботникиОрганизации.Сотрудник без обрамления в фигурные скобки. В результате:

  1. СКД не сможет выбросить данное соединение, так как поле из соединяемой таблицы жестко задействовано в условии отбора.
  2. Условие НЕ ... ЕСТЬ NULL в секции ГДЕ фактически превращает левое соединение во внутреннее (ВНУТРЕННЕЕ СОЕДИНЕНИЕ), отсекая все записи первой таблицы, не нашедшие соответствия во второй.

Для сохранения корректной логики СКД условие на поле необязательной таблицы также должно помещаться в фигурные скобки: {ГДЕ (НЕ РаботникиОрганизации.Сотрудник ЕСТЬ NULL)}, либо условие должно переноситься в секцию ПО самого соединения.

Управление группами таблиц в конструкторе СКД

При работе с несколькими связанными необязательными таблицами обратим внимание на свойство Номер группы на вкладке «Компоновка данных» в конструкторе запроса:

  1. Если у нескольких таблиц указан одинаковый номер группы, платформа объединит их соединения в один блок фигурных скобок. В этом случае обращение хотя бы к одному полю любой из этих таблиц приведет к подключению всех таблиц группы.
  2. Если каждой таблице назначен свой уникальный номер группы, таблицы будут обрамлены в независимые блоки фигурных скобок и будут подключаться в итоговый запрос изолированно друг от друга.

Программное получение текста запроса без фигурных скобок из СКД

Если необходимо получить чистый результирующий текст запроса, сформированный схемой компоновки для СУБД с учетом примененных настроек пользователя, выполним штатную процедуру компоновки макета через объекты встроенного языка:


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновкиДанных,,, Тип("ГенераторМакетаКомпоновкиДанных"));

Для Каждого НаборДанных Из МакетКомпоновки.НаборыДанных Цикл
    Если ТипЗнч(НаборДанных) = Тип("НаборДанныхЗапросМакетаКомпоновкиДанных") Тогда
        ТекстЧистогоЗапроса = НаборДанных.Запрос;
    КонецЕсли;
КонецЦикла;

В полученном значении ТекстЧистогоЗапроса фигурные скобки будут полностью раскрыты платформой: неиспользуемые соединения и условия отброшены, а нужные поля подставлены в тело запроса.

← На главную