Как в 1С 8.3 на управляемых формах закрыть редактирование реквизита или автоматически заполнять поле «Ответственный» во всех документах?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

При переходе с обычных форм платформы 1С:Предприятие 8.2 на управляемые формы 1С 8.3 разработчики часто сталкиваются с вопросом адаптации привычных механизмов. В типовых конфигурациях на обычных формах (например, в «Управление производственным предприятием» или «Бухгалтерия предприятия 2.0») существовал общий модуль РаботаСДиалогами, через который централизованно управляли доступностью элементов форм. В архитектуре управляемого приложения прямого аналога этому модулю нет, так как клиентская и серверная логика строго разделены.

Разберем типичную задачу: как зафиксировать пользователя, перезаписавшего документ, и закрыть для ручного изменения реквизит Ответственный во всех документах конфигурации с минимальными доработками кода.

Архитектурные ограничения платформы 1С 8.3 при работе с формами на сервере

Проанализируем частую ошибку при попытке перехватить форму в серверных подписках. Попытка вызвать метод ПолучитьФорму() внутри подписки на событие ПередЗаписью приводит к исключению «Интерактивные функции недоступны».

Рассмотрим, почему это происходит:

  1. Разделение клиентского и серверного контекстов: В управляемом приложении серверный контекст объекта (ДокументОбъект) ничего «не знает» о наличии открытого окна интерфейса. Запись может происходить интерактивно из формы, через веб-сервисы, регламентные задания или групповые обработки.
  2. Запрет интерактивных вызовов: На стороне сервера платформа намеренно блокирует любые обращения к визуальным элементам и окнам клиентского приложения.

Способ 1. Заполнение реквизита в подписке на событие «ПередЗаписью»

Если задача заключается исключительно в том, чтобы при сохранении документа в поле Ответственный всегда подставлялся текущий пользователь, нет необходимости проверять наличие открытой формы. Достаточно создать общую подписку на событие.

Разберем по шагам реализацию этого механизма:

  1. В дереве метаданных конфигурации создадим новую Подписку на событие (например, УстановитьОтветственногоПередЗаписью).
  2. В свойстве Источник укажем составной тип из всех необходимых документов конфигурации.
  3. В свойстве Событие выберем ПередЗаписью.
  4. В модуле обработчика подписки реализуем следующий код:

Процедура УстановитьОтветственногоПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    // Пропускаем обработку при загрузке данных через планы обмена
    Если Отказ ИЛИ Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Перезаписываем ответственного текущим пользователем сеанса
    Источник.Ответственный = Пользователи.ТекущийПользователь();
    
КонецПроцедуры

Важное предостережение: Проанализируем риски безусловной перезаписи поля в подписке. При выполнении регламентных процедур (закрытие месяца, групповое перепроведение, восстановление последовательности) поле Ответственный во всех исторических документах затрется пользователем, запустившим процедуру, либо станет пустым при выполнении фоновым заданием.

Чтобы избежать этой проблемы, разделим интерактивную и фоновую запись через ДополнительныеСвойства:

  1. В обработчике формы документа ПередЗаписьюНаСервере передаем специальный признак:

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    ТекущийОбъект.ДополнительныеСвойства.Вставить("ИнтерактивнаяЗаписьИзФормы", Истина);
    
КонецПроцедуры
  1. В общем обработчике подписки проверяем наличие флага:

Процедура УстановитьОтветственногоПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    Если Отказ ИЛИ Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    Если Источник.ДополнительныеСвойства.Свойство("ИнтерактивнаяЗаписьИзФормы") Тогда
        Источник.Ответственный = Пользователи.АвторизованныйПользователь();
    КонецЕсли;
    
КонецПроцедуры

Способ 2. Ограничение редактирования на уровне прав доступа (Ролей)

Наиболее правильным и платформенным способом закрытия доступа к реквизиту для ручного изменения является настройка прав в дереве метаданных. В этом случае не требуется писать программный код.

Разберем порядок настройки:

  1. Откроем дерево конфигурации и перейдем в ветку Роли.
  2. Выберем целевую пользовательскую роль и откроем окно редактирования прав.
  3. Найдем нужные документы и в дереве реквизитов выберем Ответственный.
  4. Снимем флаг «Редактирование», оставив включенным только флаг «Просмотр».

При таком подходе платформа на уровне ядра автоматически заблокирует поле на всех управляемых формах для пользователей с этой ролью.

Способ 3. Блокировка реквизита на форме через Расширение конфигурации

Если конфигурацию нельзя снимать с поддержки, воспользуемся механизмом расширений для модификации форм документов.

Посмотрим на пример перехвата события ПриСозданииНаСервере в расширении:


&Вместо("ПриСозданииНаСервере")
&После("ПриСозданииНаСервере")
Процедура Расш_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ЭлементОтветственный = Элементы.Найти("Ответственный");
    Если ЭлементОтветственный <> Неопределено Тогда
        ЭлементОтветственный.ТолькоПросмотр = Истина;
    КонецЕсли;
    
КонецПроцедуры

Способ 4. Использование типовой подсистемы «Версионирование объектов»

Выясним причину, по которой часто требуется перезаписывать реквизит Ответственный: контроль за тем, кто последним внес изменения в документ. Однако учетный реквизит Ответственный предназначен для указания лица, ответственного за хозяйственную операцию, а не для аудита системных действий.

Для отслеживания истории изменений в конфигурациях на базе БСП (Библиотеки стандартных подсистем) правильнее использовать штатные инструменты:

  1. Версионирование объектов: В разделе «Администрирование — Поддержка и обслуживание — История изменений» включаем версионирование для нужных типов документов. Система автоматически сохранит дату, точное время, автора изменений и детальное сравнение реквизитов каждой версии документа.
  2. Журнал регистрации: Для расследования инцидентов достаточно встроенного журнала платформы, где фиксируются все транзакции записи и проведения с указанием пользователя сеанса.
← На главную