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

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

Ошибка «Объект не найден» в 1С: как проверить в запросе и исправить

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

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

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

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

Почему появляется «Объект не найден» и как это выглядит в данных

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

Типичные источники проблемы:

  • удаление объектов напрямую, минуя пометку удаления и контроль ссылочной целостности;
  • обмены данными (РИБ, обмен с сайтом, конвертация данных), когда документ пришёл, а справочник — нет;
  • загрузка из Excel или внешних систем с подстановкой ссылок «в лоб»;
  • аварийное завершение работы во время записи в файловой базе;
  • ошибки в самописных обработках, создающих ссылки через установку значения уникального идентификатора.

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

Проверка через соединение и ЕСТЬ NULL — основной способ

Самый надёжный приём — левое соединение таблицы, где хранится ссылка, с таблицей объекта. Если объекта нет, поля соединённой таблицы вернут NULL, и это легко отфильтровать.

ВЫБРАТЬ

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

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

ИЗ

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

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

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

ГДЕ

Реализация.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

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

Логика проста: соединение по ссылке находит запись только если объект существует. Если записи нет — все поля правой таблицы равны NULL, и условие «Контрагенты.Ссылка ЕСТЬ NULL» отбирает именно битые ссылки. Условие на непустую ссылку нужно, чтобы не ловить документы, где контрагент просто не заполнен: пустая ссылка — это нормальное состояние, а не ошибка.

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

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

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

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

Проверка через точку к реквизиту

Если обратиться через точку к любому реквизиту несуществующего объекта, запрос вернёт NULL. Это позволяет проверить ссылку без явного соединения:

ВЫБРАТЬ

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

ИЗ

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

ГДЕ

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

И Реализация.Контрагент <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)

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

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

В коде на встроенном языке битую ссылку можно определить по строковому представлению: у несуществующего объекта оно содержит «Объект не найден». В запросе функции представления нет, но в коде после выборки работает вариант:

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

// ссылка битая

КонецЕсли;

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

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

Соединение + ЕСТЬ NULL

Самый быстрый и надёжный, работает на больших объёмах. Требует знать конкретный тип ссылки.

Обращение через точку к реквизиту

Короче писать, но риск ложных срабатываний на составных типах полей.

Перебор с ПолучитьОбъект()

Точный, но медленный: оправдан только для небольших выборок или одиночных проверок.

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

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

Практический шаблон: соединить поле со всеми таблицами составного типа и отобрать строки, где все соединения дали NULL, а само поле не пустое и не NULL:

ВЫБРАТЬ

Регистр.Плательщик КАК Плательщик

ИЗ

РегистрСведений.Взаиморасчеты КАК Регистр

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

ПО Регистр.Плательщик = К.Ссылка

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

ПО Регистр.Плательщик = О.Ссылка

ГДЕ

НЕ Регистр.Плательщик ЕСТЬ NULL

И К.Ссылка ЕСТЬ NULL

И О.Ссылка ЕСТЬ NULL

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

Массовый поиск битых ссылок по всей базе

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

Первый — типовая обработка «Поиск и удаление дублей» не подходит, а вот штатный механизм «Удаление помеченных объектов» (раздел «Администрирование» → «Обслуживание») при полном контроле ссылочной целостности покажет все места использования удаляемых объектов и не даст создать новые битые ссылки. Это профилактика, а не лечение.

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

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

Как исправить найденные битые ссылки

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

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

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

Профилактика: как не допустить битых ссылок

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

В обменах данными включайте режим, при котором объекты не создаются по ссылкам автоматически без данных, и контролируйте очереди загрузки: сначала справочники, потом документы. В самописных загрузках проверяйте существование объекта перед записью ссылки на него.

Периодический аудит запросом из этой статьи (раз в месяц или после крупных обменов) позволяет поймать проблему раньше, чем она всплывёт в отчётах или у пользователей.

Типичные ошибки
01
Проверять битую ссылку сравнением с пустой ссылкой — битая ссылка не равна пустой, условие её не отберёт
02
Путать пометку удаления с битой ссылкой — помеченный объект существует и соединения с ним работают
03
Использовать обращение через точку для составного поля — получаем ложные NULL для существующих объектов другого типа
04
Удалять записи с битыми ссылками без копии и анализа — теряются проведённые документы и искажается учёт
05
Игнорировать значение NULL в составных полях — оно требует отдельной обработки, отличной от битых ссылок
Итог

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

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

Частые вопросы

Почему сравнение «Ссылка = Неопределено» не находит битые ссылки?

В языке запросов 1С нет значения Неопределено для ссылочных полей в том смысле, как в коде. Битая ссылка — это заполненное значение с конкретным идентификатором, поэтому равенство с пустой ссылкой или NULL его не отберёт. Нужна проверка существования записи через соединение.

Виден ли «Объект не найден» в результате запроса в консоли?

Да, консоль запросов покажет такое значение как «<Объект не найден> (…)» с идентификатором. Но если выгрузить результат в таблицу значений и работать в коде, надёжнее проверять через соединение или ПолучитьОбъект(), а не по строковому представлению.

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

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

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

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

Что делать, если битая ссылка появилась после обмена?

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

Как проверить одну конкретную ссылку в коде, без запроса?

Вызовите у ссылки метод ПолучитьОбъект(): если он вернул Неопределено — объект не существует. Для разовой проверки это самый простой способ, но массово применять его в цикле не стоит из-за производительности.