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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

В этой статье мы подробно разберем, как эффективно очистить регистр, используя интервальный отбор, проанализируем различные подходы и выясним, какой из них лучше подходит для разных объемов данных.

Метод 1. Использование выборки и менеджера записи

Это один из самых простых и понятных способов, который подходит для небольших и средних объемов данных. Его суть заключается в получении выборки записей за период и удалении каждой записи через объект РегистрСведенийМенеджерЗаписи.

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


НачалоПериода = НачалоМесяца(ТекущаяДата());
КонецПериода = КонецМесяца(ТекущаяДата());

// Получаем выборку записей в указанном интервале
Выборка = РегистрыСведений.ИмяВашегоРегистра.Выбрать(НачалоПериода, КонецПериода);

Пока Выборка.Следующий() Цикл
    // Для каждой найденной записи получаем менеджер записи
    МенеджерЗаписи = Выборка.ПолучитьМенеджерЗаписи();
    // Удаляем запись из базы данных
    МенеджерЗаписи.Удалить();
КонецЦикла;

Важно понимать: этот метод работает последовательно. При каждой итерации цикла выполняется отдельный SQL-запрос на удаление, что может быть медленным при обработке сотен тысяч записей. Однако для оперативной очистки небольших интервалов это самый быстрый в написании код.

Метод 2. Использование набора записей с предварительным запросом

Многие начинающие разработчики пытаются установить интервал непосредственно в объекте РегистрСведенийНаборЗаписей. Здесь мы сталкиваемся с техническим ограничением платформы: отбор в наборе записей работает только на строгое равенство. Мы не можем написать Отбор.Период.Установить(Интервал), если период в регистре — это конкретный момент времени.

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

  1. Сформируем запрос к регистру с условием по периоду (ГДЕ Период МЕЖДУ &ДатаНачала И &ДатаКонца).
  2. Выберем все измерения регистра и само поле Период.
  3. В цикле по результату запроса создадим набор записей, установим точные отборы и запишем пустой набор.

Посмотрим на пример реализации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТвойРегистр.Период КАК Период,
    |   ТвойРегистр.Измерение1 КАК Измерение1
    |ИЗ
    |   РегистрСведений.ТвойРегистр КАК ТвойРегистр
    |ГДЕ
    |   ТвойРегистр.Период МЕЖДУ &Начало И &Конец";

Запрос.УстановитьПараметр("Начало", НачалоИнтервала);
Запрос.УстановитьПараметр("Конец", КонецИнтервала);

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

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

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

Метод 3. Групповое изменение реквизитов (стандартные средства БСП)

Если задача разовая и вы работаете в современной конфигурации (например, УТ 11, ERP 2, Бухгалтерия 3.0), нет необходимости писать код. В составе Библиотеки стандартных подсистем (БСП) есть мощный инструмент — обработка «Групповое изменение реквизитов».

Выясним, как ее использовать для нашей задачи:

  1. Откройте обработку (обычно находится в разделе Администрирование — Обслуживание — Корректировка данных).
  2. В поле «Изменять» выберите ваш регистр сведений.
  3. Нажмите «Добавить условие отбора». Здесь платформа позволяет использовать привычный конструктор условий, включая диапазоны «Больше», «Меньше» или «В интервале».
  4. После настройки фильтра перейдите в «Дополнительные параметры» (гиперссылка внизу) и установите флаг «В режиме записи: Удалять записи» (доступно не во всех версиях, иногда требуется включить «Режим разработчика»).
  5. Нажмите «Изменить параметры».

Этот способ безопасен, так как платформа сама сформирует оптимальные запросы и обеспечит целостность данных.

Оптимизация при больших объемах данных

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

1. Удаление порциями в транзакциях. Не пытайтесь удалить всё одним махом. Лучше делать это частями по 1000–5000 записей, фиксируя транзакцию после каждой порции. Это позволит другим пользователям работать с базой и не переполнит лог транзакций.

2. Использование явных блокировок. Перед началом программного удаления стоит установить объектную блокировку через БлокировкаДанных. Это гарантирует, что пока вы читаете данные для удаления, другой процесс не изменит их, что предотвратит возникновение Deadlocks.

3. Сжатие базы данных. После масштабной очистки данных размер файла базы данных (особенно в файловом варианте) не уменьшится автоматически. Для возврата места операционной системе необходимо выполнить операцию «Сжатие таблиц информационной базы» в режиме «Тестирование и исправление» или выполнить Shrink базы на уровне SQL-сервера.

Нюансы для периодических регистров

Если ваш регистр является периодическим, важно помнить, что поле Период технически ведет себя как измерение. Если нужно очистить все записи за месяц, а данные заносились ежедневно, вам придется либо использовать МенеджерЗаписи в цикле (Метод 1), либо четко перечислять все даты в запросе (Метод 2). Если регистр при этом не является независимым (подчинен регистратору), то очистка должна производиться через удаление или очистку движений документов-регистраторов.

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

← На главную