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