Почему работает проверка объекта на Неопределено в логическом выражении И в 1С?

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

В разработке на платформе 1С:Предприятие часто встречается конструкция, в которой проверка переменной на равенство Неопределено объединяется в одном операторе Если с вызовом метода этой же переменной. Посмотрим на классический пример такого кода:


МассивСтрок = Неопределено;
Если МассивСтрок <> Неопределено И МассивСтрок.Найти(Выборка.НомерСтроки) = Неопределено Тогда
    Продолжить;
КонецЕсли;

На первый взгляд кажется, что если переменная МассивСтрок содержит Неопределено, обращение к методу Найти() должно вызвать критическую ошибку выполнения: «Значение не является значением объекта». Однако код успешно выполняется без ошибок. Разберем подробно, почему так происходит и как платформа 1С вычисляет логические выражения.

Принцип сокращенного вычисления логических выражений

Причина безошибочной работы такого кода заключается в том, что во встроенном языке 1С 8 применяется сокращенная схема вычисления логических выражений (в программировании это также называют short-circuit evaluation или «короткозамкнутые условия»).

Согласно официальной документации 1С:Предприятие:

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

Проанализируем работу базовых логических операторов по этой схеме:

  1. Оператор И (AND): В выражении Условие1 И Условие2, если Условие1 принимает значение Ложь, результат всего выражения гарантированно будет Ложь (так как для истинности оператора И требуются истинные значения всех операндов). В этом случае Условие2 платформой не вычисляется.
  2. Оператор ИЛИ (OR): В выражении Условие1 ИЛИ Условие2, если Условие1 принимает значение Истина, результат всего выражения гарантированно будет Истина. Платформа пропускает вычисление Условие2.

В нашем примере, когда МассивСтрок равен Неопределено, левое выражение МассивСтрок <> Неопределено возвращает Ложь. Платформа 1С сразу прерывает дальнейший расчет и не переходит к правой части МассивСтрок.Найти(...), защищая программу от аварийного завершения.

Практическое применение: защита от ошибок выполнения

Сокращенное вычисление условий — это не просто оптимизация быстродействия, а стандартный безопасный паттерн написания кода в 1С. Рассмотрим основные сценарии его применения.

1. Защита от обращения к несуществующим объектам

Конструкцию удобно использовать при работе со структурами, массивами, соответствиями и ссылочными типами данных:


Если ДанныеЗаполнения <> Неопределено И ДанныеЗаполнения.Свойство("Контрагент") Тогда
    // Безопасное обращение к свойству
КонецЕсли;

2. Защита от деления на ноль

В математических расчетах можно объединять проверку делителя и само вычисление в одну строку:


Если Знаменатель <> 0 И (Числитель / Знаменатель > 5) Тогда
    // Расчет выполняется только при ненулевом знаменателе
КонецЕсли;

Важные нюансы и подводные камни

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

1. Функции с побочными эффектами

Если в правой части логического выражения стоит вызов функции, которая меняет состояние системы или значение переменных, помните: эта функция не выполнится, если левая часть предопределила результат логического выражения.


// Если Цена <= 0, функция ЗафиксироватьОшибку() НЕ будет вызвана!
Если Цена > 0 И ЗафиксироватьОшибку() Тогда
    // Логика обработки
КонецЕсли;

Если требуется, чтобы функция выполнилась в любом случае, ее результат следует предварительно вычислить в отдельную переменную перед оператором Если.

2. Различие между встроенным языком и Языком запросов 1С

Важно: Сокращенное вычисление условий гарантируется только во встроенном языке программирования 1С. В языке запросов 1С (в секциях ГДЕ, ИМЕЮЩИЕ или в конструкции ВЫБОР КОГДА) порядок вычисления условий определяет оптимизатор СУБД (MS SQL Server, PostgreSQL и др.). Полагаться на порядок следования условий слева направо в запросах нельзя.

3. Исторический контекст (1С 7.7 vs 1С 8)

Разработчики, перешедшие с платформы 1С 7.7, часто избегают подобных конструкций по привычке. В 1С 7.7 выражения вычислялись полностью, из-за чего аналогичный код приводил к ошибке. Начиная с платформы 1С 8.0 сокращенная логика работает по умолчанию и является стандартом разработки.

Альтернативные способы оформления кода

Если выражение содержит много условий или вы хотите сделать код максимально наглядным для всех членов команды, можно использовать альтернативные варианты построения логики.

Каскад вложенных условий:


Если МассивСтрок <> Неопределено Тогда
    Если МассивСтрок.Найти(Выборка.НомерСтроки) = Неопределено Тогда
        Продолжить;
    КонецЕсли;
КонецЕсли;

Предварительный расчет флагов:


ЭлементНайден = Ложь;
Если МассивСтрок <> Неопределено Тогда
    ЭлементНайден = (МассивСтрок.Найти(Выборка.НомерСтроки) <> Неопределено);
КонецЕсли;

Если Не ЭлементНайден Тогда
    Продолжить;
КонецЕсли;

Таким образом, объединение проверок через И в рамках одного оператора Если — это лаконичный, безопасный и стандартный прием во встроенном языке 1С 8, основанный на правиле сокращенного вычисления логических выражений.

← На главную