Часто в процессе разработки прикладных решений на платформе 1С:Предприятие возникает задача динамического анализа структуры конфигурации. Одной из распространенных задач является поиск всех документов, в составе реквизитов или табличных частей которых присутствует определенный тип данных (например, СправочникСсылка.Валюты). Разберем, как реализовать такую задачу максимально эффективно.
Для решения поставленной задачи нам потребуется обратиться к объекту Метаданные. Платформа 1С позволяет программно перебирать коллекции объектов конфигурации. Основной инструмент для проверки того, подходит ли реквизит под наши критерии — это метод Тип.СодержитТип(). Этот метод универсален и отлично справляется даже с составными типами данных.
Рассмотрим пошагово, как построить обход всех документов конфигурации. Нам необходимо не только проверить реквизиты «шапки» документа, но и заглянуть в каждую табличную часть, так как там также могут находиться ссылки на интересующий нас тип.
Для чистоты кода и удобства отладки вынесем логику проверки типа в отдельную функцию. Это позволит избежать дублирования кода при переборе реквизитов шапки и реквизитов табличных частей.
Ниже представлен пример функции, которая проверяет коллекцию реквизитов на наличие заданного типа:
Функция КоллекцияСодержитПроверяемыйТип(Коллекция, ПроверяемыйТип)
Результат = Ложь;
Для Каждого Реквизит Из Коллекция Цикл
Если Реквизит.Тип.СодержитТип(ПроверяемыйТип) Тогда
Результат = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Теперь, когда у нас есть инструмент проверки, мы можем реализовать основной цикл. Важно помнить, что обход метаданных — операция ресурсоемкая, поэтому выполняйте её только тогда, когда это действительно необходимо (например, при инициализации формы или в специальных обработках).
Реализуем основной алгоритм:
Процедура ПолучитьСписокДокументовСТипом(ИскомыйТип, МассивРезультат)
ПроверяемыйТип = Тип(ИскомыйТип);
Для Каждого МетаданныеДок Из Метаданные.Документы Цикл
// Проверяем реквизиты шапки
Если КоллекцияСодержитПроверяемыйТип(МетаданныеДок.Реквизиты, ПроверяемыйТип) Тогда
МассивРезультат.Добавить(МетаданныеДок.Синоним);
Продолжить;
КонецЕсли;
// Если в шапке не нашли, проверяем табличные части
Для Каждого ТабличнаяЧасть Из МетаданныеДок.ТабличныеЧасти Цикл
Если КоллекцияСодержитПроверяемыйТип(ТабличнаяЧасть.Реквизиты, ПроверяемыйТип) Тогда
МассивРезультат.Добавить(МетаданныеДок.Синоним);
Прервать; // Документ нашли, переходим к следующему
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
При работе с данным кодом обратите внимание на следующие аспекты:
ПараметрыСеанса или используя временное хранилище.СодержитТип() корректно обрабатывает составные типы данных. Если реквизит может принимать значения нескольких типов, и один из них — искомый, платформа вернет Истина. Это избавляет от необходимости парсить строку типов вручную.Документы, но и в Справочники или РегистрыСведений, просто замените в цикле Метаданные.Документы на нужную коллекцию.Используя описанный метод, вы сможете гибко управлять списком документов в интерфейсе пользователя и предоставлять им только те данные, которые действительно содержат указанный тип ссылки.