Как обеспечить корректный перенос и обновление записей регистра сведений с помощью "Конвертации Данных 2"?

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

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

Основная сложность при переносе регистров сведений заключается в том, что система 1С объединяет записи с одинаковым набором измерений. Если в базе-источнике есть несколько записей с идентичными измерениями, в базе-приемнике они будут объединены в одну, что может привести к "сжатию" данных. Кроме того, при изменении значений ресурсов (например, поля Пользователь) для уже существующих наборов измерений, нам необходимо обеспечить корректное обновление, а не создание дубликатов или сохранение устаревших данных.

Решение 1: Очистка данных с использованием наборов записей и отбора

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

Шаг 1: Использование обработчика "После загрузки" в Правиле Конвертации Объектов (ПКО)

Мы рассмотрим подробнее применение обработчика "После загрузки" в ПКО, поскольку именно на этом этапе нам уже доступен объект, который мы пытаемся загрузить, и мы можем использовать его измерения для формирования отбора.

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

Давайте посмотрим на пример кода для обработчика "После загрузки" ПКО:


НЗ = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
НЗ.Отбор.Организация.Установить(Объект.Организация);
НЗ.Отбор.Роль.Установить(Объект.Роль);
НЗ.Записать();

В этом примере, если в регистре МойРегистр уже существовали записи с такой же Организация и Роль, они будут удалены. После этого система продолжит загрузку данных, и новые записи будут добавлены или обновлены.

Иногда может потребоваться использовать Записать(Истина), чтобы явно указать, что набор записей должен быть полностью перезаписан:


НЗ = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
НЗ.Отбор.Организация.Установить(Объект.Организация, Истина); // Истина - для использования в отборе
НЗ.Отбор.Роль.Установить(Объект.Роль, Истина); // Истина - для использования в отборе
НЗ.Записать(Истина); // Истина - для записи набора записей с замещением

Важный момент: Использование НЗ.Записать() без параметров или с параметром Ложь записывает только те записи, которые были добавлены или изменены в самом наборе. Если набор пуст, он удалит записи по отбору. Если же в набор были добавлены новые записи, и мы хотим, чтобы они заменили все существующие по отбору, тогда НЗ.Записать(Истина) будет более подходящим.

Шаг 2: Использование обработчика "Перед загрузкой" в Правиле Конвертации Объектов (ПКО)

Мы также можем рассмотреть вариант очистки данных в обработчике "Перед загрузкой" ПКО. Однако, в этом обработчике сам объект, который мы переносим, еще может быть недоступен в полной мере. Тем не менее, если мы знаем значения измерений заранее (например, они переданы через параметры), мы можем использовать этот подход:


Наборчик = РегистрыСведений.Вася.СоздатьНабор записей();
Наборчик.Отбор.Организация.Установить(ПараметрыОбъекта["Организация"]);
Наборчик.Отбор.Роль.Установить(ПараметрыОбъекта["Роль"]);
Наборчик.Записать();

Здесь мы используем ПараметрыОбъекта для получения значений измерений, что позволяет нам очистить записи до того, как начнется процесс загрузки текущего объекта.

Решение 2: Использование произвольного запроса в Правиле Выгрузки Данных (ПВД)

Для более тонкой настройки выгружаемых данных и формирования нужного состава измерений мы можем использовать произвольный запрос в Правиле Выгрузки Данных (ПВД). Этот подход позволяет нам предварительно обработать данные еще на стороне источника, сгруппировав их или отфильтровав по определенным условиям. В качестве практического примера реализации таких правил можно изучить правила обмена между Комплексной автоматизацией 2.5 и WMS 5, где активно применяются механизмы КД 2 — для этой задачи подойдёт расширение механизмов КД 2 для обменов.

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

Решение 3: Размещение поля-измерения в параметр

Иногда возникает ситуация, когда поиск и идентификация записей должны происходить по одним полям, а затем необходимо заполнить или обновить другое поле, которое является измерением. В этом случае мы можем разместить поле-измерения в параметр.

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

Общие принципы и полезные рекомендации

Давайте проанализируем дополнительные важные аспекты, которые помогут нам при переносе регистров сведений:

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

  2. Безопасность и шифрование: Если данные регистра содержат конфиденциальную информацию, стоит обратить внимание на универсальную выгрузку-загрузку с возможностью шифрования, которая поддерживает работу с регистрами для всех конфигураций.

  3. Независимые и подчиненные регистратору регистры:

    • Независимые регистры сведений: Переносить их относительно просто, используя описанные выше методы — поможет организация обмена через COM или Web-сервисы.
    • Регистры сведений, подчиненные регистратору: Для таких регистров обычно не рекомендуется переносить движения напрямую. Лучше переносить сам документ-регистратор, а затем позволить ему сформировать движения в базе-приемнике. Если же необходимо изменить регистратор (например, на документ "ПереносДанных"), то вместо выгрузки самого регистра, создайте правило для выгрузки документа, а в нем уже выгружайте движения регистра.
  4. Обработчики событий "Перед загрузкой" и "После загрузки данных":

    • Обработчик "Перед загрузкой": Можно использовать для выполнения предварительной очистки, если данные для отбора доступны.
    • Обработчик "После загрузки данных": Позволяет выполнять более сложные манипуляции с данными после их загрузки.
  5. Процедура ВыгрузитьПоПравилу(): При переносе данных из табличной части документа в регистр сведений, мы можем использовать процедуру ВыгрузитьПоПравилу(). В этом случае в ПКО для регистра сведений Источник остается пустым, а в приемнике указывается регистр сведений. Затем создается запрос для выборки данных из табличной части, и в обработчике "Перед выгрузкой" ПВД этот запрос выполняется, а данные передаются через параметр ВходящиеДанные в виде таблицы значений.

Нюансы и возможные проблемы, которые следует учитывать

Мы должны быть внимательны к следующим особенностям:

  1. Поведение ВыгрузитьРегистр() с отказом: Обратите внимание на особенность работы процедуры ВыгрузитьРегистр(). Если в Правиле Конвертации Объектов (ПКО) срабатывает отказ от выгрузки (например, Отказ = Истина;), XML-узел для регистра сведений все равно создается, но с пустым отбором. При загрузке это может привести к тому, что все записи регистра будут отобраны (поскольку отбор пустой) и перезаписаны пустым набором данных. Это может привести к потере миллионов записей! Всегда тщательно проверяйте логику отбора и отказа при работе с этой процедурой.

  2. Регистры сведений, подчиненные регистратору: Если регистратор меняет дату, то при переносе в другую базу записи регистра сведений могут приходить как новые, а старые записи с прежней датой "подвисать". Необходимо продумать логику обработки таких ситуаций, возможно, через удаление старых записей по регистратору и дате.

Оптимизация процесса переноса

Для повышения производительности и удобства, особенно в распределенных системах, мы рекомендуем следующие подходы:

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

← На главную