Перенос доработок из «вскрытой» конфигурации 1С:ERP в расширение — это стандартная задача при приведении системы к типовому виду для упрощения обновлений. Однако процесс миграции данных (регистров, реквизитов, справочников) таит в себе множество подводных камней, начиная от потери информации при отключении расширения и заканчивая проблемами с закрытыми периодами. Рассмотрим подробно, как организовать этот процесс грамотно и безопасно.
Прежде чем приступать к кодингу, проанализируем две основные стратегии, которые обсуждались экспертами. Первая стратегия предполагает полный перенос объектов. Это позволяет максимально «очистить» основную конфигурацию и поставить её на замок. Вторая стратегия (рекомендуемая многими архитекторами) заключается в том, чтобы оставить структуры данных (таблицы) в основной конфигурации, а в расширение вынести только бизнес-логику и экранные формы.
Почему эксперты советуют оставлять данные в основной конфигурации? Дело в том, что расширение — это более гибкая, но менее надежная сущность. Если пользователь случайно удалит расширение из списка, данные во всех созданных в нем таблицах будут безвозвратно удалены на уровне СУБД. Объекты же основной конфигурации защищены механизмом реструктуризации, который предупреждает о потере данных.
Если же вы все же решили выполнить полный перенос, разберем, как сделать это программно.
Для конфигураций на базе БСП (включая ERP) наиболее «цивилизованным» способом является использование подсистемы обновления конфигурации. Вместо написания разовой обработки, которую нужно запускать вручную, мы можем интегрировать код миграции прямо в расширение. Рассмотрим, как зарегистрировать обработчик обновления внутри расширения.
В модуле объекта расширения или в специальном общем модуле необходимо перехватить событие ПриДобавленииОбработчиковОбновления. Это позволит системе автоматически запустить ваш код при первом запуске после установки расширения.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
НовыйОбработчик = Обработчики.Добавить();
НовыйОбработчик.Версия = "1.0.0.1"; // Версия вашего расширения
НовыйОбработчик.Процедура = "МойПрефикс_МиграцияДанных.ВыполнитьПереносВРасширение";
НовыйОбработчик.РежимВыполнения = "Отложенно"; // Или "Монопольно"
НовыйОбработчик.Комментарий = НСтр("ru = 'Перенос данных из основной конфигурации в расширение'");
КонецПроцедуры
Один из главных вопросов: не «поедут» ли данные в закрытых периодах при программной записи? Если вы просто будете использовать метод Записать(), система может инициировать стандартные проверки, расчеты итогов или даже вызвать ошибку доступа. Чтобы этого избежать, при записи данных в новые объекты расширения крайне важно использовать свойство ОбменДанными.Загрузка.
Проанализируем пример кода для переноса записей регистра сведений:
Процедура ВыполнитьПереносВРасширение() Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ * ИЗ РегистрСведений.Удалить_МойРегистр";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
МенеджерЗаписи = РегистрыСведений.МойРегистрВРасширении.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
// Важнейшая настройка для сохранения закрытых периодов
МенеджерЗаписи.ОбменДанными.Загрузка = Истина;
Попытка
МенеджерЗаписи.Записать();
Исключение
ЗаписьЖурналаРегистрации("ПереносДанных", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Использование ОбменДанными.Загрузка = Истина отключает большинство проверок в модулях наборов записей и позволяет записывать данные без изменения состояния документов-регистраторов, что критически важно для ERP.
Выясним еще одну важную техническую деталь: если вы создаете новый справочник или документ в расширении вручную (даже с тем же именем), у него будет другой внутренний идентификатор (GUID). Если на старый объект были ссылки в других документах или регистрах, они превратятся в «Объект не найден».
Разберем, как с этим работать:
НайтиПоСсылке(), чтобы найти все упоминания старого объекта в базе.После того как данные перенесены, не спешите удалять объекты из основной конфигурации. Рассмотрим правильную последовательность действий, чтобы минимизировать риски:
Удалить... ко всем старым объектам и реквизитам в основной конфигурации.Важный нюанс: Помните, что запросы в расширениях могут работать медленнее, если в них используются сложные связи между объектами расширения и основной конфигурации. Старайтесь избегать избыточного усложнения структуры метаданных внутри расширения.
Таким образом, мы выяснили, что перенос данных — это не просто копирование таблиц, а сложный архитектурный процесс. Оптимальным решением для крупных систем уровня ERP остается сохранение структуры данных в основной конфигурации с выносом всей функциональности в расширение.