Перенос нетипового функционала в расширение — одна из самых частых задач при обновлении сильно кастомизированных баз, таких как перенос изменений из «1С:Бухгалтерия предприятия 2.0» в редакцию 3.0. Основная сложность заключается в том, что платформа 1С не позволяет напрямую объединять файлы конфигурации с расширениями через стандартный механизм сравнения/объединения. Более того, простое создание аналогичного реквизита в расширении приведет к потере данных, так как для платформы это будет совершенно новый объект с другим внутренним идентификатором. Разберем подробно, как правильно организовать этот процесс, сохранив данные и вернув конфигурацию на полную поддержку.
Проанализируем техническую сторону вопроса. Когда мы добавляем реквизит в основную конфигурацию, платформа создает соответствующее поле в таблице СУБД (например, _Fld1234). Если мы создаем реквизит в расширении, платформа создает другое поле (например, _Fld1234_Ext1). Даже если имена и типы данных совпадают, физически это разные колонки в базе данных. Поэтому «перенос» реквизита — это всегда двухэтапный процесс: создание структуры в расширении и физическая миграция данных программным способом.
Рассмотрим ситуацию, когда необходимо перенести изменения из старой базы 2.0 в новую 3.0, не снимая последнюю с поддержки. Разберем этот процесс по шагам:
Доп_ВажныйПараметр).Если база уже работает на 3.0, но изменения все еще находятся в основной конфигурации, рассмотрим алгоритм «бесшовного» переноса. Выясним, как написать код для миграции данных. Предположим, у нас есть документ РеализацияТоваровУслуг и добавленный в него реквизит НомерКонтейнера.
Разберем пример кода для миграции:
Процедура ПеренестиДанныеВРасширение()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка,
| НомерКонтейнера КАК СтароеЗначение
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| НомерКонтейнера <> """""; // Условие, чтобы не обрабатывать пустые
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Объект = Выборка.Ссылка.ПолучитьОбъект();
// Реквизит_Расширения - это имя нового реквизита, созданного в расширении
Объект.Реквизит_Расширения = Выборка.СтароеЗначение;
Попытка
Объект.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Ошибка при записи объекта " + Выборка.Ссылка + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
КонецПроцедуры
Важный момент: При записи объекта в режиме Запись (не проведение!) данные сохранятся в новой колонке расширения. Проанализируйте ситуацию с проведением: если реквизит влияет на движения регистров, вам может потребоваться перепроведение документов или аналогичный перенос данных в расширениях регистров.
Рассмотрим более хитрый способ, который обсуждался программистами для сохранения идентификаторов (хотя он не отменяет логику работы колонок SQL, он помогает при массовом переносе метаданных):
.cfe..cf).В этом случае в расширении окажутся реквизиты, «привязанные» к объектам, но физически данные все равно нужно будет перекладывать, так как при возврате основной конфигурации к типовой (пункт 5) старые колонки в SQL будут удалены вместе с данными.
Проанализируем ситуацию: стоит ли вообще использовать расширение? Если ваши реквизиты носят справочный характер и не требуют сложной логики в запросах, рассмотрите механизм Дополнительных реквизитов и сведений из состава Библиотеки Стандартных Подсистем (БСП).
Преимущества этого подхода:
Однако помните, что обращение к доп. реквизитам в коде и запросах происходит медленнее и выглядит сложнее, чем работа с прямым реквизитом объекта.
При работе с расширениями всегда помните о следующих рисках:
Таким образом, мы выяснили, что прямого способа «перетащить» реквизит из основной конфигурации в расширение простым кликом мыши не существует. Оптимальный путь — это создание структуры в расширении и программная миграция данных с помощью внешней обработки. Это гарантирует сохранность информации и чистоту основной конфигурации.