Ситуация, когда в системе 1С:Предприятие не удается удалить помеченный объект, при том что стандартный поиск ссылок показывает их полное отсутствие, является довольно распространенной. Особенно часто это проявляется при переходе между версиями платформ (например, с 8.1 на 8.3) или после некорректных доработок конфигурации. В этой статье мы детально разберем, почему так происходит, и проанализируем последовательность шагов для решения данной проблемы.
Первым делом нам необходимо исключить самую очевидную, но часто забываемую причину — наличие жестких программных ограничений в самом объекте метаданных. Рассмотрим ситуацию: вы проверили базу утилитой chdbfl.exe, выполнили Тестирование и исправление (ТиИ), очистили кэш, но документ все равно не удаляется. В этом случае следует заглянуть в Конфигуратор и проверить модуль соответствующего документа.
Выясним причину, открыв модуль объекта и найдя в нем обработчик события ПередУдалением. Зачастую там можно обнаружить код, который принудительно блокирует процесс. Проанализируем пример кода, который стал причиной проблемы в одном из реальных кейсов:
Процедура ПередУдалением(Отказ)
// Вставить содержимое обработчика.
Отказ = Истина;
КонецПроцедуры
В данном примере переменной Отказ всегда присваивается значение Истина. Это означает, что система будет отменять попытку удаления любого экземпляра этого документа, независимо от прав пользователя или отсутствия ссылок. Подобный код может остаться от старых доработок или быть вставлен в целях безопасности, чтобы пользователи случайно не удалили важные данные. Для решения проблемы этот код необходимо либо удалить, либо добавить в него условия (например, проверку роли пользователя).
Если в модуле самого объекта чисто, нам следует рассмотреть другой механизм платформы — Подписки на события. Это мощный инструмент, который позволяет выполнять программный код для группы объектов, не меняя их собственные модули. Программисты часто используют подписки на событие ПередУдалением или ПриУдалении.
Разберем, как это работает. Подписка может быть настроена сразу для всех документов или справочников. Если в коде обработчика подписки стоит условие, которое возвращает Отказ = Истина, объект не будет удален. При этом внешне это может выглядеть как «критическая ошибка» или системный сбой. Нам необходимо найти в дереве метаданных раздел «Общие» — «Подписки на события» и проверить все те, которые связаны с удалением нужного типа объекта.
Иногда стандартная обработка «Удаление помеченных объектов» сообщает, что ссылок нет, но на самом деле они существуют в регистрах сведений. Рассмотрим ситуацию с регистрами, которые не подчинены регистратору. Если в таком регистре есть измерение с типом ссылки на наш объект, и у этого измерения не установлен признак Ведущее, то поиск ссылок может их пропустить.
Проанализируем два варианта настройки измерения в регистре:
В этом случае рекомендуется использовать консоль запросов или специализированные обработки для поиска упоминаний ссылки во всех таблицах базы данных.
Для того чтобы точно понять, на каком этапе происходит сбой, мы можем попробовать выполнить удаление программно. Это поможет нам увидеть конкретную ошибку, которую выдает платформа. Рассмотрим следующий пример кода для внешней обработки:
Попытка
ОбъектСсылка = Документы.СчетНаОплатуПокупателю.НайтиПоНомеру("0000002198");
Если Не ОбъектСсылка.Пустая() Тогда
УО = ОбъектСсылка.ПолучитьОбъект();
УО.Удалить();
Сообщить("Объект успешно удален");
КонецЕсли;
Исключение
Сообщить("Ошибка при удалении: " + ОписаниеОшибки());
КонецПопытки;
Использование метода Удалить() вместо УстановитьПометкуУдаления() инициирует непосредственное физическое удаление. Если выполнение этого кода приводит к критической ошибке или выводу сообщения об отказе, мы сможем по стеку вызовов (в режиме отладки) точно определить строку кода, которая блокирует процесс.
При использовании платформы 8.3 важно учитывать влияние Расширений. В расширении может быть создан метод-обертка для процедуры удаления. Рассмотрим ситуацию: основной код конфигурации типовой и не содержит блокировок, но в расширении добавлен метод с аннотацией &Перед, который устанавливает Отказ = Истина при определенных условиях.
Проанализируем порядок проверки в данном случае:
ПередУдалением.Если программный код проверен и он корректен, а объект все равно не удаляется (особенно в SQL-версии), следует обратить внимание на технические аспекты. Посмотрим на возможные причины:
1C:Enterprise 8.3 Server Agent.Подводя итог, можно сказать, что «мистическое» поведение системы при удалении почти всегда имеет под собой конкретную логическую причину в коде — будь то забытая заглушка Отказ = Истина в модуле или скрытая подписка на событие. Систематическая проверка по шагам, описанным выше, позволяет решить проблему в 99% случаев.