Как найти все объекты, содержащие ссылку на определенную организацию или уникальный идентификатор

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование стандартной функции НайтиПоСсылкам

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

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


// Создаем массив с искомой ссылкой (например, конкретная организация)
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(СсылкаНаОрганизацию);

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

// Обходим результат
Для Каждого СтрокаРезультата Из ТаблицаСсылок Цикл
    // СтрокаРезультата.Данные - это ссылка на объект, который содержит нашу организацию
    // СтрокаРезультата.Метаданные - объект метаданных реквизита, где найдена ссылка
    Сообщить("Найдено в: " + СтрокаРезультата.Данные);
КонецЦикла;

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

Метод 2: Программный перебор метаданных

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

Разберем, как обойти метаданные и составить карту соответствий:


СписокОбъектовСТипом = Новый СписокЗначений;

// Перебираем все справочники
Для Каждого МетаданныеСправочника Из Метаданные.Справочники Цикл
    Для Каждого Реквизит Из МетаданныеСправочника.Реквизиты Цикл
        Если Реквизит.Тип.СодержитТип(Тип("СправочникСсылка.Организации")) Тогда
            СписокОбъектовСТипом.Добавить(МетаданныеСправочника.ПолноеИмя(), Реквизит.Имя);
        КонецЕсли;
    КонецЦикла;
    
    // Не забываем про табличные части
    Для Каждого ТЧ Из МетаданныеСправочника.ТабличныеЧасти Цикл
        Для Каждого РеквизитТЧ Из ТЧ.Реквизиты Цикл
            Если РеквизитТЧ.Тип.СодержитТип(Тип("СправочникСсылка.Организации")) Тогда
                СписокОбъектовСТипом.Добавить(МетаданныеСправочника.ПолноеИмя(), ТЧ.Имя + "." + РеквизитТЧ.Имя);
            КонецЕсли;
        КонецЦикла;
    КонецЦикла;
КонецЦикла;

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

Метод 3: Использование критериев отбора

Если задача поиска по организации в вашей конфигурации является регулярной, наиболее производительным решением будет использование объекта метаданных Критерий отбора. В типовых конфигурациях часто уже есть критерий Организация.

Посмотрим на преимущества этого подхода:

  1. Скорость: Платформа создает специальные индексные таблицы для критериев отбора, что делает поиск практически мгновенным.
  2. Удобство: Вы один раз в конфигураторе на вкладке "Состав" отмечаете все нужные реквизиты.
  3. Программный доступ: Вызов осуществляется одной строкой кода.

Пример использования критерия отбора:


// Получаем все объекты, связанные с организацией через критерий "СвязанныеОбъектыПоОрганизации"
ЗапросПоКритерию = КритерииОтбора.СвязанныеОбъектыПоОрганизации.Найти(СсылкаНаОрганизацию);
Для Каждого Объект Из ЗапросПоКритерию Цикл
    // Обрабатываем найденный объект
КонецЦикла;

Метод 4: Реализация в правилах конвертации данных (КД 2.1)

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

Проанализируем стратегию в обработчике Перед выгрузкой объекта:

  1. В параметрах конвертации создаем структуру или соответствие, где ключами будут имена объектов метаданных, а значениями — имена реквизитов, содержащих организацию.
  2. В ПКО (Правило конвертации объектов) в обработчике Перед выгрузкой пишем код проверки.

Пример кода в обработчике ПКО:


// Проверяем, есть ли у текущего объекта реквизит "Организация"
Если Объект.Метаданные().Реквизиты.Найти("Организация") <> Неопределено Тогда
    Если Объект.Организация <> Параметры.НужнаяОрганизация Тогда
        Отказ = Истина; // Не выгружаем объект чужой организации
    КонецЕсли;
КонецЕсли;

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

Метод 5: Поиск по уникальному идентификатору (UUID) в строковых полях

Иногда организация хранится не как ссылка, а как строка (GUID). В этом случае стандартный НайтиПоСсылкам() не поможет. Выясним, как найти такие вхождения. Для этого придется использовать запрос с оператором ПОДОБНО или полнотекстовый поиск.

Если мы используем БСП (Библиотеку стандартных подсистем), можно воспользоваться функцией проверки строки на соответствие формату UUID:


СтрокаGUID = "550e8400-e29b-41d4-a716-446655440000";
Если СтроковыеФункцииКлиентСервер.ЭтоУникальныйИдентификатор(СтрокаGUID) Тогда
    // Это валидный GUID, можем искать его в строковых реквизитах через запрос
КонецЕсли;

Рассмотрим пример запроса для поиска по строковому представлению идентификатора:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Т.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.ДополнительныеРеквизиты КАК Т
    |ГДЕ
    |   Т.ЗначениеСтрокой ПОДОБНО &ИскомыйGUID";

Запрос.УстановитьПараметр("ИскомыйGUID", "%" + СтрокаGUID + "%");
Результат = Запрос.Выполнить();

Метод 6: Инструментарий конфигуратора и типовые обработки

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

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

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

← На главную