В процессе сопровождения конфигураций на платформе 1С:Предприятие 8.3, таких как ЗУП 3.1, часто возникает необходимость автоматизировать очистку базы от ненужных данных. Просто вызвать удаление недостаточно — нужно соблюсти ссылочную целостность, чтобы не превратить базу в набор «битых» ссылок. В этой статье мы подробно разберем, как программно реализовать удаление объектов, учитывая зависимости и используя современные возможности платформы и Библиотеки стандартных подсистем (БСП). Если стоит задача полностью очистить базу от сведений конкретного юридического лица с автоматическим контролем ссылочной целостности, применяется обработка для выборочного удаления организации из баз 1С.
Начнем с классического способа, который предоставляет сама платформа. Для этого нам понадобятся два основных инструмента: поиск помеченных объектов и сам метод удаления с контролем. Рассмотрим базовый алгоритм, который позволяет не только запустить процесс, но и получить обратную связь о том, какие объекты не удалось удалить.
Проанализируем следующий пример кода:
// Шаг 1. Получаем массив всех объектов, помеченных на удаление
МассивПомеченных = НайтиПомеченныеНаУдаление();
// Шаг 2. Инициализируем переменную для хранения объектов, которые не удалятся
ТаблицаНайденныхСсылок = Новый ТаблицаЗначений;
// Шаг 3. Вызываем удаление.
// Второй параметр "Истина" включает контроль ссылочной целостности.
УдалитьОбъекты(МассивПомеченных, Истина, ТаблицаНайденныхСсылок);
// Шаг 4. Анализируем результат
Для каждого СтрокаРезультата из ТаблицаНайденныхСсылок Цикл
Сообщить("Объект " + СокрЛП(СтрокаРезультата[0]) + " не удален, так как на него ссылается: " + СокрЛП(СтрокаРезультата[1]));
КонецЦикла;
В этом примере метод УдалитьОбъекты пытается очистить базу. Если на объект есть ссылки в других документах, справочниках или регистрах, он будет пропущен, а информация о блокирующей ссылке попадет в таблицу ТаблицаНайденныхСсылок.
В современных конфигурациях (ЗУП 3.1, ERP, КА) рекомендуется использовать программный интерфейс БСП. Это более «цивилизованный» способ, так как он задействует механизмы, уже настроенные разработчиками конфигурации. Рассмотрим обращение к общему модулю УдалениеПомеченныхОбъектовСлужебный.
Проанализируем ситуацию: если нам нужно запустить удаление так же, как это делает типовая обработка в меню «Администрирование», мы можем вызвать метод:
// Запуск удаления объектов в фоновом задании (как в типовых решениях)
УдалениеПомеченныхОбъектовСлужебный.УдалитьПомеченныеОбъектыИзРегламентногоЗадания();
Этот подход хорош тем, что он автоматически обрабатывает порции данных и минимизирует блокировки базы данных, что критично для высоконагруженных систем.
Часто возникает проблема, когда Объект А ссылается на Объект Б, и оба они помечены на удаление. Если удалять их по одному, платформа может выдать ошибку. Разберем, как это работает:
УдалитьОбъекты массив, содержащий сразу и Объект А, и Объект Б, платформа поймет, что они удаляются вместе, и не будет считать их ссылки друг на друга блокирующими.Выясним причину, почему объект может не удаляться, даже если ссылок в документах нет. Проверьте независимые регистры сведений. Если ссылка на объект записана в измерении такого регистра, платформа не даст удалить объект. В этом случае нужно сначала программно очистить записи регистра:
НаборЗаписей = РегистрыСведений.НашРегистр.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.НашОбъект.Установить(СсылкаНаОбъект);
НаборЗаписей.Записать(); // Очищаем записи по ссылке
Если бизнес-логика позволяет, вместо удаления блокирующего объекта можно просто «обнулить» ссылку на него в других местах. Для этого в 1С существует мощный метод ЗаменитьСсылки(). Рассмотрим его применение:
Допустим, у нас есть дублирующийся элемент справочника или объект, который точно нужно удалить, перенаправив ссылки с него на «Пустую ссылку» или другой объект.
// Массив пар: что заменяем и на что заменяем
ПарыЗамен = Новый Массив;
Замена = Новый Структура("Ссылка, Замена", УдаляемыйОбъект, ПустаяСсылкаИлиДругойОбъект);
ПарыЗамен.Добавить(Замена);
// Глобальная замена во всей базе данных
ЗаменитьСсылки(ПарыЗамен);
Важно: При очистке реквизитов справочников учитывайте, является ли реквизит обязательным для заполнения (проверка заполнения). Если записать объект с пустым обязательным реквизитом, система может выдать ошибку при выполнении метода Записать().
Нужно помнить, что предопределенные элементы нельзя просто так удалить программно через УдалитьОбъекты, даже если на них нет ссылок. Чтобы это сделать, нужно предварительно «разорвать» связь объекта с метаданными. Посмотрим на пример:
Объект = ПредопределеннаяСсылка.ПолучитьОбъект();
Объект.ИмяПредопределенныхДанных = ""; // Делаем объект обычным
Объект.Записать();
// Теперь его можно удалять обычным способом
Массив = Новый Массив;
Массив.Добавить(Объект.Ссылка);
УдалитьОбъекты(Массив, Истина);
При массовом удалении (тысячи объектов) рекомендуем придерживаться следующих правил, чтобы не нарушить работу пользователей и не переполнить лог транзакций:
УстановитьПривилегированныйРежим(Истина), чтобы обойти проверки прав доступа и ускорить процесс.Использование связки методов НайтиСсылки, ЗаменитьСсылки и УдалитьОбъекты позволяет создать гибкий и надежный механизм автоматической очистки базы данных 1С.