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

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

1С: как найти ссылки на объект программно

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

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

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

Метод НайтиПоСсылкам: синтаксис и результат

Метод вызывается как функция глобального контекста и принимает массив ссылок — можно искать сразу по нескольким объектам:

МассивСсылок = Новый Массив;

МассивСсылок.Добавить(ИскомаяСсылка);

ТаблицаСсылок = НайтиПоСсылкам(МассивСсылок);

Для Каждого Строка Из ТаблицаСсылок Цикл

Сообщить("Ссылка: " + Строка.Ссылка

+ " | Объект: " + Строка.Данные

+ " | Метаданные: " + Строка.Метаданные);

КонецЦикла;

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

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

Практический пример: проверка перед удалением

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

Функция ЕстьСсылкиНаОбъект(Ссылка)

МассивСсылок = Новый Массив;

МассивСсылок.Добавить(Ссылка);

ТаблицаСсылок = НайтиПоСсылкам(МассивСсылок);

Если ТаблицаСсылок.Количество() > 0 Тогда

Для Каждого Строка Из ТаблицаСсылок Цикл

Сообщить("Объект используется в: " + Строка.Данные);

КонецЦикла;

Возврат Истина;

КонецЕсли;

Возврат Ложь;

КонецФункции

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

Порядок действий при проверке перед удалением
  1. 1
    Сформируйте массив ссылок-кандидатов на удаление
  2. 2
    Вызовите НайтиПоСсылкам и получите таблицу использований
  3. 3
    Исключите из списка объекты, у которых найдены ссылки, или обработайте их отдельно
  4. 4
    Пометьте на удаление только объекты без ссылок
  5. 5
    Запустите штатное удаление помеченных объектов для контроля

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

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

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

|ИЗ

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

|ГДЕ

| РеализацияТоваровУслуг.Контрагент = &Контрагент";

Запрос.УстановитьПараметр("Контрагент", ИскомаяСсылка);

Результат = Запрос.Выполнить().Выгрузить();

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

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

НайтиПоСсылкам

Универсально, покрывает все метаданные автоматически. Медленнее на больших базах, нельзя фильтровать по условиям.

Запрос по конкретным таблицам

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

Обход метаданных с генерацией запросов

Автоматическое покрытие всех таблиц с контролем скорости. Сложнее в реализации, по сути повторяет логику НайтиПоСсылкам.

Типовые обработки (поиск дублей, удаление помеченных)

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

Обход метаданных своими руками

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

Для Каждого ДокументМета Из Метаданные.Документы Цикл

Для Каждого Реквизит Из ДокументМета.Реквизиты Цикл

Если Реквизит.Тип.СодержитТип(ТипЗнч(ИскомаяСсылка)) Тогда

// добавляем запрос по этой таблице в пакет

КонецЕсли;

КонецЦикла;

КонецЦикла;

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

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

Особенности и ограничения метода

У НайтиПоСсылкам есть границы, о которых нужно помнить. Ссылки в планах обмена (состав узлов) метод не возвращает как обычные данные. Значения, упакованные в ХранилищеЗначения, не анализируются. Строковые представления ссылок — тем более.

Производительность — второй момент. На объёмных базах вызов по большому массиву ссылок может выполняться долго и нагружать СУБД. Разумно разбивать массив на порции и выполнять поиск в фоновом задании, если речь о массовой обработке.

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

Частые ошибки при поиске ссылок

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

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

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

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

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

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

Полезно сверить количество найденных использований с интерактивной проверкой: в пользовательском режиме у многих объектов доступна команда «Ещё — Найти использование» (в типовых конфигурациях). Расхождение результатов — повод проверить код.

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

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

Заведомо используемый объект
Норма

Таблица содержит известные документы

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

Пустая таблица — проверьте тип и принадлежность ссылки

Колонка «Данные»
Норма

Значения открываются как реальные объекты базы

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

Неопределено или ошибки при обращении

Сравнение с интерактивным поиском
Норма

Наборы объектов совпадают

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

Расхождения — проверьте фильтры и права доступа

FAQ

Найдёт ли НайтиПоСсылкам ссылки в регистрах сведений?

Да. Метод анализирует измерения, ресурсы и реквизиты регистров сведений и накопления, если их тип включает тип искомой ссылки. В колонке «Данные» для регистров обычно возвращается ключ записи или набор записей.

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

Да, для этого метод и принимает массив. Пакетный вызов эффективнее, чем вызов в цикле по одной ссылке. Различать, к какому объекту относится найденное, помогает колонка «Ссылка» в результирующей таблице.

Почему НайтиПоСсылкам работает медленно на большой базе?

Метод проверяет все таблицы, где теоретически может встречаться ссылка. На объёмных базах это тяжёлая операция. Разбивайте массив на порции, выполняйте поиск в фоновом задании или заменяйте точечными запросами по известным таблицам.

Как найти ссылки, хранящиеся в виде строки GUID?

НайтиПоСсылкам их не обнаружит. Нужно отдельно искать по текстовым полям запросом с условием на строковое представление уникального идентификатора, полученное через XMLСтрока(Ссылка) или Ссылка.УникальныйИдентификатор().

Находит ли метод ссылки в помеченных на удаление объектах?

Да, пометка удаления не влияет на поиск. Если нужно оценить только актуальное использование, дополнительно проверяйте свойство ПометкаУдаления у найденных данных или отфильтровывайте их запросом.

Чем программный поиск отличается от штатного удаления помеченных объектов?

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

Итог

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

Основной инструмент — метод НайтиПоСсылкам с массивом ссылок на входе и таблицей «Ссылка / Данные / Метаданные» на выходе. Для известных таблиц быстрее точечные запросы. Перед удалением учитывайте помеченные объекты и обмены данными, а результат проверяйте на заведомо используемом объекте.