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

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

При работе с крупными конфигурациями, такими как «1С:Комплексная автоматизация» или «1С:ERP», часто возникает задача полной очистки базы от данных конкретной организации. Попытка решить эту задачу «в лоб» простым перебором и удалением объектов часто приводит к тому, что процесс растягивается на дни, а программа выдает бесконечные ошибки блокировок или нарушения бизнес-логики. Рассмотрим, почему это происходит, и разберем по шагам, как построить эффективный алгоритм удаления.

Анализ типичных ошибок при массовом удалении

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

  1. Динамическое построение гигантского запроса через ОБЪЕДИНИТЬ ВСЕ: Когда мы пытаемся собрать ссылки на все документы всех видов в один запрос, SQL-сервер тратит колоссальные ресурсы на построение плана выполнения. В сложных конфигурациях сотни видов документов, и такой запрос становится «неподъемным».
  2. Отсутствие флага ОбменДанными.Загрузка = Истина: Это самая критичная ошибка. Без этого флага при вызове метода Записать() или Удалить() платформа запускает все проверки, прописанные в модулях объектов (процедуры ПередЗаписью, ПриЗаписи). Если это регламентированный отчет (например, 4-ФСС), программа проверяет, не помечен ли он как «сданный». Если отчет сдан, типовая логика запрещает его изменять или удалять, выбрасывая исключение.
  3. Попытка удаления в рамках одной транзакции: Длительные операции без фиксации транзакций приводят к разрастанию лога транзакций SQL-сервера и эскалации блокировок. Программа начинает блокировать не отдельные строки, а целые таблицы, что вызывает конфликты даже при работе в одиночку.

Шаг 1: Оптимизация выборки данных

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


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

    ТекстЗапроса = "ВЫБРАТЬ Ссылка ИЗ Документ." + Вид.Имя + " ГДЕ Организация = &Организация";
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("Организация", СсылкаНаОрганизацию);
    
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        // Здесь будет логика удаления
    КонецЦикла;
КонецЦикла;

Шаг 2: Использование режима загрузки данных

Для того чтобы обойти проверки бизнес-логики (например, те самые ошибки при удалении отчетов 4-ФСС), необходимо использовать свойство ОбменДанными.Загрузка. Рассмотрим подробнее: установка этого флага в значение Истина сообщает платформе, что объект записывается в режиме «как есть», и выполнять прикладные проверки не нужно. Это не только избавляет от ошибок, но и в разы ускоряет процесс.


ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
ДокументОбъект.ОбменДанными.Загрузка = Истина;

Шаг 3: Очистка движений и физическое удаление

Перед тем как вызвать метод Удалить(), крайне важно очистить движения документа по регистрам. В «Комплексной автоматизации» документ может делать записи в десятки регистров накопления и сведений. Если просто вызвать Удалить(), платформа будет сама искать эти записи и удалять их по одной, что крайне медленно. Выясним причину: ручная очистка наборов записей через Записать() работает быстрее.

Посмотрим на пример правильной последовательности действий:


// 1. Отмена проведения, если документ проведен
Если ДокументОбъект.Проведен Тогда
    ДокументОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;

// 2. Очистка движений напрямую (опционально, но ускоряет процесс)
Для каждого Набор Из ДокументОбъект.Движения Цикл
    Набор.Записывать = Истина;
    Набор.Очистить();
    Набор.Записать();
КонецЦикла;

// 3. Непосредственное удаление
Попытка
    ДокументОбъект.Удалить();
Исключение
    Сообщить("Не удалось удалить: " + ИнформацияОбОшибке().Описание);
КонецПопытки;

Шаг 4: Управление блокировками и транзакциями

Чтобы избежать «зависаний» базы и конфликтов блокировок, о которых упоминалось в сообщениях форума, необходимо разделять процесс на порции. Рекомендуется фиксировать транзакцию каждые 100–500 объектов. Это освобождает ресурсы SQL-сервера.

Разберем пример реализации с транзакциями:


Счетчик = 0;
НачатьТранзакцию();

Пока Выборка.Следующий() Цикл
    // Логика удаления...
    
    Счетчик = Счетчик + 1;
    Если Счетчик % 200 = 0 Тогда
        ЗафиксироватьТранзакцию();
        НачатьТранзакцию();
    КонецЕсли;
КонецЦикла;

Если ТранзакцияАктивна() Тогда
    ЗафиксироватьТранзакцию();
КонецЕсли;

Альтернативные и безопасные методы

Проанализируем ситуацию: если ваша цель — именно физическое удаление, использование метода Удалить() в коде может быть опасным. Это может оставить в базе «битые ссылки» (объекты, которые ссылаются на удаленный документ). В 1С есть более безопасные способы:

  1. Пометка на удаление + стандартная обработка: Вместо Удалить() установите ПометкаУдаления = Истина (также с использованием ОбменДанными.Загрузка = Истина). Затем воспользуйтесь стандартным инструментом «Удаление помеченных объектов». Он работает в многопоточном режиме и гарантирует ссылочную целостность базы.
  2. Использование РИБ: Если объем данных колоссальный, можно создать периферийную базу по правилам миграции (отфильтровав только нужную организацию), а затем просто заменить основную базу этой периферийной. Это «варварский», но иногда единственный эффективный способ для баз объемом в терабайты.
  3. Типовая обработка «Групповое изменение реквизитов»: В ней есть возможность установить пометку удаления на выбранные документы. Она уже содержит в себе оптимизированные алгоритмы работы с метаданными.

Итоговые рекомендации

Для успешного и быстрого удаления документов по организации придерживайтесь следующих правил:

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

← На главную