При разработке и сопровождении конфигураций на платформе 1С:Предприятие 7.7 нередко возникает задача определить, открыт ли конкретный документ кем-то из пользователей сетевого сеанса. Это может потребоваться для предотвращения коллизий при вводе на основании, блокировки массовых обработок или контроля корректности проведения документов. Рассмотрим подробно, с какими архитектурными ограничениями мы сталкиваемся и какие механизмы решения существуют.
Сначала проанализируем особенности работы платформы с объектами. В 1С 7.7 отсутствуют штатные средства, позволяющие из выборки документов напрямую запросить состояние формы документа у другого пользователя. Причиной этого являются следующие особенности архитектуры:
Рассмотрим способ проверки занятости объекта на редактирование путем установки программной блокировки с помощью метода Блокировка() объекта типа Документ.
Синтаксис метода имеет следующий вид:
Блокировка(<ВклВыкл>)
Параметр <ВклВыкл> принимает значения:
1 — включить блокировку. Если объект уже заблокирован другим сеансом, метод вернет 0, если успешно заблокирован — вернет 1.0 — снять блокировку объекта.1 — заблокирован, 0 — свободен).Разберем пример кода, когда требуется предотвратить ввод нового документа на основании, если документ-основание открыт и редактируется в другом сеансе:
Перем ДокБлокировка;
Процедура ВводНаОсновании(ДокументОснование)
// Создаем объект и находим документ
ДокБлокировка = СоздатьОбъект("Документ");
ДокБлокировка.НайтиДокумент(ДокументОснование);
// Пытаемся заблокировать документ
Если ДокБлокировка.Блокировка(1) = 0 Тогда
Предупреждение("Невозможно заблокировать документ " + ДокументОснование + "!
|Ввод на основании невозможен, так как документ редактируется другим пользователем.");
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Процедура ПриЗакрытии()
// При закрытии формы снимаем установленную блокировку
Если ПустоеЗначение(ДокБлокировка) = 0 Тогда
Если ДокБлокировка.Блокировка() = 1 Тогда
ДокБлокировка.Блокировка(0);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важное замечание: При обработке выборки документов следует быть крайне осторожными. Если в цикле устанавливать Блокировка(1) и не вызывать Блокировка(0) для каждого успешно обработанного объекта, эти документы останутся заблокированными текущим сеансом до момента завершения работы процедуры или модуля.
Если в конфигурации применяется внешняя компонента FormEx, мы получаем доступ к расширенной работе с окнами платформы. В частности, можно проанализировать список локально открытых окон через функцию СписокВсехОткрытыхОкон() или использовать событие ОбработкаБлокировкиОбъекта.
Посмотрим, как работает данный механизм:
СписокВсехОткрытыхОкон позволяет получить список всех окон, запущенных в текущем сеансе пользователя, определить контексты этих окон и узнать значение свойства ТекущийДокумент.ОбработкаБлокировкиОбъекта перехватывает ситуации, когда объект переходит в состояние блокировки, что позволяет гибко реагировать на попытки одновременного редактирования.Для случаев, когда требуется гарантированно отслеживать открытие документов всеми пользователями (включая режим чтения), проанализируем вариант создания собственной системы учета открытых форм.
ПриОткрытии() записывается строка с данными: ссылка на документ, имя пользователя, имя компьютера и текущее время.ПриЗакрытии() соответствующая запись удаляется.Нюанс реализации: Чтобы избежать ситуаций, когда при аварийном завершении работы 1С (например, при сбое питания) записи остаются «зависшими», при старте системы следует предусматривать процедуру сопоставления записей журнала со списком реально активных пользователей.
Таким образом, выбор конкретного подхода зависит от стоящей задачи: для защиты данных от коллизий при изменении достаточно метода Блокировка(), а для полного контроля чтения и открытых форм потребуется разработка дополнительного журнала или применение внешней компоненты.