В процессе разработки интерфейсов в среде 1С:Предприятие часто возникает задача динамического управления доступностью элементов формы. Типичный сценарий: на форме справочника или документа присутствует флажок (булево свойство), при установке которого все остальные поля формы должны блокироваться от случайного редактирования, а при снятии — вновь становиться доступными для ввода. Разберем, как правильно реализовать этот функционал на обычных формах 1С 8.3, разберем типичные ошибки начинающих разработчиков, оптимизируем код и обсудим важные архитектурные вопросы, включая безопасность данных.
Начинающие разработчики часто сталкиваются с проблемой: код блокировки написан, при установке галочки поля блокируются, но после закрытия и повторного открытия элемента справочника флажок исчезает, а поля снова доступны для редактирования. Проанализируем, почему так происходит.
Главная причина кроется в разделении понятий Реквизит объекта и Элемент формы:
ЗаблокированоРедактирование с типом значения Булево.СправочникОбъект.ЗаблокированоРедактирование (или просто название реквизита, в зависимости от контекста).Вторая распространенная ошибка — привязка логики блокировки исключительно к событию изменения самого флажка. Когда мы открываем сохраненный элемент справочника, платформа считывает состояние реквизита из базы данных, но визуально поля остаются доступными, так как событие изменения флажка интерактивно не вызывалось.
Для решения этой проблемы нам необходимо запускать процедуру проверки состояния полей в двух местах:
ПриИзменении.ПриОткрытии.Часто в коде можно увидеть громоздкие конструкции, где вручную перечисляются все элементы формы (как в Сообщении 8 исходной темы). Это неудобно, так как при добавлении любого нового реквизита на форму разработчику придется вручную дописывать код блокировки. Посмотрим на классический пример такого «сырого» кода:
Если ЗаблокированоРедактирование = Истина Тогда
ЭлементыФормы.НазванияБанка.ТолькоПросмотр = Истина;
ЭлементыФормы.Наименование.ТолькоПросмотр = Истина;
// И так еще 15 строк...
Иначе
ЭлементыФормы.НазванияБанка.ТолькоПросмотр = Ложь;
ЭлементыФормы.Наименование.ТолькоПросмотр = Ложь;
КонецЕсли;
Давайте оптимизируем это решение. Разберем более элегантные и профессиональные подходы.
Вместо ручного прописывания свойств для каждого поля, мы можем перебрать все элементы формы в цикле. При этом важно учитывать, что не у всех элементов управления на обычной форме есть свойство ТолькоПросмотр (например, у декораций, надписей или командных панелей его нет, и обращение к нему вызовет критическую ошибку). Нам нужно программно проверять тип элемента.
Создадим одну вспомогательную процедуру в модуле формы, которая будет отвечать за установку доступности полей:
Процедура УстановитьДоступностьПолей()
// Получаем текущее состояние флага блокировки
БлокировкаАктивна = ЗаблокированоРедактирование;
Для Каждого Элемент Из ЭлементыФормы Цикл
// Проверяем типы элементов, которые поддерживают свойство "ТолькоПросмотр"
Если ТипЗнч(Элемент) = Тип("ПолеВвода")
Или ТипЗнч(Элемент) = Тип("ТабличноеПоле")
Или ТипЗнч(Элемент) = Тип("ПолеСписка") Тогда
// Исключаем сам флажок блокировки, чтобы пользователь мог его снять обратно!
Если Элемент.Имя <> "ФлажокБлокировки" Тогда
Элемент.ТолькоПросмотр = БлокировкаАктивна;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Теперь свяжем эту общую процедуру с событиями формы:
Процедура ПриОткрытии()
УстановитьДоступностьПолей();
КонецПроцедуры
Процедура ФлажокБлокировкиПриИзменении(Элемент)
УстановитьДоступностьПолей();
КонецПроцедуры
Этот подход лаконичен, безопасен и автоматически подстраивается под любые новые поля, которые вы решите добавить на форму в будущем.
Еще один профессиональный способ управления интерфейсом в обычных формах — визуальная группировка. Мы можем разместить все редактируемые поля ввода на элемент формы типа Панель. При этом у панели можно отключить отображение рамок и вкладок, сделав ее абсолютно незаметной для пользователя.
Сам флажок блокировки мы размещаем на основной форме, *вне* этой панели. В таком случае управление доступностью всех полей сводится к изменению всего одного свойства самой панели. Код будет выглядеть следующим образом:
Процедура УстановитьДоступностьПолей()
// Если флажок взведен (Истина), то панель должна стать недоступной (Доступность = Ложь)
ЭлементыФормы.ПанельДанных.Доступность = НЕ ЗаблокированоРедактирование;
КонецПроцедуры
При таком подходе кнопка сохранения «ОК» и сам флажок блокировки остаются полностью доступными, так как они находятся за пределами заблокированной панели, а все внутренние поля ввода моментально гаснут.
Если вы планируете переходить на управляемый интерфейс 1С, вам полезно знать, что там данная задача решается еще проще и зачастую вообще без написания кода в модуле формы.
Для этого используется механизм Условного оформления формы:
Объект.ЗаблокированоРедактирование Равно Истина.Платформа 1С в управляемом режиме сама отследит изменение состояния флажка и применит оформление «на лету» как при открытии формы, так и при интерактивных кликах пользователя.
В оригинальном обсуждении на форуме упоминается хранение банковских реквизитов, паролей и CVV-кодов карт непосредственно в полях справочника. Хранить конфиденциальную информацию в открытом виде в базе данных, даже «для личного пользования на одном ПК» — крайне небезопасная практика.
Если перед вами стоит задача защиты таких данных, рекомендуем использовать следующие системные механизмы платформы 1С:
РежимПароля в значение Истина. В этом случае вводимые символы на экране будут маскироваться звездочками (*), защищая информацию от случайных взглядов коллег.МенеджерКриптографии. С его помощью можно настроить шифрование строк по алгоритму AES перед записью объекта в базу данных и расшифровку только при выводе на экран по запросу пользователя, знающего мастер-пароль.