При разработке сложных алгоритмов в 1С программисты часто сталкиваются с необходимостью формировать текст запроса динамически. Традиционный подход — конкатенация строк с использованием конструкций Если...Тогда или СтрЗаменить — часто превращает код в нечитаемый набор фрагментов, который невозможно открыть в стандартном конструкторе запросов. Начиная с версии платформы 8.3.5, разработчикам доступен альтернативный инструмент — СхемаЗапроса. В этой статье мы подробно разберем, как уйти от «рваных» запросов к объектной модели, проанализируем примеры кода и выясним все подводные камни этого подхода.
Рассмотрим стандартную ситуацию: вам нужно добавить условие в запрос только в том случае, если пользователь заполнил определенный параметр на форме. Обычно это выглядит так: код загромождается вызовами Запрос.Текст = Запрос.Текст + " ГДЕ ...". Проанализируем последствия:
Некоторые разработчики используют методику «ленивого программиста», вставляя логику прямо в текст запроса через оператор ВЫБОР. Проанализируем пример такой конструкции:
Выбор Когда &СотрудникЕсть Тогда
Сотрудник = &Сотрудник
Иначе
Истина
Конец
Такой запрос открывается конструктором, но он крайне неэффективен для СУБД, так как оптимизатор может некорректно построить план выполнения. Именно для решения этих проблем и была создана СхемаЗапроса.
СхемаЗапроса — это объект встроенного языка, который представляет структуру запроса в виде дерева объектов. Мы манипулируем не текстом, а коллекциями источников, полей и условий. Рассмотрим пошагово, как программно собрать запрос с нуля, используя эту модель.
Разберем детальный пример формирования пакета запросов:
// 1. Создание схемы запроса
СхемаЗапроса = Новый СхемаЗапроса;
// По умолчанию в новой схеме уже есть один пустой запрос в пакете
ЗапросВыбораИзИБ = СхемаЗапроса.ПакетЗапросов[0];
// 2. Настройка свойств первого запроса в пакете
ЗапросВыбораИзИБ.ТаблицаДляПомещения = "ТаблицаОбороты";
ЗапросВыбораИзИБ.ВыбиратьРазрешенные = Истина;
// 3. Работа с источниками данных
ОператорВыбораЗакупок = ЗапросВыбораИзИБ.Операторы[0];
ИсточникНоменклатура = ОператорВыбораЗакупок.Источники.Добавить("Справочник.Номенклатура", "Товары");
// Добавляем виртуальную таблицу и параметры к ней
ИсточникЗакупки = ОператорВыбораЗакупок.Источники.Добавить("РегистрНакопления.Закупки.Обороты", "Закупки");
ИсточникЗакупки.Источник.Параметры[0].Выражение = Новый ВыражениеСхемыЗапроса("&Начало");
ИсточникЗакупки.Источник.Параметры[1].Выражение = Новый ВыражениеСхемыЗапроса("&Окончание");
ИсточникЗакупки.Источник.Параметры[2].Выражение = Новый ВыражениеСхемыЗапроса("Месяц");
// 4. Управление соединениями (вместо написания "ЛЕВОЕ СОЕДИНЕНИЕ")
ИсточникЗакупки.Соединения[0].ТипСоединения = ТипСоединенияСхемыЗапроса.ПравоеВнешнее;
// 5. Выбор полей и назначение псевдонимов
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Товары.Ссылка");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("Закупки.Период");
ОператорВыбораЗакупок.ВыбираемыеПоля.Добавить("ЕСТЬNULL(Закупки.СуммаОборот, 0)");
ЗапросВыбораИзИБ.Колонки[0].Псевдоним = "Номенклатура";
ЗапросВыбораИзИБ.Колонки[1].Псевдоним = "Период";
ЗапросВыбораИзИБ.Колонки[2].Псевдоним = "СуммаЗакупок";
// 6. Динамическое добавление условий
ОператорВыбораЗакупок.Отбор.Добавить("НЕ Товары.ЭтоГруппа");
// 7. Получение готового текста запроса
ТекстЗапроса = СхемаЗапроса.ПолучитьТекстЗапроса();
Часто задача стоит иначе: есть базовый текст запроса, и в него нужно добавить одно условие или поле. С объектной моделью это сделать гораздо надежнее, чем через СтрЗаменить. Мы можем загрузить текст в схему, изменить её и выгрузить обратно.
Для этого используем метод УстановитьТекстЗапроса(). Выясним важный нюанс: при загрузке текста в схему 1С выполняет синтаксический разбор. Если в тексте запроса были ваши комментарии (строки начинающиеся с //), при выгрузке через ПолучитьТекстЗапроса() они будут удалены. Платформа полностью пересобирает текст по своим внутренним правилам. Для отладки и редактирования текста без потери комментариев можно использовать инженерную консоль запросов для 1С.
Проанализируем ситуацию объективно. Использование СхемаЗапроса — это не всегда «серебряная пуля».
Преимущества:
ВыражениеСхемыЗапроса, что позволяет избежать глупых опечаток в именах полей или таблиц.Недостатки:
СхемаЗапроса и парсинг текста могут быть избыточны.Рассмотрим рекомендации по применению данного инструмента в реальной практике:
В завершение отметим, что для простых и статичных запросов классический Конструктор запросов остается лучшим выбором. Объектную модель СхемаЗапроса стоит внедрять там, где сложность динамических условий начинает угрожать стабильности и понятности вашего кода.