При проведении свертки информационной базы или массовой очистке старых данных специалисты часто сталкиваются с проблемой: электронные счета-фактуры (ЭСФ), помеченные на удаление, категорически отказываются покидать базу. Стандартная обработка "Удаление помеченных объектов" часами анализирует связи, но в итоге выдает ошибку о невозможности удаления из-за взаимных ссылок между документом и его присоединенным файлом. Рассмотрим подробнее, почему возникает этот замкнутый круг и как его разорвать.
Проанализируем архитектуру хранения электронных документов в современных конфигурациях на базе БСП (Библиотеки стандартных подсистем). Проблема кроется в двусторонней связи на уровне метаданных:
ПрисоединенныеФайлы (название может варьироваться, например, ЭСФПрисоединенныеФайлы) существует реквизит ВладелецФайла, который жестко ссылается на документ ЭСФ.ЭСФ или в связанных с ним регистрах сведений (например, подсистемы ЭДО) хранятся ссылки на эти самые файлы.Когда стандартный механизм удаления пытается удалить документ, он проверяет, не используется ли он где-то еще. Он видит ссылку в справочнике файлов. Пытаясь удалить файл, система видит, что он используется в документе или связанном регистре. В итоге механизм "топчется на месте", не понимая, что оба объекта подлежат удалению одновременно. Ситуация усугубляется при огромных объемах данных (десятки тысяч записей), когда система не может за один проход выстроить полное дерево зависимостей.
Помимо очевидных ссылок в файлах, ЭСФ "держится" за базу через многочисленные записи в регистрах. Прежде чем приступать к удалению самих документов, необходимо очистить следующие узлы:
Если эти записи не будут удалены, стандартная проверка целостности никогда не позволит удалить основной документ.
Самый надежный способ решить проблему при большом объеме данных — написать небольшую обработку, которая принудительно "разрывает" связь. Рассмотрим пример кода, который позволяет подготовить объекты к удалению. Ключевым моментом здесь является использование параметра ОбменДанными.Загрузка = Истина, который отключает платформенные проверки при записи.
// Пример программной подготовки к удалению
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЭСФПрисоединенныеФайлы.Ссылка КАК ФайлСсылка,
| ЭСФПрисоединенныеФайлы.ВладелецФайла КАК Владелец
|ИЗ
| Справочник.ЭСФПрисоединенныеФайлы КАК ЭСФПрисоединенныеФайлы
|ГДЕ
| ЭСФПрисоединенныеФайлы.ВладелецФайла.ПометкаУдаления = ИСТИНА";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Разрываем связь, очищая владельца или просто удаляя файл принудительно
ОбъектФайл = Выборка.ФайлСсылка.ПолучитьОбъект();
Если ОбъектФайл <> Неопределено Тогда
ОбъектФайл.ОбменДанными.Загрузка = Истина;
// Можно либо очистить владельца, либо сразу удалить
ОбъектФайл.УстановитьПометкуУдаления(Истина);
ОбъектФайл.Записать();
КонецЕсли;
КонецЦикла;
Важный нюанс: После того как вы программно пометили на удаление и файлы, и документы, и очистили регистры, стандартное удаление пойдет гораздо быстрее. Однако для десятков тысяч записей лучше использовать удаление порциями.
Если вы не хотите писать собственный код, воспользуйтесь профессиональным инструментарием, таким как "Инструменты разработчика". В составе этого комплекса есть обработка "Удаление объектов", которая обладает гораздо более мощным алгоритмом, чем стандартная:
<Объект не найден> осталась). Используйте его только если вы точно уверены, что все связанные регистры и документы-основания уже обработаны.Посмотрим на ситуацию с точки зрения штатных средств. Можно воспользоваться обработкой "Групповое изменение реквизитов". Проанализируем алгоритм действий:
ВладелецФайла.ПометкаУдаления Равно Истина.ВладелецФайла, очищая его (устанавливая в пустое значение).После этой манипуляции связь будет разорвана, и стандартное удаление помеченных объектов без труда справится с задачей, так как циклическая зависимость исчезнет.
Работа с десятками тысяч ЭСФ требует соблюдения правил производительности. Проанализируем основные советы:
Index и Data.ЭСФ могут срабатывать подписки на события, пытающиеся достучаться до государственных серверов (ИС ЭСФ). Отключайте интернет-соединение или используйте ОбменДанными.Загрузка = Истина, чтобы пропустить эти проверки.Таким образом, для успешного удаления "зависших" ЭСФ необходимо сначала очистить технические регистры, затем разорвать циклическую связь между документом и файлом (через программный код или групповую обработку в режиме загрузки) и только после этого запускать финальную очистку базы.