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

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

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

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

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

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

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

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

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

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


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

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

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


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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

← К списку