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