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