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