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

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

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

Реализация универсальной функции отбора

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

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


Функция СтрОтборДействие(СправочникИмя, РеквизитОтбора = "Ссылка", ВидОтбора, ОсновноеЗначение, ДополнительноеЗначение = Неопределено) Экспорт
    УстановитьПривилегированныйРежим(Истина);
    МассивЭлементов = Новый Массив;
    
    // Инициализируем массив видов сравнения, требующих работы с интервалами
    МассивВидовИнтервал = Новый Массив;
    МассивВидовИнтервал.Добавить(ВидСравнения.Интервал);
    МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяГраницы);
    МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяНачало);
    МассивВидовИнтервал.Добавить(ВидСравнения.ИнтервалВключаяОкончание);

    // Подготовим имя для отбора, заменив точки на подчеркивания для корректной работы Построителя
    ИмяОтбора = СтрЗаменить(РеквизитОтбора, ".", "_");
    
    ЭтоВидИнтервала = МассивВидовИнтервал.Найти(ВидОтбора) <> Неопределено;

    // Создаем построитель запроса
    ТекстЗапроса = "ВЫБРАТЬ РАЗЛИЧНЫЕ
                   |    тСправочника.Ссылка КАК Ссылка
                   |ИЗ
                   |    Справочник." + СправочникИмя + " КАК тСправочника
                   |{ГДЕ
                   |    тСправочника." + РеквизитОтбора + ".* КАК " + ИмяОтбора + "}";

    ПостроительЗапросаДанных = Новый ПостроительЗапроса(ТекстЗапроса);

    // Добавляем отбор
    Попытка
        ОтборПоРеквизиту = ПостроительЗапросаДанных.Отбор.Добавить(ИмяОтбора);
    Исключение
        Возврат Неопределено;
    КонецПопытки;

    ОтборПоРеквизиту.ВидСравнения = ВидОтбора;
    ОтборПоРеквизиту.Использование = Истина;

    // Устанавливаем значения отбора в зависимости от типа
    Если ТипЗнч(ОтборПоРеквизиту.Значение) = Тип("СписокЗначений") Тогда
        ОтборПоРеквизиту.Значение.ЗагрузитьЗначения(ОсновноеЗначение);
    ИначеЕсли ЭтоВидИнтервала Тогда
        ОтборПоРеквизиту.ЗначениеС = ОсновноеЗначение;
        ОтборПоРеквизиту.ЗначениеПо = ДополнительноеЗначение;
    Иначе
        ОтборПоРеквизиту.Значение = ОсновноеЗначение;
    КонецЕсли;

    // Выполняем запрос
    ЗапросДанных = ПостроительЗапросаДанных.ПолучитьЗапрос();
    РезультатЗапроса = ЗапросДанных.Выполнить();
    
    Если НЕ РезультатЗапроса.Пустой() Тогда
        Выборка = РезультатЗапроса.Выбрать();
        Пока Выборка.Следующий() Цикл
            МассивЭлементов.Добавить(Выборка.Ссылка);
        КонецЦикла;
    КонецЕсли;

    Возврат МассивЭлементов;
КонецФункции

Особенности работы с табличными частями

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

  1. Именование параметров: Если вы передаете в качестве реквизита путь вида ТабличнаяЧасть.Реквизит, сам построитель может конфликтовать с точками в именах. Мы решили эту проблему, заменив точки в переменной ИмяОтбора на подчеркивания. Это позволяет ПостроителюЗапроса корректно интерпретировать поле отбора.
  2. Дублирование ссылок: При выборе данных из справочника через табличную часть, запрос может вернуть несколько строк для одного и того же элемента справочника (если в табличной части несколько записей подходят под условие). Использование ВЫБРАТЬ РАЗЛИЧНЫЕ в тексте запроса гарантирует, что в итоговом массиве мы получим только уникальные ссылки на элементы.
  3. Гибкость: Данная функция позволяет обращаться к реквизитам любого уровня вложенности (через точку), что делает её универсальным инструментом в рамках вашего проекта.

Рекомендации по развитию кода

Хотя ПостроительЗапроса — мощный инструмент для динамических задач, помните о современном подходе к разработке на платформе 1С:

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

← На главную