При разработке интерфейсов в 1С:Предприятие 8.3 часто возникает задача динамического управления элементами формы. Одной из типовых ситуаций является блокировка ввода данных в одно поле до тех пор, пока не заполнено другое. Рассмотрим ситуацию на конкретном примере: нам необходимо сделать поле Возраст недоступным для редактирования, если в справочнике кандидатов не указан Пол.
Проанализируем типичную ошибку начинающих разработчиков. Попытка использовать процедуру ОбработкаПроверкиЗаполнения для визуального управления формой обречена на провал. Выясним причину: этот обработчик предназначен для проверки данных в момент записи объекта в базу данных. Он может прервать запись и выдать предупреждение пользователю, но он не может «на лету» менять свойства кнопок или полей на экране, пока пользователь просто перемещается между реквизитами.
Для реализации живого, отзывчивого интерфейса нам необходимо использовать события элементов формы и механизмы платформы, работающие непосредственно на клиенте.
Рассмотрим самый гибкий метод — написание кода в модуле формы. Нам нужно отслеживать два момента: когда форма открывается и когда пользователь меняет значение в поле Пол.
Шаг 1. Создание общей процедуры управления доступностью
Для соблюдения чистоты кода создадим вспомогательную процедуру, которую будем вызывать из разных мест. Это позволит нам не дублировать логику. Разберем код:
&НаКлиенте
Процедура УправлятьДоступностьюВозраста()
// Проверяем, заполнено ли поле Пол в объекте
ПолеЗаполнено = ЗначениеЗаполнено(Объект.Пол);
// Устанавливаем доступность элемента формы
Элементы.Возраст.Доступность = ПолеЗаполнено;
КонецПроцедуры
Шаг 2. Подключение к событиям формы
Теперь нам нужно вызвать эту логику при открытии формы, чтобы состояние поля Возраст соответствовало данным уже существующей записи. Воспользуемся событием ПриОткрытии:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
УправлятьДоступностьюВозраста();
КонецПроцедуры
Затем обеспечим реакцию системы на действия пользователя. Найдем в свойствах элемента Пол событие ПриИзменении и создадим обработчик. Рассмотрим важный нюанс: если у вас уже существует процедура ПолПриИзменении, нельзя создавать вторую с таким же именем — это вызовет синтаксическую ошибку. Посмотрим, как правильно объединить код:
&НаКлиенте
Процедура ПолПриИзменении(Элемент)
// Здесь может быть ваш старый код...
// Добавляем вызов нашей логики
УправлятьДоступностьюВозраста();
// Рекомендуется также очищать значение возраста, если пол был удален
Если Не ЗначениеЗаполнено(Объект.Пол) Тогда
Объект.Возраст = 0;
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию: написание кода требует поддержки, контроля за событиями и может привести к ошибкам. Платформа 1С 8.3 предоставляет более современный инструмент — Условное оформление. Это декларативный подход, при котором мы описываем правило, а платформа сама заботится о его выполнении.
Разберем по шагам, как настроить это без единой строчки кода:
Доступность и установим его в значение Ложь.Объект.Пол В значении [Пустое значение] (или используем вид сравнения «Не заполнено»).Возраст.Преимущества этого метода:
Выясним важную деталь для удобства пользователя. При управлении элементами вы можете использовать два разных свойства:
Ложь, поле становится «серым», в него нельзя поставить курсор, текст из него нельзя выделить или скопировать.Истина, поле выглядит как обычное, пользователь может кликнуть в него и скопировать содержимое (например, число возраста), но не может его изменить.В большинстве задач по ограничению ввода лучше использовать ТолькоПросмотр, так как это более дружелюбно по отношению к пользователю.
Хотя мы решили задачу визуального отображения, помните, что клиентские проверки можно обойти (например, программной загрузкой данных). Поэтому хорошим тоном считается дублирование логики в процедуре ПередЗаписью на сервере. Проанализируем пример кода для модуля объекта:
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверка бизнес-логики: нельзя указывать возраст без пола
Если Не ЗначениеЗаполнено(Пол) И ЗначениеЗаполнено(Возраст) Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Невозможно указать возраст, если не выбран пол кандидата!";
Сообщение.Поле = "Возраст";
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Таким образом, мы обеспечили комплексное решение: удобный интерфейс через Условное оформление или события формы и надежное хранение данных через серверные проверки.