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