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