Как предотвратить перехват редактирования документов в 1С и вернуть надежную блокировку данных?

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

В современных версиях платформы «1С:Предприятие 8.3» (начиная с релизов 8.3.14 и 8.3.15) разработчики существенно изменили логику совместной работы пользователей с объектами базы данных. Если раньше при открытии и изменении документа одним пользователем объект жестко блокировался для всех остальных (классическая пессимистическая блокировка), то теперь поведение системы изменилось. Появилась возможность так называемого «перехвата» редактирования.

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

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

Почему изменилось поведение блокировок в 1С?

Для начала выясним первопричину изменений. Фирма «1С» изменила логику работы платформы, чтобы решить проблему «забытых окон». В старых версиях пользователь мог открыть документ, начать его редактировать, а затем уйти на обед или уехать домой, заблокировав работу десяткам коллег. Объект оставался недоступным для записи до тех пор, пока сессия зависшего пользователя не завершалась администратором или пока он сам не закрывал форму.

Чтобы обойти эту организационную сложность, были внедрены новые механизмы:

  1. Автоматическое снятие пессимистической блокировки через 1 минуту после того, как с формы пропадал признак модифицированности (даже если форма все еще открыта на экране).
  2. Интеграция с Системой взаимодействия. По задумке разработчиков, если второй пользователь пытается отредактировать занятый документ, система должна предложить ему отправить быстрое сообщение первому пользователю через встроенный чат («Уступи документ, мне срочно нужно провести правку»).

Однако если в вашей информационной базе Система взаимодействия не подключена и не настроена, платформа все равно пытается следовать новому сценарию интерфейсного поведения. Но так как связаться с первым пользователем напрямую невозможно, система просто выводит второму пользователю диалоговое окно с предложением принудительно начать редактирование. Это и порождает конфликтную ситуацию «силового перехвата» документа.


Решение 1. Программная пессимистическая блокировка через код формы

Самый быстрый и надежный способ вернуть старое, жесткое поведение системы — принудительно блокировать объект базы данных при открытии его формы на сервере. Если попытка заблокировать объект завершается неудачей (так как его уже кто-то редактирует), мы просто переводим форму в режим только для чтения и сообщаем пользователю, кто именно занял этот документ.

Рассмотрим пример реализации этого метода в модуле формы документа. Для этого используется стандартный обработчик события ПриСозданииНаСервере:


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

КонецПроцедуры

При таком подходе, как только первый пользователь открывает документ и начинает с ним работать, платформа регистрирует транзакционную пессимистическую блокировку. Когда второй пользователь попытается открыть эту же карточку, сработает блок Исключение. Второй пользователь увидит детальное сообщение о том, на каком компьютере, под каким сеансом и в какое время документ был занят его коллегой, а сама форма откроется строго в режиме ТолькоПросмотр = Истина.


Решение 2. Использование расширения конфигурации (рекомендуемый метод)

Править формы всех документов вручную в типовой конфигурации (например, в «Управление торговлей 11») — не самое лучшее решение. Это существенно усложнит процесс последующих обновлений программы. Гораздо правильнее вынести эту логику в Расширение конфигурации.

Давайте разберем по шагам, как это реализовать:

  1. Создайте новое расширение конфигурации и снимите в его свойствах флаг «Безопасный режим».
  2. Перенесите в расширение форму нужного документа (или нескольких документов, работа с которыми наиболее критична).
  3. Создайте для перенесенной формы обработчик события ПриСозданииНаСервере с аннотацией &После.

Посмотрим на пример кода, который будет выполняться в расширении:


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

Обратите внимание на использование метода платформы ЗаблокироватьДанныеДляРедактирования(). Этот метод оптимально подходит для управляемых форм, так как он связывает блокировку с уникальным идентификатором конкретной формы. Как только пользователь закроет форму, блокировка автоматически снимется на уровне платформы.


Решение 3. Подключение Системы взаимодействия (штатный путь «1С»)

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

Разберем, почему это решает проблему:

Чтобы развернуть этот механизм, достаточно использовать бесплатный облачный сервер 1С (1С:Диалог). Подключение выполняется буквально за 5 минут в режиме Предприятия через меню Администрирование -> Настройки программы -> Система взаимодействия. После несложной регистрации по адресу электронной почты все пользователи вашей базы данных смогут бесконфликтно координировать совместную работу с объектами.


Решение 4. Создание регистра «Активные сессии редактирования»

В крупных распределенных системах или при работе в веб-клиенте стандартные объектные блокировки могут вести себя нестабильно (например, из-за обрывов интернет-соединения). В таких случаях разработчики часто создают собственный независимый механизм отслеживания занятых документов через регистр сведений.

Проанализируем архитектуру этого решения:

  1. Создается непериодический независимый регистр сведений ЗанятыеОбъектыДляРедактирования со следующей структурой:
    • Измерение: Объект (Тип: ЛюбаяСсылка).
    • Ресурс: Пользователь (Тип: СправочникСсылка.Пользователи).
    • Ресурс: ДатаБлокировки (Тип: Дата).
    • Ресурс: ИдентификаторСеанса (Тип: УникальныйИдентификатор).
  2. При открытии формы документа выполняется запись в этот регистр. Если запись по данному объекту уже существует — форма открывается только для чтения.
  3. При закрытии формы запись из регистра удаляется.
  4. Для предотвращения зависания «мертвых» блокировок (если у пользователя аварийно выключился компьютер) настраивается простое РегламентноеЗадание, которое раз в несколько минут сопоставляет активные сеансы на сервере 1С со списком записей в регистре и очищает неактуальные строки.

Такой подход гарантирует 100% контроль над совместной работой пользователей и позволяет детально логировать информацию о том, кто, когда и какие документы открывал для внесения изменений.

Подведем итоги. Мы рассмотрели несколько вариантов решения проблемы потери данных при совместном редактировании. Для быстрого исправления ситуации в локальной базе проще всего использовать Решение №2 (Создание расширения с перехватом в ПриСозданииНаСервере), а для долгосрочного системного развития бизнеса идеальным вариантом будет развертывание Системы взаимодействия (Решение №3).

← На главную