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