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

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

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

Как найти битые ссылки в 1С запросом: конструкция ЕСТЬ NULL, соединение с таблицами, примеры кода, проверка результатов и типичные ошибки при поиске.

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

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

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

Внутри базы ссылка хранится как уникальный идентификатор (GUID) плюс указание на таблицу. Пока объект существует, запрос по этой ссылке возвращает данные. Когда объект удалён физически, ссылка в других таблицах остаётся, но разыменовать её уже нельзя — платформа возвращает значение вида <Объект не найден> (123:8a9d00155d0a1a2b...).

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

Основной приём: левое соединение и условие ЕСТЬ NULL

Классический запрос для поиска битых ссылок в реквизите документа выглядит так. Берём таблицу, где хранится ссылка, присоединяем к ней таблицу-владельца по ссылке и отбираем строки, где присоединённая сторона пуста:

ВЫБРАТЬ

Реализация.Ссылка КАК Документ,

Реализация.Контрагент КАК БитаяСсылка

ИЗ

Документ.РеализацияТоваровУслуг КАК Реализация

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

ПО Реализация.Контрагент = Контрагенты.Ссылка

ГДЕ

Контрагенты.Ссылка ЕСТЬ NULL

И НЕ Реализация.Контрагент ЕСТЬ NULL

Второе условие НЕ Реализация.Контрагент ЕСТЬ NULL обязательно: без него в выборку попадут документы, где реквизит просто не заполнен. Пустая ссылка и битая ссылка — разные состояния, и смешивать их в одном отчёте не стоит, потому что действия по исправлению отличаются.

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

bsl
ВЫБРАТЬ РАЗЛИЧНЫЕ
    Т.Ссылка КАК Документ
ИЗ Документ.РеализацияТоваровУслуг КАК Т
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК К
    ПО Т.Контрагент = К.Ссылка
ГДЕ К.Ссылка ЕСТЬ NULL
    И НЕ Т.Контрагент ЕСТЬ NULL

Поиск битых ссылок в табличных частях и регистрах

В табличных частях документов битые ссылки встречаются чаще всего в колонках с товарами и договорами. Запрос строится аналогично, но таблицей-источником выступает табличная часть: Документ.РеализацияТоваровУслуг.Товары. Чтобы не получить дубли по строкам одного документа, используйте РАЗЛИЧНЫЕ или группировку по ссылке на документ.

Для регистров сведений и накопления подход тот же — соединение с таблицей-владельцем измерения или реквизита. Особый случай — регистры сведений с независимым режимом подчинения, где битая ссылка в измерении означает «мертвую» запись, которую пользователь не увидит в стандартных формах списка. Такие записи имеет смысл выводить отдельным списком с признаком «запись недоступна из интерфейса».

Проверка движений документов по регистрам требует осторожности: битая ссылка в измерении регистра накопления искажает итоги отчётов. Если отчёт по остаткам показывает строки с «Объект не найден», запрос по регистру с условием ЕСТЬ NULL покажет, какие именно документы-регистраторы привнесли эти записи.

Альтернативный способ: проверка через представление ссылки

Когда соединение недоступно (например, тип реквизита составной и заранее неизвестно, с какой таблицей соединяться), используют приём с функцией ПРЕДСТАВЛЕНИЕ. У битой ссылки представление начинается с фрагмента «Объект не найден»:

ВЫБРАТЬ

Т.Ссылка КАК Документ

ИЗ

Документ.РеализацияТоваровУслуг КАК Т

ГДЕ

ПРЕДСТАВЛЕНИЕ(Т.Контрагент) ПОДОБНО "%Объект не найден%"

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

Сравнение способов поиска

Левое соединение + ЕСТЬ NULL

Быстро и надёжно; требует точного указания таблицы-владельца, не подходит напрямую для составных типов

ПРЕДСТАВЛЕНИЕ + ПОДОБНО

Работает с любым типом без соединения; медленно на больших таблицах и зависит от текста представления

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

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

Составные типы и универсальная проверка

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

Для полного аудита базы писать запрос под каждый реквизит вручную нерационально. Практичный вариант — программный перебор метаданных: цикл по объектам метаданных, для каждого ссылочного реквизита динамически формируется текст запроса с соединением. Такую обработку запускают в привилегированном режиме, а результаты складывают в таблицу значений с колонками «Объект», «Реквизит», «Битая ссылка».

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

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

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

Полученный список — ещё не повод для массовой очистки. Перед любыми изменениями убедитесь, что ссылки действительно битые: выгрузите несколько значений и проверьте их в отдельном запросе по таблице-владельцу или через код Ссылки.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор(...)).ПолучитьОбъект() — у битой ссылки объект будет не найден.

Частая ошибка — путать битые ссылки с помеченными на удаление объектами. Помеченный объект существует, соединение с ним срабатывает, и условие ЕСТЬ NULL его не покажет. Если нужно найти ссылки на помеченные объекты (например, перед удалением помеченных), добавьте в соединение условие Контрагенты.ПометкаУдаления = ИСТИНА.

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

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

Что делать с найденными битыми ссылками

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

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

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

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

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

Повторный запрос с ЕСТЬ NULL
Норма

Выборка пуста

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

Строки остались — часть ссылок не обработана

Отчёты по регистрам
Норма

Нет строк с «Объект не найден»

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

Строки видны — битые ссылки в измерениях регистров

Проведение исправленных документов
Норма

Документ проводится без ошибок

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

Ошибки обязательных реквизитов — реквизит очищен, а не восстановлен

FAQ

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

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

Почему запрос с ЕСТЬ NULL не находит ссылку, которая в форме показывается как «Объект не найден»?

Чаще всего соединение выполнено не с той таблицей: у составного типа реквизита объект мог быть в другой таблице-владельце. Проверьте тип реквизита в конфигураторе и добавьте соединения со всеми возможными таблицами типа.

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

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

Найдёт ли битые ссылки стандартное тестирование и исправление?

Да, пункт «Проверка ссылочной целостности» в тестировании и исправлении находит все битые ссылки базы. Но он работает в монопольном режиме, проверяет всё подряд и не позволяет задать условия отбора, поэтому для точечной диагностики удобнее запрос.

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

Да, если делать это без анализа. Удаление записи регистра изменяет итоги отчётов: остатки и обороты пересчитаются. Сначала выгрузите найденные записи в файл или зафиксируйте их списком, затем выполняйте изменения и сверяйте контрольные итоги до и после.

Как по тексту «Объект не найден» узнать, что это был за объект?

В тексте после слов «Объект не найден» указан идентификатор вида (123:8a9d...). Шестнадцатеричная часть — это GUID объекта. По нему можно попытаться найти объект в архивной копии базы или в базе-источнике обмена, создав ссылку методом ПолучитьСсылку с этим уникальным идентификатором.

Итог

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

Битая ссылка находится запросом через левое соединение с таблицей-владельцем и условие ЕСТЬ NULL с обязательным исключением пустых ссылок. Перед исправлением зафиксируйте найденные GUID — по ним объекты иногда можно восстановить. После обработки повторите запрос: пустой результат — единственный признак решения проблемы.