В практике разработки на платформе 1С:Предприятие часто возникает задача сделать интерфейс отзывчивым и логичным. Классический пример, который мы разберем сегодня: необходимо запретить редактирование поля (например, «Возраст») до тех пор, пока пользователь не заполнит ключевое поле-владелец (например, «Пол»).
Казалось бы, задача тривиальная, но она имеет несколько вариантов решения, каждый из которых подходит для определенных ситуаций. Кроме того, важно различать свойства Доступность и ТолькоПросмотр, так как они по-разному влияют на пользовательский опыт (UX), для улучшения которого иногда применяют даже такие решения, как вертикальные закладки через SVG-картинки.
Давайте подробно рассмотрим, как реализовать такую логику правильно, избежав распространенных ошибок новичков, таких как дублирование кода или использование неверных событий формы.
В современных управляемых формах (Такси и новее) лучшей практикой считается использование механизма Условного оформления. Это декларативный метод: мы не пишем программный код, а настраиваем правила поведения формы в конфигураторе. Платформа сама оптимизирует выполнение этих правил на клиенте и сервере. Стоит отметить, что добавление реквизитов и элементов формы на управляемые формы часто можно выполнить легко и просто без глубокого кодирования, используя встроенные инструменты платформы.
Разберем по шагам, как это настроить:
ТолькоПросмотр (или Доступность). Установите галочку и выберите значение Истина. Это означает: "Сделать поле недоступным, если условие выполнится".Объект.Пол.Не заполнено.Возраст.Почему это лучший способ? Вам не нужно думать о том, в каких процедурах вызывать проверку. Платформа сама отследит изменение поля «Пол» и мгновенно заблокирует или разблокирует поле «Возраст». Это работает и при открытии формы, и при редактировании.
Иногда логика бывает слишком сложной для условного оформления, или вам нужно произвести дополнительные действия (например, очистить поле при блокировке). В этом случае мы прибегаем к программированию.
Для корректной работы нам нужно, чтобы код срабатывал в двух случаях:
Найдем в дереве элементов формы поле «Пол», в палитре свойств найдем событие ПриИзменении и создадим процедуру на клиенте. В ней мы будем управлять доступностью зависимого поля.
&НаКлиенте
Процедура ПолПриИзменении(Элемент)
// Устанавливаем доступность поля Возраст
// Если Пол заполнен, то ЗначениеЗаполнено вернет Истина -> Доступность = Истина
Элементы.Возраст.Доступность = ЗначениеЗаполнено(Объект.Пол);
// Дополнительная логика: если пол очистили, имеет смысл очистить и возраст
Если Не Элементы.Возраст.Доступность Тогда
Объект.Возраст = 0;
КонецЕсли;
КонецПроцедуры
Многие новички совершают ошибку, помещая код проверки в процедуру ПриОткрытии. Хотя это будет работать, более "чистым" подходом для установки начального состояния формы считается использование серверных событий создания формы.
В модуле формы используем процедуру ПриСозданииНаСервере. Это гарантирует, что форма приедет на клиент уже в правильном состоянии, без лишних "миганий" интерфейса.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем начальное состояние элемента
Элементы.Возраст.Доступность = ЗначениеЗаполнено(Объект.Пол);
КонецПроцедуры
Если вам нужно проверить поведение элементов прямо во время работы системы, можно использовать специальный редактор форм в режиме предприятия, который позволяет менять свойства элементов "на лету".
В коде выше мы использовали свойство Доступность (Enabled). Однако давайте разберемся, почему профессионалы часто предпочитают ТолькоПросмотр (ReadOnly).
Код при использовании ТолькоПросмотр немного изменится, так как логика становится обратной:
// Если пол НЕ заполнен, то ТолькоПросмотр = Истина
Элементы.Возраст.ТолькоПросмотр = Не ЗначениеЗаполнено(Объект.Пол);
В ходе обсуждения данной задачи важно отметить одну существенную деталь проектирования. Хранить Возраст как числовой реквизит — это "антипаттерн". Для создания действительно качественных решений стоит изучить приемы построения эффективных интерфейсов, которые помогают избежать подобных архитектурных ошибок.
Правильный подход:
ДатаРождения.Возраст на форму добавлять как информационную надпись. Аналогичным образом можно реализовать и другие элементы управления, например, флажок в динамическом списке.Пример функции расчета возраста:
&НаСервереБезКонтекста
Функция РассчитатьВозраст(ДатаРождения, ДатаАктуальности = Неопределено)
Если Не ЗначениеЗаполнено(ДатаРождения) Тогда
Возврат 0;
КонецЕсли;
Если ДатаАктуальности = Неопределено Тогда
ДатаАктуальности = ТекущаяДата();
КонецЕсли;
Возраст = Год(ДатаАктуальности) - Год(ДатаРождения);
Если НачалоДня(ДобавитьМесяц(ДатаРождения, Возраст * 12)) > НачалоДня(ДатаАктуальности) Тогда
Возраст = Возраст - 1;
КонецЕсли;
Возврат Возраст;
КонецФункции
Используя этот подход, вам вообще не придется блокировать поле возраста, так как оно станет вычисляемым и недоступным для прямого редактирования по определению.