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