Как отключить перезапись контрагентов при синхронизации между БП 3.0 и УТ 11.4

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

При настройке типовой синхронизации данных между конфигурациями «Бухгалтерия предприятия 3.0» (БП) и «Управление торговлей 11.4» (УТ) специалисты часто сталкиваются с проблемой «агрессивного» обновления данных. Бухгалтеры в БП нередко заводят контрагентов с минимальным набором реквизитов (только ИНН и наименование), в то время как в торговой базе (УТ) менеджеры заполняют детальную информацию: адреса, телефоны, контактных лиц и специфические параметры. При очередном обмене неполные данные из БП прилетают в УТ и затирают тщательно заполненные карточки. Разберем, как решить эту задачу несколькими способами.

Анализ механизмов обмена данными

Прежде чем переходить к коду, давайте проанализируем, как работает современный обмен. В связке БП 3.0 — УТ 11.4 используется технология EnterpriseData (универсальный формат). В отличие от старых обменов на базе Конвертации данных 2.0, где правила выгрузки и загрузки хранились в отдельных XML-файлах, в EnterpriseData (КД 3.0) логика зашита непосредственно в модули менеджеров обмена внутри конфигурации. Это накладывает определенные ограничения на привычную «постановку галочек» в интерфейсе, но дает гибкость для программной доработки.

Способ 1. Использование расширения конфигурации (Запрет записи в приемнике)

Рассмотрим вариант доработки на стороне базы-приемника (в нашем случае — УТ). Наша задача — определить, что объект записывается в процессе обмена, и если он уже существует в базе, отменить его перезапись. Для этого мы создадим расширение и воспользуемся механизмом заимствования справочника Контрагенты.

Проанализируем событие ПередЗаписью. Важно использовать именно его, а не ПриЗаписи, так как на этапе ПриЗаписи объект уже физически изменен в базе данных, и отмена операции будет некорректной или приведет к ошибкам транзакции. Напишем следующий код в модуле объекта через расширение:


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

Важный нюанс: при установке Отказ = Истина в процессе синхронизации, типовой механизм обмена может зафиксировать ошибку загрузки. Пользователь увидит сообщение о том, что данные не приняты. Тем не менее, цель будет достигнута: старые данные в УТ останутся нетронутыми. Если же контрагент новый (его еще нет в УТ), то ЭтоНовый() вернет Истина, условие не сработает, и контрагент успешно создастся.

Способ 2. Настройка правил регистрации объектов (Блокировка выгрузки из источника)

Если мы не хотим изменять код в приемнике, мы можем повлиять на процесс на стороне источника (БП 3.0). Выясним, как сделать так, чтобы БП не отправляла изменения по уже существующим контрагентам. В типовом механизме для этих целей используются Правила регистрации объектов (ПР). Для ускорения настройки правил в конфигурации можно применить обработку для группового создания правил регистрации в КД 2.

Выполним следующие шаги для изменения логики регистрации:

  1. Выгрузим текущие правила регистрации из БП 3.0 в файл XML. Это можно сделать через функции технического специалиста в узле плана обмена.
  2. Загрузим эти правила в конфигурацию «Конвертация данных 2.0» (несмотря на то, что сам формат обмена КД 3.0, правила регистрации по-прежнему редактируются в КД 2.0).
  3. Найдем в списке справочник Контрагенты и перейдем к обработчикам событий.
  4. В обработчике Перед обработкой напишем логику, которая будет проверять, нужно ли регистрировать объект к выгрузке.

// Если объект уже был ранее выгружен (есть ссылка в базе),
// и это не создание нового объекта, то отменяем регистрацию изменений.
Если Не Объект.ЭтоНовый() Тогда
    Отказ = Истина;
КонецЕсли;

После сохранения и загрузки правил обратно в БП, система перестанет добавлять контрагентов в «очередь» на выгрузку при их редактировании бухгалтером. Это эффективный метод, если обмен переполнен документами и другими объектами. В УТ будут уходить только те контрагенты, которые были созданы «с нуля».

Способ 3. Доработка менеджера обмена через универсальный формат

Рассмотрим более продвинутый метод, который упоминался коллегами на форуме. Общий модуль МенеджерОбменаЧерезУниверсальныйФормат (или аналогичный в вашей версии УТ) содержит процедуры загрузки данных. Мы можем реализовать логику «мягкого обновления» — когда заполняются только пустые реквизиты, а уже заполненные не изменяются.

Проанализируем ситуацию: в процессе загрузки XDTO-пакета система сопоставляет данные. Мы можем вмешаться в этот процесс через событие ПриЧтенииОбъекта в менеджере обмена. В этом обработчике доступна структура ПолученныеДанные.

Нам потребуется реализовать следующий алгоритм:

  1. Найти существующий объект в базе по ИНН/КПП или УИД.
  2. Если объект найден, сравнить значения полей в ПолученныеДанные и в объекте базы данных.
  3. Если поле в базе заполнено (например, ФактическийАдрес), а в ПолученныеДанные оно пустое или отличается — принудительно установить в ПолученныеДанные значение из базы.

Этот способ является самым трудоемким, но и самым корректным, так как он позволяет синхронизировать новые данные, не уничтожая старые, и при этом не вызывает ошибок «Отказ в записи» в мониторе синхронизации.

Резюме и рекомендации

Выясним, какой метод лучше выбрать в зависимости от ситуации:

Помните, что при использовании правил регистрации (Способ 2), вам придется следить за ними при обновлениях конфигурации БП 3.0. 1С часто обновляет состав правил, и ваши правки могут быть затерты типовыми, поэтому всегда сохраняйте копию своих доработанных правил регистрации в отдельном файле. Для удобного переноса и обновления правил в рабочей базе можно использовать инструмент для загрузки правил из КД 2 по HTTP.

← На главную