При разработке интерфейсов на платформе 1С начинающие программисты часто сталкиваются с ситуацией, когда для обработки множества элементов управления на форме строится огромный каскад проверок Если ... ИначеЕсли. Такой код сложно читать, неудобно отлаживать и тяжело сопровождать. Кроме того, при попытке упростить логику через составные условия нередко возникает исключение: «Преобразование значения к типу Булево не может быть выполнено».
В этой статье разберем, как грамотно провести рефакторинг громоздких логических конструкций, выясним причину ошибки типизации при работе с флажками и рассмотрим надежные варианты архитектурного решения подобной задачи.
Рассмотрим типовой пример исходного кода, где в зависимости от выбранного температурного режима (например, заморозка или охлаждение) и вида продукции формируется строка описания:
Если Форма.ЭлементыФормы["Фл5"].Значение = Истина Тогда
Если Форма.ЭлементыФормы["Фл1"].Значение = ИСТИНА Тогда
ТекстПрод = ТекстПрод + " при t -18. "
ИначеЕсли Форма.ЭлементыФормы["Фл2"].Значение = ИСТИНА Тогда
ТекстПрод = ТекстПрод + " при t -18. "
ИначеЕсли Форма.ЭлементыФормы["КостныйОстаток"].Значение = ИСТИНА Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
КонецЕсли;
Проанализируем недостатки такого подхода:
Фл1, Фл5 скрывают смысл реквизитов. Читающему код специалисту приходится постоянно сверяться с макетом формы.Форма.ЭлементыФормы["..."] загромождает код." при t -18. ") дублируется в каждой ветке ИначеЕсли.Первым шагом объединим проверки с одинаковым результатом при помощи логических операторов И и ИЛИ, а также заменим технические имена элементов на понятные переменные:
Если ФлЗаморозка И (ФлМясо1кат Или ФлСубпродукты Или ФлПолуфабрикаты Или ФлКостныйОстаток) Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
Такая запись существенно сокращает объем текста, однако здесь разработчик может столкнуться со следующей проблемой.
При выполнении сокращенного условия среда 1С может выдать ошибку времени выполнения. Выясним причину ее возникновения.
В платформе 1С конструкции вида Если А = Истина Тогда и Если А Тогда работают принципиально по-разному:
А = Истина): если переменная А имеет числовой тип (например, 0 или 1) или содержит Неопределено, платформа просто возвращает результат сравнения Ложь, так как типы данных не совпадают. Ошибки не происходит.Если А Тогда): в этом случае платформа ожидает в переменной строго тип Булево. Если туда попадает число, строка или ссылка, неявного преобразования типов не происходит, и система падает с ошибкой.В обычных формах элемент управления Флажок, если он не привязан к конкретному реквизиту объекта с типом Булево, по умолчанию хранит числовые значения (1 — флажок установлен, 0 — снят). Кроме того, если у флажка включено свойство «Три состояния», его значением может стать Неопределено. Поскольку в выражении с логическими операторами И / ИЛИ платформа может вычислять операнды, наличие хотя бы одного небулевого поля вызывает аварийное завершение.
Разберем, как предотвратить эту ошибку на практике:
Булево():0 или 1), используем явное преобразование:
Если Булево(ФлЗаморозка) И (Булево(ФлМясо1кат) Или Булево(ФлСубпродукты)) Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
Если (ФлЗаморозка = 1 Или ФлЗаморозка = Истина)
И (ФлМясо1кат = 1 Или ФлМясо1кат = Истина Или ФлСубпродукты = 1 Или ФлСубпродукты = Истина) Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
Данные, привязав флажки к реквизитам с жестко заданным типом Булево. Тогда прямое логическое выражение будет работать штатно:
Если ФлЗаморозка И (ФлМясоIкат Или ФлСубпродукты Или ФлПолуфабрикаты Или ФлФаршКур Или ФлКостныйОстаток Или ФлМясоМехОбвалки Или ФлТушкаКур1с) Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
Если ФлОхлад И ФлМясоIкат Тогда
ТекстПрод = ТекстПрод + " при t (-2;+2). ";
КонецЕсли;
Если ФлОхлад И (ФлСубпродукты Или ФлПолуфабрикаты Или ФлФаршКур) Тогда
ТекстПрод = ТекстПрод + " при t (0;+2). ";
КонецЕсли;
Если ФлКолбасы Тогда
ТекстПрод = ТекстПрод + ФлКолбасыПодсказка + " при t (0;+6). ";
КонецЕсли;
Посмотрим на задачу шире: если категорий товаров или температурных режимов станет в два раза больше, код снова разрастется. Чтобы интерфейс и код оставались гибкими, рекомендуется использовать более подходящие элементы управления платформы 1С:
Переключатель:СписокЗначений с флажками:СпискомЗначений, у которого включено свойство «Отображать флажки». В таком случае проверка выбранных позиций сводится к компактному циклу:
ЕстьВыбранныеКатегории = Ложь;
Для Каждого ЭлементСписка Из СписокКатегорий Цикл
Если ЭлементСписка.Пометка Тогда
ЕстьВыбранныеКатегории = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если ФлЗаморозка И ЕстьВыбранныеКатегории Тогда
ТекстПрод = ТекстПрод + " при t -18. ";
КонецЕсли;
СтрШаблон:+ удобнее заменять системной функцией СтрШаблон, что делает итоговый текст более читаемым и защищает от ошибок с пробелами.
Следуя этим правилам, мы получаем понятный, производительный и устойчивый к ошибкам код, который легко масштабировать при добавлении новой номенклатуры и параметров хранения.