При настройке правил обмена в конфигурации «Конвертация данных 2.1» для переноса справочника Валюты из 1С:Предприятия 7.7 в 1С:Предприятие 8 разработчики часто сталкиваются с проблемой переноса периодических данных. В 1С 7.7 реквизиты Курс и Кратность являются независимыми периодическими реквизитами справочника, тогда как в 1С 8 они хранятся как ресурсы единого периодического регистра сведений КурсыВалют. Разберем, почему возникает затирание данных и как правильно реализовать перенос как полной истории, так и актуального среза.
Проанализируем структуру хранения данных в обеих платформах:
КурсыВалют имеет ключевые поля Период и измерение Валюта. Поля Курс и Кратность являются ресурсами одной и той же записи регистра.Курс в одном цикле, а Кратность — в другом, то при загрузке в 1С 8 более поздний набор записей на ту же дату полностью перезапишет ранее загруженный ресурс значениями по умолчанию.Кроме того, важно помнить об особенностях встроенного языка 1С 7.7: в «семерке» отсутствует тип данных Булево. Для передачи флага Активность записи регистра сведений необходимо передавать числовые значения 1 или 0, а не литерал Истина.
Чтобы сохранить полную и корректную историю в 1С 8, объединим даты изменения обоих реквизитов и на каждую уникальную дату выгрузим синхронный срез значений. Разберем алгоритм по шагам:
Периодический обойдем реквизиты Курс и Кратность, заполнив таблицу дат.Получить().СписокЗначений со всеми полями и вызовем функцию ВыгрузитьПоПравилу().Посмотрим на пример кода в обработчике «После выгрузки» ПКО справочника Валюты:
ТаблицаДат = СоздатьОбъект("ТаблицаЗначений");
ТаблицаДат.НоваяКолонка("ДатаКурса", "Дата");
// 1. Собираем даты изменения Курса
ПерКурс = СоздатьОбъект("Периодический");
ПерКурс.ИспользоватьОбъект("Курс", Источник);
ПерКурс.ВыбратьЗначения();
Пока ПерКурс.ПолучитьЗначение() = 1 Цикл
Если ПустаяДата(ПерКурс.ДатаЗнач) = 0 Тогда
ТаблицаДат.НоваяСтрока();
ТаблицаДат.ДатаКурса = ПерКурс.ДатаЗнач;
КонецЕсли;
КонецЦикла;
// 2. Собираем даты изменения Кратности
ПерКратность = СоздатьОбъект("Периодический");
ПерКратность.ИспользоватьОбъект("Кратность", Источник);
ПерКратность.ВыбратьЗначения();
Пока ПерКратность.ПолучитьЗначение() = 1 Цикл
Если ПустаяДата(ПерКратность.ДатаЗнач) = 0 Тогда
ТаблицаДат.НоваяСтрока();
ТаблицаДат.ДатаКурса = ПерКратность.ДатаЗнач;
КонецЕсли;
КонецЦикла;
// 3. Оставляем только уникальные даты
ТаблицаДат.Свернуть("ДатаКурса", "");
ТаблицаДат.Сортировать("ДатаКурса+");
// 4. Выгружаем полный срез на каждую дату
ТаблицаДат.ВыбратьСтроки();
Пока ТаблицаДат.ПолучитьСтроку() = 1 Цикл
ТекДата = ТаблицаДат.ДатаКурса;
ЗзначКурс = Источник.Курс.Получить(ТекДата);
ЗзначКратность = Источник.Кратность.Получить(ТекДата);
// Проверка кратности на ноль
Если (ПустоеЗначение(ЗзначКратность) = 1) Или (ЗзначКратность = 0) Тогда
ЗзначКратность = 1;
КонецЕсли;
ПараметрыЗаписи = СоздатьОбъект("СписокЗначений");
ПараметрыЗаписи.ДобавитьЗначение(1, "Активность");
ПараметрыЗаписи.ДобавитьЗначение(ТекДата, "Период");
ПараметрыЗаписи.ДобавитьЗначение(Источник, "Валюта");
ПараметрыЗаписи.ДобавитьЗначение(ЗзначКурс, "Курс");
ПараметрыЗаписи.ДобавитьЗначение(ЗзначКратность, "Кратность");
ВыгрузитьПоПравилу(ПараметрыЗаписи, , , , "КурсыВалют");
КонецЦикла;
Если перенос всей многолетней истории не требуется (например, при переносе только остатков на определенную дату), можно выгрузить единственную запись среза. Рассмотрим настройку такого варианта:
КурсыВалют в свойствах (ПКС) настраиваем получение значений на текущую дату или дату среза:
// ПКС "Валюта" -> Перед выгрузкой:
Значение = Источник;
// ПКС "Период" -> Перед выгрузкой:
Значение = ТекущаяДата();
// ПКС "Курс" -> Перед выгрузкой:
Значение = Источник.Курс.Получить(ТекущаяДата());
// ПКС "Кратность" -> Перед выгрузкой:
ТекКратность = Источник.Кратность.Получить(ТекущаяДата());
Значение = ?((ПустоеЗначение(ТекКратность) = 1) Или (ТекКратность = 0), 1, ТекКратность);
// ПКС "Активность" -> Перед выгрузкой:
Значение = 1;
Валюты в обработчике «После выгрузки» вызываем экспорт записи регистра:
ВыгрузитьПоПравилу(Источник, , , , "КурсыВалют");
Обратим внимание на критические моменты, которые могут привести к ошибкам при загрузке данных в 1С 8:
0, обязательно переопределяем ее значение на 1.ДатаЗнач вернет пустую дату ('00.00.0000'). В 1С 8 поле Период регистра сведений не может содержать пустую дату, поэтому такие даты необходимо заменять на фиксированную минимальную дату (например, '01.01.1980') либо пропускать.