К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как найти битые ссылки в запросе 1С

Как найти битые ссылки в запросе 1С: проверка через «Объект не найден», СУБД, типизированные соединения, обработки и типовые средства поиска ссылок.

Битая ссылка в 1С — это ссылка на объект, которого уже нет в базе: элемент справочника, документ или другая сущность были удалены физически, а ссылки на них остались в других записях. В запросах такие ссылки ведут себя неоднозначно: они не равны NULL, не равны пустой ссылке и при этом не имеют ни реквизитов, ни представления. Если их не отфильтровать, отчёт покажет странные строки «<Объект не найден>», а обход результата в коде может завершиться ошибкой или выдать неполные данные.

Задача поиска битых ссылок возникает в двух ситуациях: когда нужно вычистить их из базы (например, после обмена, свёртки или восстановления из копии) и когда нужно, чтобы конкретный запрос корректно обрабатывал такие ссылки и не ломал логику. Оба сценария решаются разными приёмами, и важно не смешивать их: фильтрация в запросе не удаляет мусор из базы, а удаление из базы не заменяет защиту в коде.

Ниже разобраны рабочие способы: как битая ссылка выглядит в результате запроса, как найти её средствами языка запросов, какие ограничения есть у каждого метода и какие типовые инструменты платформы стоит использовать для массовой проверки.

Что такое битая ссылка и как она выглядит в запросе

Битая ссылка сохраняет внутренний идентификатор (GUID) удалённого объекта, но сам объект в таблице отсутствует. Платформа при обращении к такой ссылке возвращает специальное значение, которое в интерфейсе и при преобразовании к строке выглядит как «<Объект не найден> (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)». Важно понимать: это не строковое значение в базе, а результат, который платформа формирует «на лету» при попытке получить представление.

Из этого следуют три ключевых свойства, которые определяют способы поиска. Во-первых, битая ссылка не равна NULL — проверка ЕСТЬ NULL её не поймает. Во-вторых, она не равна пустой ссылке соответствующего типа, поэтому сравнение с ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) тоже не сработает. В-третьих, при соединении с таблицей-владельцем по этой ссылке соединение не состоится — строка из основной таблицы останется, а поля присоединённой таблицы будут NULL, если используется левое соединение.

Способ 1: поиск через соединение с таблицей-владельцем

Самый надёжный метод — левое соединение с таблицей, на которую ссылается проверяемое поле, и отбор строк, где присоединённая ссылка оказалась NULL. Логика проста: если ссылка существует, соединение состоится; если объект удалён — соединение не найдёт пару, и поле присоединённой таблицы будет NULL.

Пример для регистра накопления, где в измерении «Номенклатура» могли остаться битые ссылки:

ВЫБРАТЬ РАЗЛИЧНЫЕ

ТоварыНаСкладах.Номенклатура КАК БитаяСсылка

ИЗ

РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура

ПО ТоварыНаСкладах.Номенклатура = СпрНоменклатура.Ссылка

ГДЕ

СпрНоменклатура.Ссылка ЕСТЬ NULL

И НЕ ТоварыНаСкладах.Номенклатура ЕСТЬ NULL

Обратите внимание на второе условие «НЕ ... ЕСТЬ NULL»: без него в выборку попадут строки, где само поле пустое (NULL), а это не битая ссылка, а отсутствие значения — их нужно различать. Также стоит исключить пустые ссылки отдельным условием, если они допустимы по бизнес-логике и не считаются проблемой.

Метод работает для любых ссылочных типов: справочников, документов, планов счетов, планов видов характеристик. Его ограничение — нужно точно знать тип поля. Если поле составного типа (например, «Контрагент» может быть и справочником «Контрагенты», и справочником «Организации»), соединение придётся делать с каждой таблицей отдельно и комбинировать условия.

Порядок действий
  1. 1
    Определите таблицу и поле, где ищете битые ссылки
  2. 2
    Определите тип (или типы) ссылочного поля
  3. 3
    Напишите запрос с левым соединением к таблице-владельцу
  4. 4
    Добавьте условия: присоединённая ссылка ЕСТЬ NULL, исходное поле НЕ ЕСТЬ NULL
  5. 5
    Выполните запрос в консоли запросов и проверьте результат вручную
  6. 6
    Только после проверки решайте, что делать с найденными записями

Способ 2: поиск по представлению «Объект не найден»

Альтернативный приём — преобразовать ссылку к строке прямо в запросе и отобрать значения, начинающиеся с маркера «<Объект не найден>». Для этого используется функция ПОДСТРОКА в сочетании с приведением ссылки к строковому типу. В языке запросов прямого приведения ссылки к строке нет, поэтому применяют приём через ВЫРАЗИТЬ с последующим сравнением, либо проверку через представление, если поле попадает в запрос как строка (например, при выгрузке в таблицу значений и последующей обработке).

На практике чаще используют проверку уже после выполнения запроса — в коде на встроенном языке:

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

Если СтрНайти(Строка(Выборка.Номенклатура), "Объект не найден") > 0 Тогда

// битая ссылка — фиксируем или обрабатываем

КонецЕсли;

КонецЦикла;

У этого способа есть существенный минус: он зависит от локализации платформы и формата представления. В англоязычной поставке маркер будет другим («Object not found»), а сравнение строк — медленнее соединения на больших таблицах. Использовать его как основной метод поиска в запросе не стоит; он уместен как дополнительная проверка при обходе результата или как быстрый способ «увидеть глазами» проблемные строки в консоли.

Способ 3: проверка ссылочной целостности в конфигураторе

Если задача — не отфильтровать битые ссылки в конкретном запросе, а найти и устранить их во всей базе, правильнее использовать штатный механизм платформы: тестирование и исправление информационной базы. В конфигураторе откройте «Администрирование» → «Тестирование и исправление», отметьте проверку «Проверка ссылочной целостности информационной базы» и запустите.

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

Критическое ограничение: тестирование и исправление требует монопольного доступа к базе и может занять значительное время на больших объёмах. Перед запуском в режиме исправления обязательно сделайте резервную копию — операция необратима, и ошибочный выбор действия (например, удаление записей регистра вместо очистки ссылки) приведёт к потере данных.

Способ 4: типовые обработки и средства БСП

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

Типовая обработка «Групповое изменение реквизитов» позволяет уже после поиска массово очистить или заменить найденные ссылки в документах и справочниках с контролем проведения и блокировок. Это безопаснее, чем прямая запись через код, потому что обработка выполняет изменения в транзакции и умеет показывать ошибки по каждому объекту.

Если пишете собственную обработку, универсальный приём — перебрать через метаданные все объекты со ссылочными реквизитами и для каждого реквизита выполнить запрос соединением из способа 1. Такой подход даёт полную картину по базе, но требует аккуратности с составными типами и большими таблицами: проверку лучше выполнять порциями и в нерабочее время.

Сравнение вариантов

Соединение в запросе

Быстро и точно для одного известного поля. Не подходит для проверки всей базы сразу, нужно знать типы полей.

Проверка по представлению

Просто для разовой диагностики в консоли. Зависит от локализации, медленно на больших выборках, ненадёжно в промышленном коде.

Тестирование и исправление

Проверяет всю базу штатными средствами. Требует монопольного доступа, копии и осторожного выбора действия исправления.

Универсальная обработка по метаданным

Полный контроль и автоматизация. Требует разработки, аккуратности с составными типами и нагрузкой на базу.

Битые ссылки в составных типах и NULL-значениях

Составной тип — самое частое место ошибок при поиске битых ссылок. Если реквизит может хранить ссылки на несколько таблиц (например, «Владелец» в присоединённых файлах), одного соединения недостаточно: нужно соединиться с каждой возможной таблицей и проверить, что хотя бы одно соединение состоялось. Битой считается ссылка, для которой ни одно соединение не дало результата, при этом само значение не NULL.

Отдельный нюанс — поля, допускающие NULL (например, измерения регистров при незаполненном значении). NULL — это не битая ссылка, а отсутствие значения, и смешивать эти случаи в одной выборке нельзя: иначе вы «найдёте» тысячи ложных битых ссылок и можете удалить корректные записи. Всегда добавляйте явное условие «И НЕ Поле ЕСТЬ NULL» и, при необходимости, исключайте пустые ссылки через сравнение с пустым значением конкретного типа.

Для полей типа «Характеристика.<План видов характеристик>» (типизированные дополнительные реквизиты) проверка сложнее: значение хранится в ресурсе регистра сведений и может ссылаться на разные справочники в зависимости от настройки вида характеристики. Здесь надёжнее проверять через приведение типа ВЫРАЗИТЬ и соединение с конкретной таблицей по каждому виду отдельно.

Типичные ошибки
01
Проверять битые ссылки через ЕСТЬ NULL без соединения — битая ссылка не равна NULL, такая проверка ничего не найдёт
02
Сравнивать с пустой ссылкой — битая ссылка не равна ЗНАЧЕНИЕ(Справочник.Х.ПустаяСсылка), условие не сработает
03
Не исключать NULL-значения поля — в результат попадут обычные пустые измерения регистров, и вы примете их за битые ссылки
04
Искать по подстроке «Объект не найден» в промышленном коде — на другой локализации платформы проверка перестанет работать
05
Запускать исправление ссылочной целостности без копии и анализа — необратимое удаление записей регистров

Проверка результата и безопасная очистка

После того как запрос нашёл кандидатов, не переходите сразу к удалению или замене. Сначала вручную проверьте несколько найденных ссылок: откройте запись в режиме предприятия или попробуйте получить объект через ПолучитьОбъект() в консоли кода — для битой ссылки будет возвращено значение, представление которого содержит «Объект не найден». Это подтвердит, что запрос настроен правильно и не захватывает лишнего.

Дальнейшие действия зависят от источника проблемы. Если битые ссылки появились после обмена — ищите причину в правилах конвертации и регистрации, иначе после чистки они появятся снова. Если после свёртки базы — проверьте, все ли регистры и документы обработаны. Если после прямого удаления объектов минуя контроль ссылочной целостности — настройте регламент: удаление объектов должно идти через пометку и штатное удаление помеченных, которое контролирует ссылки.

Сама очистка выполняется либо через тестирование и исправление, либо через групповое изменение реквизитов, либо программно — записью объекта с очищенным реквизитом. Программный вариант требует обхода в транзакциях разумного размера и обязательного обмена данными после: если база участвует в РИБ или синхронизации, изменения должны корректно уйти в другие узлы.

Контрольные точки

Как проверить результат

Повторный запрос после очистки
Норма

Выборка битых ссылок пуста

Тревожный признак

Ссылки остались — очистка не затронула часть записей или источник проблемы не устранён

Открытие найденной ссылки вручную
Норма

Представление «<Объект не найден>» — диагноз подтверждён

Тревожный признак

Объект открывается нормально — запрос настроен неверно и захватывает корректные данные

Количество найденных записей против ожиданий
Норма

Порядок цифр соответствует истории базы (обмены, свёртки)

Тревожный признак

Найдены тысячи записей без причины — вероятно, в выборку попали NULL-значения полей

FAQ

Почему условие ЕСТЬ NULL не находит битые ссылки?

Потому что битая ссылка — это не NULL, а вполне конкретное значение с GUID удалённого объекта. NULL возникает только при отсутствии значения в поле или при несостоявшемся соединении. Именно поэтому битые ссылки ищут через левое соединение с таблицей-владельцем: NULL появляется уже в полях присоединённой таблицы.

Можно ли найти битые ссылки во всей базе одним запросом?

Одним запросом — нет, потому что ссылочные поля разбросаны по десяткам таблиц с разными типами. Правильные варианты: штатная проверка ссылочной целостности в конфигураторе либо собственная обработка, которая перебирает метаданные и для каждого ссылочного реквизита выполняет отдельный запрос соединением.

Чем битая ссылка отличается от пустой ссылки?

Пустая ссылка — это штатное значение «ничего не выбрано», объект с таким GUID в таблице существует как служебный. Битая ссылка указывает на реально существовавший, но удалённый объект. В запросе их различают сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка): пустая ссылка отбору соответствует, битая — нет.

Опасно ли оставлять битые ссылки в базе?

Да. Они искажают отчёты (строки с «Объект не найден»), могут вызывать ошибки при обходе данных в коде, мешают обменам и свёртке. Кроме того, их наличие обычно означает, что в базе нарушен регламент удаления объектов — стоит найти и устранить источник.

Почему после чистки битые ссылки появляются снова?

Почти всегда причина в обмене данными: в одном узле объект удалили, а ссылка на него пришла из другого узла. Также возможны обработки, удаляющие объекты напрямую без контроля ссылок. Чистка без устранения источника даёт временный эффект — сначала разберитесь с правилами обмена и регламентом удаления.

Нужен ли монопольный режим для поиска битых ссылок запросом?

Для поиска запросом — нет, это обычное чтение данных. Монопольный доступ нужен только для тестирования и исправления в конфигураторе. Массовую программную очистку тоже лучше выполнять без активных пользователей, чтобы избежать блокировок, но формально она монопольного режима не требует.

Итог

Что важно запомнить

Битая ссылка не равна NULL и пустой ссылке — ищите её левым соединением с таблицей-владельцем и проверкой на NULL. Для всей базы используйте проверку ссылочной целостности, обязательно с копией и сначала в режиме тестирования. После чистки устраните источник проблемы, иначе ссылки появятся снова.