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