Как удалить регистрацию изменений из плана обмена при непосредственном удалении объектов в 1С?

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

В процессе работы с распределенными базами данных (РБД) или произвольными планами обмена часто возникает необходимость удалить устаревшие документы в периферийной базе так, чтобы эта операция не передавалась в центральную базу. Однако при непосредственном удалении объектов platform или прикладной код конфигурации может автоматически зафиксировать изменения — как самого документа, так и связанных с ним регистров сведений. В результате объект попадает в очередь на выгрузку, что нарушает задуманную логику обмена.

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

Выясним причину: почему фиксируются изменения при удалении?

Проанализируем ситуацию, которая происходит на платформенном уровне при непосредственном удалении документа из базы данных:

  1. Подписки на события и обработчики: В момент вызова метода непосредственного удаления платформа выполняет события модуля объекта (например, ПередУдалением) и привязанные подписки на события. В этих обработчиках разработчики часто прописывают очистку движений или независимых регистров сведений.
  2. Изменение связанных регистров: Даже если вы отключаете автозаполнение получателей на самом объекте документа, очистка связанных наборов записей регистров фиксирует новые изменения в плане обмена уже для этих регистров.
  3. Автоматическая регистрация планом обмена: Если в составе плана обмена включена авторегистрация изменений для данного регистра сведений или документа, платформа фиксирует факт записи/удаления для всех активных узлов.

Способ 1. Полная очистка регистрации изменений регистра с помощью метода ПланыОбмена

Если изменения уже зафиксированы в таблице регистраций и их необходимо программно удалить для одного или нескольких узлов обмена, воспользуемся стандартным методом платформы ПланыОбмена.УдалитьРегистрациюИзменений().

Рассмотрим пример кода, который удаляет регистрацию всех изменений по конкретному регистру сведений:


// Формируем массив узлов, для которых нужно отменить регистрацию
МассивУзлов = Новый Массив;
МассивУзлов.Добавить(СсылкаНаУзелОбмена);

// Удаляем регистрацию изменений по всему регистру сведений
ПланыОбмена.УдалитьРегистрациюИзменений(МассивУзлов, Метаданные.РегистрыСведений.ИмяВашегоРегистра);

Обратите внимание: передача объекта метаданных Метаданные.РегистрыСведений.ИмяВашегоРегистра вторым параметром очищает всю таблицу изменений данного регистра для указанного узла. Это эффективный и быстрый способ, однако он не подходит, если в очереди выгрузки должны остаться изменения по другим документам.

Способ 2. Точечное снятие с регистрации конкретных записей регистра

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

Рассмотрим, как это реализовать программно:


// Создаем набор записей и задаем отбор по ключевому измерению или регистратору
НаборЗаписей = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ДокументОбъект.Установить(УдаляемыйДокумент);

// Удаляем из плана обмена только те записи, которые подпадают под отбор набора
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, НаборЗаписей);

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

Способ 3. Предотвращение регистрации перед удалением через флаг «Загрузка»

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

Установка свойства ОбменДанными.Загрузка = Истина блокирует выполнение прикладных обработчиков событий ПередУдалением и ПриУдалении, а также препятствует программной записи связанных данных:


// Перед удалением объекта отключаем выполнение бизнес-логики и подписок
ОбъектДокумент = СсылкаНаДокумент.ПолучитьОбъект();
ОбъектДокумент.ОбменДанными.Загрузка = Истина;

// Непосредственное удаление объекта без вызова обработчиков
ОбъектДокумент.Удалить();

Способ 4. Отключение авторегистрации для набора записей регистра

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


НаборЗаписей = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.КлючевоеИзмерение.Установить(ЗначениеИзмерения);

// Отключаем автозаполнение получателей обмена
НаборЗаписей.ОбменДанными.Получатели.Автозаполнение = Ложь;

// Альтернативный вариант — установка режима загрузки
НаборЗаписей.ОбменДанными.Загрузка = Истина;

// Очищаем набор и записываем
НаборЗаписей.Записать();

Подводя итог, проанализируем выбор подходящего решения: для оперативной очистки всей таблицы изменений используйте ПланыОбмена.УдалитьРегистрациюИзменений() с передачей объекта метаданных; для выборочной очистки применяйте НаборЗаписейРегистраСведений с установленным отбором; а для предотвращения лишних записей на этапе удаления устанавливайте свойство ОбменДанными.Загрузка = Истина.

← На главную