Каждый разработчик 1С рано или поздно сталкивается с ситуацией, когда система отказывается удалять объект (например, организацию или контрагента), ссылаясь на его использование в другом документе. При этом при детальном осмотре этого документа — как визуальном, так и через отчеты — никакой связи обнаружить не удается. Такие ссылки называют «призрачными» или «фантомными». В данной статье мы разберем алгоритм поиска таких скрытых зависимостей и методы их устранения.
Прежде чем приступать к написанию кода, давайте проанализируем, где именно платформа может «видеть» ссылку, которая не отображается на форме документа. Рассмотрим основные места хранения данных, которые часто остаются вне поля зрения пользователя:
ПартионныйУчет или Взаиморасчеты.Если визуальный осмотр через Универсальный отчет не помог, нам необходимо выполнить прямой запрос к таблицам базы данных. Мы не будем полагаться на метаданные формы, а выберем абсолютно все поля документа. Разберем пример запроса, который поможет увидеть скрытые данные:
ВЫБРАТЬ
*
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Ссылка = &СсылкаНаПроблемныйДокумент
Проанализируем результат выполнения этого запроса в консоли. Нам нужно обратить внимание на колонки, которые обычно не видны в интерфейсе. Также следует проверить все табличные части документа аналогичным образом:
ВЫБРАТЬ
*
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК ТЧТовары
ГДЕ
ТЧТовары.Ссылка = &СсылкаНаПроблемныйДокумент
Если в одной из колонок (например, Подразделение, ГруппаДоступа или служебный идентификатор) вы увидите ссылку на удаляемую организацию, значит, причина найдена.
В современных базах 1С активно используются расширения. Если в расширении к документу был добавлен реквизит, содержащий ссылку на организацию, то стандартный запрос «Выбрать *» из основной конфигурации может его проигнорировать в зависимости от версии платформы и настроек. Проверим состав расширений и убедимся, что там нет дополнительных реквизитов, связанных с удаляемым объектом.
Выясним еще одну причину: регистрация в планах обмена. Если документ помечен к выгрузке в другую базу, ссылка на объект (организацию) может удерживаться в системных таблицах регистрации изменений (префикс _ChangeRec в SQL). Даже после очистки реквизита в самом документе, запись в плане обмена может блокировать удаление.
Чтобы исключить эту вероятность, выполним программную очистку регистрации изменений для удаляемого объекта:
ПланыОбмена.УдалитьРегистрациюИзменений(УзелОбмена, СсылкаНаОрганизацию);
Если ссылка удерживается последовательностью, обычная отмена проведения документа может не помочь. В этом случае требуется пересчет итогов и реструктуризация таблиц. Проанализируем ситуацию через Тестирование и исправление. Рекомендуется выбрать следующие пункты:
Важно: Перед выполнением этих операций обязательно создайте резервную копию базы данных!
Если все вышеперечисленные методы не помогли найти «физическое» местонахождение ссылки, а стандартная обработка «Удаление помеченных объектов» все равно выдает ошибку, можно прибегнуть к программному удалению. Это допустимо в случаях, когда вы точно уверены, что связь является мусорной или возникла в результате сбоя индексов.
Рассмотрим пример простейшей обработки для принудительного удаления объекта без контроля ссылочной целостности на уровне платформы:
Процедура УдалитьОбъектБезКонтроля(ОбъектСсылка)
// Получаем объект из ссылки
ОбъектДляУдаления = ОбъектСсылка.ПолучитьОбъект();
Если ОбъектДляУдаления = Неопределено Тогда
Сообщить("Объект уже удален или не существует.");
Возврат;
КонецЕсли;
// Устанавливаем режим загрузки данных, чтобы обойти проверки в коде (ПриЗаписи, ПередУдалением)
ОбъектДляУдаления.ОбменДанными.Загрузка = Истина;
Попытка
// Удаляем объект физически из базы
ОбъектДляУдаления.Удалить();
Сообщить("Объект успешно удален.");
Исключение
Сообщить("Ошибка при удалении: " + КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Использование свойства ОбменДанными.Загрузка = Истина позволяет отключить прикладные проверки в модулях объекта, что часто помогает, если удалению мешают программные алгоритмы конфигурации.
В конфигурациях на базе БСП (таких как БП 3.0, УТ 11, ERP) встроен мощный механизм поиска ссылок. Попробуем запустить поиск программно с расширенными параметрами, чтобы система проанализировала даже те места, которые скрыты в обычном режиме:
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(УдаляемаяОрганизация);
ТаблицаСсылок = НайтиСсылки(МассивСсылок);
Для Каждого СтрокаСсылки Из ТаблицаСсылок Цикл
Сообщить("Ссылка найдена в: " + СтрокаСсылки.Данные);
Сообщить("Метаданные: " + СтрокаСсылки.Метаданные.ПолноеИмя());
КонецЦикла;
Функция НайтиСсылки() возвращает таблицу значений, в которой колонка Метаданные точно укажет на реквизит или таблицу, удерживающую объект. Если этот метод возвращает пустой результат, но интерактивное удаление не работает — значит, проблема кроется в индексах базы данных SQL или кэше полнотекстового поиска. В такой ситуации поможет только физическая реструктуризация таблиц или очистка полнотекстового индекса через «Администрирование — Полнотекстовый поиск».
Мы проанализировали основные причины появления «мистических» связей в 1С. Помните, что удаление без контроля — это крайняя мера. Всегда старайтесь сначала выяснить причину появления ссылки, используя консоль запросов и анализ последовательностей, чтобы не нарушить логическую целостность ведения учета в системе.