Как правильно удалить записи регистра сведений Объекты доступа документов в 1С:УТ 10.3

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

В процессе работы с конфигурацией «Управление торговлей» редакции 10.3 системный администратор и программист часто сталкиваются с разрастанием технических регистров. Одним из таких является независимый непериодический регистр сведений ОбъектыДоступаДокументов. В данной статье мы разберем, как очистить этот регистр от лишних записей, особенно для тех документов, которые уже помечены на удаление, и как сделать это максимально эффективно, не нарушая работу системы.

Для чего нужен регистр Объекты доступа документов

Прежде чем приступать к удалению, проанализируем назначение этого объекта. Данный регистр является ключевым звеном механизма RLS (Record Level Security) — ограничения прав доступа на уровне записей. В нем хранится информация о том, к каким объектам доступа (например, группам контрагентов или складов) относится конкретный документ. На основании этих данных система мгновенно определяет, имеет ли право текущий пользователь видеть этот документ в списке или открывать его.

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

Разбор первой ситуации: удаление через полный перебор записей

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


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

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

  1. Потребление памяти: Метод НаборЗаписей.Прочитать() без установленного отбора загружает ВЕСЬ регистр в оперативную память сервера или компьютера. Если в регистре миллионы записей, это приведет к ошибке Недостаточно памяти и аварийному завершению работы.
  2. Блокировки: Пока выполняется чтение и цикл, на таблицу регистра может накладываться S-блокировка, которая не позволит другим пользователям проводить документы или изменять права доступа.
  3. Риск потери данных: Если в процессе перебора в памяти кто-то изменит запись в базе, при итоговом методе Записать() вы можете перезаписать актуальные данные устаревшими.

Оптимальное решение: использование запроса и пустого набора записей

Теперь разберем более профессиональный и быстрый метод. Вместо того чтобы тянуть все данные в память, мы сначала выясним с помощью запроса, какие именно документы требуют очистки, а затем точечно удалим записи только по ним. Для удаления мы будем использовать запись «пустого набора» с установленным отбором.

Рассмотрим алгоритм действий:


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

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

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

Почему этот способ лучше?

Борьба с «битыми» ссылками (Объект не обнаружен)

Часто в технических регистрах остаются записи, ссылающиеся на документы, которые были удалены непосредственно (через Удалить() вместо УстановитьПометкуУдаления()). В интерфейсе такие записи выглядят как <Объект не обнаружен>. Обычное обращение через точку ДокументСсылка.ПометкаУдаления для них вернет Ложь или вызовет ошибку, так как самого объекта в базе уже нет.

Выясним, как найти и удалить такие записи. Для этого в запросе нужно использовать проверку на наличие ссылки в таблице самого документа через ЛЕВОЕ СОЕДИНЕНИЕ или проверку на NULL в условиях:


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

Условие Регистр.ДокументСсылка.Ссылка ЕСТЬ NULL сработает именно для тех записей, где ссылка в регистре есть, а самого документа в базе данных уже не существует. Эти «хвосты» обязательно нужно вычищать для поддержания целостности базы.

Рекомендации по удалению в больших базах

Если в вашем регистре накопились сотни тысяч лишних записей, выполнение удаления даже правильным способом может привести к резкому росту файла лога транзакций (.ldf в MS SQL Server). Чтобы избежать зависания системы, проанализируем следующие рекомендации:

  1. Пакетная обработка: Фиксируйте транзакции небольшими порциями. В 1С это можно сделать, просто выполняя удаление в цикле, но если вы явно открываете транзакцию через НачатьТранзакцию(), делайте ЗафиксироватьТранзакцию() каждые 1000 итераций.
  2. Регламентное задание: Если удаление записей занимает длительное время, лучше вынести этот код в регламентное задание и запускать его ночью, когда нагрузка на сервер минимальна.
  3. Использование Менеджера записи: Хотя для массового удаления эффективнее НаборЗаписей, для точечного удаления одной строки, если известны все измерения, можно использовать МенеджерЗаписи. Однако в контексте очистки «по документу» набор с отбором остается лидером по производительности.

Подведем итог: очистка регистра ОбъектыДоступаДокументов — важная процедура обслуживания 1С:УТ 10.3. Используя связку Запрос + НаборЗаписей с отбором, мы обеспечиваем стабильную работу системы и корректную работу механизмов прав доступа без лишней нагрузки на сервер.

← На главную