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