При работе в распределенных информационных базах (РИБ) на платформе 1С:Предприятие 8.3 (особенно в таких конфигурациях, как УПП 1.3) часто возникает ситуация, когда необходимо очистить справочник Контрагенты. Однако при попытке удаления система выдает ошибку, указывая на ссылки в документах, которых физически нет в текущей базе. Проанализируем, почему возникают «призрачные» ссылки и как поэтапно очистить базу от лишних данных.
Когда система сообщает, что объект используется в (389:834900248c2e5ba111e0ddd60f59555f), она дает нам прямую подсказку. Число до двоеточия (в нашем примере 389) — это внутренний идентификатор типа объекта в метаданных конкретной базы. Чтобы не гадать, какой именно документ или справочник мешает удалению, выполним программный код в консоли кода:
НомерТипа = 389; // подставьте свое число из сообщения об ошибке
НайденныйТип = Метаданные.НайтиПоНомеруТипа(НомерТипа);
Сообщить("Тип объекта, удерживающего ссылку: " + НайденныйТип.ПолноеИмя());
Разберем ситуацию: если НайденныйТип указывает на документ, который не должен был попасть в РИБ (например, по правилам обмена), значит, в базе остались «хвосты» от некорректной синхронизации или записи в служебных таблицах. Выяснив тип объекта, мы можем целенаправленно искать записи именно в его таблицах.
В конфигурации 1С:УПП 1.3 часто включена подсистема версионирования. Это одна из самых распространенных причин появления скрытых ссылок. Даже если сам документ ПоступлениеТоваровУслуг был удален из базы, записи о его изменениях могут храниться в регистре сведений ВерсииОбъектов.
Проанализируем этот регистр. В нем хранятся двоичные данные или XML-выгрузки объектов. Ссылка на контрагента может находиться внутри этого хранилища. Посмотрим, как можно программно найти такие записи для конкретного контрагента:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВерсииОбъектов.Объект,
| ВерсииОбъектов.НомерВерсии
|ИЗ
| РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
|ГДЕ
| ВерсииОбъектов.Объект = &СсылкаНаКонтрагента";
Запрос.УстановитьПараметр("СсылкаНаКонтрагента", НужныйКонтрагент);
Результат = Запрос.Выполнить();
// Если результат не пустой — записи необходимо удалить.
Важно помнить, что удалять записи из этого регистра следует только в том случае, если вы уверены, что история версий по данному контрагенту (или связанным с ним удаленным документам) больше не требуется.
Рассмотрим еще одно место хранения «невидимых» связей — механизм дополнительных реквизитов. В УПП ссылки могут удерживаться в регистре сведений ЗначенияСвойствОбъектов. Если контрагент был выбран в качестве значения какого-либо свойства (например, «Основной перевозчик» для документа), ссылка сохранится в этом регистре, даже если сам документ-владелец помечен на удаление или отсутствует.
Рекомендуем проверить все записи в этом регистре, где в поле Значение фигурирует удаляемый контрагент. Воспользуйтесь стандартной обработкой «Поиск ссылок на объект», но с включенной опцией поиска в регистрах сведений.
Если база является узлом РИБ, ссылка на объект может удерживаться в таблицах регистрации изменений. Это происходит, когда объект был изменен и «ждет» выгрузки в другие узлы. Рассмотрим алгоритм очистки регистрации:
Контрагенты.
ПланыОбмена.УдалитьРегистрациюИзменений(УзелСсылка, НужныйКонтрагент);
Иногда ссылка может «застрять» не на самом контрагенте, а на том самом «битом» документе, который система видит по UID. В этом случае нужно очистить регистрацию для объекта с тем самым идентификатором 389:....
Выясним причину, связанную с партионным учетом. В УПП 1.3 существуют таблицы границ последовательностей. Если документ когда-то участвовал в движениях и был удален напрямую (не через стандартное удаление), его ссылка может остаться в таблице Последовательности.ПартионныйУчет.Границы.
Чтобы исправить это, попробуйте запустить процедуру восстановления последовательностей или выполните тестирование и исправление базы (ТиИ) с настройками: «Проверка ссылочной целостности» -> «При наличии ссылок на несуществующие объекты: Очищать ссылки».
Если стандартный поиск ссылок не справляется, применим «хитрый» метод через замену объектов. Создадим в справочнике Контрагенты одного технического контрагента (назовем его «Пустышка для удаления»).
Разберем порядок действий:
В чем смысл этого действия? Обработка принудительно перепишет все ссылки (включая скрытые в регистрах и планах обмена) на новый объект. После этого ваш исходный контрагент станет абсолютно «чистым» и легко удалится. Проблема с «битой» ссылкой перейдет на «Пустышку», которую можно будет попытаться вычистить позже или просто оставить в базе, так как она не будет мешать работе.
Рассмотрим крайнюю меру, которую стоит использовать только опытным администраторам 1С. Если вы точно знаете, что контрагент не имеет важных движений по регистрам бухгалтерии и накопления (взаиморасчеты, остатки), его можно удалить принудительно, игнорируя проверку ссылок.
ОбъектКонтрагент = КонтрагентСсылка.ПолучитьОбъект();
ОбъектКонтрагент.Удалить(); // Метод Удалить() без параметров удаляет объект физически
Внимание: Этот метод может привести к появлению «битых ссылок» (Объект не найден) в тех местах, где контрагент ранее использовался. Используйте этот способ только после полного бэкапа базы и проверки того, что данный контрагент не участвует в управленческом или бухгалтерском балансе дочерней организации.
Для успешного удаления контрагентов в РИБ 1С:УПП 1.3 мы рекомендуем придерживаться следующей стратегии:
ВерсииОбъектов и ЗначенияСвойствОбъектов.Тестирование и исправление для очистки таблиц регистраций и последовательностей.Проанализировав все скрытые связи, вы сможете добиться чистоты справочников в распределенных базах и оптимизировать производительность системы.