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