Что происходит с записями регистра накопления при смене вида регистратора и как правильно выполнить перенос данных

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

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

Поведение платформы и СУБД при исключении регистратора

Поведение системы зависит от того, был ли тип стандартного реквизита Регистратор простым (одиночным) или составным:

  1. Простой тип регистратора. Если в метаданных регистра был указан только один регистратор (например, Документ1), а разработчик сразу заменяет его на Документ2, поле регистратора в физической таблице СУБД меняет тип с одного ссылочного типа на другой. При реструктуризации платформа пытается преобразовать значения поля, но ссылки ДокументСсылка.Документ1 не могут быть приведены к типу ДокументСсылка.Документ2. Все существующие ссылки сбрасываются в пустые значения нового типа. Так как регистратор вместе с периодом и номером строки входит в кластерный уникальный индекс таблицы движений, при наличии более одной записи по регистратору возникает ошибка СУБД: «Записи регистра стали неуникальными». В результате обновление базы данных аварийно прерывается.
  2. Составной тип регистратора. Если регистратор уже был составным или стал им в процессе, в таблице СУБД поле регистратора хранится в нескольких колонках (код типа объекта метаданных и бинарный идентификатор ссылки). Поскольку сам вид документа не удаляется из конфигурации, его внутренний код типа и идентификаторы в базе остаются валидными. Записи в физической таблице регистра сохраняются, а ссылки на документ не превращаются в «Объект не найден». Однако это создает иллюзию корректной работы, скрывая серьезные логические ошибки.

Скрытые проблемы при сохранении записей с отключенным регистратором

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

  1. Потеря управления движениями из документа. В объекте Документ1 подчиненный регистр накопления исключается из коллекции Движения. Документ больше не связан с ранее сделанными записями: при его перепроведении, отмене проведения или непосредственном удалении записи в регистре накопления останутся без изменений, превращаясь в неуправляемые «фантомные» движения.
  2. Ошибка типизации при программном доступе. Попытка прочитать или перезаписать набор записей по ссылке на старый документ завершится критической ошибкой. Метод Отбор.Регистратор.Установить() выбросит исключение «Недопустимый тип значения», так как тип ДокументСсылка.Документ1 исключен из метаданных регистратора.
  3. Ошибки при тестировании и исправлении. Штатная процедура «Тестирование и исправление» в режиме проверки логической целостности определит такие записи как некорректные и, в зависимости от выбранного действия, либо принудительно удалит их, либо вызовет системный сбой.
  4. Искажение виртуальных таблиц. Записи продолжают влиять на остатки и обороты, однако штатно пересчитать итоги или исправить данные стандартными средствами учета становится невозможно.

Пошаговый регламент безопасной замены регистратора

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

Шаг 1. Расширение состава регистраторов (Релиз 1)

Открываем конфигуратор и добавляем новый Документ2 в список регистраторов регистра накопления, обязательно оставляя включенным Документ1. Применяем изменения к базе данных. В этот момент тип регистратора гарантированно становится составным, а существующие движения старых документов остаются полностью доступными для чтения и программной перезаписи.

Шаг 2. Перенос движений на новый регистратор

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


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

Шаг 3. Контроль остатков записей по старому типу

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ ПЕРВЫЕ 1
    |    Регистр.Регистратор КАК Регистратор
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах КАК Регистр
    |ГДЕ
    |    Регистр.Регистратор ССЫЛКА Документ.Документ1";

Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
    ВызватьИсключение "В регистре еще остались движения со старым регистратором!";
КонецЕсли;

Шаг 4. Удаление старого регистратора (Релиз 2)

После того как все записи перенесены, а контрольный запрос подтвердил отсутствие записей с типом Документ1, открываем конфигуратор, снимаем флаг регистратора у Документ1 и применяем изменения конфигурации базы данных. Реструктуризация пройдет штатно, не нарушив уникальность индексов и целостность информационной базы.

← На главную