Удаление записей регистра сведений: набор, отмена проведения, итоги
Содержание
Способ очистки регистра сведений зависит от одного свойства — режима записи. Если регистр независимый, записи удаляют набором записей без отбора. Если он подчинён регистратору, напрямую очистить его нельзя: записи принадлежат документам, и чистят их отменой проведения или отбором по регистратору.
Разберём оба случая на рабочем коде, покажем выборочное удаление по измерению, периодические регистры со срезом последних и объясним, почему прямой DELETE в SQL-таблицу регистра ломает базу. Операции необратимые, поэтому перед любой из них — резервная копия.
Массовое удаление записей необратимо. Сделайте резервную копию базы и отработайте способ на копии, прежде чем запускать на рабочей.
Независимый регистр или подчинённый регистратору
Откройте регистр в конфигураторе: Конфигурация → Регистры сведений → ВашРегистр. В палитре свойств найдите Режим записи. Значений два:
- 🔹 Независимый — записи вводятся вручную, обработкой или кодом, своей жизни от документов не имеют.
- 🔹 Подчинение регистратору — у регистра появляется стандартное измерение
Регистратор, каждая запись привязана к документу, который её сформировал при проведении.
От этого зависит метод:
| Режим записи | Чем чистить |
|---|---|
| Независимый | Набор записей без отбора (весь регистр) или с отбором (часть) |
| Подчинён регистратору | Отмена проведения документов либо набор с отбором по Регистратор |
Узнать режим прямо из пользовательского режима без конфигуратора можно по косвенному признаку: если в форме списка регистра есть колонка Регистратор и записи нельзя добавить вручную (нет кнопки «Создать») — регистр подчинён регистратору.
Полная очистка независимого регистра набором записей
Самый быстрый и поддерживаемый способ стереть независимый регистр целиком — создать пустой набор записей и записать его без отбора. Платформа трактует это как «заместить все записи регистра пустым содержимым».
НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
НаборЗаписей.Записать(); // отбор не задан → весь регистр замещается пустым набором
Параметр Замещение метода Записать() по умолчанию Истина — именно он удаляет существующие записи, попадающие под отбор набора. Отбор не задан, значит под него попадает весь регистр, а писать нечего — в итоге регистр пуст.
Запускают такой код через обработку с модулем, либо разово — из консоли кода (внешней обработки «Консоль запросов и кода», «Выполнение произвольного кода» и аналогов). Писать регистр нужно в транзакции, если в модуле набора есть подписки или проверки:
Если в модуле набора записей регистра есть обработчик ПередЗаписью или ПриЗаписи, он сработает и при очистке. Проверьте, что в нём нет логики, которая упадёт на пустом наборе.
Для периодического регистра этот же код очистит все периоды — отбор по периоду так же не задан.
Если регистр входит в план обмена, запись набора регистрируется к выгрузке, и очистка уедет в другие узлы распределённой базы. Когда чистить нужно только в одной базе, отключите регистрацию изменений на время операции: Набор.ОбменДанными.Загрузка = Истина; перед Записать().
Удаление записей, подчинённых регистратору
Пустой набор без отбора для такого регистра записать не выйдет: платформа при записи потребует значение измерения Регистратор. Варианта два.
1. Отмена проведения документов. Записи регистра создаются при проведении, поэтому их штатно убирает отмена проведения. В пользовательском режиме: Все функции → Стандартные → Проведение документов, вкладка Отмена проведения. Отберите нужные документы по типу и периоду и запустите — движения по всем регистрам этих документов, включая регистр сведений
, будут удалены.
Команду Все функции включают один раз: Главное меню (значок ▾ слева вверху) → Сервис → Параметры → Отображать команду «Все функции».
2. Отбор по регистратору в коде. Если нужно стереть записи, не трогая сами документы, пройдите по регистраторам и запишите пустой набор на каждого:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| Т.Регистратор КАК Регистратор
|ИЗ
| РегистрСведений.ШтрихкодыНоменклатуры КАК Т";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Набор = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
Набор.Записать(); // замещение по умолчанию — записи этого регистратора удаляются
КонецЦикла;
3. Удаление самих документов. Если документы-регистраторы вам тоже не нужны, пометьте их на удаление и запустите Операции → Удаление помеченных объектов (или Все функции → Стандартные → Удаление помеченных объектов). При удалении документа платформа убирает и все его движения, включая записи регистра сведений. Контроль ссылок не даст удалить документ
, на который ссылаются другие объекты, — это защита от битых ссылок.
Отмена проведения перезапишет движения документа и по другим регистрам (накопления, бухгалтерии). Если вам нужен только один регистр сведений — используйте код с отбором по регистратору, а не массовую отмену проведения.
Какой из трёх способов выбрать:
| Что нужно | Способ |
|---|---|
| Убрать записи, документы оставить | Отмена проведения или код с отбором по регистратору |
| Убрать только записи этого регистра, движения по другим — сохранить | Код с отбором по Регистратор |
| Убрать и записи, и сами документы | Пометка на удаление + удаление помеченных объектов |
Выборочное удаление по измерению
Чаще нужно убрать не весь регистр, а записи по одному контрагенту, номенклатуре или дате. Для этого устанавливают отбор по измерению перед записью пустого набора.
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(СсылкаНаНоменклатуру);
Набор.Записать(); // удалит записи только по этой номенклатуре
Отбор доступен по любому измерению независимого регистра, а у периодического — ещё и по периоду:
Набор = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
Набор.Отбор.Валюта.Установить(СсылкаНаВалюту);
Набор.Отбор.Период.Установить(Дата(2025, 1, 1)); // одна конкретная запись на дату
Набор.Записать();
Удалить диапазон периодов одним набором нельзя — отбор по периоду задаёт равенство. Чтобы снести записи за интервал, выберите их запросом и пройдите циклом, устанавливая Отбор.Период на каждую дату.
Для разовой ручной чистки нескольких строк проще открыть форму списка регистра в пользовательском режиме, выделить строки и удалить клавишей Delete — но только если регистр независимый и доступно интерактивное изменение.
Интерактивное удаление зависит от двух вещей. Первое — у роли пользователя должно быть право Редактирование (или Интерактивное удаление) на этот регистр; у типовых регистров настроек оно часто закрыто намеренно. Второе — у регистра должно быть разрешено интерактивное добавление записей. Если удалить строку в списке не выходит, а право есть, значит механизм заполняет регистр кодом, и чистить его нужно тоже кодом, а не руками.
Групповая обработка «Изменение реквизитов» записи регистра не удаляет — она только меняет значения в существующих строках. Для удаления всё равно нужен набор записей.
Прямой SQL к таблицам базы: почему так делать нельзя
Запрос DELETE FROM _InfoRgNNNN напрямую в SQL Server или PostgreSQL кажется самым быстрым способом. На деле это самый опасный путь, и вот почему:
- 🔸 Имена таблиц скрыты. Физическое имя
_InfoRgNNNNне совпадает с именем регистра, меняется при реструктуризации и ничем не гарантировано. - 🔸 Ломаются итоги среза последних. У периодического регистра платформа хранит кэш итогов в отдельной таблице. Прямой
DELETEчистит основную таблицу, но не итоги — срез последних начнёт возвращать удалённые значения. - 🔸 Нет блокировок и журналирования 1С. Изменение в обход платформы не попадёт в журнал регистрации, не учтёт регламентные блокировки, может разойтись с кэшем сервера 1С.
- 🔸 Это нарушение условий поддержки. Прямое изменение таблиц базы фирма 1С относит к недопустимым операциям — после такого вмешательства по инциденту откажут.
Если регистр большой и штатное удаление идёт долго, правильный путь — очищать пакетами в коде 1С (по частям, с коммитом транзакций), а не лезть в СУБД напрямую.
Консоль запросов (внешняя обработка) данные не удаляет — язык запросов 1С умеет только читать. Для удаления всё равно нужен набор записей в коде. «Очистить через консоль запросов» означает: найти записи запросом, а стереть — кодом.
Порционное удаление больших регистров
Запись одного набора на весь регистр с миллионами строк создаёт одну длинную транзакцию: она долго держит блокировки, раздувает лог транзакций СУБД и может упасть по таймауту. Правильный приём — чистить порциями, фиксируя каждую пачку отдельной транзакцией.
Для независимого регистра удобно идти по значениям ведущего измерения. Выбираем порцию ключей, по каждому пишем пустой набор:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ ПЕРВЫЕ 1000
| Т.Номенклатура КАК Номенклатура
|ИЗ
| РегистрСведений.ЦеныНоменклатуры КАК Т";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
Набор.Записать();
КонецЦикла;
Повторяйте запуск, пока запрос не перестанет возвращать строки. Такой цикл не держит одну гигантскую транзакцию и переносится без потери прогресса: уже удалённое повторно не всплывёт.
Не оборачивайте весь проход в одну НачатьТранзакцию() — смысл порций как раз в коротких транзакциях. Пусть каждая запись набора коммитится сама.
Для регистра, подчинённого регистратору, порцией выступают регистраторы: тот же приём, что в разделе про отмену проведения, но с ПЕРВЫЕ 1000 в запросе и повторными прогонами.
Периодические регистры, срез последних и итоги
У периодического регистра сведений, кроме основной таблицы, есть виртуальные таблицы СрезПоследних и СрезПервых. «Очистить срез» отдельно нельзя — это не хранимые данные, а вычисляемый на лету результат. Как только вы удалите записи из регистра, срезы начнут возвращать пусто.
Отдельная сущность — итоги среза последних/первых. Они включаются свойствами регистра Разрешить итоги среза последних и Разрешить итоги среза первых и кэшируются платформой для ускорения запросов. Важный момент:
При записи набора через Записать() итоги среза пересчитываются платформой автоматически. Вручную их чистить не нужно. Это ещё один довод против прямого SQL — он как раз оставляет итоги рассинхронизированными.
Если итоги среза всё же разошлись с данными (например, после аварийного завершения или некорректного вмешательства в СУБД), их пересчитывают через конфигуратор: Администрирование → Тестирование и исправление → Пересчёт итогов. Эта процедура приводит итоги в соответствие с фактическими записями по всем регистрам базы.
У регистра сведений нет пользовательской команды «Управление итогами», как у регистров накопления. Пересчёт доступен только из тестирования и исправления в конфигураторе.
Что проверить после очистки
После удаления записей пройдитесь по короткому списку — он ловит типичные последствия массовой чистки:
- Срез последних возвращает пусто. Откройте отчёт или обработку, которая читает
СрезПоследнихрегистра, и убедитесь, что данных нет (или остались только нужные). - Регистр не наполнился заново. Обмен данными, регламентное задание или проведение документов по расписанию могут восстановить записи через минуты. Если чистили перед выгрузкой — отключите обмен на время.
- Нет битых ссылок. Если на записи регистра опирались другие механизмы (например, подстановка цен), проверьте, что документы и отчёты не падают с ошибкой.
- Итоги согласованы. Для периодического регистра с включёнными итогами достаточно того, что записывали набором; после прямого вмешательства в СУБД — обязательно
Пересчёт итогов.
Остановка сеансов и монопольные операции здесь не требуются: запись набора и отмена проведения работают в обычном многопользовательском режиме. Тестирование и исправление в конфигураторе — другое дело: Пересчёт итогов требует монопольного доступа, поэтому его запускают, когда в базе никто не работает.
Можно ли очистить регистр сведений без конфигуратора?
Все функции → Стандартные → Проведение документов.Почему пустой набор без отбора не записывается для подчинённого регистра?
Регистратор. Без отбора по регистратору запись не пройдёт — задайте отбор или отмените проведение документа.Как удалить записи за период, а не целиком?
Восстановятся ли данные после очистки?
Нужно ли пересчитывать итоги после удаления набором?
Пересчёт итогов в тестировании и исправлении нужен только если данные меняли в обход платформы — например, прямым SQL.