Как перенести все записи подчиненного регистра сведений в Конвертации данных 2.1, если регистраторы уже в приемнике

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

При работе с инструментом «1С:Конвертация данных 2.1» (КД 2.1) программисты часто сталкиваются с задачей выборочного переноса данных. Типичная ситуация: документы-регистраторы уже перенесены в базу-приемник или созданы там вручную, и теперь необходимо «докачать» только движения по конкретному подчиненному регистру сведений. Однако при стандартной настройке правил часто возникает проблема — в приемник загружается только одна запись на каждый регистратор, а все остальные строки «теряются» или затираются.

В этой статье мы разберем, почему это происходит, проанализируем внутренние механизмы работы КД 2.1 с регистрами и реализуем правильный алгоритм выгрузки наборов записей, который гарантирует полную передачу данных.

Выясним причину: почему загружается только одна запись?

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

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

Шаг 1. Настройка Правила конвертации объектов (ПКО)

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

  1. Создадим новое ПКО. В поле Источник выберем наш регистр сведений, в поле Приемник — соответствующий регистр в целевой базе.
  2. На закладке «Настройки» установим флаг «Выгружать объект полностью».
  3. В табличной части «Правила конвертации свойств» (ПКС) должны быть перечислены все измерения, ресурсы и реквизиты регистра.
  4. Важный момент: Для свойства Регистратор обязательно должно быть указано соответствующее ПКО документа. Поскольку документы уже в приемнике, в ПКО регистратора (в его настройках поиска) достаточно оставить только поиск по УИД или по номеру и дате, отключив обновление существующих объектов, чтобы не изменить данные самих документов.

Проанализируем работу ПКО: когда в него попадает объект типа НаборЗаписей, КД автоматически понимает, что нужно итерировать по коллекции строк. В файле выгрузки (XML) это будет выглядеть как единый блок данных, привязанный к одному регистратору. Для проверки структуры полученного XML-файла и контроля состава выгруженных объектов можно использовать обработку для анализа выгруженных данных конвертации.

Шаг 2. Создание Правила выгрузки данных (ПВД) с произвольным алгоритмом

Стандартное ПВД по регистрам часто работает некорректно для нашей задачи. Поэтому мы воспользуемся произвольным алгоритмом. Это позволит нам самим контролировать, какие именно данные и в каком виде будут отправлены на выгрузку. Для упрощения написания таких алгоритмов можно использовать доработанную конфигурацию «Конвертация данных» с подсказками по обработчикам.

Перейдем на закладку «Правила выгрузки данных» и создадим новое правило. Выберем тип выгрузки — «Произвольный алгоритм». Основная логика будет сосредоточена в обработчике Перед обработкой.

Рассмотрим пример кода, который выбирает уникальные регистраторы и выгружает их движения наборами:


// Создаем запрос для поиска всех уникальных регистраторов, по которым есть записи
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|	ТвоеИмяРегистра.Регистратор КАК Регистратор
|ИЗ
|	РегистрСведений.ТвоеИмяРегистра КАК ТвоеИмяРегистра
|ГДЕ
|	ТвоеИмяРегистра.Период МЕЖДУ &ДатаНачала И &ДатаОкончания";

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаОкончания", ДатаОкончания);

РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();

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

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

Шаг 3. Обработка загрузки в приемнике

Чтобы загрузка прошла гладко, проанализируем ситуацию на стороне базы-приемника. При загрузке набора записей КД 2.1 использует стандартные механизмы платформы 1С. По умолчанию, когда записывается набор с установленным отбором по регистратору, старые записи по этому регистратору удаляются автоматически.

Рекомендация: Убедитесь, что в ПКО для регистра на закладке «Настройки» стоит режим записи «Записывать в обмене данными» (установка свойства ОбменДанными.Загрузка = Истина). Это позволит избежать срабатывания лишних подписок на события и лишних проверок, которые могут замедлить процесс или заблокировать запись движений без перепроведения самого документа.

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

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

Разберем, как это работает:

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

Пример формирования коллекции:


// В обработчике Перед выгрузкой ПКО
ТаблицаДвижений = Новый ТаблицаЗначений;
ТаблицаДвижений.Колонки.Добавить("Период");
ТаблицаДвижений.Колонки.Добавить("Регистратор");
ТаблицаДвижений.Колонки.Добавить("Номенклатура");
// ... заполнение таблицы данными ...

КоллекцияОбъектов = ТаблицаДвижений;

Этот способ хорош тем, что позволяет гибко трансформировать данные прямо «на лету» перед отправкой в файл XML.

Подведем итоги

Для корректного переноса движений подчиненного регистра, если сами регистраторы уже есть в приемнике, следует придерживаться следующих правил:

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

← На главную