При переносе данных из конфигурации ЗУП 2.5 в ЗУП 3.1 с помощью инструмента «Конвертация данных 2.0» (КД2) разработчики иногда сталкиваются с ситуацией: данные выгружаются без ошибок, в файле XML реквизит присутствует, а после загрузки в базу-приемник текстовое или числовое поле на форме элемента справочника остается пустым. При этом прямой запрос к базе данных показывает, что в самом справочнике значение успешно записано.
Рассмотрим подробно причины возникновения такой проблемы в ЗУП 3.1 и разберем практические способы её решения.
В современных типовых конфигурациях 1С (включая ЗУП 3.1) архитектура форм часто устроена так, что некоторые реквизиты отображаются не из самого справочника, а из сведений связанных независимых регистров (например, тарифные ставки, расценки, истории назначений). При изменении реквизита в режиме интерактивной работы стандартный модуль объекта автоматически создает или обновляет запись в сопутствующем регистре сведений.
Однако при выгрузке и загрузке через «Универсальный обмен данными в формате XML» механизм обмена принудительно устанавливает флаг:
Объект.ОбменДанными.Загрузка = Истина;
Данный флаг отключает исполнение стандартных обработчиков событий (ПередЗаписью, ПриЗаписью) и встроенных подписок на события. Это делается для ускорения загрузки и исключения дублирующих проверок. В результате данные пишутся напрямую в таблицу справочника, а зависимый регистр сведений остаётся пустым. Так как форма объекта при открытии запрашивает срез последних из регистра, поле на форме выглядит незаполненным.
Проанализируем наиболее надежный способ — создание записи регистра напрямую в обработчике Правила Конвертации Объектов (ПКО) справочника. Так как данные переносятся средствами платформы, мы можем сформировать набор записей вручную.
Разберем по шагам алгоритм настройки:
// В обработчике "Перед выгрузкой" ПКС или ПКО
ПараметрыОбъекта.Вставить("Расценка", Источник.Расценка);
ПослеЗагрузки ПКО справочника прочитаем переданный параметр и запишем движения в регистр сведений:
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("Расценка") Тогда
ЗначениеРасценки = ПараметрыОбъекта.Расценка;
// Создаем набор записей целевого регистра
НаборЗаписей = РегистрыСведений.ЗначенияПериодическихПоказателейРасчетаЗарплаты.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Показатель.Установить(Объект.Ссылка);
Запись = НаборЗаписей.Добавить();
Запись.Показатель = Объект.Ссылка;
Запись.Период = ТекущаяДата(); // Указываем актуальную дату или дату переноса
Запись.Значение = ЗначениеРасценки;
// Включаем флаг загрузки для самого набора записей
НаборЗаписей.ОбменДанными.Загрузка = Истина;
НаборЗаписей.Записать(Истина);
КонецЕсли;
Рассмотрим альтернативный метод — сброс флага загрузки в обработчике ПослеЗагрузки с последующим вызовом метода Записать(). Это заставит конфигурацию выполнить типовой алгоритм записи и автоматически сформировать все связанные движения.
Объект.ОбменДанными.Загрузка = Ложь;
Попытка
Объект.Записать();
Исключение
ЗаписьЖурналаРегистрации("Перенос данных", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
Важное предупреждение: Использование данного способа несет риски. При сбросе флага ОбменДанными.Загрузка = Ложь платформа выполнит абсолютно все встроенные проверки заполнения реквизитов и подписки на события. Если другие связанные объекты еще не загружены или в справочнике не заполнено одно из обязательных полей, вызов метода Записать() вызовет ошибку выполнения и прервет процесс обмена.
Посмотрим на вариант архитектурно чистого разделения правил обмена. Вместо написания кода внутри ПКО справочника создается отдельное правило конвертации для самого регистра сведений.
ВыгрузитьПоПравилу(...) в событии ПослеВыгрузки справочника.При переносе данных в независимые периодические регистры сведений ЗУП 3.1 обратите внимание на следующие технические нюансы:
Период. Если оставить его пустым, запись сохранится с датой 01.01.0001 00:00:00 и срез последних на текущую дату её не вернет.