При настройке типовой синхронизации данных между конфигурациями «Бухгалтерия предприятия 3.0» (БП) и «Управление торговлей 11.4» (УТ) специалисты часто сталкиваются с проблемой «агрессивного» обновления данных. Бухгалтеры в БП нередко заводят контрагентов с минимальным набором реквизитов (только ИНН и наименование), в то время как в торговой базе (УТ) менеджеры заполняют детальную информацию: адреса, телефоны, контактных лиц и специфические параметры. При очередном обмене неполные данные из БП прилетают в УТ и затирают тщательно заполненные карточки. Разберем, как решить эту задачу несколькими способами.
Прежде чем переходить к коду, давайте проанализируем, как работает современный обмен. В связке БП 3.0 — УТ 11.4 используется технология EnterpriseData (универсальный формат). В отличие от старых обменов на базе Конвертации данных 2.0, где правила выгрузки и загрузки хранились в отдельных XML-файлах, в EnterpriseData (КД 3.0) логика зашита непосредственно в модули менеджеров обмена внутри конфигурации. Это накладывает определенные ограничения на привычную «постановку галочек» в интерфейсе, но дает гибкость для программной доработки.
Рассмотрим вариант доработки на стороне базы-приемника (в нашем случае — УТ). Наша задача — определить, что объект записывается в процессе обмена, и если он уже существует в базе, отменить его перезапись. Для этого мы создадим расширение и воспользуемся механизмом заимствования справочника Контрагенты.
Проанализируем событие ПередЗаписью. Важно использовать именно его, а не ПриЗаписи, так как на этапе ПриЗаписи объект уже физически изменен в базе данных, и отмена операции будет некорректной или приведет к ошибкам транзакции. Напишем следующий код в модуле объекта через расширение:
&Перед("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ)
// Проверяем, что запись инициирована механизмом обмена
Если ЭтотОбъект.ОбменДанными.Загрузка Тогда
// Проверяем, является ли объект новым.
// Если ссылка не пустая, значит объект уже существует в ИБ
Если Не ЭтотОбъект.ЭтоНовый() Тогда
// Устанавливаем отказ, чтобы не затирать существующие данные
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Важный нюанс: при установке Отказ = Истина в процессе синхронизации, типовой механизм обмена может зафиксировать ошибку загрузки. Пользователь увидит сообщение о том, что данные не приняты. Тем не менее, цель будет достигнута: старые данные в УТ останутся нетронутыми. Если же контрагент новый (его еще нет в УТ), то ЭтоНовый() вернет Истина, условие не сработает, и контрагент успешно создастся.
Если мы не хотим изменять код в приемнике, мы можем повлиять на процесс на стороне источника (БП 3.0). Выясним, как сделать так, чтобы БП не отправляла изменения по уже существующим контрагентам. В типовом механизме для этих целей используются Правила регистрации объектов (ПР). Для ускорения настройки правил в конфигурации можно применить обработку для группового создания правил регистрации в КД 2.
Выполним следующие шаги для изменения логики регистрации:
Контрагенты и перейдем к обработчикам событий.Перед обработкой напишем логику, которая будет проверять, нужно ли регистрировать объект к выгрузке.
// Если объект уже был ранее выгружен (есть ссылка в базе),
// и это не создание нового объекта, то отменяем регистрацию изменений.
Если Не Объект.ЭтоНовый() Тогда
Отказ = Истина;
КонецЕсли;
После сохранения и загрузки правил обратно в БП, система перестанет добавлять контрагентов в «очередь» на выгрузку при их редактировании бухгалтером. Это эффективный метод, если обмен переполнен документами и другими объектами. В УТ будут уходить только те контрагенты, которые были созданы «с нуля».
Рассмотрим более продвинутый метод, который упоминался коллегами на форуме. Общий модуль МенеджерОбменаЧерезУниверсальныйФормат (или аналогичный в вашей версии УТ) содержит процедуры загрузки данных. Мы можем реализовать логику «мягкого обновления» — когда заполняются только пустые реквизиты, а уже заполненные не изменяются.
Проанализируем ситуацию: в процессе загрузки XDTO-пакета система сопоставляет данные. Мы можем вмешаться в этот процесс через событие ПриЧтенииОбъекта в менеджере обмена. В этом обработчике доступна структура ПолученныеДанные.
Нам потребуется реализовать следующий алгоритм:
ПолученныеДанные и в объекте базы данных.ФактическийАдрес), а в ПолученныеДанные оно пустое или отличается — принудительно установить в ПолученныеДанные значение из базы.Этот способ является самым трудоемким, но и самым корректным, так как он позволяет синхронизировать новые данные, не уничтожая старые, и при этом не вызывает ошибок «Отказ в записи» в мониторе синхронизации.
Выясним, какой метод лучше выбрать в зависимости от ситуации:
ПередЗаписью (Способ 1). Это «жесткий» метод, который сработает даже если правила регистрации будут сброшены к типовым.Помните, что при использовании правил регистрации (Способ 2), вам придется следить за ними при обновлениях конфигурации БП 3.0. 1С часто обновляет состав правил, и ваши правки могут быть затерты типовыми, поэтому всегда сохраняйте копию своих доработанных правил регистрации в отдельном файле. Для удобного переноса и обновления правил в рабочей базе можно использовать инструмент для загрузки правил из КД 2 по HTTP.