Top.Mail.Ru
Меню
Каталог Программы 1С Опыт и отзывы Услуги Компания Интересное Контакты

Как программно определить, битая ссылка или нет

Основатель и генеральный директор компании MoscowSoft, Сорокин Сергей
Сорокин Сергей, Генеральный директор MoscowSoft  11.06.2026 Актуальность проверена: 11.06.2026   5 мин.
Подобрать перенос данных 1С

Специализируемся на переносах данных 1С с 2015г.

Подобрать перенос данных 1С >>

Интеграция 1С с маркетплейсами

Специализируемся на интеграциях 1С с маркетплейсами с 2021г.

Изучить продукты >>

Содержание

Разработчикам иногда, и даже частенько, приходится разбираться, где потерялся объект, на который имеется ссылка в реквизите. Попытка перейти по ней заканчивается печальной фразой на экране «Объект не найден».

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

Определение, причины, последствия

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

  1. ошибки в отчетах;
  2. сбои в проводках;
  3. прерывание обмена данными;
  4. процесс обновления платформы или конфигурации происходит с ошибками.

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

Программный поиск для разработчиков не ограничивается одной конструкцией «Попытка ... Исключение» замедленного действия. Рассмотрим более скоростные и производительные методы.

Рекомендуем быстрый способ

Ускорение происходит за счет того, что не требуется загружать в машину весь объект (табличные части, движения). Достаточно прямо воспользоваться индексом базы данных.

Поиск битых ссылок с использованием запроса основывается на следующих допусках:

  1. во-первых, ссылка не пустая;
  2. во-вторых, не равняется Неопределено, то есть, переменной ничего не присвоено;
  3. в-третьих, обращение к реквизиту объекта выдает NULL (отсутствие значения в поле таблицы). При этом доподлинно известно, что реквизит в живом объекте обязательно был заполнен (например, дата, номер, имя владельца и т.д.).

Создаем функцию СсылкаСуществует, как на изображении кода:

&НаСервере
Функция СсылкаСуществует(ЛюбаяСсылка) Экспорт
	
	// Если ссылка пустая, то объекта заведомо нет в базе
	Если ЛюбаяСсылка.Пустая() Тогда
		Возврат Ложь;
	КонецЕсли;
	
	// Получаем полное имя метаданных. 
	// Можно использовать Метаданные.НайтиПоТипу(ТипЗнч(ЛюбаяСсылка)).ПолноеИмя, 
	// но использование СериализаторXDTO или XMLТипЗнч иногда работает быстрее.
	ТипСсылки = XMLТипЗнч(ЛюбаяСсылка);
	ИмяТаблицы = СтрЗаменить(ТипСсылки.ИмяТипа, "Ref.", ".");
	
	ТекстЗапроса = "ВЫБРАТЬ РАЗРЕШЕННЫЕ 
                   |    Ссылка 
                   |ИЗ 
                   |    [ИмяТаблицы] 
                   |ГДЕ 
                   |    Ссылка = &Ссылка";
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "[ИмяТаблицы]", ИмяТаблицы);
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("Ссылка", ЛюбаяСсылка);
	
	// Важно использовать привилегированный режим, чтобы RLS не скрыл существующий объект
	УстановитьПривилегированныйРежим(Истина);
	Результат = Запрос.Выполнить();
	УстановитьПривилегированныйРежим(Ложь);
	
	Возврат НЕ Результат.Пустой();
КонецФункции

Заметьте, насколько важно прописать в коде следующие условия:

  1. УстановитьПривилегированныйРежим(Истина);
  2. ВЫБРАТЬ РАЗРЕШЕННЫЕ.

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

ПолучитьОбъект() ― простой, но громоздкий метод

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

Прописываем Ссылка. Далее ПолучитьОбъект(). Вся запись ниже:

Если Ссылка.ПолучитьОбъект() = Неопределено Тогда
	Сообщить("Ссылка битая!");
КонецЕсли;

Как уже сказано выше, это длительный способ. Системе приходится тратить немало секунд на считывание из базы всех реквизитов, всех строк всех табличных частей, подготовку объекта к работе. На многострочный документ уйдет масса времени.

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

Как зависит производительность от проверки через реквизиты

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

// Это будет работать так же медленно, как ПолучитьОбъект()
Если ЗначениеЗаполнено(Ссылка.ВерсияДанных) Тогда 
	// Объект существует
КонецЕсли;

Проверка ссылки на ЕСТЬNULL

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

Запрос = Новый Запрос;
Запрос.Текст = 
	"ВЫБРАТЬ
    |   Док.Номенклатура КАК БитаяСсылка
    |ИЗ
    |   Документ.РеализацияТоваровУслуг.Товары КАК Док
    |ГДЕ
    |   Док.Ссылка = &Документ
    |   И Док.Номенклатура.Ссылка ЕСТЬ NULL"; 
// Обращение через точку к .Ссылка в условии ЕСТЬ NULL — классический прием 1С

Выбирая Док.Номенклатура Как БитаяСсылка и Док.Номенклатура.Ссылка ЕСТЬ NULL, следует ожидать, что Док.Номенклатура.Ссылка вернет NULL для всех найденных битых ссылок. Далее останется настроить фильтрацию и воспользоваться универсальной обработкой регистров сведений, чтобы мгновенно очистить базу от бесполезного и даже вредного содержимого.

Обращение к механизму навигационных ссылок

Далеко не всегда обязательно напрямую обращаться через внутренний запрос к соответствующей таблице СУБД. Можно воспользоваться механизмом навигационных ссылок. Они есть у каждого объекта в .

Функция ЭтоБитаяСсылкаНавигация(Ссылка)
	МассивСсылок = Новый Массив;
	МассивСсылок.Добавить(ПолучитьНавигационнуюСсылку(Ссылка));
	
	Представления = ПолучитьПредставленияНавигационныхСсылок(МассивСсылок);
	// Для битых ссылок Текст представления будет содержать GUID или специфическую строку
	Возврат Представления[0].Текст = "" ИЛИ СтрНайти(Представления[0].Текст, "Объект не найден") > 0;
КонецФункции

Не стоит забывать, что, начиная с версии «1С: Предприятие 8.2», на платформе есть тонкий клиент. На клиенте доступен один функционал, на сервере — другой. Способ с навигационными ссылками удобно применять в специфических сценариях на клиенте.

Используя сервер-соединение, лучше обращаться с запросом. Рекомендуется в случае, если имеется представление ссылки или УИДа в виде строки, которую надо сравнить с представлением в запросе. В поисковом коде прописывается подстрока «Объект не найден».

Голосуют цифры

Убедительнее всего за выбор того или иного метода говорят конкретные цифровые показатели. Замеряем скорость выполнения задачи, повторив 1000 итераций. И вот что имеем на выходе:

  • Выборка объектов ИБ с «битыми» ссылками с помощью запроса к таблице длится около 1,2 секунды. Обеспечивает стабильность.
  • Обращение к навигационным ссылкам ПолучитьПредставленияНавигационныхСсылок() в зависимости от кэша представлений решает задачу приблизительно за 0,9 секунды.
  • Метод ПолучитьОбъект() самый продолжительный. Для многострочных документов длительность от 25 до 40 секунд.
  • Идентичен по временным затратам с ПолучитьОбъект() способ «Обращение через точку (Ссылка.Код)». Также можно рассчитывать на время от 25 до 40 секунд.

Выводы и рекомендации

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

  1. Если нужно просто проверить наличие «битой» ссылки, не обращайтесь к малопродуктивным и долгим методам ПолучитьОбъект() и аналогичному способу «Обращение через точку (Ссылка.Код)». Эффективно сократит время обработка «удаление помеченных объектов с исключениями» с возможностью сохранять неудаляемые объекты, последовательно исключая их из списка.
  2. Функция на основе запроса служит универсальным методом поиска.
  3. Когда требуется не просто проверить право доступа к объекту, а убедиться в его физическом существовании в базе данных, надо установить Привилегированный режим проверки.
  4. Достаточно одного запроса с левым соединением, чтобы проверить большое количество данных, если использовать в запросе специальный оператор ЕСТЬ NULL. Он возвращает Истина, если значение действительно равно NULL. В остальных случаях будет Ложь.
  5. Сравнивайте между собой разные состояния: Ссылка.Пустая() (GUID выглядит как нули), а у «битой» ссылки уникальный идентификатор GUID имеется, но соответствующей записи в СУБД нет).
  6. При использовании метода ЗначениеЗаполнено() возвращается Истина для битой ссылки.

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

MoscowSoft логотип

Подпишитесь на телеграм-канал MoscowSoft!
QR-код (ссылка приглашение) в канал MoscowSoft

https://t.me/MoscowSoft

Публикуем:
- инструкции и советы по разработке на 1С;
- рекомендации по интеграции 1С;
- бесплатно делимся своими обработками;
- публикуем секретные спецпредложения только для подписчиков.

Возврат к списку