При переносе данных из конфигураций на платформе 1С 7.7 в 1С:Предприятие 8 часто возникает необходимость перенести историю периодических реквизитов справочников или периодических констант в регистры сведений платформы 1С 8. Если целевой регистр сведений имеет режим записи «Подчинение регистратору», разработчики нередко сталкиваются с ситуацией, когда после загрузки в регистре оказывается всего одна строка, хотя в файле выгрузки присутствовали сотни и тысячи записей.
Выясним причину такого поведения платформы и разберем по шагам надежные способы настройки правил обмена в конфигурации «Конвертация данных 2.1» (КД 2.1).
Проанализируем архитектуру хранения данных в платформе 1С 8.3:
РегистрСведенийЗапись автономно в базе существовать и записываться не может. Запись физически возможна только через объект РегистрСведенийНаборЗаписей с обязательной установкой отбора по конкретному документу: Отбор.Регистратор.Установить(...).РегистрСведенийЗапись, обработка загрузки данных в базе-приемнике на каждую входящую строку создает отдельный набор записей по регистратору и выполняет метод Записать(Истина).Разберем наиболее архитектурно правильный подход: выгружать данные не напрямую в регистр, а в документ-регистратор (например, типовой документ КорректировкаРегистров или специальный документ ввода начальных остатков), где регистр сведений выступает табличной частью движений.
Рассмотрим пошаговый алгоритм настройки:
КорректировкаРегистров.
ВыборкаДанных = СоздатьОбъект("ТаблицаЗначений");
ВыборкаДанных.НоваяКолонка("Сотрудник");
ВыборкаДанных.НоваяКолонка("Период");
ВыборкаДанных.НоваяКолонка("ДатаПриема");
ВыборкаДанных.НоваяКолонка("ДатаУвольнения");
СпрСотр = СоздатьОбъект("Справочник.Сотрудники");
СпрСотр.ВыбратьЭлементы();
Периодический = СоздатьОбъект("Периодический");
Пока СпрСотр.ПолучитьЭлемент() = 1 Цикл
Ссылка = СпрСотр.ТекущийЭлемент();
Если СпрСотр.ЭтоГруппа() = 1 Тогда
Продолжить;
КонецЕсли;
// Считываем историю приема
Периодический.ИспользоватьОбъект("ДатаПриема", Ссылка);
Периодический.ВыбратьЗначения();
Пока Периодический.ПолучитьЗначение() = 1 Цикл
ВыборкаДанных.НоваяСтрока();
ВыборкаДанных.Сотрудник = Ссылка;
ВыборкаДанных.Период = Периодический.ДатаЗнач;
ВыборкаДанных.ДатаПриема = Периодический.Значение;
КонецЦикла;
// Считываем историю увольнения
Периодический.ИспользоватьОбъект("ДатаУвольнения", Ссылка);
Периодический.ВыбратьЗначения();
Пока Периодический.ПолучитьЗначение() = 1 Цикл
ВыборкаДанных.НоваяСтрока();
ВыборкаДанных.Сотрудник = Ссылка;
ВыборкаДанных.Период = Периодический.ДатаЗнач;
ВыборкаДанных.ДатаУвольнения = Периодический.Значение;
ВыборкаДанных.ДатаПриема = Ссылка.ДатаПриема.Получить(ВыборкаДанных.Период);
КонецЦикла;
КонецЦикла;
ВыборкаДанных.НоваяКолонка("Сверт", "Число", 15, 2);
ВыборкаДанных.Свернуть("Сотрудник,Период,ДатаПриема,ДатаУвольнения", "");
ВыборкаДанных.Сортировать("Сотрудник,Период,ДатаПриема");
Передавая собранную таблицу значений в качестве движений документа, мы гарантируем, что при загрузке платформа 1С 8.3 сформирует полный набор записей и запишет его за одну транзакцию.
Если в источнике 7.7 неудобно конфигурировать структуру документа, рассмотрим альтернативный вариант с использованием глобальных параметров обмена:
Параметры.Вставить("ТаблицаДанных", ВыборкаДанных).
СсылкаНаРегистратор = Документы.КорректировкаРегистров.НайтиПоНомеру("000000001", ТекущаяДата());
Если ЗначениеЗаполнено(СсылкаНаРегистратор) И Параметры.ТаблицаДанных <> Неопределено Тогда
Набор = РегистрыСведений.ПриемУвольнениеСотрудников.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(СсылкаНаРегистратор);
Для Каждого Стр Из Параметры.ТаблицаДанных Цикл
Запись = Набор.Добавить();
ЗаполнитьЗначенияСвойств(Запись, Стр);
Запись.Регистратор = СсылкаНаРегистратор;
Запись.Активность = Истина;
КонецЦикла;
Набор.Записать(Истина);
КонецЕсли;
Обратим внимание на критически важные настройки в конфигурации 1С 8.3:
Записать() вызовет исключение.КорректировкаРегистров содержит специальную табличную часть (или реквизит), где хранится список отображаемых в форме регистров. При программной записи набора данные попадают в регистр, однако чтобы они отобразились в интерфейсе самого документа, необходимо также добавить строку с именем регистра в соответствующую служебную табличную часть документа.