Как правильно добавить новое измерение в регистр накопления и закрыть исторические остатки в 1С?

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

Добавление нового измерения в существующий регистр накопления (особенно ключевой, такой как партии товаров или взаиморасчеты) — одна из наиболее ответственных задач в 1С. Главная сложность заключается в том, что в исторических движениях новое измерение остается незаполненным (содержит значение по умолчанию — пустую ссылку, 0 или пустую строку), тогда как новые документы начинают формировать движения с заполненной аналитикой. В результате регистр перестает «схлопываться» в ноль: по пустому значению зависает отрицательный остаток, а по заполненному — положительный, что приводит к разрастанию таблицы итогов и деградации производительности всей системы.

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

Причина возникновения проблемы и технические риски

Проанализируем, что происходит на уровне СУБД и платформы при добавлении измерения:

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

Вариант 1. Пакетное дозаполнение исторических движений обработкой

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

Разберем по шагам правильную механику программной перезаписи наборов записей:

  1. Отключение пересчета итогов: Перед массовой перезаписью необходимо программно отключить использование итогов для регистра, иначе при каждой записи платформа будет выполнять дорогостоящий пересчет итогов от даты документа до текущего момента.
  2. Использование режима загрузки: Для набора записей выставляется признак ОбменДанными.Загрузка = Истина. Это отключает прикладные проверки в модуле набора записей и предотвращает ненужные перерасчеты.
  3. Пакетная обработка транзакций: Дозаполнение обязательно разделяется на порции (например, помесячно или по 500–1000 документов) с явной фиксацией транзакций для исключения блокировок СУБД.
  4. Полный пересчет итогов: После завершения работы обработки выполняется регламентный пересчет итогов регистра накопления.

Посмотрим на пример кода обработки наборов записей:


// 1. Отключаем использование итогов перед массовой обработкой
РегистрыНакопления.ВзаиморасчетыСКонтрагентами.УстановитьИспользованиеИтогов(Ложь);

ВыборкаДокументов = Документы.РеализацияТоваровУслуг.Выбрать(ДатаНачала, ДатаОкончания);

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

// 2. Включаем итоги обратно и выполняем полный пересчет
РегистрыНакопления.ВзаиморасчетыСКонтрагентами.УстановитьИспользованиеИтогов(Истина);
РегистрыНакопления.ВзаиморасчетыСКонтрагентами.ПересчитатьИтоги();

Вариант 2. Корректировка остатков на фиксированную дату

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

Рассмотрим порядок действий:

  1. Выбирается дата перехода (например, начало нового финансового года или отчетного месяца).
  2. Документом КорректировкаЗаписейРегистров (или универсальной корректировкой движений) списываются все остатки без заполненного измерения (расход с пустым значением) и одновременно приходуются с заполненным новым измерением на ту же сумму и количество.
  3. Все документы и движения до даты корректировки жестко закрываются для редактирования через дату запрета изменения данных.

Ограничение метода: При формировании отчетов за периоды, пересекающие дату корректировки, обороты по приходу и расходу будут завышены на величину переброски остатков, что требует адаптации отчетов.

Вариант 3. Создание параллельного регистра и подписок на события

В типовых и сильно доработанных конфигурациях (например, УПП или ERP) прямое изменение ключевых регистров влечет необходимость переписывания сотен общих модулей, механизмов закрытия месяца, расчетов курсовых разниц и проведения документов. Чтобы этого избежать, часто применяется архитектурный паттерн с выносом аналитики в отдельный регистр.

Разберем реализацию этого подхода:

  1. Создается новый собственный регистр накопления с необходимым составом измерений и ресурсов.
  2. Вводятся начальные остатки в новый регистр на дату запуска.
  3. Создается ПодпискаНаСобытие на запись наборов записей или проведение документов основного регистра. В обработчике подписки данные транслируются в новый регистр с параллельным вычислением новой аналитики из реквизитов документа или строк табличных частей.
  4. Отчеты, которым требуется углубленная аналитика, перенаправляются на чтение данных из нового регистра. Типовой контур закрытия месяца и расчетов продолжает работать стабильно без модификации типового регистра.

Рекомендации по выбору решения

Выясним, какой вариант предпочесть в зависимости от условий:

  1. Если конфигурация полностью снята с поддержки, логика проведения документов уже переписана, а объем базы позволяет провести регламентные работы — используем Вариант 1 с отключением итогов и пакетным обновлением.
  2. Если исторический период закрыт для аудита, а база содержит данные за много лет — используем Вариант 2 с вводом остатков на дату и установкой даты запрета.
  3. Если требуется минимизировать риски поломки типовых расчетных модулей конфигурации — оптимальным является Вариант 3 с параллельным регистром накопления.
← На главную