Как динамически изменить текст запроса в 1С в зависимости от условия

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

При разработке отчетов и механизмов выборки данных часто возникает задача динамического изменения структуры запроса в зависимости от условий или переданных параметров. Например, требуется изменить секцию ИТОГИ ПО, сгруппировать данные по разным полям или переключить сортировку.

Разберем основные ограничения платформы 1С:Предприятие при работе с запросами, а также рассмотрим все доступные практические способы решения этой задачи.

Ограничение параметров запроса

Прежде чем приступать к формированию условий, выясним важную особенность платформы: параметры запроса (передаваемые через метод УстановитьПараметр() и обозначаемые символом &) передаются в СУБД исключительно как константы или значения выражений.

Параметры нельзя использовать вместо структурных элементов запроса:

  1. Имен таблиц и полей.
  2. Условий соединений таблиц.
  3. Секций СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО и ИТОГИ ПО.

Поэтому простая передача имени поля через параметр внутри секции итогов вызовет синтаксическую ошибку. Для решения задачи требуется динамически менять сам текст запроса либо использовать специализированные объекты платформы.

Способ 1. Конкатенация строк

Проанализируем базовый и наиболее распространенный метод — склеивание строк текста запроса в зависимости от логических условий в коде 1С.

Посмотрим на пример реализации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗаказПокупателя.Ссылка КАК Ссылка,
    |	ЗаказПокупателя.Номер КАК НомерЗаказ,
    |	ЗаказПокупателя.Дата КАК ДатаЗаказ,
    |	ЗаказПокупателя.СуммаДокумента КАК Сумма
    |ИЗ
    |	Документ.ЗаказПокупателя КАК ЗаказПокупателя
    |УПОРЯДОЧИТЬ ПО
    |	ДатаЗаказ";

Если ГруппироватьПоНомерам Тогда
    Запрос.Текст = Запрос.Текст + "
    |ИТОГИ
    |	СУММА(Сумма)
    |ПО
    |	НомерЗаказ";
Иначе
    Запрос.Текст = Запрос.Текст + "
    |ИТОГИ
    |	СУММА(Сумма)
    |ПО
    |	ДатаЗаказ";
КонецЕсли;

Результат = Запрос.Выполнить();

Способ 2. Подстановка через СтрЗаменить или СтрШаблон

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

Посмотрим на пример с использованием функции СтрЗаменить:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Заказ.Номер КАК НомерЗаказ,
    |	Заказ.Дата КАК ДатаЗаказ,
    |	Заказ.Сумма КАК Сумма
    |ИЗ
    |	Документ.ЗаказПокупателя КАК Заказ
    |ИТОГИ
    |	СУММА(Сумма)
    |ПО
    |	#ПолеИтогов";

ПолеИтога = ?(ГруппироватьПоНомерам, "НомерЗаказ", "ДатаЗаказ");
Запрос.Текст = СтрЗаменить(Запрос.Текст, "#ПолеИтогов", ПолеИтога);

Результат = Запрос.Выполнить();

Также для форматирования строк удобно использовать системную функцию СтрШаблон(), которая повышает читаемость кода при подстановке нескольких фрагментов.

Способ 3. Программное изменение через объект СхемаЗапроса

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

Посмотрим на пример работы со схемой:


Схема = Новый СхемаЗапроса;
Схема.УстановитьТекстЗапроса(БазовыйТекстЗапроса);

Выборка = Схема.ПакетЗапросов[0];

// Очищаем коллекцию итогов и добавляем нужное измерение
Выборка.КонтрольныеТочкиИтогов.Очистить();
Если ГруппироватьПоНомерам Тогда
    Выборка.Итоги.Добавить("НомерЗаказ");
Иначе
    Выборка.Итоги.Добавить("ДатаЗаказ");
КонецЕсли;

Запрос = Новый Запрос;
Запрос.Текст = Схема.ПолучитьТекстЗапроса();
Результат = Запрос.Выполнить();

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

Альтернатива: Система компоновки данных (СКД)

Если задача заключается в формировании отчета с динамическими группировками, полями и итогами, оптимальным стандартом платформы 1С является использование Системы компоновки данных. Через КомпоновщикНастроек разработчик или пользователь может включать и отключать любые группировки, а платформа автоматически сформирует оптимальный SQL-запрос только с необходимыми соединениями и полями.

← На главную