Разработка и Конфигурация · 11 мин
Как в 1С проверить, что документ открыт другим пользователем
Как в 1С проверить, что документ открыт другим пользователем: механизм блокировок, ЗаблокироватьДанныеДляРедактирования, обработка ошибок и практические примеры кода.
Когда пользователь открывает документ в форме, платформа 1С автоматически устанавливает объектную блокировку данных. Второй пользователь, пытающийся открыть тот же документ на редактирование, получает сообщение об ошибке блокировки. Задача разработчика — проверить состояние блокировки до начала изменений, корректно обработать конфликт и при необходимости сообщить пользователю, кто именно держит документ открытым.
В управляемом режиме блокировки платформа работает в двух плоскостях: транзакционные блокировки СУБД возникают при записи, а объектные блокировки данных — при открытии формы объекта. Именно вторые отвечают за сообщение «Данные редактируются другим пользователем». Проверить такую блокировку можно программно — через попытку установить блокировку самостоятельно и перехват исключения.
Важно понимать ограничение: штатный API не возвращает список «кто открыл объект» напрямую. Информацию о пользователе, установившем блокировку, можно получить из текста ошибки, из журнала регистрации либо через административные инструменты кластера серверов 1С. Ниже разобраны рабочие способы проверки, обработки и снятия блокировок.
Как платформа 1С блокирует документ при открытии формы
При открытии формы объекта (документа, элемента справочника) в режиме редактирования платформа вызывает механизм блокировки данных для редактирования. Блокировка привязана к сеансу пользователя и хранится на сервере 1С или в файловой базе до тех пор, пока форма открыта или пока не выполнена явная разблокировка.
Если второй пользователь открывает тот же объект, платформа пытается установить блокировку повторно, получает отказ и показывает форму в режиме «только просмотр» либо выдаёт ошибку — поведение зависит от конфигурации и версии платформы. В файловом варианте блокировка снимается при закрытии формы или завершении сеанса; в клиент-серверном — также при аварийном завершении сеанса по таймауту кластера.
Из этого следуют два практических вывода. Во-первых, «зависшая» блокировка от аварийно закрытого сеанса снимается не мгновенно — сеанс может висеть в кластере до истечения таймаута. Во-вторых, программная проверка блокировки сводится к попытке её установить: свободный объект заблокируется успешно, занятый — вызовет исключение.
Проверка блокировки через ЗаблокироватьДанныеДляРедактирования
Универсальный способ проверки — вызвать метод ЗаблокироватьДанныеДляРедактирования() внутри конструкции «Попытка…Исключение». Метод принимает ключ блокировки (ссылка на документ), версию данных и идентификатор формы. Если объект уже редактируется другим сеансом, генерируется исключение, в тексте которого обычно содержится информация о сеансе и пользователе, установившем блокировку.
Функция ДокументЗаблокирован(СсылкаНаДокумент, ОписаниеБлокировки = "") Экспорт
Попытка
ЗаблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
// Объект свободен: сразу снимаем проверочную блокировку
РазблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
Возврат Ложь;
Исключение
ОписаниеБлокировки = ОписаниеОшибки();
Возврат Истина;
КонецПопытки;
КонецФункцииТретий параметр метода — идентификатор формы (UUID). Если передать идентификатор текущей формы, блокировка будет привязана к ней и автоматически снимется при закрытии. Для разовой проверки идентификатор обычно не передают, но тогда блокировку обязательно нужно снять вручную через РазблокироватьДанныеДляРедактирования(), иначе объект останется заблокированным до конца сеанса.
Текст исключения зависит от режима работы. В клиент-серверном варианте сообщение обычно включает имя пользователя, компьютер и номер сеанса, что позволяет сразу показать пользователю, кто держит документ. В файловом варианте детализация скромнее, но факт конфликта фиксируется надёжно.
Как узнать, кто именно открыл документ
Прямого метода «получить владельца блокировки» во встроенном языке нет, поэтому информацию собирают из нескольких источников. Самый простой — разобрать текст исключения: в клиент-серверном варианте он, как правило, содержит имя пользователя и сеанс. Этот текст можно показать пользователю как есть или извлечь из него нужные фрагменты строковыми функциями.
Второй источник — журнал регистрации. События ошибок блокировок фиксируются там с указанием пользователя, сеанса и времени. Программно журнал читается через ВыгрузитьЖурналРегистрации() с отбором по интервалу времени и имени события, содержащему признак блокировки. Способ трудоёмкий, но даёт историю конфликтов, а не только текущее состояние.
Третий вариант — административный: консоль кластера серверов 1С показывает активные сеансы и соединения, по которым администратор видит, кто работает с базой. Совместив это со временем ошибки блокировки, можно точно определить владельца. В типовых конфигурациях на БСП есть подсистема работы с блокировками и служебные функции, которые упрощают получение информации о сеансах.
Разобрать текст ошибки: имя пользователя и сеанс
Сразу снять проверочную блокировку
Проверить сеансы в консоли кластера
Изучить журнал регистрации за период
Проверка блокировки перед записью и из внешних механизмов
Частый сценарий — фоновое задание, обмен или обработка, которые должны изменить документ, но не имеют права молча перезаписать данные, редактируемые пользователем. Перед записью такой код должен проверить блокировку и при конфликте отложить операцию или сообщить об ошибке, а не перезаписывать объект принудительно.
Принудительная запись через Записать() без проверки приведёт либо к ошибке оптимистичной блокировки (если версия объекта изменилась с момента чтения), либо к потере изменений пользователя при повторном сохранении из формы. Поэтому корректный шаблон: проверить блокировку → при успехе установить её за собой → изменить и записать объект → снять блокировку.
Обработка ошибки версии данных
Метод ЗаблокироватьДанныеДляРедактирования() позволяет передать версию данных объекта. Если версия в базе не совпадает с переданной, возникает ошибка «версия данных изменилась» — это признак того, что объект изменили с момента чтения. Такую ошибку нужно отличать от ошибки занятости: в первом случае объект следует перечитать, во втором — дождаться освобождения или отказаться от операции.
Процедура БезопасноИзменитьДокумент(СсылкаНаДокумент) Экспорт
Попытка
ЗаблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
Исключение
ЗаписьЖурналаРегистрации("Изменение документа",
УровеньЖурналаРегистрации.Предупреждение, , ,
"Документ занят: " + ОписаниеОшибки());
Возврат; // операцию можно повторить позже
КонецПопытки;
Попытка
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
// ... изменения реквизитов ...
ДокументОбъект.Записать();
Исключение
РазблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
ВызватьИсключение;
КонецПопытки;
РазблокироватьДанныеДляРедактирования(СсылкаНаДокумент);
КонецПроцедурыСнятие зависших блокировок и завершение сеансов
Если документ «висит» в блокировке, хотя пользователь утверждает, что закрыл его, чаще всего причина — зависший сеанс: клиентское приложение завершилось аварийно, но кластер ещё не удалил сеанс по таймауту. В этом случае блокировка снимется сама через некоторое время либо после принудительного завершения сеанса администратором.
Порядок действий администратора в клиент-серверном варианте: открыть консоль кластера серверов, найти нужную информационную базу, просмотреть список сеансов, определить сеанс пользователя по имени и времени последней активности, завершить его. После завершения сеанса объектные блокировки снимаются автоматически. В файловом варианте помогает завершение процесса 1cv8 на компьютере пользователя либо монопольный перезапуск базы в крайнем случае.
Принудительное завершение сеансов — крайняя мера: несохранённые данные пользователя будут потеряны. Перед этим стоит убедиться, что сеанс действительно «мёртвый», а не принадлежит работающему сотруднику, который просто отошёл с открытым документом.
- 1Уточните у пользователя, закрыл ли он документ и программу
- 2Проверьте список сеансов в консоли кластера серверов
- 3Найдите сеанс по имени пользователя и времени активности
- 4Дождитесь таймаута или завершите зависший сеанс принудительно
- 5Попросите повторно открыть документ и проверьте доступность
Типовые ошибки при работе с блокировками
Самая распространённая ошибка разработчика — проверка блокировки без её последующего снятия. Проверочный вызов ЗаблокироватьДанныеДляРедактирования() на свободном объекте сам устанавливает блокировку, и если не вызвать разблокировку, документ станет недоступен другим до конца сеанса. Второй типичный просчёт — игнорирование различия между ошибкой занятости и ошибкой версии данных: для них нужны разные ветки обработки.
Третья ошибка — попытка обойти блокировку прямой записью в обход механизмов платформы. Это разрушает целостность данных: изменения пользователя в форме будут потеряны или возникнут конфликты версий. Любое изменение занятого объекта должно либо ждать освобождения, либо отклоняться с понятным сообщением.
Как проверить результат
Форма открывается на редактирование без ошибок
Снова сообщение о блокировке
Нет новых ошибок блокировок по этому объекту
Ошибки повторяются от того же сеанса
Зависший сеанс отсутствует
Сеанс активен без реальной работы пользователя
Частые вопросы о проверке блокировок документов в 1С
Можно ли узнать, кто открыл документ, без программирования?
Да, в клиент-серверном варианте администратор видит сеансы в консоли кластера серверов, а текст ошибки блокировки у второго пользователя обычно содержит имя того, кто держит объект. В файловом варианте ориентируйтесь на журнал регистрации и список активных пользователей.
Почему документ остаётся заблокированным после закрытия программы?
При аварийном завершении клиента сеанс в кластере удаляется не мгновенно, а по таймауту. До истечения этого времени блокировка считается активной. Решение — дождаться таймаута или завершить зависший сеанс вручную в консоли кластера.
Чем отличается ошибка «объект заблокирован» от «версия данных изменилась»?
Первая означает, что объект сейчас редактируется другим сеансом — нужно ждать освобождения. Вторая означает, что объект изменили с момента вашего чтения — нужно перечитать данные и повторить операцию с актуальной версией.
Можно ли снять чужую блокировку программно?
Штатного метода снятия чужой объектной блокировки из встроенного языка нет. Блокировка снимается владельцем, при закрытии его формы, при завершении сеанса или по таймауту кластера. Программно можно только завершить сеанс через средства администрирования кластера.
Нужно ли проверять блокировку в фоновых заданиях?
Да, если задание изменяет документы, которые могут редактировать пользователи. Без проверки задание либо упадёт с ошибкой блокировки, либо перезапишет чужие изменения. Корректный шаблон — попытка блокировки, запись при успехе и обязательная разблокировка.
Работает ли ЗаблокироватьДанныеДляРедактирования в файловой базе?
Да, метод работает и в файловом варианте, механизм блокировок данных для редактирования присутствует в обоих режимах. Различие в детализации текста ошибок и в способах административного снятия зависших блокировок.
Что важно запомнить
Проверка «открыт ли документ другим пользователем» выполняется попыткой установить блокировку через ЗаблокироватьДанныеДляРедактирования с перехватом исключения. Проверочную блокировку всегда снимайте сразу, владельца блокировки ищите в тексте ошибки, журнале регистрации и консоли кластера, а зависшие сеансы завершайте только после проверки, что они действительно неактивны.