Как перенести отборы из СКД в текст обычного запроса?

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

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

Метод 1: Использование СКД как генератора макета

Самый простой способ, который приходит на ум — попытаться вытянуть готовый запрос из объекта МакетКомпоновкиДанных. Суть метода заключается в том, что мы просим систему собрать макет на основе настроек, а затем вытаскиваем текст запроса из набора данных.

Рассмотрим по шагам, как это выглядит программно:


Компоновщик = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = Компоновщик.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки());
НаборДанных = Макет.НаборыДанных[0];
ТекстЗапроса = НаборДанных.Запрос;

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

Метод 2: Выгрузка результата в таблицу значений (Рекомендуемый)

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

  1. Выполняем компоновку данных с заданными отборами через ПроцессорКомпоновкиДанных.
  2. Выгружаем результат в ТаблицаЗначений.
  3. Передаем полученную таблицу в метод Запрос.УстановитьПараметр().
  4. В тексте запроса используем конструкцию ПОМЕСТИТЬ ВременнаяТаблица.

Этот способ позволяет избежать необходимости «парсить» структуру отборов и гарантирует, что система применит условия ровно так, как это делает механизм СКД.

Метод 3: Рекурсивная генерация условий «ГДЕ»

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

Разберем логику построения такого генератора:

При реализации этого метода помните о сложностях:

  1. Разыменование полей: Если пользователь в отборе выбрал поле через точку, например Контрагент.ИНН, в вашем запросе должен существовать соответствующий источник данных, иначе запрос упадет с ошибкой.
  2. Виды сравнения: ВидСравненияКомпоновкиДанных сложнее, чем стандартные операторы =, <>, В. Вам придется прописать логику обработки для каждого случая, включая «В группе», «В списке», «Содержит» и прочие.

Подводя итог: если вы хотите избежать огромного количества повторяющегося кода и сложностей при поддержке, старайтесь использовать Метод 2 (Таблицы значений). Он наиболее универсален и надежен. Если же вы ограничены в ресурсах памяти или объеме передаваемых данных, используйте Метод 3, но будьте готовы уделить много времени тестированию логики обхода дерева отборов.

← На главную