Почему документ в 1С ссылается сам на себя и как это исправить

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с платформой «1С:Предприятие» разработчики часто сталкиваются со странным поведением стандартной функции НайтиПоСсылкам(). Ситуация, когда система сообщает, что документ ссылается на самого себя, может вызвать недоумение, особенно если у объекта нет явных движений по регистрам и отсутствуют реквизиты соответствующего типа. Разберем детально, почему это происходит, как проанализировать скрытые связи и можно ли безопасно удалять такие объекты.

Понимание работы механизма поиска ссылок

Прежде всего, проанализируем, как работает функция НайтиПоСсылкам(). Платформа не просто просматривает метаданные, которые мы видим в конфигураторе. Она выполняет прямой запрос к таблицам базы данных (СУБД), сканируя все поля всех таблиц, которые могут содержать тип данного объекта. Если в какой-то таблице (даже системной или скрытой) обнаруживается GUID нашего документа, функция включает эту запись в результат поиска.

Рассмотрим стандартный пример вызова функции:


МассивСсылок = Новый Массив;
МассивСсылок.Добавить(СсылкаНаДокумент);
ТаблицаСсылок = НайтиПоСсылкам(МассивСсылок);

Для Каждого СтрокаСсылки Из ТаблицаСсылок Цикл
    Сообщить("Объект: " + СтрокаСсылки.Данные + " ссылается на: " + СтрокаСсылки.Ссылка);
КонецЦикла;

Если в колонке Данные оказывается тот же самый документ, что и в колонке Ссылка, мы имеем дело с «самоссылкой».

Причина №1: Системное версионирование объектов (БСП)

Выясним причину, связанную с Библиотекой стандартных подсистем (БСП). Одной из самых распространенных причин является включенное версионирование объектов. Механизм работает следующим образом: при записи документа создается запись в регистре сведений ВерсииОбъектов. В этом регистре хранятся данные о состоянии объекта в виде двоичных данных (XML или Fast Infoset).

Несмотря на то что ссылка в регистре ведет на документ, внутри сериализованных данных версии может храниться ссылка на этот же объект. Кроме того, при программном анализе через НайтиПоСсылкам() система может обнаруживать связи в измерениях регистра, где хранится ссылка на объект-владелец версии. Если документ был записан хотя бы один раз с включенным версионированием, «самоссылка» может отображаться как связь с данными версии.

Причина №2: Скрытые реквизиты и составные типы данных

Проанализируем структуру самого документа. Часто разработчики проверяют только реквизиты шапки с явным типом «ДокументСсылка.ИмяДокумента». Однако ссылка может скрываться в более глубоких слоях:

  1. Реквизиты с типом ЛюбаяСсылка: Если в документе есть поле с неограниченным составным типом, туда программно могла попасть ссылка на самого себя (например, при некорректном заполнении реквизита «ДокументОснование» в коде перед записью).
  2. Табличные части: Проверьте не только шапку, но и все строки табличных частей. Реквизит в табличной части может иметь составной тип, включающий тип самого документа.
  3. Общие реквизиты: Если в конфигурации используются общие реквизиты, входящие в состав данного документа, проверьте их значения.

Чтобы найти такое поле, можно воспользоваться простым перебором метаданных:


ОбъектДок = СсылкаНаДокумент.ПолучитьОбъект();
Для Каждого Реквизит Из ОбъектДок.Метаданные().Реквизиты Цикл
    Если ОбъектДок[Реквизит.Имя] = СсылкаНаДокумент Тогда
        Сообщить("Найдена ссылка в реквизите: " + Реквизит.Имя);
    КонецЕсли;
КонецЦикла;

Причина №3: Критерии отбора

Разберем ситуацию с Критериями отбора. В конфигурации часто создаются критерии типа «СвязанныеДокументы». Если в состав критерия включен ваш тип документа и какой-либо из его реквизитов (например, «Основание»), то при поиске ссылок система обращается к индексу критерия отбора. Если документ указан в качестве собственного основания, критерий зафиксирует эту связь как циклическую.

Причина №4: Планы обмена и регистрация изменений

Рассмотрим механизмы синхронизации данных. Если документ участвует в обмене данными, он регистрируется на узлах планов обмена. Записи о регистрации изменений хранятся в специальных системных таблицах (таблицы регистрации). В некоторых случаях, особенно при использовании распределенных информационных баз (РИБ), наличие записи о регистрации объекта может интерпретироваться механизмом контроля целостности как наличие ссылки на объект. Хотя технически это не реквизит документа, это «живая» запись в базе данных, содержащая GUID объекта.

Причина №5: Бизнес-процессы и задачи

Посмотрим на связь с бизнес-логикой. Если документ является ведущим объектом для бизнес-процесса, платформа создает жесткую связь. В некоторых конфигурациях логика построена так, что задача или бизнес-процесс создаются «на основании» документа, а сам документ в своих скрытых системных полях (например, связанных с состоянием процесса) может хранить обратную ссылку. В этом случае НайтиПоСсылкам() может показать документ в контексте его участия в процессе.

Причина №6: Логическое повреждение базы данных

Выясним техническую причину, связанную с состоянием СУБД. Иногда «самоссылка» — это не реальная связь в метаданных, а результат **повреждения индексов** или таблиц базы данных. Это случается при аварийном завершении работы сервера или сбоях в файловой системе. В таблице ссылок БД (или в индексах) остается «фантомная» запись, указывающая на объект.

Для решения этой проблемы необходимо выполнить процедуру **Тестирования и исправления (ТиИ)**:

  1. Запустите информационную базу в режиме Конфигуратора.
  2. Перейдите в меню Администрирование — Тестирование и исправление...
  3. Установите флажки на пунктах «Проверка логической целостности» и «Проверка ссылочной целостности».
  4. В параметрах выберите «Очищать ссылки» или «Создавать объекты» при наличии битых ссылок (в данном случае поможет именно пересчет индексов).
  5. Нажмите «Выполнить».

Можно ли удалять такой документ?

Проанализируем риски при удалении объекта с самоссылкой. Ответ зависит от способа удаления:

1. Непосредственное удаление в коде

Метод Объект.Удалить() полностью игнорирует проверку ссылочной целостности. Если вы уверены, что документ лишний, вы можете удалить его программно. Наличие самоссылки не помешает этой операции.

2. Интерактивное удаление (через пометку удаления)

Стандартная обработка «Удаление помеченных объектов» выполняет проверку через ту же функцию НайтиПоСсылкам(). Если она увидит, что документ ссылается сам на себя, она может посчитать его «используемым» и отказаться удалять. В этом случае придется либо использовать программное удаление, либо предварительно очистить реквизит, содержащий самоссылку (если это реквизит документа).

Безопасность: Если анализ показал, что ссылка находится внутри самого объекта (в реквизите или ТЧ), удаление абсолютно безопасно для системы. Если же это признак повреждения БД, обязательно выполните «ТиИ» перед удалением, чтобы избежать проблем с целостностью всей базы в будущем.

Резюме по шагам

Подведем итог. Если вы обнаружили, что документ ссылается сам на себя, выполните следующие действия:

  1. Проверьте наличие документа в регистрах сведений БСП (Версии объектов, Дополнительные сведения).
  2. Используйте внешние обработки (например, «Поиск и замена дублей» или «Консоль запросов»), чтобы увидеть, в каких именно полях таблицы БД встречается ссылка.
  3. Проверьте планы обмена и удалите регистрацию документа на всех узлах, если он не должен передаваться.
  4. При подозрении на сбой базы выполните Тестирование и исправление.

Помните, что НайтиПоСсылкам() — это мощный инструмент, который иногда показывает нам внутреннюю «кухню» платформы, скрытую за интерфейсом конфигуратора.

← На главную