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