Зачем в условиях 1С пишут «Ложь Или» и «Если Ложь Тогда»? Разбор практических приемов

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

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

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

Прием 1. Концепция «И-ИЛИ дерева» в сложных логических условиях

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

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

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


Если Ложь
    Или Кнопка = ирОбщий.ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ПолеВстроенногоЯзыка, "Проверить")
    Или ЭтоВыполнениеКода
Тогда
    // Какая-то логика обработки
КонецЕсли;

На первый взгляд, Если Ложь Или кажется избыточным. Однако этот прием дает разработчику три важнейших преимущества:

1. Исключительное удобство при отладке и комментировании

Если вам в процессе отладки нужно временно отключить проверку одного из условий, вы можете просто закомментировать нужную строку. При этом вам не придется переносить операторы ИЛИ на другие строчки или следить за тем, чтобы не нарушился синтаксис первой строки выражения.

Проанализируем ситуацию на примере. Если мы хотим отключить проверку кнопки, мы просто пишем:


Если Ложь
    // Или Кнопка = ирОбщий.ПолучитьКнопкуКоманднойПанелиЭкземпляраКомпонентыЛкс(ПолеВстроенногоЯзыка, "Проверить")
    Или ЭтоВыполнениеКода
Тогда
    // Логика продолжит работать корректно
КонецЕсли;

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

2. Чистота при работе с системами контроля версий (Git, Снегопат, хранилище 1С)

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

3. Читаемость и документирование

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

Аналогично строится дерево условий по «И»:


Если Истина
    И ПользовательРазрешен
    И Не ЭтоНовыйОбъект
    И РольДоступна("ПолныеПрава")
Тогда
    // Выполнение действия
КонецЕсли;

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

---

Прием 2. Трюк с «Если Ложь Тогда» для вызова контекстной подсказки

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

Рассмотрим по шагам, как решить эту проблему с помощью конструкции Если Ложь Тогда:


Процедура ОбработатьТЧДокумента(Сумма = 0)
    
    Перем ТекДок;
    ТекДок = НайтиДокументПоСумме(Сумма); // Возвращает неопределенный тип
    
    // Для того чтобы конфигуратор понял, с каким типом мы работаем:
    Если Ложь Тогда
        ТекДок = Документы.ПоступлениеТоваровИУслуг.СоздатьДокумент();
    КонецЕсли;
    
    // Теперь при вводе "ТекДок." конфигуратор отобразит все свойства и методы документа!
    ТекДок.Записать(); 
    
КонецПроцедуры

Выясним, почему этот прием работает и почему он безопасен:

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

---

Плюсы и минусы использования данных подходов

Разумеется, у любого «художественного» приема программирования есть свои сторонники и противники. Давайте взвесим все «за» и «против».

Преимущества:

Недостатки:

Резюме

Рассмотренные приемы — это мощные инструменты в арсенале опытного разработчика 1С. Использовать их или нет — зависит от стандартов вашей команды и личных предпочтений. Однако знать их назначение необходимо каждому профессионалу, чтобы при анализе чужого качественного кода сразу понимать логику и архитектурный замысел автора.

← На главную