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