Как изменить тип измерения регистра накопления со строки на ссылку без потери данных

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе развития конфигурации 1С часто возникает ситуация, когда первоначальные проектные решения требуют пересмотра. Типичный пример — замена строкового типа измерения в регистре накопления на ссылочный тип (например, на справочник). Основная сложность заключается в том, что при простом изменении типа в Конфигураторе 1С все существующие данные в этой колонке будут безвозвратно удалены. Рассмотрим подробнее, как правильно выполнить эту операцию, сохранив целостность базы данных и корректность отчетов.

Анализ проблемы и подготовительные действия

Перед тем как приступать к изменениям, нам необходимо проанализировать структуру метаданных. Регистр накопления не является самостоятельной сущностью в плане наполнения данными — его записи (движения) формируются документами-регистраторами. Если мы просто изменим тип в регистре, но оставим старую логику в документах, любое перепроведение документа приведет к очистке данных или ошибкам. Разберем по шагам, что нужно сделать на подготовительном этапе:

  1. Создадим резервную копию информационной базы. Это обязательное условие при работе с реструктуризацией таблиц.
  2. Выявим все документы, которые являются регистраторами для данного регистра. Это можно сделать в Конфигураторе на закладке "Регистраторы" в окне редактирования регистра.
  3. Проанализируем строковые данные в текущем измерении. Если в строках записаны названия складов или контрагентов, нам нужно убедиться, что в соответствующем справочнике есть элементы с такими же именами, или подготовить алгоритм их создания.

Метод 1: Использование временного измерения (Стандартный подход)

Этот метод считается наиболее безопасным с точки зрения сохранения данных внутри транзакций 1С. Проанализируем ситуацию: нам нужно временно где-то хранить старые строковые значения, пока мы меняем тип основного поля.

Шаг 1. Создание временного поля. В Конфигураторе добавим в регистр накопления новое измерение, например, с именем ВременноеИзмерение и типом Строка. Обновим конфигурацию базы данных.

Шаг 2. Перенос данных во временное поле. Напишем и запустим обработку, которая скопирует значения из старого строкового измерения в новое. Посмотрим на пример логики такой обработки:


ВыборкаРегистраторов = РегистрыНакопления.ИмяВашегоРегистра.ВыбратьПоПериоду(ДатаНачала, ДатаКонца);
Пока ВыборкаРегистраторов.Следующий() Цикл
    НаборЗаписей = РегистрыНакопления.ИмяВашегоРегистра.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Регистратор.Установить(ВыборкаРегистраторов.Регистратор);
    НаборЗаписей.Прочитать();
    
    Для Каждого Запись Из НаборЗаписей Цикл
        Запись.ВременноеИзмерение = Запись.СтароеИзмерение;
    КонецЦикла;
    
    НаборЗаписей.Записать();
КонецЦикла;

Шаг 3. Изменение типа основного измерения. Теперь, когда данные задублированы во временном поле, мы можем смело менять тип основного измерения СтароеИзмерение со строки на нужную СправочникСсылка в Конфигураторе. После применения изменений значения в СтароеИзмерение обнулятся.

Шаг 4. Обратная конвертация данных. Теперь нам нужно перенести данные из ВременноеИзмерение обратно в СтароеИзмерение, преобразуя строку в ссылку. Выясним причину, почему это важно делать программно: нам нужно найти (или создать) элемент справочника, соответствующий строке.


// Фрагмент кода для поиска или создания ссылки
СсылкаНаОбъект = Справочники.ИмяСправочника.НайтиПоНаименованию(Запись.ВременноеИзмерение);
Если СсылкаНаОбъект.Пустая() Тогда
    // Логика создания нового элемента, если нужно
    НовыйОбъект = Справочники.ИмяСправочника.СоздатьЭлемент();
    НовыйОбъект.Наименование = Запись.ВременноеИзмерение;
    НовыйОбъект.Записать();
    СсылкаНаОбъект = НовыйОбъект.Ссылка;
КонецЕсли;
Запись.СтароеИзмерение = СсылкаНаОбъект;

Метод 2: Переименование с префиксом "Удалить"

Этот способ часто используется в типовых конфигурациях при обновлении. Рассмотрим подробнее его суть: мы не меняем тип существующего объекта, а создаем новый, помечая старый как устаревший.

  1. В Конфигураторе переименуем измерение Склад в УдалитьСклад.
  2. Создадим новое измерение с именем Склад и типом СправочникСсылка.Склады.
  3. В документах-регистраторах также добавим новые реквизиты или изменим существующие, чтобы они соответствовали новому типу.
  4. Используем обработку для переноса данных из УдалитьСклад в Склад аналогично первому методу.
  5. После проверки корректности данных старое измерение с префиксом Удалить можно будет удалить в следующем релизе.

Важность работы с документами-регистраторами

Недостаточно просто изменить данные в регистре. Проанализируем ситуацию: если пользователь перепроведет старый документ, система обратится к модулю проведения этого документа. Если в коде прописано Движение.Склад = СтрокаИзДокумента, а измерение теперь ожидает ссылку, возникнет ошибка или запись пустого значения.

Обязательно выполните следующие действия:

Работа с большими объемами данных через Наборы Записей

Если ваш регистр содержит миллионы записей, обычный перебор может привести к зависанию базы или нехватке памяти. Разберем по шагам, как оптимизировать процесс с помощью объекта РегистрНакопленияНаборЗаписей.

Вместо того чтобы выбирать все записи регистра сразу, следует обрабатывать их порциями в разрезе регистраторов. Посмотрим на пример эффективного алгоритма:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Регистратор ИЗ РегистрНакопления.ИмяРегистра";
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Набор = РегистрыНакопления.ИмяРегистра.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
    Набор.Прочитать();
    
    Для Каждого Запись Из Набор Цикл
        // Здесь логика трансформации данных
        // Например: Запись.НовоеИзмерение = ПреобразоватьСтрокуВСсылку(Запись.СтароеИзмерение);
    КонецЦикла;
    
    Если Набор.Модифицированность() Тогда
        Набор.Записать();
    КонецЕсли;
КонецЦикла;

Такой подход позволяет фиксировать изменения транзакциями по каждому документу, что значительно снижает нагрузку на таблицу транзакций SQL-сервера.

Завершающий этап: Пересчет итогов

Любое изменение измерений в регистре накопления — это серьезная реструктуризация таблиц итогов. Рассмотрим подробнее, почему это критично. Физически в базе данных 1С хранятся не только записи движений, но и рассчитанные остатки на начало каждого месяца. Если вы программно изменили значения в измерениях "в обход" стандартных механизмов проведения, таблицы итогов могут стать неактуальными.

После завершения всех манипуляций с данными необходимо выполнить:

  1. Тестирование и исправление информационной базы (пункт "Пересчет итогов").
  2. Либо через режим "1С:Предприятие" зайти в "Управление итогами" и выполнить полный пересчет для измененного регистра.

Подведем итог: изменение типа измерения — это комплексная задача, требующая не только программного переноса данных, но и корректировки логики проведения документов, а также обязательного обслуживания таблиц итогов после завершения работ. Использование временных реквизитов и объектной модели НаборЗаписей гарантирует предсказуемый результат и сохранность информации.

← На главную