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