В практике разработчика 1С часто встречается коварная ситуация: необходимо полностью удалить объект (например, номенклатуру), вы очищаете все ссылки на него в документах и регистрах, но стандартная обработка «Удаление помеченных объектов» или метод НайтиПоСсылкам продолжает утверждать, что объект используется. Особенно остро эта проблема проявляется в современных конфигурациях, таких как «1С:Управление торговлей 11», «1С:ERP» или «1С:Комплексная автоматизация 2».
Разберем детально, где прячутся «ссылки-невидимки», почему программная очистка табличных частей бывает недостаточной и как правильно вычистить базу от нежелательных связей.
Рассмотрим стандартную задачу: программно обойти все документы и удалить из их табличных частей ссылки на помеченную номенклатуру. Типичный код для решения этой задачи выглядит следующим образом:
Для Каждого МетаДок Из Метаданные.Документы Цикл
Для Каждого ТЧДок Из МетаДок.ТабличныеЧасти Цикл
// Формируем запрос для поиска документов, где в ТЧ есть ссылка на номенклатуру
// ... (логика формирования условий)
// Перебираем найденные документы
Пока ВыборкаСсылка.Следующий() Цикл
ДокументОбъект = ВыборкаСсылка.Ссылка.ПолучитьОбъект();
// Важный момент: удаление строк нужно делать с конца ТЧ, чтобы не сбивались индексы
КолвоСтрок = ДокументОбъект[ТЧДок.Имя].Количество();
Для Счетчик = 1 По КолвоСтрок Цикл
Индекс = КолвоСтрок - Счетчик;
СтрокаТЧ = ДокументОбъект[ТЧДок.Имя][Индекс];
// Проверяем реквизиты строки на наличие ссылки
// Если ссылка найдена - удаляем строку
ДокументОбъект[ТЧДок.Имя].Удалить(Индекс);
КонецЦикла;
// Записываем документ
Если ДокументОбъект.Проведен Тогда
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Иначе
ДокументОбъект.Записать(РежимЗаписиДокумента.Запись);
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
Казалось бы, код корректен: мы проходим по метаданным, находим ссылки и удаляем их. Однако после выполнения такой обработки система все равно может показывать наличие ссылок в этих же самых документах. Выясним причину этого феномена.
В конфигурациях на базе УТ 11/ERP используется механизм ключей аналитики. Ссылка на номенклатуру в регистрах накопления (например, СебестоимостьТоваров, ВыручкаИСебестоимостьПродаж) часто хранится не напрямую, а через вспомогательный справочник КлючиАналитикиУчетаНоменклатуры.
Проанализируем ситуацию: вы удалили номенклатуру из документа, но документ остался проведенным. При проведении он сформировал движения, в которых зафиксирован «Ключ аналитики». Внутри этого ключа содержится ссылка на вашу номенклатуру. Пока жив ключ аналитики или движение в регистре, ссылающееся на этот ключ, номенклатура считается используемой.
Что делать:
КлючиАналитикиУчетаНоменклатуры.Это самая частая причина появления «невидимок». Когда вы записываете документ, платформа фиксирует это изменение в планах обмена для синхронизации с другими базами (например, с Бухгалтерией). Данные записываются в скрытые таблицы _DocumentChngR.
Если сама номенклатура также зарегистрирована к обмену, в таблицах регистрации изменений планов обмена будет лежать ссылка на этот объект. Стандартные отчеты и консоли запросов по метаданным эти таблицы не показывают, но НайтиПоСсылкам их видит.
Решение: Воспользуйтесь обработкой «Регистрация изменений для обмена данными». Выберите нужный план обмена, найдите ваш объект (номенклатуру) и удалите регистрацию изменений для него. Также проверьте регистрацию документов, в которых эта номенклатура упоминалась.
Если в базе включена функциональность «История изменений» (версионирование), то при каждой записи документа платформа сохраняет его копию в регистре сведений ВерсииОбъектов. Данные там хранятся в сжатом бинарном виде (XML).
Даже если в текущем состоянии документа ссылки на номенклатуру нет, она осталась в предыдущих версиях документа. Платформа 1С считает это легитимной ссылкой и блокирует удаление.
Как исправить: Рассмотрим порядок действий для очистки истории:
Проанализируем программный код из первого сообщения. Он перебирает метаданные основной конфигурации. Однако в современной разработке часто используются Расширения. Если реквизит с типом СправочникСсылка.Номенклатура был добавлен в документ через расширение, ваш цикл по Метаданные.Документы может его просто «не увидеть», если код выполняется в контексте, где расширения не полностью инициализированы, или если алгоритм не учитывает структуру расширений.
Также проверьте Общие реквизиты. Ссылка может находиться в общем реквизите, который включен для ряда документов, но не отображается на формах.
Иногда проблема носит чисто технический характер. Индекс полнотекстового поиска или кэш сервера приложений могут хранить информацию о связи объектов, которая уже была удалена из таблиц СУБД. Именно поэтому ручное перепроведение (которое принудительно обновляет кэш конкретного объекта) часто помогает.
Рекомендации:
Если ничего из вышеперечисленного не помогло, воспользуемся проверенным методом — поиском по всей базе через универсальный запрос к таблице ссылок. Рассмотрим алгоритм действий:
ID вашей номенклатуры и выполните поиск этого значения по всем таблицам базы данных. Это позволит точно определить таблицу (например, таблицу регистрации изменений или системную таблицу итогов), в которой «застрял» объект.Подводя итог, можно составить правильный алгоритм полной очистки ссылок:
ВерсииОбъектов).Только после выполнения всех этих шагов метод НайтиПоСсылкам покажет пустой результат, и вы сможете безболезненно удалить объект из информационной базы.