Как программно наложить отборы компоновки данных на произвольный текст запроса?

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

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

Почему не стоит использовать свойство ВыраженияОтбораКомпоновкиДанныхСхемыЗапроса?

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

Реализация динамического отбора через СхемуЗапроса

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

Для начала, проанализируем настройки компоновки. Мы берем каждый элемент отбора, который установил пользователь, и формируем строку условия. Важно корректно обрабатывать вид сравнения, чтобы корректно сформировать текст условия в предложении ГДЕ.


// Пример формирования отбора для схемы запроса
Для Каждого ЭлементОтбора Из КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
    Если ЭлементОтбора.Использование Тогда
        ЛевоеЗначениеСтрока = Строка(ЭлементОтбора.ЛевоеЗначение);
        ИмяПараметра = "Параметр_" + СтрЗаменить(ЛевоеЗначениеСтрока, ".", "_");
        
        // Формируем элемент отбора в схеме запроса
        СхемаЗапроса.Пакеты[0].Операторы[0].Отбор.Добавить(
            Новый ВыражениеСхемыЗапроса(
                ВыражениеСтрокой(ЭлементОтбора.ВидСравнения, ЛевоеЗначениеСтрока, "&" + ИмяПараметра)
            )
        );
    КонецЕсли;
КонецЦикла;

В результате выполнения этого кода, к вашему исходному запросу автоматически добавится условие вида: ГДЕ Номенклатура = &Параметр_Номенклатура.

Управление параметрами запроса

Основная сложность, с которой сталкиваются разработчики при таком подходе — это потеря параметров. Когда мы добавляем текст &ИмяПараметра в схему, объект Запрос ничего не знает об этих параметрах, пока мы их не установим явно. Для решения этой задачи выполним следующие действия:

  1. При добавлении выражения в СхемуЗапроса, мы параллельно сохраняем соответствие между именем параметра и его значением, полученным из ЭлементОтбора.ПравоеЗначение.
  2. После формирования итогового текста запроса из схемы (через СхемаЗапроса.ПолучитьТекстЗапроса()), мы создаем объект Запрос.
  3. Переносим накопленные значения параметров из нашего соответствия непосредственно в объект Запрос.УстановитьПараметр().

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

Особенности и советы

Разберем несколько важных моментов, которые помогут избежать ошибок при реализации:

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

← На главную