Почему Конструктор запросов 1С убирает скобки в условиях и как это влияет на логику?

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

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

Суть проблемы и визуальный пример

Рассмотрим ситуацию, с которой столкнулся автор темы. Ему необходимо отобрать данные по двум группам условий. Логика звучит так: "Выбрать записи, где либо ведется учет по характеристикам и характеристика не заполнена, либо ведется учет по сериям и серия не заполнена".

Изначально программист пишет условие со скобками для визуального разделения логических блоков:


ГДЕ
    (ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоХарактеристикам
        И ОприходованиеТоваровТовары.ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка))
    ИЛИ (ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоСериям
        И ОприходованиеТоваровТовары.СерияНоменклатуры = ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка))

Однако после нажатия кнопки "ОК" в Конструкторе запросов 1С, текст трансформируется в следующий вид:


ГДЕ
    ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоХарактеристикам
        И ОприходованиеТоваровТовары.ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)
    ИЛИ ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоСериям
        И ОприходованиеТоваровТовары.СерияНоменклатуры = ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка)

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

Приоритет логических операций

В языке запросов 1С, как и в большинстве языков программирования (и в математике), существует строгая иерархия выполнения операций. Разберем приоритеты от самого высокого к самому низкому:

  1. НЕ (NOT) — логическое отрицание выполняется в первую очередь.
  2. И (AND) — логическое умножение имеет средний приоритет.
  3. ИЛИ (OR) — логическое сложение выполняется в последнюю очередь.

Проанализируем наше выражение. Поскольку оператор И имеет более высокий приоритет, чем ИЛИ, система сначала вычислит выражения, связанные через И, а затем объединит полученные результаты по ИЛИ. Это в точности соответствует математическому правилу: (A * B) + (C * D) дает тот же результат, что и A * B + C * D. Скобки в данном случае являются избыточными.

Механизм нормализации в Конструкторе запросов

Важно понимать, что Конструктор запросов — это не текстовый редактор. Это мощный инструмент синтаксического анализа (парсер). Когда вы открываете запрос в конструкторе:

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

Таким образом, исчезновение скобок — это признак того, что Конструктор "понял" вашу логику и подтвердил, что она будет работать корректно согласно стандартным приоритетам.

Влияние на производительность и SQL

Многие разработчики переживают, не станет ли запрос работать медленнее без явного указания скобок. Выясним причину этого спокойствия: платформа 1С не исполняет запрос напрямую. Она транслирует его в SQL-запрос, который отправляется на СУБД (MS SQL, PostgreSQL, Oracle или IBM DB2).

Оптимизатор СУБД строит план выполнения запроса, исходя из логической структуры условий. Наличие избыточных скобок в исходном тексте никак не влияет на итоговый Execution Plan. Для сервера базы данных выражения (A AND B) OR C и A AND B OR C абсолютно идентичны.

Когда скобки НЕ будут удалены?

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


ГДЕ
    Номенклатура.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар)
    И (Номенклатура.Услуга ИЛИ Номенклатура.БезвозвратнаяТара)

В этом случае, если убрать скобки, условие Номенклатура.Тип = ... И Номенклатура.Услуга выполнится первым, что полностью исказит смысл запроса. В таких ситуациях Конструктор никогда не удалит скобки, так как они являются семантически значимыми.

Практические советы по работе с запросами

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

Резюме

Исчезновение скобок в Конструкторе запросов 1С — это штатное поведение системы, обусловленное правилами логического приоритета. Операция И всегда сильнее, чем ИЛИ. Если вы видите, что скобки пропали, это означает, что ваш запрос написан логически верно и платформа оптимизировала его текст, удалив лишние синтаксические конструкции. Это не является ошибкой "сырой" платформы, а является следствием работы парсера, приводящего код к каноническому виду.

← На главную