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