Как правильно перенести историю курсов и кратностей валют из 1С 7.7 в 1С 8 через КД 2.1?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При настройке правил обмена в конфигурации «Конвертация данных 2.1» для переноса справочника Валюты из 1С:Предприятия 7.7 в 1С:Предприятие 8 разработчики часто сталкиваются с проблемой переноса периодических данных. В 1С 7.7 реквизиты Курс и Кратность являются независимыми периодическими реквизитами справочника, тогда как в 1С 8 они хранятся как ресурсы единого периодического регистра сведений КурсыВалют. Разберем, почему возникает затирание данных и как правильно реализовать перенос как полной истории, так и актуального среза.

В чем заключается архитектурная проблема?

Проанализируем структуру хранения данных в обеих платформах:

  1. Раздельное хранение в 1С 7.7: каждый периодический реквизит справочника хранит собственную историю изменений в отдельной системной таблице. Даты изменения курса и кратности могут не совпадать.
  2. Единая запись в 1С 8: регистр сведений КурсыВалют имеет ключевые поля Период и измерение Валюта. Поля Курс и Кратность являются ресурсами одной и той же записи регистра.
  3. Эффект перезаписи: если выгружать значения реквизита Курс в одном цикле, а Кратность — в другом, то при загрузке в 1С 8 более поздний набор записей на ту же дату полностью перезапишет ранее загруженный ресурс значениями по умолчанию.

Кроме того, важно помнить об особенностях встроенного языка 1С 7.7: в «семерке» отсутствует тип данных Булево. Для передачи флага Активность записи регистра сведений необходимо передавать числовые значения 1 или 0, а не литерал Истина.

Способ 1. Перенос всей истории курсов и кратностей (Рекомендуемый)

Чтобы сохранить полную и корректную историю в 1С 8, объединим даты изменения обоих реквизитов и на каждую уникальную дату выгрузим синхронный срез значений. Разберем алгоритм по шагам:

  1. Создадим таблицу для сбора всех дат изменения курса и кратности по текущей валюте.
  2. С помощью объекта Периодический обойдем реквизиты Курс и Кратность, заполнив таблицу дат.
  3. Свернем таблицу дат для исключения дубликатов.
  4. В цикле по полученным датам запросим актуальные значения курса и кратности на каждую дату через метод Получить().
  5. Сформируем СписокЗначений со всеми полями и вызовем функцию ВыгрузитьПоПравилу().

Посмотрим на пример кода в обработчике «После выгрузки» ПКО справочника Валюты:


ТаблицаДат = СоздатьОбъект("ТаблицаЗначений");
ТаблицаДат.НоваяКолонка("ДатаКурса", "Дата");

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

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

// 3. Оставляем только уникальные даты
ТаблицаДат.Свернуть("ДатаКурса", "");
ТаблицаДат.Сортировать("ДатаКурса+");

// 4. Выгружаем полный срез на каждую дату
ТаблицаДат.ВыбратьСтроки();
Пока ТаблицаДат.ПолучитьСтроку() = 1 Цикл
    ТекДата = ТаблицаДат.ДатаКурса;
    
    ЗзначКурс = Источник.Курс.Получить(ТекДата);
    ЗзначКратность = Источник.Кратность.Получить(ТекДата);
    
    // Проверка кратности на ноль
    Если (ПустоеЗначение(ЗзначКратность) = 1) Или (ЗзначКратность = 0) Тогда
        ЗзначКратность = 1;
    КонецЕсли;
    
    ПараметрыЗаписи = СоздатьОбъект("СписокЗначений");
    ПараметрыЗаписи.ДобавитьЗначение(1, "Активность");
    ПараметрыЗаписи.ДобавитьЗначение(ТекДата, "Период");
    ПараметрыЗаписи.ДобавитьЗначение(Источник, "Валюта");
    ПараметрыЗаписи.ДобавитьЗначение(ЗзначКурс, "Курс");
    ПараметрыЗаписи.ДобавитьЗначение(ЗзначКратность, "Кратность");
    
    ВыгрузитьПоПравилу(ПараметрыЗаписи, , , , "КурсыВалют");
КонецЦикла;

Способ 2. Перенос только последнего актуального значения

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

  1. В ПКО регистра сведений КурсыВалют в свойствах (ПКС) настраиваем получение значений на текущую дату или дату среза:
    
    // ПКС "Валюта" -> Перед выгрузкой:
    Значение = Источник;
    
    // ПКС "Период" -> Перед выгрузкой:
    Значение = ТекущаяДата();
    
    // ПКС "Курс" -> Перед выгрузкой:
    Значение = Источник.Курс.Получить(ТекущаяДата());
    
    // ПКС "Кратность" -> Перед выгрузкой:
    ТекКратность = Источник.Кратность.Получить(ТекущаяДата());
    Значение = ?((ПустоеЗначение(ТекКратность) = 1) Или (ТекКратность = 0), 1, ТекКратность);
    
    // ПКС "Активность" -> Перед выгрузкой:
    Значение = 1;
    
  2. В ПКО Валюты в обработчике «После выгрузки» вызываем экспорт записи регистра: ВыгрузитьПоПравилу(Источник, , , , "КурсыВалют");

Важные нюансы и возможные ошибки

Обратим внимание на критические моменты, которые могут привести к ошибкам при загрузке данных в 1С 8:

  1. Контроль нулевой кратности: в 1С 8 деление на ноль при проведении документов вызовет фатальную ошибку. Если в 1С 7.7 кратность не была заполнена или равнялась 0, обязательно переопределяем ее значение на 1.
  2. Пустые даты: если курс в 1С 7.7 был введен без указания даты, метод ДатаЗнач вернет пустую дату ('00.00.0000'). В 1С 8 поле Период регистра сведений не может содержать пустую дату, поэтому такие даты необходимо заменять на фиксированную минимальную дату (например, '01.01.1980') либо пропускать.
  3. Использование ПВД с произвольным алгоритмом: если валют много, для повышения производительности выгрузку курсов можно вынести из ПКО справочника в отдельное Правило Выгрузки Данных (ПВД) с произвольным алгоритмом, собрав общую таблицу курсов сразу по всем валютам.
← На главную