Как предотвратить выгрузку изменений существующих объектов (например, номенклатуры) из базы-источника в 1С:Конвертации Данных 3.0, используя уже имеющиеся объекты в базе-приемнике?

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

При обмене данными между различными конфигурациями 1С, особенно в связке 1С:Комплексная автоматизация (КА) и 1С:Розница (РТ), часто возникает задача, когда мы хотим, чтобы определенные объекты (например, номенклатура или физические лица), измененные в одной из баз, не перезаписывали аналогичные объекты в другой базе, а использовались уже существующие, либо новые объекты создавались, а существующие оставались без изменений. Мы рассмотрим, как добиться этого с помощью Конвертации Данных 3.0 (КД3) и расширений.

Понимание механизмов обмена данными в 1С:КД3 и БСП

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

В типовых конфигурациях, использующих БСП, логика регистрации изменений объектов очень развита и нередко довольно сложна. Изменения регистрируются с помощью подписок на события (например, ПриЗаписи, ПриУдалении), которые вызывают общие процедуры по регистрации изменений в планах обмена. Это может быть проблемой, если мы хотим изменить это поведение, не затрагивая типовую конфигурацию, чтобы избежать сложностей при обновлении.

Метод 1: Управление выгрузкой через правила регистрации объектов

Наиболее "правильный" и системный способ контроля выгрузки данных в КД3 — это настройка правил регистрации изменений для каждого типа объекта. Мы можем указать, какие объекты и при каких условиях будут регистрироваться для выгрузки в конкретный узел обмена. Если объект не должен выгружаться из базы-источника, мы можем настроить правила таким образом, чтобы его изменения не регистрировались.

Шаги по настройке правил регистрации:

  1. Откройте конфигурацию КД3, через которую настраивается обмен.
  2. Найдите раздел с правилами регистрации объектов.
  3. Выберите нужный тип объекта (например, Номенклатура или ФизическиеЛица).
  4. В правилах регистрации мы можем установить условия, при которых изменения объекта будут или не будут регистрироваться для конкретного узла обмена. Например, мы можем указать, что изменения Номенклатуры, созданной в РТ, не должны регистрироваться для обмена с КА.

Этот метод позволяет гибко управлять тем, что попадает в выгрузку, но требует прямого изменения правил, что не всегда удобно при обновлениях, если эти правила не являются частью типового обмена.

Метод 2: Модификация подписок на события через расширения

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

Почему используем расширения:

  1. Сохранение поддержки: Конфигурация остается типовой, что упрощает обновление.
  2. Изоляция изменений: Все наши доработки находятся в отдельном объекте, что облегчает управление ими.
  3. Гибкость: В современных версиях платформы 1С (начиная с 8.3.16) возможности расширений значительно расширены, позволяя создавать новые подписки на события и перехватывать процедуры типовых конфигураций.

Как найти и перехватить процедуру регистрации изменений:

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

  1. Отладка: Мы можем использовать отладчик, чтобы проследить стек вызовов при изменении и записи объекта. Например, при изменении элемента Номенклатуры в РТ, мы можем установить точку останова на событии ПриЗаписи модуля объекта Номенклатура и проследить, какие процедуры вызываются далее, до момента фактической регистрации в плане обмена.
  2. Поиск подписок: В типовых конфигурациях БСП часто используются подписки на событие, например, ЗарегистрироватьИзмененияДляОбмена или аналогичные. Мы можем найти эти подписки в конфигураторе.
  3. Создание расширения и перехват:
    • Создайте новое расширение.
    • В расширении мы можем либо создать новую подписку на событие, которая будет выполняться ДО типовой подписки, и в ней отменять регистрацию для определенных объектов и узлов.
    • Либо, что чаще бывает эффективнее, перехватить процедуру общего модуля, которая отвечает за регистрацию. Для этого мы "замещаем" (Заимствовать с замещением) нужную процедуру в расширении.

Пример перехвата процедуры регистрации (концептуально):

Предположим, мы выяснили, что процедура ОбменДаннымиСобытия.ЗарегистрироватьИзмененияОбъекта(Объект, Отказ, ЗаписываемыеСвойства) отвечает за регистрацию. Мы можем заместить ее в расширении и добавить нашу логику:


// В расширении, в общем модуле, замещающем типовой (или созданном для новой подписки)
Процедура ЗарегистрироватьИзмененияОбъекта(Объект, Отказ, ЗаписываемыеСвойства) Экспорт

    Если ТипЗнч(Объект) = Тип("СправочникСсылка.Номенклатура") Или ТипЗнч(Объект) = Тип("СправочникСсылка.ФизическиеЛица") Тогда
        // Проверяем, для какого узла обмена идет регистрация, если нужно
        // Например, если текущий узел обмена является узлом для КА, и мы не хотим выгружать
        // изменения Номенклатуры из РТ в КА
        //
        // Для демонстрации мы просто отказываем в регистрации для этих типов объектов
        // без дополнительных условий для узла, но в реальной задаче проверка узла ОБЯЗАТЕЛЬНА!
        Отказ = Истина;
        Возврат;
    КонецЕсли;

    // Если это не те объекты, которые мы хотим исключить, вызываем типовую логику.
    // Если это замещенная процедура, то обычно здесь будет вызов оригинальной процедуры
    // с помощью специального синтаксиса, который зависит от версии платформы
    // и способа замещения (например, вызов 'ПродолжитьВыполнение' или оригинальной процедуры с 'БезРасширения').
    //
    // В случае с новой подпиской, просто не делаем ничего и позволяем типовой подписке отработать,
    // если Отказ не установлен.
    //
    // Для версии 8.3.16+ и замещения, это может выглядеть так:
    #Если НЕ МодульСуществует("ОбменДаннымиСобытия", "БезРасширения") Тогда
        // Этот код выполняется, если процедура 'ЗарегистрироватьИзмененияОбъекта'
        // не замещена в расширении, и это, по сути, исходный код типовой процедуры
        // или если мы хотим, чтобы после нашей логики отработала оригинальная процедура
        ОбменДаннымиСобытияБезРасширения.ЗарегистрироватьИзмененияОбъекта(Объект, Отказ, ЗаписываемыеСвойства);
    #Иначе
        // Если процедура 'ЗарегистрироватьИзмененияОбъекта' замещена в расширении,
        // этот блок не будет выполнен, так как мы сами управляем вызовом оригинальной логики.
        // Если мы хотим вызвать оригинальную логику после наших проверок,
        // нам нужно явно указать это, например, с помощью:
        // ПродолжитьВыполнение(Объект, Отказ, ЗаписываемыеСвойства);
        // Или если процедура замещена с "Вызывать вместо", то оригинальная не будет вызвана без явного указания.
        // В данном примере, если Отказ установлен, то вызова типовой логики не будет.
        // Если Отказ не установлен, значит, объект должен регистрироваться по типовым правилам.
        // Для простоты примера, если Отказ не установлен, просто выходим, полагая, что оригинальная
        // процедура отработает самостоятельно, или она будет вызвана после нашей логики.
    #КонецЕсли
    
КонецПроцедуры

Важно: При таком подходе мы должны тщательно проверять тип объекта и узел обмена, чтобы не нарушить обмен для других объектов или других узлов (например, для РИБ, если он также используется). Отладка здесь является нашим лучшим другом.

Метод 3: Принцип сопоставления объектов по ключевым полям в КД3

Когда данные выгружаются из одной базы и загружаются в другую, КД3 использует механизм сопоставления объектов. Этот механизм основан на "ключевых полях". Мы должны понять, как это работает, чтобы правильно управлять тем, что "берется существующее".

  1. Ссылка как главное ключевое поле: В КД3 при обмене, если объекты уже синхронизированы (например, после первоначальной выгрузки и загрузки), они получают внутренние GUID (уникальные идентификаторы), которые становятся "ссылками" между базами. Если объект в базе-источнике имеет GUID, который соответствует GUID существующего объекта в базе-приемнике, то система будет сопоставлять их именно по этой ссылке.
  2. Другие ключевые поля: Если GUID не совпадает (например, это совершенно новый объект, или объект был создан независимо в обеих базах), КД3 начинает искать соответствие по другим "ключевым полям", которые определены в правилах обмена. Это могут быть Код, Наименование, ИНН, КПП и т.д. Если по этим полям находится единственный совпадающий объект, то система сопоставит их.
  3. Что происходит при изменении наименования, если ссылка совпадает: Если объекты уже сопоставлены по ссылке (т.е. имеют одинаковый GUID в обеих базах), то при изменении, например, наименования объекта в базе-источнике, система все равно найдет соответствующий объект по GUID в базе-приемнике. Далее, если не настроены правила, запрещающие обновление этого поля, наименование в базе-приемнике будет обновлено. Для предотвращения этого нам и требуется управлять выгрузкой изменений (как в Методах 1 и 2).
  4. Первоначальная синхронизация: Для корректной работы сопоставления по ссылкам, критически важна первоначальная синхронизация данных. Мы должны убедиться, что существующая номенклатура и другие объекты в КА и РТ были правильно сопоставлены и получили единые GUID в рамках обмена. Это можно сделать через стандартные механизмы синхронизации или с помощью специальных обработок сопоставления.

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

Метод 4: Управление загрузкой данных в базе-приемнике (предотвращение перезаписи)

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

В КД3 и в типовых обменах есть возможность использовать обработчики событий при загрузке данных. Одним из таких событий может быть ПриЗагрузкеДанных или ПриЗагрузкеОбъекта в модуле объекта обмена (или в правилах обмена).

Пример кода из сообщения 26 для управления загрузкой:


Если НЕ ДанныеИБ = Неопределено Тогда // Не замещать существующие объекты в приемнике при загрузке, а только создавать новые и заполнять их
    ПолученныеДанные = Неопределено;
КонецЕсли;

Разберем этот фрагмент подробнее:

  1. ДанныеИБ: Эта переменная обычно содержит ссылку на объект в информационной базе-приемнике, если он уже существует (т.е., если КД3 смогла найти соответствующий объект по своим правилам сопоставления). Если объект не найден, ДанныеИБ будет Неопределено.
  2. Если НЕ ДанныеИБ = Неопределено Тогда: Это условие проверяет, существует ли уже объект в базе-приемнике, который соответствует выгруженному объекту из файла обмена.
  3. ПолученныеДанные = Неопределено;: Если объект уже существует в базе-приемнике (т.е. ДанныеИБ не Неопределено), мы устанавливаем переменную ПолученныеДанные в Неопределено. Это сигнализирует системе обмена, что для данного объекта нет необходимости обновлять его на основании данных из файла обмена. По сути, мы говорим: "Этот объект уже есть, и мы не хотим, чтобы он изменялся данными из выгрузки".

Где использовать:

Этот код может быть вставлен в событие ПриЗагрузкеДанных в модуле правил конвертации, или в специальном обработчике события, который вызывается при загрузке объекта определенного типа. В зависимости от версии КД3 и используемых настроек, мы можем иметь доступ к этим обработчикам либо через визуальный редактор правил, либо через код модуля обмена.

Преимущества этого подхода:

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

Дополнительные возможности: Обработка выгрузки на стороне источника

Помимо перечисленных методов, существует еще один способ тонкой настройки процесса выгрузки: использование обработчика ПриОбработкеВыгрузкиДанных. Этот обработчик доступен в правилах обмена и позволяет нам вмешиваться в процесс выгрузки каждого объекта.

  1. Анализ объекта: В обработчике ПриОбработкеВыгрузкиДанных мы получаем доступ к выгружаемому объекту и его данным. Мы можем проанализировать его текущее состояние, историю изменений или любые другие параметры.
  2. Исключение из выгрузки: Если по каким-то условиям мы решаем, что данный объект не должен быть выгружен, мы можем установить параметр Отказ = Истина. В этом случае объект не попадет в файл обмена.
  3. Изменение выгружаемых данных: Мы также можем изменить выгружаемые реквизиты объекта, чтобы, например, выгрузить только определенные поля или преобразовать данные перед отправкой.

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

Заключение

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

← На главную