Как программно удалить помеченные объекты в 1С 8.3: Полное руководство

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

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

Постановка задачи и анализ механизмов 1С

Прежде всего, давайте выясним причину, по которой нельзя просто «стереть» объект из базы. Платформа 1С:Предприятие использует ссылочную модель данных. Это означает, что один объект (например, СправочникСсылка.Контрагенты) может упоминаться в сотнях документов. Если мы удалим контрагента, в документах останется «битая» ссылка (Объект не найден). Чтобы этого избежать, процесс удаления разделен на два этапа: установка пометки удаления и непосредственное (физическое) удаление с проверкой ссылок.

Рассмотрим основные способы решения этой задачи:

  1. Использование стандартной обработки «Удаление помеченных объектов».
  2. Программное удаление через метод НайтиПомеченныеНаУдаление().
  3. Использование нового метода платформы УдалитьОбъекты().
  4. Применение функций БСП (Библиотеки стандартных подсистем) для фонового удаления.

Способ 1. Программный поиск и удаление через массив ссылок

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

Разберем пример кода, который реализует эту логику:


// Шаг 1: Получаем массив всех помеченных на удаление объектов
МассивПомеченных = НайтиПомеченныеНаУдаление();

// Шаг 2: Проверяем возможность удаления (поиск ссылок на эти объекты)
ТаблицаСсылок = НайтиСсылки(МассивПомеченных);

// Если в таблице ссылок есть записи, значит, объекты где-то используются
Если ТаблицаСсылок.Количество() > 0 Тогда
    Сообщить("Некоторые объекты нельзя удалить, так как на них есть ссылки!");
КонецЕсли;

Важно понимать, что метод НайтиПомеченныеНаУдаление() без параметров возвращает все помеченные объекты в базе. В больших базах это может привести к серьезным задержкам. Рассмотрим подробнее, как ограничить область поиска, передав массив метаданных или конкретный список ссылок.

Способ 2. Использование метода УдалитьОбъекты

В современных версиях платформы 8.3 появился более эффективный метод — УдалитьОбъекты(). Посмотрим на его синтаксис и преимущества. Данный метод позволяет выполнить удаление одной командой, передав массив ссылок. Третий параметр метода определяет, нужно ли проверять ссылки перед удалением.

Проанализируем ситуацию, когда нам нужно удалить объекты безвозвратно:


// Массив объектов для удаления
ОбъектыДляУдаления = Новый Массив;
ОбъектыДляУдаления.Добавить(СсылкаНаОбъект1);
ОбъектыДляУдаления.Добавить(СсылкаНаОбъект2);

// Попытка удаления с контролем ссылок
// Истина в третьем параметре означает проверку ссылочной целостности
ТаблицаОстающихсяСсылок = Новый ТаблицаЗначений;
УдалитьОбъекты(ОбъектыДляУдаления, Истина, ТаблицаОстающихсяСсылок);

Если ТаблицаОстающихсяСсылок.Количество() > 0 Тогда
    // Разберем по шагам, что делать с оставшимися ссылками
    Для Каждого Строка Из ТаблицаОстающихсяСсылок Цикл
        Сообщить("Объект " + Строка.Данные + " используется в " + Строка.Ссылка);
    КонецЦикла;
КонецЕсли;

Этот подход значительно ускоряет работу, так как платформа оптимизирует запросы к базе данных на уровне СУБД. Рекомендуем использовать именно этот метод для разработки в среде 1С v8.3 (Управляемые формы).

Способ 3. Автоматизация через Библиотеку стандартных подсистем (БСП)

Если ваша конфигурация построена на базе БСП (например, 1С:ERP, УТ 11 или БП 3.0), мы можем воспользоваться встроенными механизмами, которые уже включают в себя обработку исключений и работу в фоновом режиме. Выясним причину, почему это выгодно: фоновое удаление не блокирует работу пользователя и позволяет избежать тайм-аутов сеанса.

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


// Пример вызова фонового удаления (упрощенно)
ПараметрыУдаления = УдалениеПомеченныхОбъектовСлужебный.ПараметрыУдаления();
ПараметрыУдаления.ВключитьПроверкуСсылок = Истина;
УдалениеПомеченныхОбъектовСлужебный.УдалитьПомеченныеОбъекты(ПараметрыУдаления);

Использование БСП позволяет автоматически записывать результаты в ЖурналРегистрации, что критически важно для последующего аудита действий пользователей — для этой задачи есть обработка регистрации изменений и аудита удаления объектов.

Тонкости и оптимизация производительности

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

  1. Удаление порциями: Не пытайтесь удалить все объекты за один раз. Разбейте массив ссылок на части по 500-1000 элементов — для этого подойдёт обработка безопасного удаления данных и очистки базы.
  2. Индексация: Перед массовым удалением убедитесь, что в базе актуализированы индексы. Это напрямую влияет на скорость работы метода НайтиСсылки().
  3. Монопольный режим: Если это возможно, выполняйте процедуру в моменты минимальной активности пользователей или в монопольном режиме.
  4. Отключение итогов: При удалении огромного количества документов может помочь временное отключение итогов регистров, хотя это радикальный метод, требующий осторожности.

Посмотрим на пример кода с удалением порциями:


ВсеПомеченные = НайтиПомеченныеНаУдаление();
ВсегоОбъектов = ВсеПомеченные.Количество();
РазмерПорции = 500;
ТекущийИндекс = 0;

Пока ТекущийИндекс < ВсегоОбъектов Цикл
    Порция = Новый Массив;
    Для К = 1 По РазмерПорции Цикл
        Если ТекущийИндекс >= ВсегоОбъектов Тогда
            Прервать;
        КонецЕсли;
        Порция.Добавить(ВсеПомеченные[ТекущийИндекс]);
        ТекущийИндекс = ТекущийИндекс + 1;
    КонецЦикла;
    
    // Выполняем удаление порции
    УдалитьОбъекты(Порция, Истина);
    // Делаем паузу или записываем лог, чтобы не перегружать транзакционный лог СУБД
КонецЦикла;

Выясним причину ошибок при удалении

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

Также стоит проверить права доступа. Метод УдалитьОбъекты требует наличия права ИнтерактивноеУдалениеПомеченных или просто Удаление (в зависимости от параметров вызова). Если у пользователя недостаточно прав, система выдаст исключение, которое необходимо обрабатывать через конструкцию Попытка...Исключение.

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

Подводя итог, мы рассмотрели различные подходы к программному удалению. Выбор конкретного метода зависит от архитектуры вашей конфигурации и объема данных. Использование метода УдалитьОбъекты() является наиболее современным и производительным решением для платформы 8.3.

← На главную