Как устранить ошибку блокировки при закрытии заказа клиента из формы реализации в УТ 11.5

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

В процессе работы с конфигурацией «1С:Управление торговлей 11.5» разработчики и пользователи часто сталкиваются с ситуацией, когда при попытке закрыть Заказ клиента непосредственно из формы созданной на его основании Реализации товаров и услуг система выдает ошибку блокировки объекта. Проанализируем, почему это происходит, и рассмотрим методики решения этой задачи.

Разберем механику возникновения проблемы

Для начала выясним причину конфликта. В системе «1С:Предприятие 8.3» реализован механизм пессимистической блокировки. Когда пользователь открывает документ и начинает его редактировать, платформа вызывает метод ЗаблокироватьДанныеДляРедактирования(). Это предотвращает одновременное изменение одних и тех же данных разными пользователями или разными программными процессами.

Проанализируем две ситуации, описанные в обращении:

  1. Ситуация №1 (Ошибка блокировки): Вы создаете Заказ клиента, записываете его, и, не закрывая форму заказа, создаете на его основании Реализацию товаров и услуг. В этот момент форма заказа удерживает блокировку, так как она считается «активной» в текущем сеансе. При попытке вызвать Помощник закрытия заказов из формы реализации, программа пытается программно заблокировать тот же самый заказ для изменения его статуса. Возникает конфликт: объект заблокирован «вами же», но в другом контексте (в другой форме).
  2. Ситуация №2 (Успешное закрытие): Вы переоткрываете заказ. Если вы ничего в нем не меняли, признак модифицированности формы не установлен, и жесткая блокировка может не накладываться до момента начала редактирования. Поэтому ПомощникЗакрытияЗаказов получает доступ к объекту и успешно выполняет процедуру.

Рассмотрим подробнее программный аспект. В модуле ПомощникЗакрытияЗаказов.ФормаЗакрытия.ГотовоСервер в цикле выполняется код:


Для Каждого ТекСтрока Из СписокЗаказов Цикл
    ЗаблокироватьДанныеДляРедактирования(ТекСтрока.Значение);
    // Дальнейшая логика закрытия
КонецЦикла;

Если форма заказа открыта и модифицирована, этот метод вызовет исключение, которое пользователь видит как ошибку блокировки.

Вариант 1. Использование механизма оповещений (для разработчиков)

Чтобы избежать прямого конфликта блокировок, мы можем использовать механизм оповещений. Вместо того чтобы пытаться изменить состояние заказа из «чужой» формы (реализации), мы отправим сигнал, который поймает сама форма заказа.

Проанализируем алгоритм:

  1. В форме реализации после успешного проведения вызываем метод Оповестить().
  2. В форме заказа настраиваем обработчик ОбработкаОповещения.
  3. При получении сигнала форма заказа сама инициирует свое закрытие или обновление.

Пример кода в форме реализации:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        Оповестить("ЗаказДолженБытьЗакрыт", Объект.ЗаказКлиента);
    КонецЕсли;
КонецПроцедуры

В форме заказа это позволит избежать ситуации, когда две формы пытаются одновременно владеть правом на редактирование одного объекта.

Вариант 2. Автоматизация через регламентное задание

Если бизнес-логика организации предполагает, что заказ должен закрываться сразу после частичной отгрузки (как в схеме «1 заказ = 1 реализация»), рассмотрим вариант с отложенным закрытием. Это самый надежный способ с точки зрения стабильности системы.

Выясним преимущества этого метода:

Для этого в настройках системы (НСИ и администрирование -> Обслуживание -> Регламентные операции) необходимо проверить активность задания Закрытие заказов. Если типовой логики недостаточно, можно создать расширение, которое будет помечать такие заказы к закрытию, а ночной процесс будет их обрабатывать.

Вариант 3. Программная отмена строк через расширение

Посмотрим на ситуацию со стороны данных. Закрытие заказа в УТ 11 — это, по сути, установка признака Отменено для всех строк, которые не были отгружены, с указанием причины отмены. Мы можем автоматизировать этот процесс в модуле менеджера или в подписке на событие при проведении реализации.

Рассмотрим пример логики, которую можно реализовать в расширении:


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

Рекомендации по организации бизнес-процесса

Часто технические проблемы являются следствием неоптимального процесса. Проанализируем, как можно упростить работу пользователям без изменения кода:

Резюме: Основная причина вашей проблемы — удержание формы Заказа клиента в состоянии редактирования при вызове серверного метода закрытия. Наиболее корректным решением будет либо использование Оповестить() для передачи управления форме заказа, либо делегирование функции закрытия фоновому регламентному заданию, что полностью снимет вопрос блокировок в многопользовательской среде.

← На главную