Разработка и Конфигурация · 13 мин
Как найти битые ссылки в запросе 1С
Как найти битые ссылки в запросе 1С: проверка через «Объект не найден», СУБД, типизированные соединения, обработки и типовые средства поиска ссылок.
Битая ссылка в 1С — это ссылка на объект, которого уже нет в базе: элемент справочника, документ или другая сущность были удалены физически, а ссылки на них остались в других записях. В запросах такие ссылки ведут себя неоднозначно: они не равны NULL, не равны пустой ссылке и при этом не имеют ни реквизитов, ни представления. Если их не отфильтровать, отчёт покажет странные строки «<Объект не найден>», а обход результата в коде может завершиться ошибкой или выдать неполные данные.
Задача поиска битых ссылок возникает в двух ситуациях: когда нужно вычистить их из базы (например, после обмена, свёртки или восстановления из копии) и когда нужно, чтобы конкретный запрос корректно обрабатывал такие ссылки и не ломал логику. Оба сценария решаются разными приёмами, и важно не смешивать их: фильтрация в запросе не удаляет мусор из базы, а удаление из базы не заменяет защиту в коде.
Ниже разобраны рабочие способы: как битая ссылка выглядит в результате запроса, как найти её средствами языка запросов, какие ограничения есть у каждого метода и какие типовые инструменты платформы стоит использовать для массовой проверки.
Что такое битая ссылка и как она выглядит в запросе
Битая ссылка сохраняет внутренний идентификатор (GUID) удалённого объекта, но сам объект в таблице отсутствует. Платформа при обращении к такой ссылке возвращает специальное значение, которое в интерфейсе и при преобразовании к строке выглядит как «<Объект не найден> (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)». Важно понимать: это не строковое значение в базе, а результат, который платформа формирует «на лету» при попытке получить представление.
Из этого следуют три ключевых свойства, которые определяют способы поиска. Во-первых, битая ссылка не равна NULL — проверка ЕСТЬ NULL её не поймает. Во-вторых, она не равна пустой ссылке соответствующего типа, поэтому сравнение с ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка) тоже не сработает. В-третьих, при соединении с таблицей-владельцем по этой ссылке соединение не состоится — строка из основной таблицы останется, а поля присоединённой таблицы будут NULL, если используется левое соединение.
Способ 1: поиск через соединение с таблицей-владельцем
Самый надёжный метод — левое соединение с таблицей, на которую ссылается проверяемое поле, и отбор строк, где присоединённая ссылка оказалась NULL. Логика проста: если ссылка существует, соединение состоится; если объект удалён — соединение не найдёт пару, и поле присоединённой таблицы будет NULL.
Пример для регистра накопления, где в измерении «Номенклатура» могли остаться битые ссылки:
ВЫБРАТЬ РАЗЛИЧНЫЕ
ТоварыНаСкладах.Номенклатура КАК БитаяСсылка
ИЗ
РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
ПО ТоварыНаСкладах.Номенклатура = СпрНоменклатура.Ссылка
ГДЕ
СпрНоменклатура.Ссылка ЕСТЬ NULL
И НЕ ТоварыНаСкладах.Номенклатура ЕСТЬ NULL
Обратите внимание на второе условие «НЕ ... ЕСТЬ NULL»: без него в выборку попадут строки, где само поле пустое (NULL), а это не битая ссылка, а отсутствие значения — их нужно различать. Также стоит исключить пустые ссылки отдельным условием, если они допустимы по бизнес-логике и не считаются проблемой.
Метод работает для любых ссылочных типов: справочников, документов, планов счетов, планов видов характеристик. Его ограничение — нужно точно знать тип поля. Если поле составного типа (например, «Контрагент» может быть и справочником «Контрагенты», и справочником «Организации»), соединение придётся делать с каждой таблицей отдельно и комбинировать условия.
- 1Определите таблицу и поле, где ищете битые ссылки
- 2Определите тип (или типы) ссылочного поля
- 3Напишите запрос с левым соединением к таблице-владельцу
- 4Добавьте условия: присоединённая ссылка ЕСТЬ NULL, исходное поле НЕ ЕСТЬ NULL
- 5Выполните запрос в консоли запросов и проверьте результат вручную
- 6Только после проверки решайте, что делать с найденными записями
Способ 2: поиск по представлению «Объект не найден»
Альтернативный приём — преобразовать ссылку к строке прямо в запросе и отобрать значения, начинающиеся с маркера «<Объект не найден>». Для этого используется функция ПОДСТРОКА в сочетании с приведением ссылки к строковому типу. В языке запросов прямого приведения ссылки к строке нет, поэтому применяют приём через ВЫРАЗИТЬ с последующим сравнением, либо проверку через представление, если поле попадает в запрос как строка (например, при выгрузке в таблицу значений и последующей обработке).
На практике чаще используют проверку уже после выполнения запроса — в коде на встроенном языке:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если СтрНайти(Строка(Выборка.Номенклатура), "Объект не найден") > 0 Тогда
// битая ссылка — фиксируем или обрабатываем
КонецЕсли;
КонецЦикла;
У этого способа есть существенный минус: он зависит от локализации платформы и формата представления. В англоязычной поставке маркер будет другим («Object not found»), а сравнение строк — медленнее соединения на больших таблицах. Использовать его как основной метод поиска в запросе не стоит; он уместен как дополнительная проверка при обходе результата или как быстрый способ «увидеть глазами» проблемные строки в консоли.
Способ 3: проверка ссылочной целостности в конфигураторе
Если задача — не отфильтровать битые ссылки в конкретном запросе, а найти и устранить их во всей базе, правильнее использовать штатный механизм платформы: тестирование и исправление информационной базы. В конфигураторе откройте «Администрирование» → «Тестирование и исправление», отметьте проверку «Проверка ссылочной целостности информационной базы» и запустите.
Есть два режима. «Только тестирование» покажет список битых ссылок без изменений — это безопасный вариант для первичной диагностики. Режим «Тестирование и исправление» предложит варианты обработки: удалять объекты с битыми ссылками, очищать ссылки или не изменять. Для регистров сведений и накопления обычно применяется удаление записей, для реквизитов документов — очистка ссылки, но выбор зависит от прикладной логики.
Критическое ограничение: тестирование и исправление требует монопольного доступа к базе и может занять значительное время на больших объёмах. Перед запуском в режиме исправления обязательно сделайте резервную копию — операция необратима, и ошибочный выбор действия (например, удаление записей регистра вместо очистки ссылки) приведёт к потере данных.
Способ 4: типовые обработки и средства БСП
В конфигурациях на Библиотеке стандартных подсистем (БСП) есть готовые инструменты. Обработка «Поиск и удаление дублей» решает смежную задачу — она заменяет дублирующиеся ссылки на одну, но битые ссылки не чистит. Для битых ссылок в типовых решениях применяют регламентное тестирование или сторонние обработки с диска ИТС и инфостарта, которые обходят метаданные и проверяют все ссылочные поля автоматически.
Типовая обработка «Групповое изменение реквизитов» позволяет уже после поиска массово очистить или заменить найденные ссылки в документах и справочниках с контролем проведения и блокировок. Это безопаснее, чем прямая запись через код, потому что обработка выполняет изменения в транзакции и умеет показывать ошибки по каждому объекту.
Если пишете собственную обработку, универсальный приём — перебрать через метаданные все объекты со ссылочными реквизитами и для каждого реквизита выполнить запрос соединением из способа 1. Такой подход даёт полную картину по базе, но требует аккуратности с составными типами и большими таблицами: проверку лучше выполнять порциями и в нерабочее время.
Сравнение вариантов
Быстро и точно для одного известного поля. Не подходит для проверки всей базы сразу, нужно знать типы полей.
Просто для разовой диагностики в консоли. Зависит от локализации, медленно на больших выборках, ненадёжно в промышленном коде.
Проверяет всю базу штатными средствами. Требует монопольного доступа, копии и осторожного выбора действия исправления.
Полный контроль и автоматизация. Требует разработки, аккуратности с составными типами и нагрузкой на базу.
Битые ссылки в составных типах и NULL-значениях
Составной тип — самое частое место ошибок при поиске битых ссылок. Если реквизит может хранить ссылки на несколько таблиц (например, «Владелец» в присоединённых файлах), одного соединения недостаточно: нужно соединиться с каждой возможной таблицей и проверить, что хотя бы одно соединение состоялось. Битой считается ссылка, для которой ни одно соединение не дало результата, при этом само значение не NULL.
Отдельный нюанс — поля, допускающие NULL (например, измерения регистров при незаполненном значении). NULL — это не битая ссылка, а отсутствие значения, и смешивать эти случаи в одной выборке нельзя: иначе вы «найдёте» тысячи ложных битых ссылок и можете удалить корректные записи. Всегда добавляйте явное условие «И НЕ Поле ЕСТЬ NULL» и, при необходимости, исключайте пустые ссылки через сравнение с пустым значением конкретного типа.
Для полей типа «Характеристика.<План видов характеристик>» (типизированные дополнительные реквизиты) проверка сложнее: значение хранится в ресурсе регистра сведений и может ссылаться на разные справочники в зависимости от настройки вида характеристики. Здесь надёжнее проверять через приведение типа ВЫРАЗИТЬ и соединение с конкретной таблицей по каждому виду отдельно.
Проверка результата и безопасная очистка
После того как запрос нашёл кандидатов, не переходите сразу к удалению или замене. Сначала вручную проверьте несколько найденных ссылок: откройте запись в режиме предприятия или попробуйте получить объект через ПолучитьОбъект() в консоли кода — для битой ссылки будет возвращено значение, представление которого содержит «Объект не найден». Это подтвердит, что запрос настроен правильно и не захватывает лишнего.
Дальнейшие действия зависят от источника проблемы. Если битые ссылки появились после обмена — ищите причину в правилах конвертации и регистрации, иначе после чистки они появятся снова. Если после свёртки базы — проверьте, все ли регистры и документы обработаны. Если после прямого удаления объектов минуя контроль ссылочной целостности — настройте регламент: удаление объектов должно идти через пометку и штатное удаление помеченных, которое контролирует ссылки.
Сама очистка выполняется либо через тестирование и исправление, либо через групповое изменение реквизитов, либо программно — записью объекта с очищенным реквизитом. Программный вариант требует обхода в транзакциях разумного размера и обязательного обмена данными после: если база участвует в РИБ или синхронизации, изменения должны корректно уйти в другие узлы.
Как проверить результат
Выборка битых ссылок пуста
Ссылки остались — очистка не затронула часть записей или источник проблемы не устранён
Представление «<Объект не найден>» — диагноз подтверждён
Объект открывается нормально — запрос настроен неверно и захватывает корректные данные
Порядок цифр соответствует истории базы (обмены, свёртки)
Найдены тысячи записей без причины — вероятно, в выборку попали NULL-значения полей
FAQ
Почему условие ЕСТЬ NULL не находит битые ссылки?
Потому что битая ссылка — это не NULL, а вполне конкретное значение с GUID удалённого объекта. NULL возникает только при отсутствии значения в поле или при несостоявшемся соединении. Именно поэтому битые ссылки ищут через левое соединение с таблицей-владельцем: NULL появляется уже в полях присоединённой таблицы.
Можно ли найти битые ссылки во всей базе одним запросом?
Одним запросом — нет, потому что ссылочные поля разбросаны по десяткам таблиц с разными типами. Правильные варианты: штатная проверка ссылочной целостности в конфигураторе либо собственная обработка, которая перебирает метаданные и для каждого ссылочного реквизита выполняет отдельный запрос соединением.
Чем битая ссылка отличается от пустой ссылки?
Пустая ссылка — это штатное значение «ничего не выбрано», объект с таким GUID в таблице существует как служебный. Битая ссылка указывает на реально существовавший, но удалённый объект. В запросе их различают сравнением с ЗНАЧЕНИЕ(Тип.ПустаяСсылка): пустая ссылка отбору соответствует, битая — нет.
Опасно ли оставлять битые ссылки в базе?
Да. Они искажают отчёты (строки с «Объект не найден»), могут вызывать ошибки при обходе данных в коде, мешают обменам и свёртке. Кроме того, их наличие обычно означает, что в базе нарушен регламент удаления объектов — стоит найти и устранить источник.
Почему после чистки битые ссылки появляются снова?
Почти всегда причина в обмене данными: в одном узле объект удалили, а ссылка на него пришла из другого узла. Также возможны обработки, удаляющие объекты напрямую без контроля ссылок. Чистка без устранения источника даёт временный эффект — сначала разберитесь с правилами обмена и регламентом удаления.
Нужен ли монопольный режим для поиска битых ссылок запросом?
Для поиска запросом — нет, это обычное чтение данных. Монопольный доступ нужен только для тестирования и исправления в конфигураторе. Массовую программную очистку тоже лучше выполнять без активных пользователей, чтобы избежать блокировок, но формально она монопольного режима не требует.
Что важно запомнить
Битая ссылка не равна NULL и пустой ссылке — ищите её левым соединением с таблицей-владельцем и проверкой на NULL. Для всей базы используйте проверку ссылочной целостности, обязательно с копией и сначала в режиме тестирования. После чистки устраните источник проблемы, иначе ссылки появятся снова.