Разработка и Конфигурация · 10 мин
Как работает оператор ИЛИ в 1С
Разбираем логический оператор ИЛИ в 1С: синтаксис в запросах и коде, приоритет операторов, сочетание с И и НЕ, типичные ошибки и способы проверки результата.
Логический оператор ИЛИ в 1С встречается в двух контекстах: во встроенном языке (в конструкциях Если...Тогда) и в языке запросов (в секциях ГДЕ, ИМЕЮЩИЕ, в условиях соединений). В обоих случаях смысл одинаков: условие считается истинным, если истинно хотя бы одно из сравнений. Но синтаксис, приоритет вычислений и поведение с NULL отличаются, и именно здесь чаще всего возникают ошибки.
Типичная ситуация: разработчик пишет условие «ГДЕ Склад = &Склад1 ИЛИ Склад = &Склад2 И Активен», ожидая два активных варианта, а получает выборку, в которую попадают лишние записи. Причина — приоритет операторов: И вычисляется раньше ИЛИ. Понимание этих правил позволяет писать условия, которые работают предсказуемо и не требуют отладки «методом тыка».
Ниже разобран синтаксис ИЛИ в коде и запросах, правила приоритета, работа с NULL, альтернатива через В(...) и способы проверить, что условие отбирает именно то, что задумано.
Синтаксис ИЛИ во встроенном языке 1С
Во встроенном языке оператор пишется как ИЛИ (в английском варианте синтаксиса — OR) и используется в логических выражениях: Если А ИЛИ Б Тогда ... КонецЕсли;. Оба операнда должны иметь тип Булево. Если хотя бы один из них равен Истина, всё выражение возвращает Истина.
Важная особенность встроенного языка — полное вычисление выражения. В отличие от некоторых языков, 1С вычисляет обе части условия, даже если первой достаточно для результата. Поэтому конструкция вида Если ЗначениеЗаполнено(Ссылка) И Ссылка.Проведен Тогда безопасна, а вот вызов метода у потенциально пустого значения во второй части ИЛИ может вызвать ошибку, если первая часть не защищает от этого.
Если Контрагент.ЭтоГруппа ИЛИ Контрагент.ПометкаУдаления Тогда
Продолжить;
КонецЕсли;
Оператор можно комбинировать с И и НЕ в одном выражении. Читаемость при этом быстро падает, поэтому сложные условия лучше выносить в отдельную функцию с говорящим именем или разбивать на несколько проверок.
Оператор ИЛИ в языке запросов
В запросах ИЛИ применяется в секции ГДЕ, в условиях соединения таблиц (ПО ...), в ИМЕЮЩИЕ и внутри конструкции ВЫБОР КОГДА. Синтаксис тот же: ГДЕ Поле1 = &Значение1 ИЛИ Поле2 = &Значение2. Запрос вернёт строки, где выполняется хотя бы одно из условий.
ВЫБРАТЬ
Товары.Ссылка,
Товары.Наименование
ИЗ
Справочник.Номенклатура КАК Товары
ГДЕ
Товары.ВидНоменклатуры = &Вид1
ИЛИ Товары.ВидНоменклатуры = &Вид2
Конструктор запроса в конфигураторе позволяет собирать условия мышью, но при группировке И/ИЛИ он не всегда расставляет скобки так, как ожидает разработчик. После редактирования условий в конструкторе полезно переключиться в текст запроса и проверить итоговую структуру вручную.
Приоритет операторов и роль скобок
Порядок вычисления в 1С (и в коде, и в запросах): сначала НЕ, затем И, затем ИЛИ. Это значит, что выражение А И Б ИЛИ В эквивалентно (А И Б) ИЛИ В, а не А И (Б ИЛИ В). Разница в результате может быть принципиальной.
Практическое правило: как только в одном выражении встречаются И и ИЛИ одновременно, расставляйте скобки явно, даже если приоритет формально совпадает с задуманным. Это защищает от ошибок при последующих правках, когда другой разработчик добавит ещё одно условие и не заметит изменения логики.
Как читается условие
Вычисляется как (А И Б) ИЛИ В. Вариант В срабатывает независимо от А.
А обязательно, а из Б и В достаточно одного. Логика принципиально другая.
Две независимые группы условий, обе должны быть истинны.
Замена цепочек ИЛИ конструкцией В
Когда ИЛИ сравнивает одно поле с несколькими значениями, цепочку стоит заменить оператором В. Вместо Склад = &С1 ИЛИ Склад = &С2 ИЛИ Склад = &С3 пишется Склад В (&СписокСкладов), где параметр — массив или список значений. Такой запрос короче, легче поддерживается и, как правило, не хуже по производительности.
Дополнительное преимущество — динамичность: количество значений в списке можно менять из кода без переписывания текста запроса. Это стандартный приём для отборов, которые пользователь настраивает через множественный выбор в форме.
СписокСкладов = Новый Массив;
СписокСкладов.Добавить(Склад1);
СписокСкладов.Добавить(Склад2);
Запрос.УстановитьПараметр("Склады", СписокСкладов);
// В тексте запроса: ГДЕ Продажи.Склад В (&Склады)Аналог в условиях кода — проверка через массив и метод Найти() или через соответствие, когда значений много и проверка выполняется в цикле.
ИЛИ и значения NULL в запросах
В запросах 1С действует трёхзначная логика: результат сравнения может быть Истина, Ложь или NULL (неопределено), если один из операндов — NULL. Условие Поле = &Значение ИЛИ Поле ЕСТЬ NULL — корректный способ отобрать и совпадающие, и незаполненные значения. А вот Поле = &Значение ИЛИ Поле <> &Значение не вернёт строки с NULL, потому что оба сравнения для NULL дают неопределённость.
NULL чаще всего появляется при левых соединениях, когда в присоединяемой таблице нет подходящей строки. Если условие с ИЛИ накладывается на поле из правой таблицы левого соединения, проверяйте поведение на данных, где связь отсутствует, — иначе часть записей «потеряется» незаметно.
Как проверить, что условие с ИЛИ работает правильно
Самый надёжный способ — проверить условие на контрольном наборе данных, где заранее известно, какие записи должны попасть в выборку. Для запроса удобно временно добавить в выборку само проверяемое поле и отбор по конкретным тестовым значениям, затем сравнить результат с ожиданием.
Во встроенном языке сложное условие можно разложить на переменные с промежуточными результатами и посмотреть их в отладчике. Если условие собирается динамически (например, в СКД или через построитель запроса), выведите итоговый текст запроса в журнал или сообщение — часто ошибка видна сразу после того, как условие предстало в собранном виде.
Как проверить результат
Группы И/ИЛИ явно обёрнуты в скобки по задуманной логике
Условия идут подряд без скобок, приоритет определяет результат
Незаполненные поля либо явно включены через ЕСТЬ NULL, либо осознанно исключены
Часть ожидаемых записей пропала без объяснения
На тестовых данных выборка совпадает с ожидаемым списком
В выборку попадают лишние или пропадают нужные записи
Помеченные объекты исключены для всех веток ИЛИ
Пометка исключается только для одной ветки условия
Типичные ошибки при использовании ИЛИ
Отдельная группа проблем — производительность. Условия с ИЛИ по разным полям иногда мешают оптимизатору использовать индексы, особенно в больших таблицах. Если запрос с ИЛИ работает медленно, попробуйте вариант с объединением (ОБЪЕДИНИТЬ ВСЕ) двух простых запросов или пересмотрите логику отбора.
Как выбрать конструкцию
FAQ
Чем ИЛИ отличается от исключающего ИЛИ в 1С?
Во встроенном языке и языке запросов 1С есть только обычное ИЛИ: результат истинен, когда истинна хотя бы одна часть, включая случай, когда истинны обе. Отдельного оператора «исключающее ИЛИ» нет; при необходимости его моделируют конструкцией вида (А И НЕ Б) ИЛИ (НЕ А И Б).
Можно ли использовать ИЛИ в условии соединения таблиц?
Да, в секции ПО при соединении допустимы составные условия с И и ИЛИ. Учтите, что сложные условия соединения могут заметно замедлить запрос, а при левом соединении добавляют неопределённые значения NULL, которые нужно обрабатывать отдельно.
Почему запрос с ИЛИ не возвращает записи с пустым полем?
Потому что сравнение NULL с любым значением даёт неопределённый результат, а не Истину. Добавьте в условие явную проверку «ИЛИ Поле ЕСТЬ NULL» либо используйте функцию ЕСТЬNULL(Поле, ЗначениеПоУмолчанию) в выражении сравнения.
Вычисляет ли 1С обе части условия, если первая уже истинна?
Во встроенном языке — да, выражение вычисляется полностью. Поэтому во второй части ИЛИ нельзя полагаться на то, что первая часть «отсечёт» опасный случай: обращение к свойству пустого объекта вызовет ошибку независимо от результата первой проверки.
Что быстрее: цепочка ИЛИ или оператор В?
Для одного поля и списка значений разница обычно невелика, но В(&Список) короче, понятнее и удобнее для динамических отборов. Цепочки ИЛИ по разным полям — отдельный случай: там при проблемах со скоростью стоит проверить вариант с ОБЪЕДИНИТЬ ВСЕ.
Как отладить сложное условие с несколькими И и ИЛИ?
Разбейте выражение на переменные-флаги с промежуточными результатами и посмотрите их значения в отладчике. Для запроса временно выведите проверяемые поля в выборку и сравните результат на данных, где правильный ответ известен заранее.
Что важно запомнить
ИЛИ возвращает истину, если истинно хотя бы одно условие, но приоритет И выше, поэтому сложные выражения всегда группируйте скобками. Для перечисления значений одного поля применяйте В(&Список), а работу с NULL контролируйте через ЕСТЬ NULL. Проверяйте логику на контрольных данных — это быстрее, чем искать пропавшие записи в отчётах.