Зачем в коде 1С используют заведомо невыполнимые условия вида Если Ложь Тогда?

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

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


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

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

1. Принудительное указание типа для контекстной подсказки Конфигуратора

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

Посмотрим, как устроен синтаксический анализ в стандартном Конфигураторе:

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

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

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


#Если Сервер И Не Сервер Тогда
    Организация = Справочники.Организации.СоздатьЭлемент();
#КонецЕсли

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

2. Сохранение типового кода при доработках и обновлениях

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

Вместо привычного комментирования строк используется следующая схема:


Если Ложь Тогда
    // Исходный типовой блок конфигурации поставщика
    РассчитатьСкидкиПоУмолчанию(ПараметрыРасчета);
Иначе
    // Доработанный пользовательский алгоритм
    РассчитатьИндивидуальныеСкидки(ПараметрыРасчета);
КонецЕсли;

Рассмотрим мотивы применения такого приема:

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

Недостатки и побочные эффекты использования «Если Ложь»

Несмотря на кажущееся удобство, применение заведомо ложных условий порождает серьезные технические проблемы, о которых важно помнить:

  1. Накладные расходы в рантайме: в отличие от директив препроцессора, блок Если Ложь Тогда ... КонецЕсли; компилируется в исполняемый байт-код платформы. При каждом вызове процедуры виртуальная машина тратит ресурсы на проверку условия и выполнение перехода, что создает лишнюю нагрузку на сервер.
  2. Срабатывание статических анализаторов: автоматизированные проверки качества кода (включая встроенный контроль, стандарты разработки фирмы 1С и внешние инструменты анализа BSL) помечают такие фрагменты как критические ошибки: Обнаружен недостижимый код (Unreachable code) и Неиспользуемое присваивание переменной.
  3. Ухудшение метрик качества: добавление искусственных условий увеличивает цикломатическую сложность функций, усложняет чтение исходного текста и вводит в заблуждение других разработчиков.

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

Разберем, как следует решать задачи типизации и версионирования кода в соответствии с современными стандартами разработки 1С без использования мертвых блоков.

  1. Документирующие комментарии (BSL / 1C:Enterprise Development Tools): в современных средах разработки типизация для автодополнения и валидации решается через стандартизированные комментарии. Для параметров и функций указывается блок // Параметры: с явным типом метаданных. Для локальных переменных в развитых инструментах применяются специальные директивы вида // @type ИмяТипа, которые считываются языковым сервером без внедрения фиктивных инструкций в исполняемый код.
  2. Выделение типизированных функций: вместо искусственного переопределения переменных логику извлечения данных выносят во вспомогательные функции с четко задокументированным возвращаемым значением. Среда разработки автоматически определяет тип возвращаемого значения и предоставляет корректную контекстную подсказку после точки.
  3. Использование расширений конфигурации: для модификации типового функционала сегодня стандартом является использование механизма расширений с аннотациями &Вместо, &Перед или &После. Это избавляет от необходимости редактировать код поставщика в основной конфигурации и полностью снимает проблему конфликтов при обновлении.
← На главную