К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно очистить регистр сведений в 1С 8.3

Способы программной очистки регистра сведений в 1С 8.3: набор записей, запрос, удаление по отбору. Примеры кода, ошибки и проверка результата.

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

Главный инструмент — набор записей регистра сведений с методом Записать(). Если записать пустой набор без отбора, регистр очистится целиком. Если установить отбор по измерениям или периоду — удалятся только нужные записи. Это безопаснее, чем прямое удаление через запрос, потому что платформа корректно обрабатывает блокировки и контролирует целостность.

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

Как полностью очистить регистр сведений через набор записей

Самый простой и надёжный способ — создать набор записей без отбора и записать его пустым. Платформа удалит все записи регистра одной транзакцией. Код занимает три строки и работает как для независимых регистров, так и для регистров, подчинённых регистратору (с оговорками, о которых ниже).

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

НаборЗаписей.Записать();

Метод Записать() без параметров выполняется с замещением: то, что есть в наборе (ничего), заменяет то, что есть в базе (все записи). Если нужно контролировать процесс, можно использовать Записать(Истина) — флаг замещения указан явно, что улучшает читаемость кода.

Для больших регистров (миллионы записей) такая операция может занять заметное время и заблокировать таблицу для других пользователей. Выполняйте очистку в монопольном режиме или в нерабочее время, особенно в клиент-серверных базах.

Как очистить регистр частично: отбор по измерениям и периоду

Часто требуется удалить не всё, а записи по конкретному объекту, организации или за определённый период. Для этого в наборе записей устанавливается отбор. Элементы отбора добавляются по именам измерений регистра и, для периодических регистров, по полю «Период».

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

НаборЗаписей.Отбор.Номенклатура.Установить(НужнаяНоменклатура);

НаборЗаписей.Записать();

Для периодического регистра можно ограничить удаление по дате. Отбор по периоду работает только на равенство, поэтому для диапазона дат удобнее сначала получить записи запросом, а затем удалять их в цикле или использовать несколько наборов. Альтернатива — запрос с УНИЧТОЖИТЬ недоступен: язык запросов 1С не умеет удалять данные напрямую, поэтому выборка запросом и последующая запись пустых наборов с отбором — стандартный приём.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ РАЗЛИЧНЫЕ

| КурсыВалют.Валюта КАК Валюта

|ИЗ

| РегистрСведений.КурсыВалют КАК КурсыВалют

|ГДЕ

| КурсыВалют.Период < &ГраницаПериода";

Запрос.УстановитьПараметр("ГраницаПериода", ДатаГраницы);

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

// дальнейшая обработка по каждой валюте

КонецЦикла;

Очистка регистра, подчинённого регистратору

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

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

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

НаборЗаписей.Записать();

Чтобы очистить такой регистр полностью, нужно перебрать всех регистраторов и для каждого записать пустой набор. Это медленнее, чем очистка независимого регистра, поэтому для массовой обработки стоит получить список регистраторов запросом и работать в транзакции.

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

Очистка в транзакции и обработка ошибок

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

НачатьТранзакцию();

Попытка

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

НаборЗаписей.Записать();

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ЗаписьЖурналаРегистрации("Очистка регистра",

УровеньЖурналаРегистрации.Ошибка, , ,

ОписаниеОшибки());

ВызватьИсключение;

КонецПопытки;

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

bsl
НаборЗаписей = РегистрыСведений.ИмяРегистра.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.ИмяИзмерения.Установить(ЗначениеОтбора);
НаборЗаписей.Записать(Истина); // Истина - с замещением существующих записей

Проверка результата после очистки

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ

| РегистрСведений.КурсыВалют КАК КурсыВалют";

Результат = Запрос.Выполнить().Выбрать();

Если Результат.Следующий() Тогда

Сообщить("Записей в регистре: " + Результат.КоличествоЗаписей);

КонецЕсли;

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

Контрольные точки

Как проверить результат

Количество записей запросом
Норма

Равно нулю при полной очистке или совпадает с ожидаемым остатком

Тревожный признак

Записи остались — отбор не сработал или транзакция отменена

Журнал регистрации
Норма

Нет ошибок за время выполнения операции

Тревожный признак

Ошибки блокировок или обрыва транзакции

Отчёты по данным регистра
Норма

Формируются без ошибок, итоги соответствуют ожиданиям

Тревожный признак

Пустые или некорректные итоги — удалено лишнее

Типичные ошибки при программной очистке

Чаще всего проблемы возникают не из-за самого кода, а из-за невнимательности к контексту. Ниже — ситуации, которые регулярно приводят к потере данных или бесполезной работе.

Типичные ошибки
01
Запись пустого набора без отбора вместо набора с отбором — удаляются все записи вместо нужных; всегда проверяйте, что отбор установлен до вызова Записать()
02
Очистка регистра, подчинённого регистратору, без последующего перепроведения документов — данные документов и регистра расходятся
03
Выполнение очистки без резервной копии — при ошибке в отборе данные теряются безвозвратно
04
Игнорирование планов обмена — после очистки узлы обмена получают рассинхронизированные данные
05
Запуск на рабочей базе в разгар дня — длинная транзакция блокирует пользователей и вызывает таймауты

Отдельно стоит упомянуть попытки «ускорить» очистку прямым удалением записей через Удалить() у менеджера записи в цикле. Для больших объёмов это в разы медленнее записи пустого набора и создаёт отдельную транзакцию на каждую запись. Используйте набор записей — он выполняет операцию одним SQL-запросом.

Когда лучше использовать альтернативные подходы

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

Для регулярной очистки устаревших данных (например, хранение истории только за последний год) правильнее создать регламентное задание, которое периодически удаляет записи старше заданной даты. Так база не разрастается, а операция выполняется автоматически в нерабочее время.

Сравнение вариантов

Запись пустого набора

Быстрый способ полной очистки независимого регистра; не подходит для регистра с регистратором без перебора регистраторов

Набор с отбором

Точечное удаление по измерениям и периоду; не работает с отбором по ресурсам

Цикл с менеджером записи

Позволяет удалять по любым условиям, включая ресурсы; очень медленно на больших объёмах

Регламентное задание

Автоматическая очистка устаревших данных по расписанию; требует разработки и тестирования

Итог

Что важно запомнить

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

Частые вопросы

Можно ли очистить регистр сведений запросом, как в SQL — DELETE FROM?

Нет. Язык запросов 1С предназначен только для чтения данных и не поддерживает удаление. Удаление выполняется через объектную модель: набор записей с методом Записать() или менеджер записи с методом Удалить(). Запрос используется лишь для поиска записей, которые нужно удалить.

Что произойдёт, если записать набор с отбором, не прочитав его?

Набор, который не читался из базы, считается пустым. При вызове Записать() с замещением все записи, попадающие под отбор, будут удалены. Именно на этом основан механизм очистки: читать набор перед записью не требуется.

Почему возникает ошибка при очистке регистра с регистратором без отбора?

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

Удалятся ли записи в узлах обмена после очистки центральной базы?

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

Как очистить регистр, если база файловая и монопольный режим недоступен?

Монопольный режим для записи набора не обязателен — он нужен только чтобы избежать блокировок со стороны других пользователей. В файловой базе попросите пользователей выйти или выполните очистку вне рабочего времени; при конфликте блокировок транзакция откатится, и операцию можно повторить.

Можно ли восстановить записи после случайной очистки?

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