Как выгрузить подчиненный регистр сведений и привязать записи к одному документу в 1С

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

При переносе данных между базами 1С часто возникает задача выгрузить записи регистра сведений (например, ЦеныНоменклатуры) и привязать их в базе-приемнике к единому служебному документу. Однако при стандартной настройке правил обмена разработчики сталкиваются с тем, что в регистре остается всего одна запись: каждая следующая строка просто перезаписывает предыдущую. Разберем, почему это происходит и как правильно организовать перенос данных.

Почему происходит перезапись данных при загрузке

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

  1. Создает объект РегистрСведенийНаборЗаписей для целевого регистра.
  2. Устанавливает отбор по указанному регистратору: Отбор.Регистратор.Установить(СлужебныйДокумент).
  3. Добавляет одну полученную строку в набор.
  4. Вызывает метод НаборЗаписей.Записать(Истина).

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

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

Способ 1. Перенос через документ «Корректировка записей регистров»

Рассмотрим наиболее надежный и быстрый вариант, если в конфигурации-приемнике присутствует универсальный документ ручной корректировки движений (например, КорректировкаРегистров или КорректировкаЗаписейРегистров).

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

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


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

// Получаем набор движений по регистру ЦеныНоменклатуры
НаборЦен = ДокументКорректировки.Движения.ЦеныНоменклатуры;

Для Каждого СтрДанных Из ТаблицаВыгруженныхЦен Цикл
    НоваяЗапись = НаборЦен.Добавить();
    НоваяЗапись.Период = ДокументКорректировки.Дата;
    НоваяЗапись.Номенклатура = СтрДанных.Номенклатура;
    НоваяЗапись.ВидЦены = СтрДанных.ВидЦены;
    НоваяЗапись.Цена = СтрДанных.Цена;
КонецЦикла;

// Записываем сформированные движения
НаборЦен.Записать(Истина);

Способ 2. Накопление данных и пакетная запись набора в правилах обмена

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

Разберем по шагам настройку обработчиков:

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

Параметры.Вставить("ТаблицаНакопленныхЦен", Новый ТаблицаЗначений);
Параметры.ТаблицаНакопленныхЦен.Колонки.Добавить("Номенклатура");
Параметры.ТаблицаНакопленныхЦен.Колонки.Добавить("ВидЦены");
Параметры.ТаблицаНакопленныхЦен.Колонки.Добавить("Цена");
  1. В ПКО регистра сведений в обработчике ПослеЗагрузки переносим значения в таблицу параметров и отменяем стандартную запись объекта:

НоваяСтрока = Параметры.ТаблицаНакопленныхЦен.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, Объект);

// Отменяем стандартную построчную запись набора
Отказ = Истина;
  1. В обработчике ПослеЗагрузкиВсехДанных (или ПослеЗагрузкиПравилаОбмена) выполняем однократную запись всех накопленных строк под созданным служебным документом:

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

Способ 3. Загрузка через табличный документ и типовую обработку

Если перенос выполняется разово без сложных правил конвертации:

  1. Выгружаем результат запроса по регистру цен из исходной базы в файл формата Excel (XLS/XLSX).
  2. В базе-приемнике создаем типовой документ (например, УстановкаЦенНоменклатуры) или документ корректировки.
  3. С помощью внешней обработки ЗагрузкаДанныхИзТабличногоДокумента.epf загружаем строки непосредственно в табличную часть созданного документа и проводим его.

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

← На главную