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