Удаление записей регистра сведений: набор, отмена проведения, итоги

· 10 мин

Содержание

Способ очистки регистра сведений зависит от одного свойства — режима записи. Если регистр независимый, записи удаляют набором записей без отбора. Если он подчинён регистратору, напрямую очистить его нельзя: записи принадлежат документам, и чистят их отменой проведения или отбором по регистратору.

Разберём оба случая на рабочем коде, покажем выборочное удаление по измерению, периодические регистры со срезом последних и объясним, почему прямой DELETE в SQL-таблицу регистра ломает базу. Операции необратимые, поэтому перед любой из них — резервная копия.

Массовое удаление записей необратимо. Сделайте резервную копию базы и отработайте способ на копии, прежде чем запускать на рабочей.

Перед очисткой регистра
Выполнено: 0 / 5

Независимый регистр или подчинённый регистратору

Откройте регистр в конфигураторе: Конфигурация → Регистры сведений → ВашРегистр. В палитре свойств найдите Режим записи. Значений два:

  • 🔹 Независимый — записи вводятся вручную, обработкой или кодом, своей жизни от документов не имеют.
  • 🔹 Подчинение регистратору — у регистра появляется стандартное измерение Регистратор, каждая запись привязана к документу, который её сформировал при проведении.

От этого зависит метод:

Режим записиЧем чистить
НезависимыйНабор записей без отбора (весь регистр) или с отбором (часть)
Подчинён регистраторуОтмена проведения документов либо набор с отбором по Регистратор

Узнать режим прямо из пользовательского режима без конфигуратора можно по косвенному признаку: если в форме списка регистра есть колонка Регистратор и записи нельзя добавить вручную (нет кнопки «Создать») — регистр подчинён регистратору.

Какой у вас регистр сведений?

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

Самый быстрый и поддерживаемый способ стереть независимый регистр целиком — создать пустой набор записей и записать его без отбора. Платформа трактует это как «заместить все записи регистра пустым содержимым».

НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
НаборЗаписей.Записать(); // отбор не задан → весь регистр замещается пустым набором

Параметр Замещение метода Записать() по умолчанию Истина — именно он удаляет существующие записи, попадающие под отбор набора. Отбор не задан, значит под него попадает весь регистр, а писать нечего — в итоге регистр пуст.

Запускают такой код через обработку с модулем, либо разово — из консоли кода (внешней обработки «Консоль запросов и кода», «Выполнение произвольного кода» и аналогов). Писать регистр нужно в транзакции, если в модуле набора есть подписки или проверки:

Если в модуле набора записей регистра есть обработчик ПередЗаписью или ПриЗаписи, он сработает и при очистке. Проверьте, что в нём нет логики, которая упадёт на пустом наборе.

Для периодического регистра этот же код очистит все периоды — отбор по периоду так же не задан.

Если регистр входит в план обмена, запись набора регистрируется к выгрузке, и очистка уедет в другие узлы распределённой базы. Когда чистить нужно только в одной базе, отключите регистрацию изменений на время операции: Набор.ОбменДанными.Загрузка = Истина; перед Записать().

Удаление записей, подчинённых регистратору

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

1. Отмена проведения документов. Записи регистра создаются при проведении, поэтому их штатно убирает отмена проведения. В пользовательском режиме: Все функции → Стандартные → Проведение документов, вкладка Отмена проведения. Отберите нужные документы по типу и периоду и запустите — движения по всем регистрам этих документов, включая регистр сведений , будут удалены.

Команду Все функции включают один раз: Главное меню (значок ▾ слева вверху) → Сервис → Параметры → Отображать команду «Все функции».

2. Отбор по регистратору в коде. Если нужно стереть записи, не трогая сами документы, пройдите по регистраторам и запишите пустой набор на каждого:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|   Т.Регистратор КАК Регистратор
|ИЗ
|   РегистрСведений.ШтрихкодыНоменклатуры КАК Т";
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    Набор = РегистрыСведений.ШтрихкодыНоменклатуры.СоздатьНаборЗаписей();
    Набор.Отбор.Регистратор.Установить(Выборка.Регистратор);
    Набор.Записать(); // замещение по умолчанию — записи этого регистратора удаляются
КонецЦикла;

3. Удаление самих документов. Если документы-регистраторы вам тоже не нужны, пометьте их на удаление и запустите Операции → Удаление помеченных объектов (или Все функции → Стандартные → Удаление помеченных объектов). При удалении документа платформа убирает и все его движения, включая записи регистра сведений. Контроль ссылок не даст удалить документ , на который ссылаются другие объекты, — это защита от битых ссылок.

Отмена проведения перезапишет движения документа и по другим регистрам (накопления, бухгалтерии). Если вам нужен только один регистр сведений — используйте код с отбором по регистратору, а не массовую отмену проведения.

Какой из трёх способов выбрать:

Что нужноСпособ
Убрать записи, документы оставитьОтмена проведения или код с отбором по регистратору
Убрать только записи этого регистра, движения по другим — сохранитьКод с отбором по Регистратор
Убрать и записи, и сами документыПометка на удаление + удаление помеченных объектов

Выборочное удаление по измерению

Чаще нужно убрать не весь регистр, а записи по одному контрагенту, номенклатуре или дате. Для этого устанавливают отбор по измерению перед записью пустого набора.

Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(СсылкаНаНоменклатуру);
Набор.Записать(); // удалит записи только по этой номенклатуре

Отбор доступен по любому измерению независимого регистра, а у периодического — ещё и по периоду:

Набор = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
Набор.Отбор.Валюта.Установить(СсылкаНаВалюту);
Набор.Отбор.Период.Установить(Дата(2025, 1, 1)); // одна конкретная запись на дату
Набор.Записать();

Удалить диапазон периодов одним набором нельзя — отбор по периоду задаёт равенство. Чтобы снести записи за интервал, выберите их запросом и пройдите циклом, устанавливая Отбор.Период на каждую дату.

Для разовой ручной чистки нескольких строк проще открыть форму списка регистра в пользовательском режиме, выделить строки и удалить клавишей Delete — но только если регистр независимый и доступно интерактивное изменение.

Интерактивное удаление зависит от двух вещей. Первое — у роли пользователя должно быть право Редактирование (или Интерактивное удаление) на этот регистр; у типовых регистров настроек оно часто закрыто намеренно. Второе — у регистра должно быть разрешено интерактивное добавление записей. Если удалить строку в списке не выходит, а право есть, значит механизм заполняет регистр кодом, и чистить его нужно тоже кодом, а не руками.

Групповая обработка «Изменение реквизитов» записи регистра не удаляет — она только меняет значения в существующих строках. Для удаления всё равно нужен набор записей.

Прямой SQL к таблицам базы: почему так делать нельзя

Запрос DELETE FROM _InfoRgNNNN напрямую в SQL Server или PostgreSQL кажется самым быстрым способом. На деле это самый опасный путь, и вот почему:

  • 🔸 Имена таблиц скрыты. Физическое имя _InfoRgNNNN не совпадает с именем регистра, меняется при реструктуризации и ничем не гарантировано.
  • 🔸 Ломаются итоги среза последних. У периодического регистра платформа хранит кэш итогов в отдельной таблице. Прямой DELETE чистит основную таблицу, но не итоги — срез последних начнёт возвращать удалённые значения.
  • 🔸 Нет блокировок и журналирования 1С. Изменение в обход платформы не попадёт в журнал регистрации, не учтёт регламентные блокировки, может разойтись с кэшем сервера 1С.
  • 🔸 Это нарушение условий поддержки. Прямое изменение таблиц базы фирма 1С относит к недопустимым операциям — после такого вмешательства по инциденту откажут.

Если регистр большой и штатное удаление идёт долго, правильный путь — очищать пакетами в коде 1С (по частям, с коммитом транзакций), а не лезть в СУБД напрямую.

Консоль запросов (внешняя обработка) данные не удаляет — язык запросов 1С умеет только читать. Для удаления всё равно нужен набор записей в коде. «Очистить через консоль запросов» означает: найти записи запросом, а стереть — кодом.

Порционное удаление больших регистров

Запись одного набора на весь регистр с миллионами строк создаёт одну длинную транзакцию: она долго держит блокировки, раздувает лог транзакций СУБД и может упасть по таймауту. Правильный приём — чистить порциями, фиксируя каждую пачку отдельной транзакцией.

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

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

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
    Набор.Отбор.Номенклатура.Установить(Выборка.Номенклатура);
    Набор.Записать();
КонецЦикла;

Повторяйте запуск, пока запрос не перестанет возвращать строки. Такой цикл не держит одну гигантскую транзакцию и переносится без потери прогресса: уже удалённое повторно не всплывёт.

Не оборачивайте весь проход в одну НачатьТранзакцию() — смысл порций как раз в коротких транзакциях. Пусть каждая запись набора коммитится сама.

Для регистра, подчинённого регистратору, порцией выступают регистраторы: тот же приём, что в разделе про отмену проведения, но с ПЕРВЫЕ 1000 в запросе и повторными прогонами.

Периодические регистры, срез последних и итоги

У периодического регистра сведений, кроме основной таблицы, есть виртуальные таблицы СрезПоследних и СрезПервых. «Очистить срез» отдельно нельзя — это не хранимые данные, а вычисляемый на лету результат. Как только вы удалите записи из регистра, срезы начнут возвращать пусто.

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

При записи набора через Записать() итоги среза пересчитываются платформой автоматически. Вручную их чистить не нужно. Это ещё один довод против прямого SQL — он как раз оставляет итоги рассинхронизированными.

Если итоги среза всё же разошлись с данными (например, после аварийного завершения или некорректного вмешательства в СУБД), их пересчитывают через конфигуратор: Администрирование → Тестирование и исправление → Пересчёт итогов. Эта процедура приводит итоги в соответствие с фактическими записями по всем регистрам базы.

У регистра сведений нет пользовательской команды «Управление итогами», как у регистров накопления. Пересчёт доступен только из тестирования и исправления в конфигураторе.

Что проверить после очистки

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

  1. Срез последних возвращает пусто. Откройте отчёт или обработку, которая читает СрезПоследних регистра, и убедитесь, что данных нет (или остались только нужные).
  2. Регистр не наполнился заново. Обмен данными, регламентное задание или проведение документов по расписанию могут восстановить записи через минуты. Если чистили перед выгрузкой — отключите обмен на время.
  3. Нет битых ссылок. Если на записи регистра опирались другие механизмы (например, подстановка цен), проверьте, что документы и отчёты не падают с ошибкой.
  4. Итоги согласованы. Для периодического регистра с включёнными итогами достаточно того, что записывали набором; после прямого вмешательства в СУБД — обязательно Пересчёт итогов.

Остановка сеансов и монопольные операции здесь не требуются: запись набора и отмена проведения работают в обычном многопользовательском режиме. Тестирование и исправление в конфигураторе — другое дело: Пересчёт итогов требует монопольного доступа, поэтому его запускают, когда в базе никто не работает.

Можно ли очистить регистр сведений без конфигуратора?
Да. Независимый регистр чистят через внешнюю обработку с кодом (пустой набор записей) или удалением строк прямо в форме списка. Подчинённый регистратору — отменой проведения документов через Все функции → Стандартные → Проведение документов.
Почему пустой набор без отбора не записывается для подчинённого регистра?
Потому что у такого регистра записи принадлежат документу, и платформа при записи требует значение измерения Регистратор. Без отбора по регистратору запись не пройдёт — задайте отбор или отмените проведение документа.
Как удалить записи за период, а не целиком?
Отбор по периоду задаёт равенство конкретной дате, диапазон одним набором не удалить. Выберите записи запросом с условием по периоду, затем пройдите циклом и запишите пустой набор на каждую дату из выборки.
Восстановятся ли данные после очистки?
Сами по себе — нет, удаление необратимо, вернуть можно только из резервной копии. Но записи могут появиться заново, если регистр наполняется обменом, регламентным заданием или при проведении документов. На время чистки такие механизмы лучше отключить.
Нужно ли пересчитывать итоги после удаления набором?
Нет. При записи набора платформа пересчитывает итоги среза автоматически. Ручной Пересчёт итогов в тестировании и исправлении нужен только если данные меняли в обход платформы — например, прямым SQL.