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