Как правильно писать логические выражения в 1С: выбираем между «Если», тернарным оператором и прямым присваиванием

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

В процессе разработки на платформе 1С программисты часто сталкиваются с необходимостью присвоить булево значение (Истина или Ложь) свойству объекта или переменной на основании какого-либо условия. Существует как минимум три популярных способа реализации этой задачи. На первый взгляд они кажутся равнозначными, но при детальном анализе выясняется, что каждый из них имеет свои особенности в плане читаемости, производительности и соответствия стандартам разработки 1С. В этой статье мы подробно разберем все варианты, проанализируем их преимущества и недостатки, а также выясним, как писать «чистый» код.

Вариант №1: Использование тернарного оператора «?»

Первый вариант, который часто встречается в типовых конфигурациях, — это использование встроенной функции ?(). Выглядит это следующим образом:

Элементы.Календарь.Доступность = ?(РежимУчетаОтсрочки = 1, Истина, Ложь);

Давайте проанализируем эту конструкцию. Функция ?() принимает три параметра: логическое выражение, значение в случае Истина и значение в случае Ложь. На первый взгляд код выглядит компактным, но у него есть несколько существенных минусов:

  1. Тавтология: Если результат выражения (РежимУчетаОтсрочки = 1) уже является булевым (Истина или Ложь), то возвращать явно Истина или Ложь — это избыточность. Это все равно что сказать: «Если идет дождь, то это правда, иначе это неправда».
  2. Особенности вычисления: В 1С функция ?() — это именно функция, а не встроенная синтаксическая конструкция, как в языках C-семейства. В некоторых случаях платформа может вычислять оба аргумента (и второй, и третий) перед тем, как выбрать один из них. Если вместо простых значений Истина/Ложь там будут вызовы тяжелых функций, это приведет к потере производительности.
  3. Сложность отладки: При использовании тернарного оператора невозможно поставить точку останова (breakpoint) только на одну из веток условия. При пошаговой отладке вы просто пройдете всю строку целиком, не видя промежуточного результата.

Вариант №2: Прямое присваивание логического выражения

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

Элементы.Календарь.Доступность = (РежимУчетаОтсрочки = 1);

Рассмотрим, почему этот вариант хорош и какие у него есть «подводные камни»:

Преимущества: Во-первых, это минимальный объем кода. Мы напрямую берем результат сравнения и записываем его в свойство. Во-вторых, этот вариант обладает самой низкой когнитивной сложностью согласно метрикам статического анализа (например, BSL Language Server). Мы не создаем лишних ветвлений в логике программы.

Нюансы: Главная претензия к этому варианту — использование знака = в двух разных ролях в одной строке (как оператор присваивания и как оператор сравнения). Для начинающих разработчиков это может выглядеть запутанно. Именно поэтому рекомендуется всегда заключать логическое выражение в скобки, чтобы визуально отделить сравнение от присваивания.

Также стоит помнить о значении NULL. Если переменная РежимУчетаОтсрочки придет из запроса и будет содержать NULL, то результат сравнения с числом также даст Ложь (в контексте логики 1С), и ошибки не возникнет. Однако, если выражение станет сложным (содержащим И, ИЛИ, НЕ), отладка такого выражения в одну строку может стать затруднительной.

Вариант №3: Конструкция «Если... Тогда... Иначе»

Третий вариант — классическое ветвление. Многие считают его наиболее надежным для будущего развития системы:


Если РежимУчетаОтсрочки = 1 Тогда
    Элементы.Календарь.Доступность = Истина;
Иначе
    Элементы.Календарь.Доступность = Ложь;
КонецЕсли;

Проанализируем ситуацию, когда этот вариант предпочтительнее:

Однако у этого способа есть и минус — он слишком «многословен». Написание 5 строк кода там, где можно обойтись одной, часто называют «раздуванием» конфигурации.

Проблема «Магических чисел» и чистота кода

Обратите внимание на фрагмент РежимУчетаОтсрочки = 1. В программировании число 1 в данном контексте называется «магическим числом». Разработчик, который будет читать ваш код через год, может не понять, что именно означает единица. Рассмотрим, как сделать этот код идеальным, используя Перечисления:


// Правильный подход с использованием метаданных
Элементы.Календарь.Доступность = (РежимУчетаОтсрочки = Перечисления.РежимыУчета.СОтсрочкой);

Такой код является самодокументированным. Нам даже не нужны комментарии, чтобы понять смысл операции.

Вынос логики в отдельную переменную или функцию

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


НужноЛиРедактироватьКалендарь = (РежимУчетаОтсрочки = 1);
// Далее по коду используем переменную
Элементы.Календарь.Доступность = НужноЛиРедактироватьКалендарь;

Или еще более профессиональный подход — вынос проверки в отдельную функцию (особенно если эта логика используется в нескольких местах):


Функция КалендарьДоступен(Режим)
    Возврат Режим = 1;
КонецФункции

// Вызов
Элементы.Календарь.Доступность = КалендарьДоступен(РежимУчетаОтсрочки);

Подведем итоги: какой вариант выбрать?

Выясним причину выбора того или иного стиля в зависимости от ситуации:

  1. Вариант 2 (Прямое присваивание в скобках) — используем для максимально простых условий в одну строку. Это делает код чистым и быстрым.
  2. Вариант 3 (Если... Тогда) — используем, если логика сложная, требует комментариев или предполагается, что она будет расширяться в ближайшее время.
  3. Вариант 1 (Тернарный оператор) — стараемся избегать, если результатом являются просто Истина или Ложь. Используйте его только тогда, когда нужно вернуть разные объекты или строки, например: СтатусТекстом = ?(ЭтоНовый, "Новый", "В работе");.

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

← На главную